aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2025-01-30 14:35:30 -0600
committerTom Rini <trini@konsulko.com>2025-01-30 14:35:30 -0600
commitac3eeb154257f422d87c3e4ad5414c350238c3b9 (patch)
tree327e4678e280abc5d809a19bfd1ae7b4bcf28f78
parent5e46a06950a9bc6a4e70e20b90a903fe55eca025 (diff)
parentc80a3fb96135394d4724bbd2c887c8a372b8f5ee (diff)
downloadu-boot-ac3eeb154257f422d87c3e4ad5414c350238c3b9.tar.gz
Merge patch series "Add support for MediaTek MT7987 SoC"WIP/30Jan2025
Weijie Gao <weijie.gao@mediatek.com> says: This patch series add support for MediaTek MT7987 SoC with its reference boards and related drivers. This patch series add basic boot support on eMMC/SD/SPI-NOR/SPI-NAND for these boards. The clock, pinctrl drivers and the SoC initializaton code are also included. Link: https://lore.kernel.org/r/cover.1737621362.git.weijie.gao@mediatek.com
-rw-r--r--arch/arm/dts/mt7987-emmc.dtsi50
-rw-r--r--arch/arm/dts/mt7987-netsys-u-boot.dtsi51
-rw-r--r--arch/arm/dts/mt7987-pinctrl-u-boot.dtsi146
-rw-r--r--arch/arm/dts/mt7987-pinctrl.dtsi200
-rw-r--r--arch/arm/dts/mt7987-sd.dtsi37
-rw-r--r--arch/arm/dts/mt7987.dtsi808
-rw-r--r--arch/arm/dts/mt7987a-emmc-rfb-u-boot.dtsi61
-rw-r--r--arch/arm/dts/mt7987a-emmc-rfb.dts37
-rw-r--r--arch/arm/dts/mt7987a-rfb-u-boot.dtsi71
-rw-r--r--arch/arm/dts/mt7987a-rfb.dts34
-rw-r--r--arch/arm/dts/mt7987a-sd-rfb-u-boot.dtsi59
-rw-r--r--arch/arm/dts/mt7987a-sd-rfb.dts37
-rw-r--r--arch/arm/dts/mt7987a-u-boot.dtsi66
-rw-r--r--arch/arm/dts/mt7987a.dtsi96
-rw-r--r--arch/arm/mach-mediatek/Kconfig19
-rw-r--r--arch/arm/mach-mediatek/Makefile2
-rw-r--r--arch/arm/mach-mediatek/mt7987/Makefile4
-rw-r--r--arch/arm/mach-mediatek/mt7987/init.c62
-rw-r--r--arch/arm/mach-mediatek/mt7987/lowlevel_init.S30
-rw-r--r--arch/arm/mach-mediatek/tzcfg.c242
-rw-r--r--board/mediatek/mt7987/MAINTAINERS8
-rw-r--r--board/mediatek/mt7987/Makefile3
-rw-r--r--board/mediatek/mt7987/mt7987_rfb.c10
-rw-r--r--configs/mt7987_emmc_rfb_defconfig91
-rw-r--r--configs/mt7987_rfb_defconfig87
-rw-r--r--configs/mt7987_sd_rfb_defconfig91
-rw-r--r--drivers/clk/mediatek/Makefile1
-rw-r--r--drivers/clk/mediatek/clk-mt7987.c848
-rw-r--r--drivers/mmc/mtk-sd.c21
-rw-r--r--drivers/pinctrl/mediatek/Kconfig4
-rw-r--r--drivers/pinctrl/mediatek/Makefile1
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mt7987.c736
-rw-r--r--include/configs/mt7987.h14
-rw-r--r--include/dt-bindings/clock/mediatek,mt7987-clk.h206
34 files changed, 4230 insertions, 3 deletions
diff --git a/arch/arm/dts/mt7987-emmc.dtsi b/arch/arm/dts/mt7987-emmc.dtsi
new file mode 100644
index 00000000000..80ab04d9d20
--- /dev/null
+++ b/arch/arm/dts/mt7987-emmc.dtsi
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+
+#include "mt7987-pinctrl.dtsi"
+
+/ {
+ 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;
+ };
+};
+
+/* Disable spi0/spi1 node since MSDC shares pins with spi0 and spi1*/
+&spi0 {
+ status = "disabled";
+};
+
+&spi1 {
+ status = "disabled";
+};
+
+&mmc0 {
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&mmc_pins_default>;
+ pinctrl-1 = <&mmc_pins_uhs>;
+ bus-width = <8>;
+ max-frequency = <200000000>;
+ cap-mmc-highspeed;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ hs400-ds-delay = <0x12814>;
+ vqmmc-supply = <&reg_1p8v>;
+ vmmc-supply = <&reg_3p3v>;
+ non-removable;
+ no-sd;
+ no-sdio;
+ status = "okay";
+};
diff --git a/arch/arm/dts/mt7987-netsys-u-boot.dtsi b/arch/arm/dts/mt7987-netsys-u-boot.dtsi
new file mode 100644
index 00000000000..3d6640b33ab
--- /dev/null
+++ b/arch/arm/dts/mt7987-netsys-u-boot.dtsi
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2025 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+#include <dt-bindings/clock/mediatek,mt7987-clk.h>
+#include <dt-bindings/reset/mt7988-reset.h>
+
+&netsys {
+ eth0: ethernet@15110100 {
+ compatible = "mediatek,mt7987-eth", "syscon";
+ reg = <0 0x15100000 0 0x20000>;
+ mediatek,gmac-id = <0>;
+ mediatek,ethsys = <&ethsys>;
+ mediatek,sgmiisys = <&sgmiisys0>;
+ mediatek,infracfg = <&topmisc>;
+ resets = <&ethsys ETHDMA_FE_RST>;
+ reset-names = "fe";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ eth1: ethernet@15110200 {
+ compatible = "mediatek,mt7987-eth", "syscon";
+ reg = <0 0x15100000 0 0x20000>;
+ mediatek,gmac-id = <1>;
+ mediatek,ethsys = <&ethsys>;
+ mediatek,infracfg = <&topmisc>;
+ resets = <&ethsys ETHDMA_FE_RST>;
+ reset-names = "fe";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ eth2: ethernet@15110300 {
+ compatible = "mediatek,mt7987-eth", "syscon";
+ reg = <0 0x15100000 0 0x20000>;
+ mediatek,gmac-id = <2>;
+ mediatek,ethsys = <&ethsys>;
+ mediatek,sgmiisys = <&sgmiisys1>;
+ mediatek,infracfg = <&topmisc>;
+ resets = <&ethsys ETHDMA_FE_RST>;
+ reset-names = "fe";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/dts/mt7987-pinctrl-u-boot.dtsi b/arch/arm/dts/mt7987-pinctrl-u-boot.dtsi
new file mode 100644
index 00000000000..991f38efef9
--- /dev/null
+++ b/arch/arm/dts/mt7987-pinctrl-u-boot.dtsi
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2025 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/mt65xx.h>
+
+&pio {
+ /delete-node/ mmc-pins-default;
+ /delete-node/ mmc-pins-uhs;
+ /delete-node/ sd-pins-default;
+ /delete-node/ sd-pins-uhs;
+ /delete-node/ spi0-pins;
+ /delete-node/ spi2-pins;
+
+ mmc_pins_default: mmc0default {
+ mux {
+ function = "flash";
+ groups = "emmc_45";
+ };
+
+ conf-cmd-dat {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO",
+ "SPI0_CS", "SPI0_HOLD", "SPI0_WP",
+ "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO";
+ input-enable;
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
+ };
+
+ conf-clk {
+ pins = "SPI1_CS";
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
+ };
+
+ conf-rst {
+ pins = "USB_VBUS";
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
+ };
+ };
+
+ mmc_pins_uhs: mmc-pins-uhs {
+ mux {
+ function = "flash";
+ groups = "emmc_45";
+ };
+ conf-cmd-dat {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO",
+ "SPI0_CS", "SPI0_HOLD", "SPI0_WP",
+ "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO";
+ input-enable;
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
+ };
+ conf-clk {
+ pins = "SPI1_CS";
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
+ };
+ conf-rst {
+ pins = "USB_VBUS";
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
+ };
+ };
+
+ sd_pins_default: sd-pins-default {
+ mux {
+ function = "flash";
+ groups = "sd";
+ };
+ conf-cmd-dat {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO",
+ "SPI0_CS", "SPI1_MISO";
+ input-enable;
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
+ };
+ conf-clk {
+ pins = "SPI1_CS";
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
+ };
+ };
+
+ sd_pins_uhs: sd-pins-uhs {
+ mux {
+ function = "flash";
+ groups = "sd";
+ };
+ conf-cmd-dat {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO",
+ "SPI0_CS", "SPI1_MISO";
+ input-enable;
+ drive-strength = <MTK_DRIVE_4mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>; /* pull-up 10K */
+ };
+ conf-clk {
+ pins = "SPI1_CS";
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>; /* pull-down 50K */
+ };
+ };
+
+ spi0_flash_pins: spi0-pins {
+ mux {
+ function = "spi";
+ groups = "spi0", "spi0_wp_hold";
+ };
+
+ conf-pu {
+ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+ };
+
+ conf-pd {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
+ };
+ };
+
+ spi2_flash_pins: spi2-pins {
+ mux {
+ function = "spi";
+ groups = "spi2", "spi2_wp_hold";
+ };
+
+ conf-pu {
+ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
+ };
+
+ conf-pd {
+ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
+ };
+ };
+};
diff --git a/arch/arm/dts/mt7987-pinctrl.dtsi b/arch/arm/dts/mt7987-pinctrl.dtsi
new file mode 100644
index 00000000000..b5e643feffe
--- /dev/null
+++ b/arch/arm/dts/mt7987-pinctrl.dtsi
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+&pio {
+ mmc_pins_default: mmc-pins-default {
+ mux {
+ function = "flash";
+ groups = "emmc_45";
+ };
+ conf-cmd-dat {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO",
+ "SPI0_CS", "SPI0_HOLD", "SPI0_WP",
+ "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO";
+ input-enable;
+ drive-strength = <MTK_DRIVE_4mA>;
+ mediatek,pull-up-adv = <1>; /* pull-up 10K */
+ };
+ conf-clk {
+ pins = "SPI1_CS";
+ drive-strength = <MTK_DRIVE_6mA>;
+ mediatek,pull-down-adv = <2>; /* pull-down 50K */
+ };
+ conf-rst {
+ pins = "USB_VBUS";
+ drive-strength = <MTK_DRIVE_4mA>;
+ mediatek,pull-up-adv = <1>; /* pull-up 10K */
+ };
+ };
+
+ mmc_pins_uhs: mmc-pins-uhs {
+ mux {
+ function = "flash";
+ groups = "emmc_45";
+ };
+ conf-cmd-dat {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO",
+ "SPI0_CS", "SPI0_HOLD", "SPI0_WP",
+ "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO";
+ input-enable;
+ drive-strength = <MTK_DRIVE_4mA>;
+ mediatek,pull-up-adv = <1>; /* pull-up 10K */
+ };
+ conf-clk {
+ pins = "SPI1_CS";
+ drive-strength = <MTK_DRIVE_6mA>;
+ mediatek,pull-down-adv = <2>; /* pull-down 50K */
+ };
+ conf-rst {
+ pins = "USB_VBUS";
+ drive-strength = <MTK_DRIVE_4mA>;
+ mediatek,pull-up-adv = <1>; /* pull-up 10K */
+ };
+ };
+
+ sd_pins_default: sd-pins-default {
+ mux {
+ function = "flash";
+ groups = "sd";
+ };
+ conf-cmd-dat {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO",
+ "SPI0_CS", "SPI1_MISO";
+ input-enable;
+ drive-strength = <MTK_DRIVE_4mA>;
+ mediatek,pull-up-adv = <1>; /* pull-up 10K */
+ };
+ conf-clk {
+ pins = "SPI1_CS";
+ drive-strength = <MTK_DRIVE_6mA>;
+ mediatek,pull-down-adv = <2>; /* pull-down 50K */
+ };
+ };
+
+ sd_pins_uhs: sd-pins-uhs {
+ mux {
+ function = "flash";
+ groups = "sd";
+ };
+ conf-cmd-dat {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO",
+ "SPI0_CS", "SPI1_MISO";
+ input-enable;
+ drive-strength = <MTK_DRIVE_4mA>;
+ mediatek,pull-up-adv = <1>; /* pull-up 10K */
+ };
+ conf-clk {
+ pins = "SPI1_CS";
+ drive-strength = <MTK_DRIVE_6mA>;
+ mediatek,pull-down-adv = <2>; /* pull-down 50K */
+ };
+ };
+
+ mdio0_pins: mdio0-pins {
+ mux {
+ function = "eth";
+ groups = "mdc_mdio";
+ };
+
+ conf {
+ groups = "mdc_mdio";
+ drive-strength = <MTK_DRIVE_6mA>;
+ };
+ };
+
+ i2p5gbe_led0_pins: i2p5gbe0-pins {
+ mux {
+ function = "led";
+ groups = "2p5gbe_led0";
+ };
+ };
+
+ i2p5gbe_led1_0_pins: i2p5gbe1-pins {
+ mux {
+ function = "led";
+ groups = "2p5gbe_led1_0";
+ };
+ };
+
+ i2p5gbe_led1_1_pins: i2p5gbe2-pins {
+ mux {
+ function = "led";
+ groups = "2p5gbe_led1_1";
+ };
+ };
+
+ i2c0_pins: i2c0-pins-g2 {
+ mux {
+ function = "i2c";
+ groups = "i2c0_2";
+ };
+ };
+
+ pcie0_pins: pcie0-pins {
+ mux {
+ function = "pcie";
+ groups = "pcie0_pereset", "pcie0_clkreq",
+ "pcie0_wake";
+ };
+ };
+
+ pcie1_pins: pcie1-pins {
+ mux {
+ function = "pcie";
+ groups = "pcie1_pereset", "pcie1_clkreq",
+ "pcie1_wake";
+ };
+ };
+
+ spi0_flash_pins: spi0-pins {
+ mux {
+ function = "spi";
+ groups = "spi0", "spi0_wp_hold";
+ };
+ };
+
+ spic_pins: spi1-pins {
+ mux {
+ function = "spi";
+ groups = "spi1";
+ };
+ };
+
+ spi2_flash_pins: spi2-pins {
+ mux {
+ function = "spi";
+ groups = "spi2", "spi2_wp_hold";
+ };
+ };
+
+ i2c1_pins: i2c1-pins {
+ mux {
+ function = "i2c";
+ groups = "i2c0_2";
+ };
+ };
+
+ i2s_pins: i2s-pins {
+ mux {
+ function = "i2s";
+ groups = "pcm0_1";
+ };
+ };
+
+ pcm_pins: pcm-pins {
+ mux {
+ function = "pcm";
+ groups = "pcm0_1";
+ };
+ };
+
+ uart1_pins: uart1-pins {
+ mux {
+ function = "uart";
+ groups = "uart1_2";
+ };
+ };
+};
diff --git a/arch/arm/dts/mt7987-sd.dtsi b/arch/arm/dts/mt7987-sd.dtsi
new file mode 100644
index 00000000000..4c8ca48c293
--- /dev/null
+++ b/arch/arm/dts/mt7987-sd.dtsi
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+#include "mt7987-pinctrl.dtsi"
+
+/ {
+ 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;
+ };
+};
+
+/* Disable spi0/spi1 node since MSDC shares pins with spi0 and spi1*/
+&spi0 {
+ status = "disabled";
+};
+
+&spi1 {
+ status = "disabled";
+};
+
+&mmc0 {
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&sd_pins_default>;
+ pinctrl-1 = <&sd_pins_uhs>;
+ bus-width = <4>;
+ max-frequency = <50000000>;
+ cap-sd-highspeed;
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&reg_3p3v>;
+ no-mmc;
+ no-sdio;
+ status = "okay";
+};
diff --git a/arch/arm/dts/mt7987.dtsi b/arch/arm/dts/mt7987.dtsi
new file mode 100644
index 00000000000..fd1585f658d
--- /dev/null
+++ b/arch/arm/dts/mt7987.dtsi
@@ -0,0 +1,808 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/reset/ti-syscon.h>
+#include <dt-bindings/clock/mediatek,mt7987-clk.h>
+#include <dt-bindings/pinctrl/mt65xx.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
+#include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
+
+/ {
+ compatible = "mediatek,mt7987";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ clkxtal: oscillator@0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <40000000>;
+ clock-output-names = "clkxtal";
+ };
+
+ vproc: regulator-vproc {
+ compatible = "regulator-fixed";
+ regulator-name = "proc";
+ regulator-min-microvolt = <8500000>;
+ regulator-max-microvolt = <8500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ firmware {
+ optee {
+ method = "smc";
+ compatible = "linaro,optee-tz";
+ status = "okay";
+ };
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ enable-method = "psci";
+ next-level-cache = <&l2_cache>;
+ reg = <0x0>;
+ clocks = <&mcusys CLK_MCU_BUS_DIV_SEL>,
+ <&topckgen CLK_TOP_CB_CKSQ_40M>,
+ <&apmixedsys CLK_APMIXED_ARM_LL>;
+ clock-names = "cpu", "intermediate", "armpll";
+ operating-points-v2 = <&cluster0_opp>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ enable-method = "psci";
+ next-level-cache = <&l2_cache>;
+ reg = <0x1>;
+ clocks = <&mcusys CLK_MCU_BUS_DIV_SEL>,
+ <&topckgen CLK_TOP_CB_CKSQ_40M>,
+ <&apmixedsys CLK_APMIXED_ARM_LL>;
+ clock-names = "cpu", "intermediate", "armpll";
+ operating-points-v2 = <&cluster0_opp>;
+ };
+
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ enable-method = "psci";
+ next-level-cache = <&l2_cache>;
+ reg = <0x2>;
+ clocks = <&mcusys CLK_MCU_BUS_DIV_SEL>,
+ <&topckgen CLK_TOP_CB_CKSQ_40M>,
+ <&apmixedsys CLK_APMIXED_ARM_LL>;
+ clock-names = "cpu", "intermediate", "armpll";
+ operating-points-v2 = <&cluster0_opp>;
+ };
+
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53";
+ enable-method = "psci";
+ next-level-cache = <&l2_cache>;
+ reg = <0x3>;
+ clocks = <&mcusys CLK_MCU_BUS_DIV_SEL>,
+ <&topckgen CLK_TOP_CB_CKSQ_40M>,
+ <&apmixedsys CLK_APMIXED_ARM_LL>;
+ clock-names = "cpu", "intermediate", "armpll";
+ operating-points-v2 = <&cluster0_opp>;
+ };
+
+ cluster0_opp: opp_table0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+ opp00 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <850000>;
+ };
+ opp01 {
+ opp-hz = /bits/ 64 <1300000000>;
+ opp-microvolt = <850000>;
+ };
+ opp02 {
+ opp-hz = /bits/ 64 <1600000000>;
+ opp-microvolt = <850000>;
+ };
+ opp03 {
+ opp-hz = /bits/ 64 <2000000000>;
+ opp-microvolt = <850000>;
+ };
+ };
+
+ l2_cache: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ };
+ };
+
+ clk40m: clk40m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <40000000>;
+ };
+
+ clkitg: clkitg {
+ compatible = "simple-bus";
+ status = "disabled";
+ };
+
+ clksys: soc_clksys {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "simple-bus";
+ ranges;
+
+ infracfg: infracfg@10001000 {
+ compatible = "mediatek,mt7987-infracfg", "syscon";
+ reg = <0 0x10001000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ topckgen: topckgen@1001b000 {
+ compatible = "mediatek,mt7987-topckgen", "syscon";
+ reg = <0 0x1001b000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ apmixedsys: apmixedsys@1001e000 {
+ compatible = "mediatek,mt7987-apmixedsys", "syscon";
+ reg = <0 0x1001e000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ sgmiisys0: syscon@10060000 {
+ compatible = "mediatek,mt7987-sgmiisys",
+ "mediatek,mt7987-sgmiisys_0",
+ "syscon";
+ reg = <0 0x10060000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ sgmiisys1: syscon@10070000 {
+ compatible = "mediatek,mt7987-sgmiisys",
+ "mediatek,mt7987-sgmiisys_1",
+ "syscon";
+ reg = <0 0x10070000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ mcusys: mcusys@10400000 {
+ compatible = "mediatek,mt7987-mcusys", "syscon";
+ reg = <0 0x10400000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ ethsys: syscon@15000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mediatek,mt7987-ethdma",
+ "mediatek,mt7987-ethsys",
+ "syscon";
+ reg = <0 0x15000000 0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ ethsysrst: reset-controller {
+ compatible = "ti,syscon-reset";
+ #reset-cells = <1>;
+ ti,reset-bits =
+ <0x34 4 0x34 4 0x34 4
+ (ASSERT_SET | DEASSERT_CLEAR |
+ STATUS_SET)>;
+ };
+ };
+ };
+
+ fan: pwm-fan {
+ compatible = "pwm-fan";
+ cooling-levels = <0 128 255>;
+ #cooling-cells = <2>;
+ #thermal-sensor-cells = <1>;
+ status = "disabled";
+ };
+
+ pmu: pmu {
+ compatible = "arm,cortex-a53-pmu";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ wmcpu_emi: wmcpu-reserved@50000000 {
+ compatible = "mediatek,wmcpu-reserved";
+ no-map;
+ reg = <0 0x50000000 0 0x00100000>;
+ };
+ };
+
+ thermal-zones {
+ thermal_zone0: soc_thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <1000>;
+ thermal-sensors = <&lvts 0>;
+ trips {
+ cpu_trip_crit: crit {
+ temperature = <125000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+
+ cpu_trip_hot: hot {
+ temperature = <120000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ cpu_trip_active1: active1 {
+ temperature = <115000>;
+ hysteresis = <2000>;
+ type = "active";
+ };
+
+ cpu_trip_active0: active0 {
+ temperature = <85000>;
+ hysteresis = <2000>;
+ type = "active";
+ };
+
+ cpu_trip_passive: passive {
+ temperature = <40000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ };
+
+ cooling-maps {
+ cpu-active-high {
+ cooling-device = <&fan 2 2>;
+ trip = <&cpu_trip_active1>;
+ };
+
+ cpu-active-low {
+ cooling-device = <&fan 1 1>;
+ trip = <&cpu_trip_active0>;
+ };
+
+ cpu-passive {
+ cooling-device = <&fan 0 0>;
+ trip = <&cpu_trip_passive>;
+ };
+ };
+ };
+
+ thermal_zone1: mcusys_thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <1000>;
+ thermal-sensors = <&lvts 1>;
+ };
+
+ thermal_zone2: eth2p5g_thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <1000>;
+ thermal-sensors = <&lvts 2>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ soc: soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "simple-bus";
+ ranges;
+
+ hwver: hwver@8000000 {
+ compatible = "mediatek,hwver", "syscon";
+ reg = <0 0x8000000 0 0x1000>;
+ };
+
+ gic: interrupt-controller@c000000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ interrupt-controller;
+ reg = <0 0x0c000000 0 0x40000>, /* GICD */
+ <0 0x0c080000 0 0x200000>, /* GICR */
+ <0 0x0c400000 0 0x2000>, /* GICC */
+ <0 0x0c410000 0 0x1000>, /* GICH */
+ <0 0x0c420000 0 0x2000>; /* GICV */
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ infra_bus_prot: infra_bus_prot@1000310c {
+ compatible = "mediatek,infracfg_ao_bus_hang_prot";
+ reg = <0 0x1000310c 0 0x14>;
+ status = "disabled";
+ };
+
+ watchdog: watchdog@1001c000 {
+ compatible = "mediatek,mt7622-wdt",
+ "mediatek,mt6589-wdt",
+ "syscon";
+ reg = <0 0x1001c000 0 0x1000>;
+ interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ #reset-cells = <1>;
+ status = "disabled";
+ };
+
+ pio: pinctrl@1001f000 {
+ compatible = "mediatek,mt7987-pinctrl";
+ reg = <0 0x1001f000 0 0x1000>,
+ <0 0x11d00000 0 0x1000>,
+ <0 0x11e00000 0 0x1000>,
+ <0 0x11f00000 0 0x1000>,
+ <0 0x11f40000 0 0x1000>,
+ <0 0x11f60000 0 0x1000>,
+ <0 0x1000b000 0 0x1000>;
+ reg-names = "gpio", "iocfg_rb", "iocfg_lb", "iocfg_rt1",
+ "iocfg_rt2", "iocfg_tl", "eint";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pio 0 0 50>;
+ interrupt-controller;
+ interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <2>;
+
+ pcie1pereset {
+ gpio-hog;
+ gpios = <36 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
+ };
+
+ boottrap: boottrap@1001f6f0 {
+ compatible = "mediatek,boottrap";
+ reg = <0 0x1001f6f0 0 0x20>;
+ status = "disabled";
+ };
+
+ trng: trng@1020f000 {
+ compatible = "mediatek,mt7987-rng";
+ status = "disabled";
+ };
+
+ pwm: pwm@10048000 {
+ compatible = "mediatek,mt7988-pwm";
+ reg = <0 0x10048000 0 0x1000>;
+ #pwm-cells = <2>;
+ clocks = <&infracfg CLK_INFRA_66M_PWM_BCK>,
+ <&infracfg CLK_INFRA_66M_PWM_HCK>,
+ <&clkxtal>,
+ <&clkxtal>,
+ <&clkxtal>,
+ <&clkxtal>,
+ <&clkxtal>,
+ <&clkxtal>,
+ <&clkxtal>,
+ <&clkxtal>;
+ clock-names = "top", "main", "pwm1", "pwm2", "pwm3",
+ "pwm4","pwm5","pwm6","pwm7","pwm8";
+ status = "disabled";
+ };
+
+ uart0: serial@11000000 {
+ compatible = "mediatek,mt7986-uart",
+ "mediatek,mt6577-uart";
+ reg = <0 0x11000000 0 0x100>;
+ interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg CLK_INFRA_52M_UART0_CK>,
+ <&infracfg CLK_INFRA_66M_UART0_PCK>;
+ clock-names = "baud", "bus";
+ assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
+ <&infracfg CLK_INFRA_MUX_UART0_SEL>;
+ assigned-clock-parents = <&topckgen
+ CLK_TOP_CB_CKSQ_40M>,
+ <&topckgen CLK_TOP_UART_SEL>;
+ status = "disabled";
+ };
+
+ uart1: serial@11000100 {
+ compatible = "mediatek,mt7986-uart",
+ "mediatek,mt6577-uart";
+ reg = <0 0x11000100 0 0x100>;
+ interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg CLK_INFRA_52M_UART1_CK>,
+ <&infracfg CLK_INFRA_66M_UART1_PCK>;
+ clock-names = "baud", "bus";
+ assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
+ <&infracfg CLK_INFRA_MUX_UART1_SEL>;
+ assigned-clock-parents = <&topckgen
+ CLK_TOP_CB_CKSQ_40M>,
+ <&topckgen CLK_TOP_UART_SEL>;
+ status = "disabled";
+ };
+
+ uart2: serial@11000200 {
+ compatible = "mediatek,mt7986-uart",
+ "mediatek,mt6577-uart";
+ reg = <0 0x11000200 0 0x100>;
+ interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg CLK_INFRA_52M_UART2_CK>,
+ <&infracfg CLK_INFRA_66M_UART2_PCK>;
+ clock-names = "baud", "bus";
+ assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
+ <&infracfg CLK_INFRA_MUX_UART2_SEL>;
+ assigned-clock-parents = <&topckgen
+ CLK_TOP_CB_CKSQ_40M>,
+ <&topckgen CLK_TOP_UART_SEL>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@11003000 {
+ compatible = "mediatek,mt7988-i2c",
+ "mediatek,mt7981-i2c";
+ reg = <0 0x11003000 0 0x1000>,
+ <0 0x10217080 0 0x80>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+ clock-div = <1>;
+ clocks = <&infracfg CLK_INFRA_I2C_BCK>,
+ <&infracfg CLK_INFRA_66M_AP_DMA_BCK>;
+ clock-names = "main", "dma";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spi0: spi@11007800 {
+ compatible = "mediatek,ipm-spi-quad",
+ "mediatek,spi-ipm";
+ reg = <0 0x11007800 0 0x100>;
+ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&topckgen CLK_TOP_CB_M_D2>,
+ <&topckgen CLK_TOP_SPI_SEL>,
+ <&infracfg CLK_INFRA_104M_SPI0>,
+ <&infracfg CLK_INFRA_66M_SPI0_HCK>;
+ assigned-clocks = <&topckgen CLK_TOP_SPI_SEL>,
+ <&infracfg CLK_INFRA_MUX_SPI0_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D2>,
+ <&topckgen CLK_TOP_SPI_SEL>;
+ clock-names = "parent-clk", "sel-clk", "spi-clk",
+ "hclk";
+ status = "disabled";
+ };
+
+ spi1: spi@11008800 {
+ compatible = "mediatek,ipm-spi-single",
+ "mediatek,spi-ipm";
+ reg = <0 0x11008800 0 0x100>;
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&topckgen CLK_TOP_CB_M_D2>,
+ <&topckgen CLK_TOP_SPI_SEL>,
+ <&infracfg CLK_INFRA_104M_SPI1>,
+ <&infracfg CLK_INFRA_66M_SPI1_HCK>;
+ assigned-clocks = <&topckgen CLK_TOP_SPIM_MST_SEL>,
+ <&infracfg CLK_INFRA_MUX_SPI1_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D2>,
+ <&topckgen
+ CLK_TOP_SPIM_MST_SEL>;
+ clock-names = "parent-clk", "sel-clk", "spi-clk",
+ "hclk";
+ status = "disabled";
+ };
+
+ spi2: spi@11009800 {
+ compatible = "mediatek,ipm-spi-quad",
+ "mediatek,spi-ipm";
+ reg = <0 0x11009800 0 0x100>;
+ interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&topckgen CLK_TOP_CB_M_D2>,
+ <&topckgen CLK_TOP_SPI_SEL>,
+ <&infracfg CLK_INFRA_104M_SPI2_BCK>,
+ <&infracfg CLK_INFRA_66M_SPI2_HCK>;
+ assigned-clocks = <&topckgen CLK_TOP_SPI_SEL>,
+ <&infracfg
+ CLK_INFRA_MUX_SPI2_BCK_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D2>,
+ <&topckgen CLK_TOP_SPI_SEL>;
+ clock-names = "parent-clk", "sel-clk", "spi-clk",
+ "hclk";
+ status = "disabled";
+ };
+
+ lvts: lvts@1100a000 {
+ compatible = "mediatek,mt7987-lvts";
+ #thermal-sensor-cells = <1>;
+ reg = <0 0x1100a000 0 0x1000>;
+ clocks = <&infracfg CLK_INFRA_26M_THERM_SYSTEM>;
+ clock-names = "lvts_clk";
+ nvmem-cells = <&lvts_calibration>;
+ nvmem-cell-names = "e_data1";
+ status = "disabled";
+ };
+
+ usbtphy: usb-phy@11c50000 {
+ compatible = "mediatek,mt7987",
+ "mediatek,generic-tphy-v2";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ tphyu2port0: usb-phy@11c50000 {
+ reg = <0 0x11c50000 0 0x700>;
+ clocks = <&infracfg CLK_INFRA_USB_UTMI_CK_P1>;
+ clock-names = "ref";
+ #phy-cells = <1>;
+
+ auto_load_valid;
+ nvmem-cells = <&u2_intr_p0>,
+ <&u2_auto_load_valid_p0>;
+ nvmem-cell-names = "intr", "auto_load_valid";
+ };
+
+ tphyu3port0: usb-phy@11c50700 {
+ reg = <0 0x11c50700 0 0x900>;
+ clocks = <&infracfg CLK_INFRA_USB_PIPE_CK_P1>;
+ clock-names = "ref";
+ #phy-cells = <1>;
+
+ auto_load_valid;
+ nvmem-cells = <&comb_intr_p0>,
+ <&comb_rx_imp_p0>,
+ <&comb_tx_imp_p0>,
+ <&comb_auto_load_valid>;
+ nvmem-cell-names = "intr", "rx_imp", "tx_imp",
+ "auto_load_valid";
+
+ /* MT7987: 4'b0010 default USB30
+ * Don't change the '0'
+ */
+ mediatek,syscon-type = <&topmisc 0x218 0>;
+
+ status = "disabled";
+ };
+ };
+
+ xhci: xhci@11200000 {
+ compatible = "mediatek,mt7987-xhci",
+ "mediatek,mtk-xhci";
+ reg = <0 0x11200000 0 0x2e00>,
+ <0 0x11203e00 0 0x0100>;
+ reg-names = "mac", "ippc";
+ interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+ usb2-lpm-disable;
+ status = "disabled";
+ };
+
+ afe: audio-controller@11210000 {
+ compatible = "mediatek,mt79xx-audio";
+ reg = <0 0x11210000 0 0x9000>;
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg CLK_INFRA_66M_AUD_SLV_BCK>,
+ <&infracfg CLK_INFRA_AUD_26M>,
+ <&infracfg CLK_INFRA_AUD_L>,
+ <&infracfg CLK_INFRA_AUD_AUD>,
+ <&infracfg CLK_INFRA_AUD_EG2>,
+ <&topckgen CLK_TOP_AUD_SEL>,
+ <&topckgen CLK_TOP_AUD_I2S_M>;
+ clock-names = "aud_bus_ck",
+ "aud_26m_ck",
+ "aud_l_ck",
+ "aud_aud_ck",
+ "aud_eg2_ck",
+ "aud_sel",
+ "aud_i2s_m";
+ assigned-clocks = <&topckgen CLK_TOP_AUD_SEL>,
+ <&topckgen CLK_TOP_A1SYS_SEL>,
+ <&topckgen CLK_TOP_AUD_L_SEL>,
+ <&topckgen CLK_TOP_A_TUNER_SEL>;
+ assigned-clock-parents = <&apmixedsys
+ CLK_APMIXED_APLL2>,
+ <&topckgen
+ CLK_TOP_CB_APLL2_D4>,
+ <&apmixedsys
+ CLK_APMIXED_APLL2>,
+ <&topckgen
+ CLK_TOP_CB_APLL2_D4>;
+ status = "disabled";
+ };
+
+ mmc0: mmc@11230000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "mediatek,mt7986-mmc";
+ reg = <0 0x11230000 0 0x1000>,
+ <0 0x11f50000 0 0x1000>;
+ interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&topckgen CLK_TOP_EMMC_200M_SEL>,
+ <&infracfg CLK_INFRA_MSDC400>,
+ <&infracfg CLK_INFRA_133M_MSDC_0_HCK>,
+ <&infracfg CLK_INFRA_MSDC2_HCK>,
+ <&infracfg CLK_INFRA_MSDC200_SRC>,
+ <&infracfg CLK_INFRA_66M_MSDC_0_HCK>;
+ clock-names = "source", "bus_clk", "axi_cg", "hclk",
+ "source_cg", "ahb_cg";
+ status = "disabled";
+ };
+
+ wed: wed {
+ compatible = "mediatek,wed";
+ wed_num = <1>;
+ };
+
+ wed0: wed0@15010000 {
+ compatible = "mediatek,wed0";
+ /* add this property for wed get the pci slot number */
+ pci_slot_map = <0>;
+ reg = <0 0x15010000 0 0x2000>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ wdma: wdma@15104800 {
+ compatible = "mediatek,wed-wdma";
+ reg = <0 0x15104800 0 0x400>;
+ };
+
+ pcie0: pcie@11280000 {
+ compatible = "mediatek,mt7988-pcie",
+ "mediatek,mt7987-pcie",
+ "mediatek,mt7986-pcie";
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ reg = <0 0x11280000 0 0x2000>;
+ reg-names = "pcie-mac";
+ linux,pci-domain = <0>;
+ interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+ bus-range = <0x00 0xff>;
+ ranges = <0x81000000 0x00 0x20000000 0x00
+ 0x20000000 0x00 0x00200000>,
+ <0x82000000 0x00 0x20200000 0x00
+ 0x20200000 0x00 0x0fe00000>;
+ clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P0>,
+ <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P0>,
+ <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P0>,
+ <&infracfg CLK_INFRA_133M_PCIE_CK_P0>;
+ clock-names = "pl_250m", "tl_26m", "peri_26m",
+ "top_133m";
+ status = "disabled";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &pcie_intc2 0>,
+ <0 0 0 2 &pcie_intc2 1>,
+ <0 0 0 3 &pcie_intc2 2>,
+ <0 0 0 4 &pcie_intc2 3>;
+ pcie_intc2: interrupt-controller {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+
+ pcie1: pcie@11290000 {
+ compatible = "mediatek,mt7988-pcie",
+ "mediatek,mt7987-pcie",
+ "mediatek,mt7986-pcie";
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ reg = <0 0x11290000 0 0x2000>;
+ reg-names = "pcie-mac";
+ linux,pci-domain = <1>;
+ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+ bus-range = <0x00 0xff>;
+ ranges = <0x81000000 0x00 0x30000000 0x00
+ 0x30000000 0x00 0x00200000>,
+ <0x82000000 0x00 0x30200000 0x00
+ 0x30200000 0x00 0x0fe00000>;
+ clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P1>,
+ <&infracfg CLK_INFRA_PCIE_GFMUX_TL_P1>,
+ <&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P1>,
+ <&infracfg CLK_INFRA_133M_PCIE_CK_P1>;
+ clock-names = "pl_250m", "tl_26m", "peri_26m",
+ "top_133m";
+ status = "disabled";
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &pcie_intc1 0>,
+ <0 0 0 2 &pcie_intc1 1>,
+ <0 0 0 3 &pcie_intc1 2>,
+ <0 0 0 4 &pcie_intc1 3>;
+ pcie_intc1: interrupt-controller {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ slot1: pcie@0,0 {
+ reg = <0x0000 0 0 0 0>;
+ };
+ };
+
+ topmisc: topmisc@10021000 {
+ compatible = "mediatek,mt7987-topmisc", "syscon",
+ "mediatek,mt7987-power-controller";
+ reg = <0 0x10021000 0 0x10000>;
+ #clock-cells = <1>;
+ #power-domain-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /* power domain of the SoC */
+ /* eth2p5@MT7988_POWER_DOMAIN_ETH2P5 {
+ * reg = <MT7988_POWER_DOMAIN_ETH2P5>;
+ * #power-domain-cells = <0>;
+ * };
+ */
+ };
+
+ efuse: efuse@11d30000 {
+ compatible = "mediatek,efuse";
+ reg = <0 0x11d30000 0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ lvts_calibration: calib@918 {
+ reg = <0x918 0x10>;
+ };
+
+ comb_auto_load_valid: usb3-alv-imp@8ee {
+ reg = <0x8ee 1>;
+ bits = <0 1>;
+ };
+
+ comb_rx_imp_p0: usb3-rx-imp@8ec {
+ reg = <0x8ec 1>;
+ bits = <0 5>;
+ };
+
+ comb_tx_imp_p0: usb3-tx-imp@8ec {
+ reg = <0x8ec 2>;
+ bits = <5 5>;
+ };
+
+ comb_intr_p0: usb3-intr@8ec {
+ reg = <0x8ec 2>;
+ bits = <10 6>;
+ };
+
+ u2_auto_load_valid_p0: usb2-alv-p0@8cc {
+ reg = <0x8cc 1>;
+ bits = <0 1>;
+ };
+
+ u2_intr_p0: usb2-intr-p0@8cc {
+ reg = <0x8cc 1>;
+ bits = <1 5>;
+ };
+ };
+
+ devapc: devapc@1a110000 {
+ compatible = "mediatek,mt7987-devapc";
+ reg = <0 0x1a110000 0 0x1000>;
+ interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ netsys: soc_netsys {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "simple-bus";
+ ranges;
+ };
+};
diff --git a/arch/arm/dts/mt7987a-emmc-rfb-u-boot.dtsi b/arch/arm/dts/mt7987a-emmc-rfb-u-boot.dtsi
new file mode 100644
index 00000000000..54cf72b3bf8
--- /dev/null
+++ b/arch/arm/dts/mt7987a-emmc-rfb-u-boot.dtsi
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "mt7987a-u-boot.dtsi"
+#include "mt7987-netsys-u-boot.dtsi"
+
+/ {
+ model = "mt7987";
+ compatible = "mediatek,mt7987", "mediatek,mt7987-emmc-rfb";
+};
+
+&eth0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio0_pins>;
+ phy-mode = "2500base-x";
+ mediatek,switch = "auto";
+ reset-gpios = <&pio 42 GPIO_ACTIVE_HIGH>;
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc_pins_default>;
+ max-frequency = <48000000>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ cap-mmc-hw-reset;
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&reg_3p3v>;
+ non-removable;
+ status = "okay";
+};
+
+&spi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_flash_pins>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ must_tx;
+ enhance_timing;
+ dma_ext;
+ ipm_design;
+ support_quad;
+ tick_dly = <2>;
+ sample_sel = <0>;
+
+ /delete-node/ spi_nor@0;
+ spi_nor@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <52000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <4>;
+ };
+};
diff --git a/arch/arm/dts/mt7987a-emmc-rfb.dts b/arch/arm/dts/mt7987a-emmc-rfb.dts
new file mode 100644
index 00000000000..f59e5bd97bf
--- /dev/null
+++ b/arch/arm/dts/mt7987a-emmc-rfb.dts
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+/dts-v1/;
+#include "mt7987a.dtsi"
+#include "mt7987-emmc.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "MediaTek MT7987 EMMC RFB";
+ compatible = "mediatek,mt7987a-emmc",
+ "mediatek,mt7987a", "mediatek,mt7987";
+
+ chosen {
+ bootargs = "console=ttyS0,115200n1 loglevel=8 \
+ earlycon=uart8250,mmio32,0x11000000 \
+ pci=pcie_bus_perf ubi.block=0,firmware \
+ root=/dev/fit0 rootwait";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&pio 1 GPIO_ACTIVE_LOW>;
+ debounce-interval = <10>;
+ };
+
+ wps {
+ label = "wps";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&pio 0 GPIO_ACTIVE_LOW>;
+ debounce-interval = <10>;
+ };
+ };
+};
diff --git a/arch/arm/dts/mt7987a-rfb-u-boot.dtsi b/arch/arm/dts/mt7987a-rfb-u-boot.dtsi
new file mode 100644
index 00000000000..f1ed51e21c4
--- /dev/null
+++ b/arch/arm/dts/mt7987a-rfb-u-boot.dtsi
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include "mt7987a-u-boot.dtsi"
+#include "mt7987-netsys-u-boot.dtsi"
+
+&eth0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio0_pins>;
+ phy-mode = "2500base-x";
+ mediatek,switch = "auto";
+ reset-gpios = <&pio 42 GPIO_ACTIVE_HIGH>;
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_flash_pins>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ must_tx;
+ enhance_timing;
+ dma_ext;
+ ipm_design;
+ support_quad;
+ tick_dly = <2>;
+ sample_sel = <0>;
+
+ /delete-node/ spi_nand@0;
+ spi_nand@0 {
+ compatible = "spi-nand";
+ reg = <0>;
+ spi-max-frequency = <52000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <4>;
+ };
+};
+
+&spi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_flash_pins>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ must_tx;
+ enhance_timing;
+ dma_ext;
+ ipm_design;
+ support_quad;
+ tick_dly = <2>;
+ sample_sel = <0>;
+
+ /delete-node/ spi_nor@0;
+ spi_nor@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <52000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <4>;
+ };
+};
diff --git a/arch/arm/dts/mt7987a-rfb.dts b/arch/arm/dts/mt7987a-rfb.dts
new file mode 100644
index 00000000000..0ba6b8d9ad7
--- /dev/null
+++ b/arch/arm/dts/mt7987a-rfb.dts
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+/dts-v1/;
+#include "mt7987a.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "MediaTek MT7987A RFB";
+ compatible = "mediatek,mt7987a", "mediatek,mt7987";
+
+ chosen {
+ bootargs = "console=ttyS0,115200n1 loglevel=8 \
+ earlycon=uart8250,mmio32,0x11000000 \
+ pci=pcie_bus_perf";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&pio 1 GPIO_ACTIVE_LOW>;
+ debounce-interval = <10>;
+ };
+
+ wps {
+ label = "wps";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&pio 0 GPIO_ACTIVE_LOW>;
+ debounce-interval = <10>;
+ };
+ };
+};
diff --git a/arch/arm/dts/mt7987a-sd-rfb-u-boot.dtsi b/arch/arm/dts/mt7987a-sd-rfb-u-boot.dtsi
new file mode 100644
index 00000000000..b07e6da41e2
--- /dev/null
+++ b/arch/arm/dts/mt7987a-sd-rfb-u-boot.dtsi
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "mt7987a-u-boot.dtsi"
+#include "mt7987-netsys-u-boot.dtsi"
+
+/ {
+ model = "mt7987";
+ compatible = "mediatek,mt7987", "mediatek,mt7987-sd-rfb";
+};
+
+&eth0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio0_pins>;
+ phy-mode = "2500base-x";
+ mediatek,switch = "auto";
+ reset-gpios = <&pio 42 GPIO_ACTIVE_HIGH>;
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd_pins_default>;
+ max-frequency = <48000000>;
+ bus-width = <4>;
+ cap-sd-highspeed;
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&spi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_flash_pins>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+ must_tx;
+ enhance_timing;
+ dma_ext;
+ ipm_design;
+ support_quad;
+ tick_dly = <2>;
+ sample_sel = <0>;
+
+ /delete-node/ spi_nor@0;
+ spi_nor@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <52000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <4>;
+ };
+};
diff --git a/arch/arm/dts/mt7987a-sd-rfb.dts b/arch/arm/dts/mt7987a-sd-rfb.dts
new file mode 100644
index 00000000000..85de4990682
--- /dev/null
+++ b/arch/arm/dts/mt7987a-sd-rfb.dts
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+/dts-v1/;
+#include "mt7987a.dtsi"
+#include "mt7987-sd.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "MediaTek MT7987 SD RFB";
+ compatible = "mediatek,mt7987a-sd",
+ "mediatek,mt7987a", "mediatek,mt7987";
+
+ chosen {
+ bootargs = "console=ttyS0,115200n1 loglevel=8 \
+ earlycon=uart8250,mmio32,0x11000000 \
+ pci=pcie_bus_perf ubi.block=0,firmware \
+ root=/dev/fit0 rootwait";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&pio 1 GPIO_ACTIVE_LOW>;
+ debounce-interval = <10>;
+ };
+
+ wps {
+ label = "wps";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&pio 0 GPIO_ACTIVE_LOW>;
+ debounce-interval = <10>;
+ };
+ };
+};
diff --git a/arch/arm/dts/mt7987a-u-boot.dtsi b/arch/arm/dts/mt7987a-u-boot.dtsi
new file mode 100644
index 00000000000..ec0a6389d8b
--- /dev/null
+++ b/arch/arm/dts/mt7987a-u-boot.dtsi
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include "mt7987-pinctrl-u-boot.dtsi"
+
+/ {
+ cpus {
+ cpu@0 {
+ mediatek,hwver = <&hwver>;
+ };
+
+ cpu@1 {
+ mediatek,hwver = <&hwver>;
+ };
+
+ cpu@2 {
+ mediatek,hwver = <&hwver>;
+ };
+
+ cpu@3 {
+ mediatek,hwver = <&hwver>;
+ };
+ };
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+};
+
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_pins>;
+ status = "okay";
+};
+
+&pcie1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie1_pins>;
+ status = "disabled";
+};
+
+&spi0 {
+ compatible = "mediatek,ipm-spi";
+ clocks = <&infracfg CLK_INFRA_104M_SPI0>,
+ <&topckgen CLK_TOP_SPI_SEL>;
+ clock-names = "spi-clk", "sel-clk";
+};
+
+&spi1 {
+ compatible = "mediatek,ipm-spi";
+ clocks = <&infracfg CLK_INFRA_104M_SPI1>,
+ <&topckgen CLK_TOP_SPIM_MST_SEL>;
+ clock-names = "spi-clk", "sel-clk";
+};
+
+&spi2 {
+ compatible = "mediatek,ipm-spi";
+ clocks = <&infracfg CLK_INFRA_104M_SPI2_BCK>,
+ <&topckgen CLK_TOP_SPI_SEL>;
+ clock-names = "spi-clk", "sel-clk";
+};
diff --git a/arch/arm/dts/mt7987a.dtsi b/arch/arm/dts/mt7987a.dtsi
new file mode 100644
index 00000000000..028f563fb39
--- /dev/null
+++ b/arch/arm/dts/mt7987a.dtsi
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7987.dtsi"
+#include "mt7987-pinctrl.dtsi"
+
+/ {
+ compatible = "mediatek,mt7987a", "mediatek,mt7987";
+
+ memory {
+ reg = <0 0x40000000 0 0x10000000>;
+ };
+
+};
+
+&afe {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcm_pins>;
+ status = "okay";
+};
+
+&boottrap {
+ status = "okay";
+};
+
+&fan {
+ pwms = <&pwm 0 50000 0>;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+};
+
+&infra_bus_prot {
+ status = "okay";
+};
+
+&lvts {
+ status = "okay";
+};
+
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_pins>;
+ status = "okay";
+};
+
+&pcie1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie1_pins>;
+ status = "disabled";
+};
+
+&pwm {
+ status = "okay";
+};
+
+&spi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spic_pins>;
+ status = "okay";
+};
+
+&trng {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&watchdog {
+ status = "okay";
+};
+
+&xhci {
+ mediatek,u3p-dis-msk = <0x00000001>;
+ phys = <&tphyu2port0 PHY_TYPE_USB2>;
+
+ clocks = <&infracfg CLK_INFRA_USB_SYS_CK_P1>,
+ <&infracfg CLK_INFRA_USB_XHCI_CK_P1>,
+ <&infracfg CLK_INFRA_USB_CK_P1>,
+ <&infracfg CLK_INFRA_66M_USB_HCK_CK_P1>,
+ <&infracfg CLK_INFRA_133M_USB_HCK_CK_P1>;
+ clock-names = "sys_ck", "xhci_ck", "ref_ck", "mcu_ck",
+ "dma_ck";
+
+ status = "okay";
+};
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
index ff1fdee5c8d..39eea055f70 100644
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -59,6 +59,16 @@ config TARGET_MT7986
including UART, SPI, SPI flash, USB3.0, MMC, NAND, SNFI, PWM, PCIe,
Gigabit Ethernet, I2C, built-in 4x4 Wi-Fi, and PCIe.
+config TARGET_MT7987
+ bool "MediaTek MT7987 SoC"
+ select ARM64
+ select CPU
+ select MTK_TZ_MOVABLE
+ help
+ The MediaTek MT7987 is a ARM64-based SoC with a quad-core Cortex-A53.
+ including UART, I2C, PWM, SPI controller which support SPI flash,
+ USB3.0, MMC, PCIe, SGMII and built-in Ethernet PHY.
+
config TARGET_MT7988
bool "MediaTek MT7988 SoC"
select ARM64
@@ -122,6 +132,7 @@ config SYS_BOARD
default "mt7629" if TARGET_MT7629
default "mt7981" if TARGET_MT7981
default "mt7986" if TARGET_MT7986
+ default "mt7987" if TARGET_MT7987
default "mt7988" if TARGET_MT7988
default "mt8183" if TARGET_MT8183
default "mt8512" if TARGET_MT8512
@@ -139,6 +150,7 @@ config SYS_CONFIG_NAME
default "mt7629" if TARGET_MT7629
default "mt7981" if TARGET_MT7981
default "mt7986" if TARGET_MT7986
+ default "mt7987" if TARGET_MT7987
default "mt7988" if TARGET_MT7988
default "mt8183" if TARGET_MT8183
default "mt8365" if TARGET_MT8365
@@ -150,7 +162,12 @@ config MTK_BROM_HEADER_INFO
string
default "media=nor" if TARGET_MT8518 || TARGET_MT8512 || TARGET_MT7629 || TARGET_MT7622
default "media=emmc" if TARGET_MT8516 || TARGET_MT8365 || TARGET_MT8183
- default "media=snand;nandinfo=2k+64" if TARGET_MT7981 || TARGET_MT7986 || TARGET_MT7988
+ default "media=snand;nandinfo=2k+64" if TARGET_MT7981 || TARGET_MT7986 || TARGET_MT7987 || TARGET_MT7988
default "lk=1" if TARGET_MT7623
+config MTK_TZ_MOVABLE
+ select ARCH_MISC_INIT
+ select OF_SYSTEM_SETUP
+ bool
+
endif
diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
index 3d9e4684fb4..344434c6029 100644
--- a/arch/arm/mach-mediatek/Makefile
+++ b/arch/arm/mach-mediatek/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-y += cpu.o
+obj-$(CONFIG_MTK_TZ_MOVABLE) += tzcfg.o
obj-$(CONFIG_XPL_BUILD) += spl.o
obj-$(CONFIG_MT8512) += mt8512/
@@ -9,6 +10,7 @@ obj-$(CONFIG_TARGET_MT7623) += mt7623/
obj-$(CONFIG_TARGET_MT7629) += mt7629/
obj-$(CONFIG_TARGET_MT7981) += mt7981/
obj-$(CONFIG_TARGET_MT7986) += mt7986/
+obj-$(CONFIG_TARGET_MT7987) += mt7987/
obj-$(CONFIG_TARGET_MT7988) += mt7988/
obj-$(CONFIG_TARGET_MT8183) += mt8183/
obj-$(CONFIG_TARGET_MT8365) += mt8365/
diff --git a/arch/arm/mach-mediatek/mt7987/Makefile b/arch/arm/mach-mediatek/mt7987/Makefile
new file mode 100644
index 00000000000..007eb4a3679
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7987/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += init.o
+obj-y += lowlevel_init.o
diff --git a/arch/arm/mach-mediatek/mt7987/init.c b/arch/arm/mach-mediatek/mt7987/init.c
new file mode 100644
index 00000000000..8b268297809
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7987/init.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include <fdtdec.h>
+#include <init.h>
+#include <asm/armv8/mmu.h>
+#include <asm/global_data.h>
+#include <asm/u-boot.h>
+#include <asm/system.h>
+#include <linux/sizes.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+ int ret;
+
+ ret = fdtdec_setup_mem_size_base();
+ if (ret)
+ return ret;
+
+ gd->ram_size = get_ram_size((void *)gd->ram_base, SZ_4G);
+
+ return 0;
+}
+
+int dram_init_banksize(void)
+{
+ gd->bd->bi_dram[0].start = gd->ram_base;
+ gd->bd->bi_dram[0].size = gd->ram_size;
+
+ return 0;
+}
+
+void reset_cpu(ulong addr)
+{
+ psci_system_reset();
+}
+
+static struct mm_region mt7987_mem_map[] = {
+ {
+ /* DDR */
+ .virt = 0x40000000UL,
+ .phys = 0x40000000UL,
+ .size = 0x200000000ULL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE,
+ }, {
+ .virt = 0x00000000UL,
+ .phys = 0x00000000UL,
+ .size = 0x40000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ 0,
+ }
+};
+
+struct mm_region *mem_map = mt7987_mem_map;
diff --git a/arch/arm/mach-mediatek/mt7987/lowlevel_init.S b/arch/arm/mach-mediatek/mt7987/lowlevel_init.S
new file mode 100644
index 00000000000..2f972551277
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7987/lowlevel_init.S
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2023 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/*
+ * Switch from AArch64 EL2 to AArch32 EL2
+ * @param inputs:
+ * x0: argument, zero
+ * x1: machine nr
+ * x2: fdt address
+ * x3: input argument
+ * x4: kernel entry point
+ * @param outputs for secure firmware:
+ * x0: function id
+ * x1: kernel entry point
+ * x2: machine nr
+ * x3: fdt address
+*/
+
+.global armv8_el2_to_aarch32
+armv8_el2_to_aarch32:
+ mov x3, x2
+ mov x2, x1
+ mov x1, x4
+ mov x4, #0
+ ldr x0, =0x82000200
+ SMC #0
+ ret
diff --git a/arch/arm/mach-mediatek/tzcfg.c b/arch/arm/mach-mediatek/tzcfg.c
new file mode 100644
index 00000000000..71982ba4d20
--- /dev/null
+++ b/arch/arm/mach-mediatek/tzcfg.c
@@ -0,0 +1,242 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <asm/global_data.h>
+#include <linux/kernel.h>
+#include <linux/arm-smccc.h>
+#include <linux/sizes.h>
+#include <command.h>
+#include <fdtdec.h>
+#include <fdt_support.h>
+#include <lmb.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define MTK_SIP_GET_BL31_REGION 0x82000300
+#define MTK_SIP_GET_BL32_REGION 0x82000301
+
+#define BL31_DEFAULT_ADDR 0x43000000
+#define BL31_DEFAULT_SIZE 0x80000
+
+#define TZ_REGION_MAX_SIZE SZ_16M
+#define U_BOOT_MIN_SIZE SZ_4M
+#define U_BOOT_MIN_STACK_SIZE SZ_1M
+#define REGION_ALIGNMENT SZ_64K
+
+struct tz_reserved_region {
+ phys_addr_t addr;
+ phys_addr_t size;
+};
+
+static bool fix_tz_region(struct tz_reserved_region region[],
+ uint32_t used_regions)
+{
+ phys_addr_t size;
+
+ if (region[0].addr + region[0].size > gd->ram_top) {
+ if (region[0].addr >= gd->ram_top) {
+ debug("Discarded region 0x%08llx, size 0x%llx\n",
+ region[0].addr, region[0].size);
+
+ if (used_regions > 1)
+ region[0] = region[1];
+
+ return true;
+ }
+
+ size = gd->ram_top - region[0].addr;
+
+ debug("Truncated region 0x%08llx, size 0x%llx -> 0x%llx\n",
+ region[0].addr, region[0].size, size);
+
+ region[0].size = size;
+ }
+
+ return false;
+}
+
+phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
+{
+ phys_addr_t uboot_ram_top, pstore_size, uboot_size = 0;
+ struct tz_reserved_region region[2], tmp;
+ phys_addr_t top_addr, low_addr;
+ struct arm_smccc_res res;
+ u32 used_regions = 1;
+
+ /* BL31 region */
+ arm_smccc_smc(MTK_SIP_GET_BL31_REGION, 0, 0, 0, 0, 0, 0, 0, &res);
+ if (res.a0) {
+ /* Assume PIE is not enabled for BL31 */
+ region[0].addr = BL31_DEFAULT_ADDR;
+ region[0].size = BL31_DEFAULT_SIZE;
+ } else {
+ region[0].addr = res.a1;
+ region[0].size = res.a2;
+ }
+
+ debug("BL31 @ 0x%08llx, size 0x%llx\n", region[0].addr,
+ region[0].size);
+
+ /* BL32 region is optional */
+ arm_smccc_smc(MTK_SIP_GET_BL32_REGION, 0, 0, 0, 0, 0, 0, 0, &res);
+ if (!res.a0 && res.a1 && res.a2) {
+ region[used_regions].addr = res.a1;
+ region[used_regions].size = res.a2;
+
+ debug("BL32 @ 0x%08llx, size 0x%llx\n",
+ region[used_regions].addr, region[used_regions].size);
+
+ used_regions++;
+ }
+
+ if (used_regions == 2) {
+ if (region[0].addr < region[1].addr) {
+ /* Make sure region[0] is higher than region[1] */
+ tmp = region[0];
+ region[0] = region[1];
+ region[1] = tmp;
+ }
+
+ top_addr = region[0].addr + region[0].size;
+ low_addr = min_t(phys_addr_t, region[0].addr, region[1].addr);
+
+ if (top_addr - low_addr <= TZ_REGION_MAX_SIZE) {
+ /* Merge region if they're overlapped or close enough */
+ region[0].size = top_addr - low_addr;
+ region[0].addr = low_addr;
+
+ debug("Merged region @ 0x%08llx, size 0x%llx\n",
+ region[0].addr, region[0].size);
+
+ used_regions = 1;
+ }
+ }
+
+ debug("Effective memory @ 0x%08zx, size 0x%llx\n", gd->ram_base,
+ gd->ram_top - gd->ram_base);
+
+ /* Discard/fix region which is outside the effective memory */
+ if (fix_tz_region(region, used_regions)) {
+ used_regions--;
+
+ if (used_regions) {
+ if (fix_tz_region(region, used_regions))
+ used_regions--;
+ }
+ }
+
+ /* Size needed for u-boot & pstore */
+#if IS_ENABLED(CONFIG_CMD_PSTORE)
+ /* pstore will be placed under ram top */
+ pstore_size = (CONFIG_CMD_PSTORE_MEM_SIZE + REGION_ALIGNMENT - 1) &
+ ~(REGION_ALIGNMENT - 1);
+ /* u-boot will be placed under pstore */
+ uboot_size += pstore_size;
+#endif
+
+ uboot_size += max_t(uintptr_t, U_BOOT_MIN_SIZE, total_size);
+ uboot_size += U_BOOT_MIN_STACK_SIZE + REGION_ALIGNMENT - 1;
+ uboot_size &= ~(REGION_ALIGNMENT - 1);
+
+ uboot_ram_top = gd->ram_top & ~(REGION_ALIGNMENT - 1);
+
+ if (!used_regions ||
+ (uboot_ram_top - region[0].addr - region[0].size >= uboot_size)) {
+ /* No reserved region present,
+ * or gap between high region and ram top is large enough
+ */
+ uboot_ram_top -= pstore_size;
+ return uboot_ram_top;
+ }
+
+ uboot_ram_top = region[0].addr & ~(REGION_ALIGNMENT - 1);
+
+ if (used_regions == 2 &&
+ (uboot_ram_top - region[1].addr - region[1].size >= uboot_size)) {
+ /* Gap between high region and low region is large enough */
+ uboot_ram_top -= pstore_size;
+ return uboot_ram_top;
+ }
+
+ uboot_ram_top = region[used_regions - 1].addr & ~(REGION_ALIGNMENT - 1);
+
+ /* Under low region */
+ uboot_ram_top -= pstore_size;
+ return uboot_ram_top;
+}
+
+int arch_misc_init(void)
+{
+ struct arm_smccc_res res;
+
+ /*
+ * Since board_get_usable_ram_top is be called before arch_misc_init,
+ * there's no need to check the result
+ */
+ arm_smccc_smc(MTK_SIP_GET_BL31_REGION, 0, 0, 0, 0, 0, 0, 0, &res);
+ lmb_reserve(res.a1, res.a2, LMB_NOMAP);
+
+ arm_smccc_smc(MTK_SIP_GET_BL32_REGION, 0, 0, 0, 0, 0, 0, 0, &res);
+ if (!res.a0 && res.a1 && res.a2)
+ lmb_reserve(res.a1, res.a2, LMB_NOMAP);
+
+#if IS_ENABLED(CONFIG_CMD_PSTORE)
+ char cmd[64];
+
+ /* Override default pstore address */
+ snprintf(cmd, sizeof(cmd), "pstore set 0x%llx 0x%x", gd->ram_top,
+ CONFIG_CMD_PSTORE_MEM_SIZE);
+ run_command(cmd, 0);
+#endif
+
+ return 0;
+}
+
+/* For board-level setup */
+__weak int mtk_ft_system_setup(void *blob, struct bd_info *bd)
+{
+ return 0;
+}
+
+int ft_system_setup(void *blob, struct bd_info *bd)
+{
+ struct arm_smccc_res res;
+ struct fdt_memory mem;
+ int ret;
+
+ arm_smccc_smc(MTK_SIP_GET_BL31_REGION, 0, 0, 0, 0, 0, 0, 0, &res);
+
+ mem.start = res.a1;
+ mem.end = res.a1 + res.a2 - 1;
+
+ ret = fdtdec_add_reserved_memory(blob, "secmon", &mem, NULL, 0, NULL,
+ FDTDEC_RESERVED_MEMORY_NO_MAP);
+ if (ret < 0) {
+ log_err("Failed to add reserved-memory for BL31: %s\n",
+ fdt_strerror(ret));
+ return ret;
+ }
+
+ arm_smccc_smc(MTK_SIP_GET_BL32_REGION, 0, 0, 0, 0, 0, 0, 0, &res);
+ if (!res.a0 && res.a1 && res.a2) {
+ mem.start = res.a1;
+ mem.end = res.a1 + res.a2 - 1;
+
+ ret = fdtdec_add_reserved_memory(blob, "trustzone", &mem, NULL,
+ 0, NULL,
+ FDTDEC_RESERVED_MEMORY_NO_MAP);
+ if (ret < 0) {
+ log_err("Failed to add reserved-memory for BL32: %s\n",
+ fdt_strerror(ret));
+ return ret;
+ }
+ }
+
+ return mtk_ft_system_setup(blob, bd);
+}
diff --git a/board/mediatek/mt7987/MAINTAINERS b/board/mediatek/mt7987/MAINTAINERS
new file mode 100644
index 00000000000..c257d0b09df
--- /dev/null
+++ b/board/mediatek/mt7987/MAINTAINERS
@@ -0,0 +1,8 @@
+MT7987
+M: Sam Shih <sam.shih@mediatek.com>
+S: Maintained
+F: board/mediatek/mt7987
+F: include/configs/mt7987.h
+F: configs/mt7987_rfb_defconfig
+F: configs/mt7987_emmc_rfb_defconfig
+F: configs/mt7987_sd_rfb_defconfig
diff --git a/board/mediatek/mt7987/Makefile b/board/mediatek/mt7987/Makefile
new file mode 100644
index 00000000000..9f3f493f3c9
--- /dev/null
+++ b/board/mediatek/mt7987/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += mt7987_rfb.o
diff --git a/board/mediatek/mt7987/mt7987_rfb.c b/board/mediatek/mt7987/mt7987_rfb.c
new file mode 100644
index 00000000000..fcb844deed8
--- /dev/null
+++ b/board/mediatek/mt7987/mt7987_rfb.c
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+int board_init(void)
+{
+ return 0;
+}
diff --git a/configs/mt7987_emmc_rfb_defconfig b/configs/mt7987_emmc_rfb_defconfig
new file mode 100644
index 00000000000..022ca32169b
--- /dev/null
+++ b/configs/mt7987_emmc_rfb_defconfig
@@ -0,0 +1,91 @@
+CONFIG_ARM=y
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_DEFAULT_DEVICE_TREE="mt7987a-emmc-rfb"
+CONFIG_TARGET_MT7987=y
+CONFIG_SYS_BOOTM_LEN=0x6000000
+CONFIG_SYS_LOAD_ADDR=0x48000000
+CONFIG_DEBUG_UART_BASE=0x11000000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_DEBUG_UART=y
+# CONFIG_EFI_LOADER is not set
+CONFIG_FIT=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7987a-emmc-rfb"
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7987> "
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_PWM=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_EFI_PARTITION=y
+CONFIG_PARTITION_TYPE_GUID=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_USE_IPADDR=y
+CONFIG_IPADDR="192.168.1.1"
+CONFIG_USE_NETMASK=y
+CONFIG_NETMASK="255.255.255.0"
+CONFIG_USE_SERVERIP=y
+CONFIG_SERVERIP="192.168.1.2"
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_MTK=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_MTK=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_PUYA=y
+CONFIG_SPI_FLASH_SILICONKAISER=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_SPI_FLASH_XTX=y
+CONFIG_SPI_FLASH_ZBIT=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_MTD_UBI=y
+CONFIG_PHY_ETHERNET_ID=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7987=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_PWM=y
+CONFIG_PWM_MTK=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_MTK_SPIM=y
+CONFIG_HEXDUMP=y
diff --git a/configs/mt7987_rfb_defconfig b/configs/mt7987_rfb_defconfig
new file mode 100644
index 00000000000..00e3cea5264
--- /dev/null
+++ b/configs/mt7987_rfb_defconfig
@@ -0,0 +1,87 @@
+CONFIG_ARM=y
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_DEFAULT_DEVICE_TREE="mt7987a-rfb"
+CONFIG_TARGET_MT7987=y
+CONFIG_SYS_BOOTM_LEN=0x6000000
+CONFIG_SYS_LOAD_ADDR=0x48000000
+CONFIG_DEBUG_UART_BASE=0x11000000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_DEBUG_UART=y
+# CONFIG_EFI_LOADER is not set
+CONFIG_FIT=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7987a-rfb"
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7987> "
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_PWM=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_USE_IPADDR=y
+CONFIG_IPADDR="192.168.1.1"
+CONFIG_USE_NETMASK=y
+CONFIG_NETMASK="255.255.255.0"
+CONFIG_USE_SERVERIP=y
+CONFIG_SERVERIP="192.168.1.2"
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_MTK=y
+# CONFIG_MMC is not set
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_PUYA=y
+CONFIG_SPI_FLASH_SILICONKAISER=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_SPI_FLASH_XTX=y
+CONFIG_SPI_FLASH_ZBIT=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_MTD_UBI=y
+CONFIG_PHY_ETHERNET_ID=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7987=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_PWM=y
+CONFIG_PWM_MTK=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_MTK_SPIM=y
+CONFIG_HEXDUMP=y
diff --git a/configs/mt7987_sd_rfb_defconfig b/configs/mt7987_sd_rfb_defconfig
new file mode 100644
index 00000000000..ca7714b1242
--- /dev/null
+++ b/configs/mt7987_sd_rfb_defconfig
@@ -0,0 +1,91 @@
+CONFIG_ARM=y
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_DEFAULT_DEVICE_TREE="mt7987a-sd-rfb"
+CONFIG_TARGET_MT7987=y
+CONFIG_SYS_BOOTM_LEN=0x6000000
+CONFIG_SYS_LOAD_ADDR=0x48000000
+CONFIG_DEBUG_UART_BASE=0x11000000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_DEBUG_UART=y
+# CONFIG_EFI_LOADER is not set
+CONFIG_FIT=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7987a-sd-rfb"
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7987> "
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_PWM=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_EFI_PARTITION=y
+CONFIG_PARTITION_TYPE_GUID=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_USE_IPADDR=y
+CONFIG_IPADDR="192.168.1.1"
+CONFIG_USE_NETMASK=y
+CONFIG_NETMASK="255.255.255.0"
+CONFIG_USE_SERVERIP=y
+CONFIG_SERVERIP="192.168.1.2"
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_MTK=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_MTK=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_PUYA=y
+CONFIG_SPI_FLASH_SILICONKAISER=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_SPI_FLASH_XTX=y
+CONFIG_SPI_FLASH_ZBIT=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_MTD_UBI=y
+CONFIG_PHY_ETHERNET_ID=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7987=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_PWM=y
+CONFIG_PWM_MTK=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_MTK_SPIM=y
+CONFIG_HEXDUMP=y
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index e631f79e4dd..e412c92cafc 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_TARGET_MT7629) += clk-mt7629.o
obj-$(CONFIG_TARGET_MT7986) += clk-mt7986.o
obj-$(CONFIG_TARGET_MT7981) += clk-mt7981.o
obj-$(CONFIG_TARGET_MT7988) += clk-mt7988.o
+obj-$(CONFIG_TARGET_MT7987) += clk-mt7987.o
obj-$(CONFIG_TARGET_MT8183) += clk-mt8183.o
obj-$(CONFIG_TARGET_MT8365) += clk-mt8365.o
obj-$(CONFIG_TARGET_MT8516) += clk-mt8516.o
diff --git a/drivers/clk/mediatek/clk-mt7987.c b/drivers/clk/mediatek/clk-mt7987.c
new file mode 100644
index 00000000000..173686a38e8
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7987.c
@@ -0,0 +1,848 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek clock driver for MT7987 SoC
+ *
+ * Copyright (C) 2024 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include <dm.h>
+#include <log.h>
+#include <asm/arch-mediatek/reset.h>
+#include <asm/io.h>
+#include <dt-bindings/clock/mediatek,mt7987-clk.h>
+#include <linux/bitops.h>
+
+#include "clk-mtk.h"
+
+#define MT7987_XTAL_RATE (40 * MHZ)
+#define MT7987_CLK_PDN 0x250
+#define MT7987_CLK_PDN_EN_WRITE BIT(31)
+
+#define XTAL_FACTOR(_id, _name, _parent, _mult, _div) \
+ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_XTAL)
+
+#define PLL_FACTOR(_id, _name, _parent, _mult, _div) \
+ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED)
+
+#define TOP_FACTOR(_id, _name, _parent, _mult, _div) \
+ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN)
+
+#define INFRA_FACTOR(_id, _name, _parent, _mult, _div) \
+ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_INFRASYS)
+
+/* FIXED PLLS */
+static const struct mtk_fixed_clk apmixedsys_mtk_plls[] = {
+ FIXED_CLK(CLK_APMIXED_MPLL, CLK_XTAL, 416000000),
+ FIXED_CLK(CLK_APMIXED_APLL2, CLK_XTAL, 196608000),
+ FIXED_CLK(CLK_APMIXED_NET1PLL, CLK_XTAL, 2500000000),
+ FIXED_CLK(CLK_APMIXED_NET2PLL, CLK_XTAL, 800000000),
+ FIXED_CLK(CLK_APMIXED_WEDMCUPLL, CLK_XTAL, 208000000),
+ FIXED_CLK(CLK_APMIXED_SGMPLL, CLK_XTAL, 325000000),
+ FIXED_CLK(CLK_APMIXED_ARM_LL, CLK_XTAL, 2000000000),
+ FIXED_CLK(CLK_APMIXED_MSDCPLL, CLK_XTAL, 384000000),
+};
+
+static const struct mtk_clk_tree mt7987_fixed_pll_clk_tree = {
+ .fdivs_offs = ARRAY_SIZE(apmixedsys_mtk_plls),
+ .fclks = apmixedsys_mtk_plls,
+ .flags = CLK_APMIXED,
+ .xtal_rate = 40 * MHZ,
+};
+
+static const struct udevice_id mt7987_fixed_pll_compat[] = {
+ { .compatible = "mediatek,mt7987-fixed-plls" },
+ { .compatible = "mediatek,mt7987-apmixedsys" },
+ {}
+};
+
+static int mt7987_fixed_pll_probe(struct udevice *dev)
+{
+ return mtk_common_clk_init(dev, &mt7987_fixed_pll_clk_tree);
+}
+
+U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+ .name = "mt7987-clock-fixed-pll",
+ .id = UCLASS_CLK,
+ .of_match = mt7987_fixed_pll_compat,
+ .probe = mt7987_fixed_pll_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+/* TOPCKGEN FIXED DIV */
+static const struct mtk_fixed_factor topckgen_mtk_fixed_factors[] = {
+ PLL_FACTOR(CLK_TOP_CB_M_D2, "cb_m_d2", CLK_APMIXED_MPLL, 1, 2),
+ PLL_FACTOR(CLK_TOP_CB_M_D3, "cb_m_d3", CLK_APMIXED_MPLL, 1, 3),
+ PLL_FACTOR(CLK_TOP_M_D3_D2, "m_d3_d2", CLK_APMIXED_MPLL, 1, 6),
+ PLL_FACTOR(CLK_TOP_CB_M_D4, "cb_m_d4", CLK_APMIXED_MPLL, 1, 4),
+ PLL_FACTOR(CLK_TOP_CB_M_D8, "cb_m_d8", CLK_APMIXED_MPLL, 1, 8),
+ PLL_FACTOR(CLK_TOP_M_D8_D2, "m_d8_d2", CLK_APMIXED_MPLL, 1, 16),
+ PLL_FACTOR(CLK_TOP_CB_APLL2_D4, "cb_apll2_d4", CLK_APMIXED_APLL2, 1, 4),
+ PLL_FACTOR(CLK_TOP_CB_NET1_D3, "cb_net1_d3", CLK_APMIXED_NET1PLL, 1, 3),
+ PLL_FACTOR(CLK_TOP_CB_NET1_D4, "cb_net1_d4", CLK_APMIXED_NET1PLL, 1, 4),
+ PLL_FACTOR(CLK_TOP_CB_NET1_D5, "cb_net1_d5", CLK_APMIXED_NET1PLL, 1, 5),
+ PLL_FACTOR(CLK_TOP_NET1_D5_D2, "net1_d5_d2", CLK_APMIXED_NET1PLL, 1, 10),
+ PLL_FACTOR(CLK_TOP_NET1_D5_D4, "net1_d5_d4", CLK_APMIXED_NET1PLL, 1, 20),
+ PLL_FACTOR(CLK_TOP_CB_NET1_D7, "cb_net1_d7", CLK_APMIXED_NET1PLL, 1, 7),
+ PLL_FACTOR(CLK_TOP_NET1_D7_D2, "net1_d7_d2", CLK_APMIXED_NET1PLL, 1, 14),
+ PLL_FACTOR(CLK_TOP_NET1_D7_D4, "net1_d7_d4", CLK_APMIXED_NET1PLL, 1, 28),
+ PLL_FACTOR(CLK_TOP_NET1_D8_D2, "net1_d8_d2", CLK_APMIXED_NET1PLL, 1, 16),
+ PLL_FACTOR(CLK_TOP_NET1_D8_D4, "net1_d8_d4", CLK_APMIXED_NET1PLL, 1, 32),
+ PLL_FACTOR(CLK_TOP_NET1_D8_D8, "net1_d8_d8", CLK_APMIXED_NET1PLL, 1, 64),
+ PLL_FACTOR(CLK_TOP_NET1_D8_D16, "net1_d8_d16", CLK_APMIXED_NET1PLL, 1, 128),
+ PLL_FACTOR(CLK_TOP_CB_NET2_D2, "cb_net2_d2", CLK_APMIXED_NET2PLL, 1, 2),
+ PLL_FACTOR(CLK_TOP_CB_NET2_D4, "cb_net2_d4", CLK_APMIXED_NET2PLL, 1, 4),
+ PLL_FACTOR(CLK_TOP_NET2_D4_D4, "net2_d4_d4", CLK_APMIXED_NET2PLL, 1, 16),
+ PLL_FACTOR(CLK_TOP_NET2_D4_D8, "net2_d4_d8", CLK_APMIXED_NET2PLL, 1, 32),
+ PLL_FACTOR(CLK_TOP_CB_NET2_D6, "cb_net2_d6", CLK_APMIXED_NET2PLL, 1, 6),
+ PLL_FACTOR(CLK_TOP_NET2_D7_D2, "net2_d7_d2", CLK_APMIXED_NET2PLL, 1, 14),
+ PLL_FACTOR(CLK_TOP_CB_NET2_D8, "cb_net2_d8", CLK_APMIXED_NET2PLL, 1, 8),
+ PLL_FACTOR(CLK_TOP_MSDC_D2, "msdc_d2", CLK_APMIXED_MSDCPLL, 1, 2),
+ XTAL_FACTOR(CLK_TOP_CB_CKSQ_40M, "cb_cksq_40m", CLK_XTAL, 1, 1),
+ TOP_FACTOR(CLK_TOP_CKSQ_40M_D2, "cksq_40m_d2", CLK_TOP_CB_CKSQ_40M, 1, 2),
+ TOP_FACTOR(CLK_TOP_CB_RTC_32K, "cb_rtc_32k", CLK_TOP_CB_CKSQ_40M, 1, 1250),
+ TOP_FACTOR(CLK_TOP_CB_RTC_32P7K, "cb_rtc_32p7k", CLK_TOP_CB_CKSQ_40M, 1, 1221),
+};
+
+/* TOPCKGEN MUX PARENTS */
+#define APMIXED_PARENT(_id) PARENT(_id, CLK_PARENT_APMIXED)
+#define TOP_PARENT(_id) PARENT(_id, CLK_PARENT_TOPCKGEN)
+
+/* CLK_TOP_NETSYS_SEL (netsys_sel) in topckgen */
+static const struct mtk_parent netsys_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_CB_NET2_D2)
+};
+
+/* CLK_TOP_NETSYS_500M_SEL (netsys_500m_sel) in topckgen */
+static const struct mtk_parent netsys_500m_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_CB_NET1_D5),
+ TOP_PARENT(CLK_TOP_NET1_D5_D2)
+};
+
+/* CLK_TOP_NETSYS_2X_SEL (netsys_2x_sel) in topckgen */
+static const struct mtk_parent netsys_2x_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ APMIXED_PARENT(CLK_APMIXED_NET2PLL)
+};
+
+/* CLK_TOP_ETH_GMII_SEL (eth_gmii_sel) in topckgen */
+static const struct mtk_parent eth_gmii_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_NET1_D5_D4)
+};
+
+/* CLK_TOP_EIP_SEL (eip_sel) in topckgen */
+static const struct mtk_parent eip_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_CB_NET1_D3),
+ APMIXED_PARENT(CLK_APMIXED_NET2PLL),
+ TOP_PARENT(CLK_TOP_CB_NET1_D4),
+ TOP_PARENT(CLK_TOP_CB_NET1_D5)
+};
+
+/* CLK_TOP_AXI_INFRA_SEL (axi_infra_sel) in topckgen */
+static const struct mtk_parent axi_infra_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_NET1_D8_D2)
+};
+
+/* CLK_TOP_UART_SEL (uart_sel) in topckgen */
+static const struct mtk_parent uart_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_CB_M_D8),
+ TOP_PARENT(CLK_TOP_M_D8_D2)
+};
+
+/* CLK_TOP_EMMC_250M_SEL (emmc_250m_sel) in topckgen */
+static const struct mtk_parent emmc_250m_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_NET1_D5_D2),
+ TOP_PARENT(CLK_TOP_NET1_D7_D2)
+};
+
+/* CLK_TOP_EMMC_400M_SEL (emmc_400m_sel) in topckgen */
+static const struct mtk_parent emmc_400m_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ APMIXED_PARENT(CLK_APMIXED_MSDCPLL),
+ TOP_PARENT(CLK_TOP_CB_NET1_D7),
+ TOP_PARENT(CLK_TOP_CB_M_D2),
+ TOP_PARENT(CLK_TOP_NET1_D7_D2),
+ TOP_PARENT(CLK_TOP_CB_NET2_D6)
+};
+
+/* CLK_TOP_SPI_SEL (spi_sel) in topckgen */
+static const struct mtk_parent spi_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_CB_M_D2),
+ TOP_PARENT(CLK_TOP_NET1_D7_D2),
+ TOP_PARENT(CLK_TOP_NET1_D8_D2),
+ TOP_PARENT(CLK_TOP_CB_NET2_D6),
+ TOP_PARENT(CLK_TOP_NET1_D5_D4),
+ TOP_PARENT(CLK_TOP_CB_M_D4),
+ TOP_PARENT(CLK_TOP_NET1_D8_D4)
+};
+
+/* CLK_TOP_NFI_SEL (nfi_sel) in topckgen */
+static const struct mtk_parent nfi_parents[] = {
+ TOP_PARENT(CLK_TOP_CKSQ_40M_D2),
+ TOP_PARENT(CLK_TOP_NET1_D8_D2),
+ TOP_PARENT(CLK_TOP_CB_M_D3),
+ TOP_PARENT(CLK_TOP_NET1_D5_D4),
+ TOP_PARENT(CLK_TOP_CB_M_D4),
+ TOP_PARENT(CLK_TOP_NET1_D7_D4),
+ TOP_PARENT(CLK_TOP_NET1_D8_D4),
+ TOP_PARENT(CLK_TOP_M_D3_D2),
+ TOP_PARENT(CLK_TOP_NET2_D7_D2),
+ TOP_PARENT(CLK_TOP_CB_M_D8)
+};
+
+/* CLK_TOP_PWM_SEL (pwm_sel) in topckgen */
+static const struct mtk_parent pwm_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_NET1_D8_D2),
+ TOP_PARENT(CLK_TOP_NET1_D5_D4),
+ TOP_PARENT(CLK_TOP_CB_M_D4),
+ TOP_PARENT(CLK_TOP_M_D8_D2),
+ TOP_PARENT(CLK_TOP_CB_RTC_32K)
+};
+
+/* CLK_TOP_I2C_SEL (i2c_sel) in topckgen */
+static const struct mtk_parent i2c_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_NET1_D5_D4),
+ TOP_PARENT(CLK_TOP_CB_M_D4),
+ TOP_PARENT(CLK_TOP_NET1_D8_D4)
+};
+
+/* CLK_TOP_PCIE_MBIST_250M_SEL (pcie_mbist_250m_sel) in topckgen */
+static const struct mtk_parent pcie_mbist_250m_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_NET1_D5_D2)
+};
+
+/* CLK_TOP_PEXTP_TL_SEL (pextp_tl_ck_sel) in topckgen */
+static const struct mtk_parent pextp_tl_ck_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_CB_NET2_D6),
+ TOP_PARENT(CLK_TOP_NET1_D7_D4),
+ TOP_PARENT(CLK_TOP_M_D8_D2),
+ TOP_PARENT(CLK_TOP_CB_RTC_32K)
+};
+
+/* CLK_TOP_AUD_SEL (aud_sel) in topckgen */
+static const struct mtk_parent aud_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ APMIXED_PARENT(CLK_APMIXED_APLL2)
+};
+
+/* CLK_TOP_A1SYS_SEL (a1sys_sel) in topckgen */
+static const struct mtk_parent a1sys_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_CB_APLL2_D4)
+};
+
+/* CLK_TOP_AUD_L_SEL (aud_l_sel) in topckgen */
+static const struct mtk_parent aud_l_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ APMIXED_PARENT(CLK_APMIXED_APLL2),
+ TOP_PARENT(CLK_TOP_M_D8_D2)
+};
+
+/* CLK_TOP_USB_PHY_SEL (usb_phy_sel) in topckgen */
+static const struct mtk_parent usb_phy_parents[] = {
+ TOP_PARENT(CLK_TOP_CKSQ_40M_D2),
+ TOP_PARENT(CLK_TOP_M_D8_D2)
+};
+
+/* CLK_TOP_SGM_0_SEL (sgm_0_sel) in topckgen */
+static const struct mtk_parent sgm_0_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ APMIXED_PARENT(CLK_APMIXED_SGMPLL)
+};
+
+/* CLK_TOP_SGM_SBUS_0_SEL (sgm_sbus_0_sel) in topckgen */
+static const struct mtk_parent sgm_sbus_0_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_NET1_D8_D4)
+};
+
+/* CLK_TOP_SYSAPB_SEL (sysapb_sel) in topckgen */
+static const struct mtk_parent sysapb_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_M_D3_D2)
+};
+
+/* CLK_TOP_ETH_REFCK_50M_SEL (eth_refck_50m_sel) in topckgen */
+static const struct mtk_parent eth_refck_50m_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_NET2_D4_D4)
+};
+
+/* CLK_TOP_ETH_SYS_200M_SEL (eth_sys_200m_sel) in topckgen */
+static const struct mtk_parent eth_sys_200m_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_CB_NET2_D4)
+};
+
+/* CLK_TOP_ETH_XGMII_SEL (eth_xgmii_sel) in topckgen */
+static const struct mtk_parent eth_xgmii_parents[] = {
+ TOP_PARENT(CLK_TOP_CKSQ_40M_D2),
+ TOP_PARENT(CLK_TOP_NET1_D8_D8),
+ TOP_PARENT(CLK_TOP_NET1_D8_D16)
+};
+
+/* CLK_TOP_DRAMC_MD32_SEL (dramc_md32_sel) in topckgen */
+static const struct mtk_parent dramc_md32_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_CB_M_D2),
+ APMIXED_PARENT(CLK_APMIXED_WEDMCUPLL)
+};
+
+/* CLK_TOP_DA_XTP_GLB_P0_SEL (da_xtp_glb_p0_sel) in topckgen */
+static const struct mtk_parent da_xtp_glb_p0_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_CB_NET2_D8)
+};
+
+/* CLK_TOP_DA_CKM_XTAL_SEL (da_ckm_xtal_sel) in topckgen */
+static const struct mtk_parent da_ckm_xtal_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_M_D8_D2)
+};
+
+/* CLK_TOP_ETH_MII_SEL (eth_mii_sel) in topckgen */
+static const struct mtk_parent eth_mii_parents[] = {
+ TOP_PARENT(CLK_TOP_CKSQ_40M_D2),
+ TOP_PARENT(CLK_TOP_NET2_D4_D8)
+};
+
+/* CLK_TOP_EMMC_200M_SEL (emmc_200m_sel) in topckgen */
+static const struct mtk_parent emmc_200m_parents[] = {
+ TOP_PARENT(CLK_TOP_CB_CKSQ_40M),
+ TOP_PARENT(CLK_TOP_MSDC_D2),
+ TOP_PARENT(CLK_TOP_NET1_D7_D2),
+ TOP_PARENT(CLK_TOP_CB_NET2_D6),
+ TOP_PARENT(CLK_TOP_NET1_D7_D4)
+};
+
+#define TOP_MUX(_id, _name, _parents, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \
+ _shift, _width, _gate, _upd_ofs, _upd) \
+ { \
+ .id = (_id), .mux_reg = (_mux_ofs), \
+ .mux_set_reg = (_mux_set_ofs), .mux_clr_reg = (_mux_clr_ofs), \
+ .upd_reg = (_upd_ofs), .upd_shift = (_upd), \
+ .mux_shift = (_shift), .mux_mask = BIT(_width) - 1, \
+ .gate_reg = (_mux_ofs), .gate_shift = (_gate), \
+ .parent_flags = (_parents), \
+ .num_parents = ARRAY_SIZE(_parents), \
+ .flags = CLK_MUX_SETCLR_UPD | CLK_PARENT_MIXED, \
+ }
+
+/* TOPCKGEN MUX_GATE */
+static const struct mtk_composite topckgen_mtk_muxes[] = {
+ TOP_MUX(CLK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents,
+ 0x000, 0x004, 0x008, 0, 1, 7, 0x1C0, 0),
+ TOP_MUX(CLK_TOP_NETSYS_500M_SEL, "netsys_500m_sel",
+ netsys_500m_parents, 0x000, 0x004, 0x008, 8, 2, 15, 0x1C0, 1),
+ TOP_MUX(CLK_TOP_NETSYS_2X_SEL, "netsys_2x_sel", netsys_2x_parents,
+ 0x000, 0x004, 0x008, 16, 1, 23, 0x1C0, 2),
+ TOP_MUX(CLK_TOP_ETH_GMII_SEL, "eth_gmii_sel", eth_gmii_parents,
+ 0x000, 0x004, 0x008, 24, 1, 31, 0x1C0, 3),
+ TOP_MUX(CLK_TOP_EIP_SEL, "eip_sel", eip_parents,
+ 0x010, 0x014, 0x018, 0, 3, 7, 0x1C0, 4),
+ TOP_MUX(CLK_TOP_AXI_INFRA_SEL, "axi_infra_sel", axi_infra_parents,
+ 0x010, 0x014, 0x018, 8, 1, 15, 0x1C0, 5),
+ TOP_MUX(CLK_TOP_UART_SEL, "uart_sel", uart_parents,
+ 0x010, 0x014, 0x018, 16, 2, 23, 0x1C0, 6),
+ TOP_MUX(CLK_TOP_EMMC_250M_SEL, "emmc_250m_sel", emmc_250m_parents,
+ 0x010, 0x014, 0x018, 24, 2, 31, 0x1C0, 7),
+ TOP_MUX(CLK_TOP_EMMC_400M_SEL, "emmc_400m_sel", emmc_400m_parents,
+ 0x020, 0x024, 0x028, 0, 3, 7, 0x1C0, 8),
+ TOP_MUX(CLK_TOP_SPI_SEL, "spi_sel", spi_parents,
+ 0x020, 0x024, 0x028, 8, 3, 15, 0x1C0, 9),
+ TOP_MUX(CLK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents,
+ 0x020, 0x024, 0x028, 16, 3, 23, 0x1C0, 10),
+ TOP_MUX(CLK_TOP_NFI_SEL, "nfi_sel", nfi_parents,
+ 0x020, 0x024, 0x028, 24, 4, 31, 0x1C0, 11),
+ TOP_MUX(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents,
+ 0x030, 0x034, 0x038, 0, 3, 7, 0x1C0, 12),
+ TOP_MUX(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents,
+ 0x030, 0x034, 0x038, 8, 2, 15, 0x1C0, 13),
+ TOP_MUX(CLK_TOP_PCIE_MBIST_250M_SEL, "pcie_mbist_250m_sel",
+ pcie_mbist_250m_parents, 0x030, 0x034, 0x038, 16, 1, 23, 0x1C0, 14),
+ TOP_MUX(CLK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel", pextp_tl_ck_parents,
+ 0x030, 0x034, 0x038, 24, 3, 31, 0x1C0, 15),
+ TOP_MUX(CLK_TOP_PEXTP_TL_P1_SEL, "pextp_tl_ck_p1_sel",
+ pextp_tl_ck_parents, 0x040, 0x044, 0x048, 0, 3, 7, 0x1C0, 16),
+ TOP_MUX(CLK_TOP_USB_SYS_P1_SEL, "usb_sys_p1_sel", eth_gmii_parents,
+ 0x040, 0x044, 0x048, 8, 1, 15, 0x1C0, 17),
+ TOP_MUX(CLK_TOP_USB_XHCI_P1_SEL, "usb_xhci_p1_sel", eth_gmii_parents,
+ 0x040, 0x044, 0x048, 16, 1, 23, 0x1C0, 18),
+ TOP_MUX(CLK_TOP_AUD_SEL, "aud_sel", aud_parents,
+ 0x040, 0x044, 0x048, 24, 1, 31, 0x1C0, 19),
+ TOP_MUX(CLK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents,
+ 0x050, 0x054, 0x058, 0, 1, 7, 0x1C0, 20),
+ TOP_MUX(CLK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents,
+ 0x050, 0x054, 0x058, 8, 2, 15, 0x1C0, 21),
+ TOP_MUX(CLK_TOP_A_TUNER_SEL, "a_tuner_sel", a1sys_parents,
+ 0x050, 0x054, 0x058, 16, 1, 23, 0x1C0, 22),
+ TOP_MUX(CLK_TOP_USB_PHY_SEL, "usb_phy_sel", usb_phy_parents,
+ 0x050, 0x054, 0x058, 24, 1, 31, 0x1C0, 23),
+ TOP_MUX(CLK_TOP_SGM_0_SEL, "sgm_0_sel", sgm_0_parents,
+ 0x060, 0x064, 0x068, 0, 1, 7, 0x1C0, 24),
+ TOP_MUX(CLK_TOP_SGM_SBUS_0_SEL, "sgm_sbus_0_sel", sgm_sbus_0_parents,
+ 0x060, 0x064, 0x068, 8, 1, 15, 0x1C0, 25),
+ TOP_MUX(CLK_TOP_SGM_1_SEL, "sgm_1_sel", sgm_0_parents,
+ 0x060, 0x064, 0x068, 16, 1, 23, 0x1C0, 26),
+ TOP_MUX(CLK_TOP_SGM_SBUS_1_SEL, "sgm_sbus_1_sel", sgm_sbus_0_parents,
+ 0x060, 0x064, 0x068, 24, 1, 31, 0x1C0, 27),
+ TOP_MUX(CLK_TOP_SYSAXI_SEL, "sysaxi_sel", axi_infra_parents,
+ 0x070, 0x074, 0x078, 0, 1, 7, 0x1C0, 28),
+ TOP_MUX(CLK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents,
+ 0x070, 0x074, 0x078, 8, 1, 15, 0x1C0, 29),
+ TOP_MUX(CLK_TOP_ETH_REFCK_50M_SEL, "eth_refck_50m_sel",
+ eth_refck_50m_parents, 0x070, 0x074, 0x078, 16, 1, 23, 0x1C0, 30),
+ TOP_MUX(CLK_TOP_ETH_SYS_200M_SEL, "eth_sys_200m_sel",
+ eth_sys_200m_parents, 0x070, 0x074, 0x078, 24, 1, 31, 0x1C4, 0),
+ TOP_MUX(CLK_TOP_ETH_SYS_SEL, "eth_sys_sel", pcie_mbist_250m_parents,
+ 0x080, 0x084, 0x088, 0, 1, 7, 0x1C4, 1),
+ TOP_MUX(CLK_TOP_ETH_XGMII_SEL, "eth_xgmii_sel", eth_xgmii_parents,
+ 0x080, 0x084, 0x088, 8, 2, 15, 0x1C4, 2),
+ TOP_MUX(CLK_TOP_DRAMC_SEL, "dramc_sel", usb_phy_parents,
+ 0x080, 0x084, 0x088, 16, 1, 23, 0x1C4, 3),
+ TOP_MUX(CLK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel", dramc_md32_parents,
+ 0x080, 0x084, 0x088, 24, 2, 31, 0x1C4, 4),
+ TOP_MUX(CLK_TOP_INFRA_F26M_SEL, "csw_infra_f26m_sel",
+ usb_phy_parents, 0x090, 0x094, 0x098, 0, 1, 7, 0x1C4, 5),
+ TOP_MUX(CLK_TOP_PEXTP_P0_SEL, "pextp_p0_sel", usb_phy_parents,
+ 0x090, 0x094, 0x098, 8, 1, 15, 0x1C4, 6),
+ TOP_MUX(CLK_TOP_PEXTP_P1_SEL, "pextp_p1_sel", usb_phy_parents,
+ 0x090, 0x094, 0x098, 16, 1, 23, 0x1C4, 7),
+ TOP_MUX(CLK_TOP_DA_XTP_GLB_P0_SEL, "da_xtp_glb_p0_sel",
+ da_xtp_glb_p0_parents, 0x090, 0x094, 0x098, 24, 1, 31, 0x1C4, 8),
+ TOP_MUX(CLK_TOP_DA_XTP_GLB_P1_SEL, "da_xtp_glb_p1_sel",
+ da_xtp_glb_p0_parents, 0x0A0, 0x0A4, 0x0A8, 0, 1, 7, 0x1C4, 9),
+ TOP_MUX(CLK_TOP_CKM_SEL, "ckm_sel", usb_phy_parents,
+ 0x0A0, 0x0A4, 0x0A8, 8, 1, 15, 0x1C4, 10),
+ TOP_MUX(CLK_TOP_DA_CKM_XTAL_SEL, "da_ckm_xtal_sel",
+ da_ckm_xtal_parents, 0x0A0, 0x0A4, 0x0A8, 16, 1, 23, 0x1C4, 11),
+ TOP_MUX(CLK_TOP_PEXTP_SEL, "pextp_sel", usb_phy_parents,
+ 0x0A0, 0x0A4, 0x0A8, 24, 1, 31, 0x1C4, 12),
+ TOP_MUX(CLK_TOP_ETH_MII_SEL, "eth_mii_sel", eth_mii_parents,
+ 0x0B0, 0x0B4, 0x0B8, 0, 1, 7, 0x1C4, 13),
+ TOP_MUX(CLK_TOP_EMMC_200M_SEL, "emmc_200m_sel", emmc_200m_parents,
+ 0x0B0, 0x0B4, 0x0B8, 8, 3, 15, 0x1C4, 14),
+};
+
+static const struct mtk_clk_tree mt7987_topckgen_clk_tree = {
+ .muxes_offs = CLK_TOP_NETSYS_SEL,
+ .fdivs = topckgen_mtk_fixed_factors,
+ .muxes = topckgen_mtk_muxes,
+ .flags = CLK_BYPASS_XTAL | CLK_TOPCKGEN,
+ .xtal_rate = MT7987_XTAL_RATE,
+};
+
+static const struct udevice_id mt7987_topckgen_compat[] = {
+ { .compatible = "mediatek,mt7987-topckgen" },
+ {}
+};
+
+static int mt7987_topckgen_probe(struct udevice *dev)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(dev);
+
+ priv->base = dev_read_addr_ptr(dev);
+ if (!priv->base)
+ return -ENOENT;
+
+ writel(MT7987_CLK_PDN_EN_WRITE, priv->base + MT7987_CLK_PDN);
+ return mtk_common_clk_init(dev, &mt7987_topckgen_clk_tree);
+}
+
+U_BOOT_DRIVER(mtk_clk_topckgen) = {
+ .name = "mt7987-clock-topckgen",
+ .id = UCLASS_CLK,
+ .of_match = mt7987_topckgen_compat,
+ .probe = mt7987_topckgen_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+/* INFRASYS MUX PARENTS */
+
+/* CLK_INFRA_MUX_UART0_SEL (infra_mux_uart0_sel) in infracfg */
+static const int infra_mux_uart0_parents[] = {
+ CLK_TOP_INFRA_F26M_SEL,
+ CLK_TOP_UART_SEL
+};
+
+/* CLK_INFRA_MUX_UART1_SEL (infra_mux_uart1_sel) in infracfg */
+static const int infra_mux_uart1_parents[] = {
+ CLK_TOP_INFRA_F26M_SEL,
+ CLK_TOP_UART_SEL
+};
+
+/* CLK_INFRA_MUX_UART2_SEL (infra_mux_uart2_sel) in infracfg */
+static const int infra_mux_uart2_parents[] = {
+ CLK_TOP_INFRA_F26M_SEL,
+ CLK_TOP_UART_SEL
+};
+
+/* CLK_INFRA_MUX_SPI0_SEL (infra_mux_spi0_sel) in infracfg */
+static const int infra_mux_spi0_parents[] = {
+ CLK_TOP_I2C_SEL,
+ CLK_TOP_SPI_SEL
+};
+
+/* CLK_INFRA_MUX_SPI1_SEL (infra_mux_spi1_sel) in infracfg */
+static const int infra_mux_spi1_parents[] = {
+ CLK_TOP_I2C_SEL,
+ CLK_TOP_SPIM_MST_SEL
+};
+
+/* CLK_INFRA_MUX_SPI2_BCK_SEL (infra_mux_spi2_bck_sel) in infracfg */
+static const int infra_mux_spi2_bck_parents[] = {
+ CLK_TOP_I2C_SEL,
+ CLK_TOP_SPI_SEL
+};
+
+/* CLK_INFRA_PWM_BCK_SEL (infra_pwm_bck_sel) in infracfg */
+static const int infra_pwm_bck_parents[] = {
+ CLK_TOP_CB_RTC_32P7K,
+ CLK_TOP_INFRA_F26M_SEL,
+ CLK_TOP_SYSAXI_SEL,
+ CLK_TOP_PWM_SEL
+};
+
+/* CLK_INFRA_PCIE_GFMUX_TL_O_P0_SEL (infra_pcie_gfmux_tl_ck_o_p0_sel) in infracfg */
+static const int infra_pcie_gfmux_tl_ck_o_p0_parents[] = {
+ CLK_TOP_CB_RTC_32P7K,
+ CLK_TOP_INFRA_F26M_SEL,
+ CLK_TOP_INFRA_F26M_SEL,
+ CLK_TOP_PEXTP_TL_SEL
+};
+
+/* CLK_INFRA_PCIE_GFMUX_TL_O_P1_SEL (infra_pcie_gfmux_tl_ck_o_p1_sel) in infracfg */
+static const int infra_pcie_gfmux_tl_ck_o_p1_parents[] = {
+ CLK_TOP_CB_RTC_32P7K,
+ CLK_TOP_INFRA_F26M_SEL,
+ CLK_TOP_INFRA_F26M_SEL,
+ CLK_TOP_PEXTP_TL_P1_SEL
+};
+
+#define INFRA_MUX(_id, _name, _parents, _reg, _shift, _width) \
+ { \
+ .id = (_id), .mux_reg = (_reg) + 0x8, \
+ .mux_clr_reg = (_reg) + 0x4, .mux_set_reg = (_reg) + 0x0, \
+ .mux_shift = (_shift), .mux_mask = BIT(_width) - 1, \
+ .gate_shift = -1, .upd_shift = -1, \
+ .parent = (_parents), .num_parents = ARRAY_SIZE(_parents), \
+ .flags = CLK_MUX_SETCLR_UPD | CLK_PARENT_TOPCKGEN, \
+ }
+
+/* INFRA MUX */
+static const struct mtk_composite infracfg_mtk_mux[] = {
+ INFRA_MUX(CLK_INFRA_MUX_UART0_SEL, "infra_mux_uart0_sel",
+ infra_mux_uart0_parents, 0x0010, 0, 1),
+ INFRA_MUX(CLK_INFRA_MUX_UART1_SEL, "infra_mux_uart1_sel",
+ infra_mux_uart1_parents, 0x0010, 1, 1),
+ INFRA_MUX(CLK_INFRA_MUX_UART2_SEL, "infra_mux_uart2_sel",
+ infra_mux_uart2_parents, 0x0010, 2, 1),
+ INFRA_MUX(CLK_INFRA_MUX_SPI0_SEL, "infra_mux_spi0_sel",
+ infra_mux_spi0_parents, 0x0010, 4, 1),
+ INFRA_MUX(CLK_INFRA_MUX_SPI1_SEL, "infra_mux_spi1_sel",
+ infra_mux_spi1_parents, 0x0010, 5, 1),
+ INFRA_MUX(CLK_INFRA_MUX_SPI2_BCK_SEL, "infra_mux_spi2_bck_sel",
+ infra_mux_spi2_bck_parents, 0x0010, 6, 1),
+ INFRA_MUX(CLK_INFRA_PWM_BCK_SEL, "infra_pwm_bck_sel",
+ infra_pwm_bck_parents, 0x0010, 14, 2),
+ INFRA_MUX(CLK_INFRA_PCIE_GFMUX_TL_O_P0_SEL, "infra_pcie_gfmux_tl_ck_o_p0_sel",
+ infra_pcie_gfmux_tl_ck_o_p0_parents, 0x0020, 0, 2),
+ INFRA_MUX(CLK_INFRA_PCIE_GFMUX_TL_O_P1_SEL, "infra_pcie_gfmux_tl_ck_o_p1_sel",
+ infra_pcie_gfmux_tl_ck_o_p1_parents, 0x0020, 2, 2),
+};
+
+static const struct mtk_gate_regs infra_0_cg_regs = {
+ .set_ofs = 0x10,
+ .clr_ofs = 0x14,
+ .sta_ofs = 0x18,
+};
+
+static const struct mtk_gate_regs infra_1_cg_regs = {
+ .set_ofs = 0x40,
+ .clr_ofs = 0x44,
+ .sta_ofs = 0x48,
+};
+
+static const struct mtk_gate_regs infra_2_cg_regs = {
+ .set_ofs = 0x50,
+ .clr_ofs = 0x54,
+ .sta_ofs = 0x58,
+};
+
+static const struct mtk_gate_regs infra_3_cg_regs = {
+ .set_ofs = 0x60,
+ .clr_ofs = 0x64,
+ .sta_ofs = 0x68,
+};
+
+#define GATE_INFRA0(_id, _name, _parent, _shift, _flags) \
+ { \
+ .id = (_id), .parent = (_parent), .regs = &infra_0_cg_regs, \
+ .shift = (_shift), \
+ .flags = (_flags), \
+ }
+#define GATE_INFRA0_INFRA(_id, _name, _parent, _shift) \
+ GATE_INFRA0(_id, _name, _parent, _shift, CLK_GATE_SETCLR | CLK_PARENT_INFRASYS)
+#define GATE_INFRA0_TOP(_id, _name, _parent, _shift) \
+ GATE_INFRA0(_id, _name, _parent, _shift, CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN)
+
+#define GATE_INFRA1(_id, _name, _parent, _shift, _flags) \
+ { \
+ .id = (_id), .parent = (_parent), .regs = &infra_1_cg_regs, \
+ .shift = (_shift), \
+ .flags = (_flags), \
+ }
+#define GATE_INFRA1_INFRA(_id, _name, _parent, _shift) \
+ GATE_INFRA1(_id, _name, _parent, _shift, CLK_GATE_SETCLR | CLK_PARENT_INFRASYS)
+#define GATE_INFRA1_TOP(_id, _name, _parent, _shift) \
+ GATE_INFRA1(_id, _name, _parent, _shift, CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN)
+
+#define GATE_INFRA2(_id, _name, _parent, _shift, _flags) \
+ { \
+ .id = (_id), .parent = (_parent), .regs = &infra_2_cg_regs, \
+ .shift = (_shift), \
+ .flags = (_flags), \
+ }
+#define GATE_INFRA2_INFRA(_id, _name, _parent, _shift) \
+ GATE_INFRA2(_id, _name, _parent, _shift, CLK_GATE_SETCLR | CLK_PARENT_INFRASYS)
+#define GATE_INFRA2_TOP(_id, _name, _parent, _shift) \
+ GATE_INFRA2(_id, _name, _parent, _shift, CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN)
+
+#define GATE_INFRA3(_id, _name, _parent, _shift, _flags) \
+ { \
+ .id = (_id), .parent = (_parent), .regs = &infra_3_cg_regs, \
+ .shift = (_shift), \
+ .flags = (_flags), \
+ }
+#define GATE_INFRA3_INFRA(_id, _name, _parent, _shift) \
+ GATE_INFRA3(_id, _name, _parent, _shift, CLK_GATE_SETCLR | CLK_PARENT_INFRASYS)
+#define GATE_INFRA3_TOP(_id, _name, _parent, _shift) \
+ GATE_INFRA3(_id, _name, _parent, _shift, CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN)
+#define GATE_INFRA3_XTAL(_id, _name, _parent, _shift) \
+ GATE_INFRA3(_id, _name, _parent, _shift, CLK_GATE_SETCLR | CLK_PARENT_XTAL)
+
+/* INFRA GATE */
+static const struct mtk_gate infracfg_mtk_gates[] = {
+ GATE_INFRA1_TOP(CLK_INFRA_66M_GPT_BCK,
+ "infra_hf_66m_gpt_bck", CLK_TOP_SYSAXI_SEL, 0),
+ GATE_INFRA1_TOP(CLK_INFRA_66M_PWM_HCK,
+ "infra_hf_66m_pwm_hck", CLK_TOP_SYSAXI_SEL, 1),
+ GATE_INFRA1_INFRA(CLK_INFRA_66M_PWM_BCK,
+ "infra_hf_66m_pwm_bck", CLK_INFRA_PWM_BCK_SEL, 2),
+ GATE_INFRA1_TOP(CLK_INFRA_133M_CQDMA_BCK,
+ "infra_hf_133m_cqdma_bck", CLK_TOP_SYSAXI_SEL, 12),
+ GATE_INFRA1_TOP(CLK_INFRA_66M_AUD_SLV_BCK,
+ "infra_66m_aud_slv_bck", CLK_TOP_SYSAXI_SEL, 13),
+ GATE_INFRA1_TOP(CLK_INFRA_AUD_26M, "infra_f_faud_26m",
+ CLK_TOP_INFRA_F26M_SEL, 14),
+ GATE_INFRA1_TOP(CLK_INFRA_AUD_L, "infra_f_faud_l", CLK_TOP_AUD_L_SEL, 15),
+ GATE_INFRA1_TOP(CLK_INFRA_AUD_AUD, "infra_f_aud_aud", CLK_TOP_A1SYS_SEL, 16),
+ GATE_INFRA1_TOP(CLK_INFRA_AUD_EG2, "infra_f_faud_eg2",
+ CLK_TOP_A_TUNER_SEL, 18),
+ GATE_INFRA1_TOP(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m",
+ CLK_TOP_INFRA_F26M_SEL, 19),
+ GATE_INFRA1_TOP(CLK_INFRA_133M_DBG_ACKM,
+ "infra_hf_133m_dbg_ackm", CLK_TOP_SYSAXI_SEL, 20),
+ GATE_INFRA1_TOP(CLK_INFRA_66M_AP_DMA_BCK,
+ "infra_66m_ap_dma_bck", CLK_TOP_SYSAXI_SEL, 21),
+ GATE_INFRA1_TOP(CLK_INFRA_MSDC200_SRC, "infra_f_fmsdc200_src",
+ CLK_TOP_EMMC_200M_SEL, 28),
+ GATE_INFRA1_TOP(CLK_INFRA_66M_SEJ_BCK,
+ "infra_hf_66m_sej_bck", CLK_TOP_SYSAXI_SEL, 29),
+ GATE_INFRA1_TOP(CLK_INFRA_PRE_CK_SEJ_F13M,
+ "infra_pre_ck_sej_f13m", CLK_TOP_INFRA_F26M_SEL, 30),
+ GATE_INFRA1_TOP(CLK_INFRA_66M_TRNG, "infra_hf_66m_trng",
+ CLK_TOP_SYSAXI_SEL, 31),
+ GATE_INFRA2_TOP(CLK_INFRA_26M_THERM_SYSTEM,
+ "infra_hf_26m_therm_system", CLK_TOP_INFRA_F26M_SEL, 0),
+ GATE_INFRA2_TOP(CLK_INFRA_I2C_BCK, "infra_i2c_bck", CLK_TOP_I2C_SEL, 1),
+ GATE_INFRA2_TOP(CLK_INFRA_66M_UART0_PCK,
+ "infra_hf_66m_uart0_pck", CLK_TOP_SYSAXI_SEL, 3),
+ GATE_INFRA2_TOP(CLK_INFRA_66M_UART1_PCK,
+ "infra_hf_66m_uart1_pck", CLK_TOP_SYSAXI_SEL, 4),
+ GATE_INFRA2_TOP(CLK_INFRA_66M_UART2_PCK,
+ "infra_hf_66m_uart2_pck", CLK_TOP_SYSAXI_SEL, 5),
+ GATE_INFRA2_INFRA(CLK_INFRA_52M_UART0_CK,
+ "infra_f_52m_uart0", CLK_INFRA_MUX_UART0_SEL, 3),
+ GATE_INFRA2_INFRA(CLK_INFRA_52M_UART1_CK,
+ "infra_f_52m_uart1", CLK_INFRA_MUX_UART1_SEL, 4),
+ GATE_INFRA2_INFRA(CLK_INFRA_52M_UART2_CK,
+ "infra_f_52m_uart2", CLK_INFRA_MUX_UART2_SEL, 5),
+ GATE_INFRA2_TOP(CLK_INFRA_NFI, "infra_f_fnfi", CLK_TOP_NFI_SEL, 9),
+ GATE_INFRA2_TOP(CLK_INFRA_66M_NFI_HCK,
+ "infra_hf_66m_nfi_hck", CLK_TOP_SYSAXI_SEL, 11),
+ GATE_INFRA2_INFRA(CLK_INFRA_104M_SPI0, "infra_hf_104m_spi0",
+ CLK_INFRA_MUX_SPI0_SEL, 12),
+ GATE_INFRA2_INFRA(CLK_INFRA_104M_SPI1, "infra_hf_104m_spi1",
+ CLK_INFRA_MUX_SPI1_SEL, 13),
+ GATE_INFRA2_INFRA(CLK_INFRA_104M_SPI2_BCK,
+ "infra_hf_104m_spi2_bck", CLK_INFRA_MUX_SPI2_BCK_SEL, 14),
+ GATE_INFRA2_TOP(CLK_INFRA_66M_SPI0_HCK,
+ "infra_hf_66m_spi0_hck", CLK_TOP_SYSAXI_SEL, 15),
+ GATE_INFRA2_TOP(CLK_INFRA_66M_SPI1_HCK,
+ "infra_hf_66m_spi1_hck", CLK_TOP_SYSAXI_SEL, 16),
+ GATE_INFRA2_TOP(CLK_INFRA_66M_SPI2_HCK,
+ "infra_hf_66m_spi2_hck", CLK_TOP_SYSAXI_SEL, 17),
+ GATE_INFRA2_TOP(CLK_INFRA_66M_FLASHIF_AXI,
+ "infra_hf_66m_flashif_axi", CLK_TOP_SYSAXI_SEL, 18),
+ GATE_INFRA2_TOP(CLK_INFRA_RTC, "infra_f_frtc", CLK_TOP_CB_RTC_32K, 19),
+ GATE_INFRA2_TOP(CLK_INFRA_26M_ADC_BCK, "infra_f_26m_adc_bck",
+ CLK_TOP_INFRA_F26M_SEL, 20),
+ GATE_INFRA2_INFRA(CLK_INFRA_RC_ADC, "infra_f_frc_adc",
+ CLK_INFRA_26M_ADC_BCK, 21),
+ GATE_INFRA2_TOP(CLK_INFRA_MSDC400, "infra_f_fmsdc400",
+ CLK_TOP_EMMC_400M_SEL, 22),
+ GATE_INFRA2_TOP(CLK_INFRA_MSDC2_HCK, "infra_f_fmsdc2_hck",
+ CLK_TOP_EMMC_250M_SEL, 23),
+ GATE_INFRA2_TOP(CLK_INFRA_133M_MSDC_0_HCK,
+ "infra_hf_133m_msdc_0_hck", CLK_TOP_SYSAXI_SEL, 24),
+ GATE_INFRA2_TOP(CLK_INFRA_66M_MSDC_0_HCK,
+ "infra_66m_msdc_0_hck", CLK_TOP_SYSAXI_SEL, 25),
+ GATE_INFRA2_TOP(CLK_INFRA_133M_CPUM_BCK,
+ "infra_hf_133m_cpum_bck", CLK_TOP_SYSAXI_SEL, 26),
+ GATE_INFRA2_TOP(CLK_INFRA_BIST2FPC, "infra_hf_fbist2fpc",
+ CLK_TOP_NFI_SEL, 27),
+ GATE_INFRA2_TOP(CLK_INFRA_I2C_X16W_MCK_CK_P1,
+ "infra_hf_i2c_x16w_mck_ck_p1", CLK_TOP_SYSAXI_SEL, 29),
+ GATE_INFRA2_TOP(CLK_INFRA_I2C_X16W_PCK_CK_P1,
+ "infra_hf_i2c_x16w_pck_ck_p1", CLK_TOP_SYSAXI_SEL, 31),
+ GATE_INFRA3_TOP(CLK_INFRA_133M_USB_HCK,
+ "infra_133m_usb_hck", CLK_TOP_SYSAXI_SEL, 0),
+ GATE_INFRA3_TOP(CLK_INFRA_133M_USB_HCK_CK_P1,
+ "infra_133m_usb_hck_ck_p1", CLK_TOP_SYSAXI_SEL, 1),
+ GATE_INFRA3_TOP(CLK_INFRA_66M_USB_HCK, "infra_66m_usb_hck",
+ CLK_TOP_SYSAXI_SEL, 2),
+ GATE_INFRA3_TOP(CLK_INFRA_66M_USB_HCK_CK_P1,
+ "infra_66m_usb_hck_ck_p1", CLK_TOP_SYSAXI_SEL, 3),
+ GATE_INFRA3_TOP(CLK_INFRA_USB_SYS_CK_P1,
+ "infra_usb_sys_ck_p1", CLK_TOP_USB_SYS_P1_SEL, 5),
+ GATE_INFRA3_TOP(CLK_INFRA_USB_CK_P1, "infra_usb_ck_p1",
+ CLK_TOP_CB_CKSQ_40M, 7),
+ GATE_INFRA3_TOP(CLK_INFRA_USB_FRMCNT_CK_P1,
+ "infra_usb_frmcnt_ck_p1", CLK_TOP_CKSQ_40M_D2, 9),
+ GATE_INFRA3_XTAL(CLK_INFRA_USB_PIPE_CK_P1,
+ "infra_usb_pipe_ck_p1", CLK_XTAL, 11),
+ GATE_INFRA3_XTAL(CLK_INFRA_USB_UTMI_CK_P1,
+ "infra_usb_utmi_ck_p1", CLK_XTAL, 13),
+ GATE_INFRA3_TOP(CLK_INFRA_USB_XHCI_CK_P1,
+ "infra_usb_xhci_ck_p1", CLK_TOP_USB_XHCI_P1_SEL, 15),
+ GATE_INFRA3_INFRA(CLK_INFRA_PCIE_GFMUX_TL_P0,
+ "infra_pcie_gfmux_tl_ck_p0", CLK_INFRA_PCIE_GFMUX_TL_O_P0_SEL, 20),
+ GATE_INFRA3_INFRA(CLK_INFRA_PCIE_GFMUX_TL_P1,
+ "infra_pcie_gfmux_tl_ck_p1", CLK_INFRA_PCIE_GFMUX_TL_O_P1_SEL, 21),
+ GATE_INFRA3_XTAL(CLK_INFRA_PCIE_PIPE_P0,
+ "infra_pcie_pipe_ck_p0", CLK_XTAL, 24),
+ GATE_INFRA3_XTAL(CLK_INFRA_PCIE_PIPE_P1,
+ "infra_pcie_pipe_ck_p1", CLK_XTAL, 25),
+ GATE_INFRA3_TOP(CLK_INFRA_133M_PCIE_CK_P0,
+ "infra_133m_pcie_ck_p0", CLK_TOP_SYSAXI_SEL, 28),
+ GATE_INFRA3_TOP(CLK_INFRA_133M_PCIE_CK_P1,
+ "infra_133m_pcie_ck_p1", CLK_TOP_SYSAXI_SEL, 29),
+ GATE_INFRA0_TOP(CLK_INFRA_PCIE_PERI_26M_CK_P0,
+ "infra_pcie_peri_ck_26m_ck_p0", CLK_TOP_INFRA_F26M_SEL, 7),
+ GATE_INFRA0_TOP(CLK_INFRA_PCIE_PERI_26M_CK_P1,
+ "infra_pcie_peri_ck_26m_ck_p1", CLK_TOP_INFRA_F26M_SEL, 8),
+};
+
+static const struct mtk_clk_tree mt7987_infracfg_clk_tree = {
+ .muxes_offs = CLK_INFRA_MUX_UART0_SEL,
+ .gates_offs = CLK_INFRA_66M_GPT_BCK,
+ .muxes = infracfg_mtk_mux,
+ .gates = infracfg_mtk_gates,
+ .flags = CLK_BYPASS_XTAL,
+ .xtal_rate = MT7987_XTAL_RATE,
+};
+
+static const struct udevice_id mt7987_infracfg_compat[] = {
+ { .compatible = "mediatek,mt7987-infracfg_ao" },
+ { .compatible = "mediatek,mt7987-infracfg" },
+ {}
+};
+
+static int mt7987_infracfg_probe(struct udevice *dev)
+{
+ return mtk_common_clk_infrasys_init(dev, &mt7987_infracfg_clk_tree);
+}
+
+U_BOOT_DRIVER(mtk_clk_infracfg) = {
+ .name = "mt7987-clock-infracfg",
+ .id = UCLASS_CLK,
+ .of_match = mt7987_infracfg_compat,
+ .probe = mt7987_infracfg_probe,
+ .priv_auto = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_infrasys_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+/* ethsys */
+static const struct mtk_gate_regs eth_cg_regs = {
+ .set_ofs = 0x30,
+ .clr_ofs = 0x30,
+ .sta_ofs = 0x30,
+};
+
+#define GATE_ETH_TOP(_id, _name, _parent, _shift) \
+ { \
+ .id = (_id), .parent = (_parent), .regs = &eth_cg_regs, \
+ .shift = (_shift), \
+ .flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN, \
+ }
+
+static const struct mtk_gate eth_cgs[] = {
+ GATE_ETH_TOP(CLK_ETHDMA_FE_EN, "ethdma_fe_en", CLK_TOP_NETSYS_2X_SEL, 6),
+ GATE_ETH_TOP(CLK_ETHDMA_GP2_EN, "ethdma_gp2_en", CLK_TOP_NETSYS_500M_SEL, 7),
+ GATE_ETH_TOP(CLK_ETHDMA_GP1_EN, "ethdma_gp1_en", CLK_TOP_NETSYS_500M_SEL, 8),
+ GATE_ETH_TOP(CLK_ETHDMA_GP3_EN, "ethdma_gp3_en", CLK_TOP_NETSYS_500M_SEL, 10),
+};
+
+static int mt7987_ethsys_probe(struct udevice *dev)
+{
+ return mtk_common_clk_gate_init(dev, &mt7987_topckgen_clk_tree,
+ eth_cgs);
+}
+
+static int mt7987_ethsys_bind(struct udevice *dev)
+{
+ int ret = 0;
+
+ if (CONFIG_IS_ENABLED(RESET_MEDIATEK)) {
+ ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1);
+ if (ret)
+ debug("Warning: failed to bind reset controller\n");
+ }
+
+ return ret;
+}
+
+static const struct udevice_id mt7987_ethsys_compat[] = {
+ {
+ .compatible = "mediatek,mt7987-ethsys",
+ },
+ {}
+};
+
+U_BOOT_DRIVER(mtk_clk_ethsys) = {
+ .name = "mt7987-clock-ethsys",
+ .id = UCLASS_CLK,
+ .of_match = mt7987_ethsys_compat,
+ .probe = mt7987_ethsys_probe,
+ .bind = mt7987_ethsys_bind,
+ .priv_auto = sizeof(struct mtk_cg_priv),
+ .ops = &mtk_clk_gate_ops,
+};
diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c
index d676cf9e314..2bc700b0d05 100644
--- a/drivers/mmc/mtk-sd.c
+++ b/drivers/mmc/mtk-sd.c
@@ -329,6 +329,7 @@ struct msdc_compatible {
u8 clk_div_bits;
bool pad_tune0;
bool async_fifo;
+ bool async_fifo_crcsts;
bool data_tune;
bool busy_check;
bool stop_clk_fix;
@@ -1553,8 +1554,12 @@ static void msdc_init_hw(struct msdc_host *host)
/* 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->async_fifo_crcsts)
+ setbits_le32(&host->base->patch_bit2,
+ MSDC_PB2_CFGCRCSTS);
+ else
+ clrbits_le32(&host->base->patch_bit2,
+ MSDC_PB2_CFGCRCSTS);
}
if (host->dev_comp->data_tune) {
@@ -1844,6 +1849,17 @@ static const struct msdc_compatible mt7986_compat = {
.enhance_rx = true,
};
+static const struct msdc_compatible mt7987_compat = {
+ .clk_div_bits = 12,
+ .pad_tune0 = true,
+ .async_fifo = true,
+ .async_fifo_crcsts = true,
+ .data_tune = true,
+ .busy_check = true,
+ .stop_clk_fix = true,
+ .enhance_rx = true,
+};
+
static const struct msdc_compatible mt7981_compat = {
.clk_div_bits = 12,
.pad_tune0 = true,
@@ -1886,6 +1902,7 @@ static const struct udevice_id msdc_ids[] = {
{ .compatible = "mediatek,mt7622-mmc", .data = (ulong)&mt7622_compat },
{ .compatible = "mediatek,mt7623-mmc", .data = (ulong)&mt7623_compat },
{ .compatible = "mediatek,mt7986-mmc", .data = (ulong)&mt7986_compat },
+ { .compatible = "mediatek,mt7987-mmc", .data = (ulong)&mt7987_compat },
{ .compatible = "mediatek,mt7981-mmc", .data = (ulong)&mt7981_compat },
{ .compatible = "mediatek,mt8512-mmc", .data = (ulong)&mt8512_compat },
{ .compatible = "mediatek,mt8516-mmc", .data = (ulong)&mt8516_compat },
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index 34d23cece51..8b9180bd2aa 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -24,6 +24,10 @@ config PINCTRL_MT7986
bool "MT7986 SoC pinctrl driver"
select PINCTRL_MTK
+config PINCTRL_MT7987
+ bool "MT7987 SoC pinctrl driver"
+ select PINCTRL_MTK
+
config PINCTRL_MT7988
bool "MT7988 SoC pinctrl driver"
select PINCTRL_MTK
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
index de39d1ea436..b25e74e4e00 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o
obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o
obj-$(CONFIG_PINCTRL_MT7981) += pinctrl-mt7981.o
obj-$(CONFIG_PINCTRL_MT7986) += pinctrl-mt7986.o
+obj-$(CONFIG_PINCTRL_MT7987) += pinctrl-mt7987.o
obj-$(CONFIG_PINCTRL_MT7988) += pinctrl-mt7988.o
obj-$(CONFIG_PINCTRL_MT8512) += pinctrl-mt8512.o
obj-$(CONFIG_PINCTRL_MT8516) += pinctrl-mt8516.o
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7987.c b/drivers/pinctrl/mediatek/pinctrl-mt7987.c
new file mode 100644
index 00000000000..db672d26798
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7987.c
@@ -0,0 +1,736 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024 MediaTek Inc.
+ * Author: Tim.Kuo <tim.kuo@mediatek.com>
+ */
+
+#include <dm.h>
+#include "pinctrl-mtk-common.h"
+
+enum MT7987_PINCTRL_REG_PAGE {
+ GPIO_BASE,
+ IOCFG_RB_BASE,
+ IOCFG_LB_BASE,
+ IOCFG_RT1_BASE,
+ IOCFG_RT2_BASE,
+ IOCFG_TL_BASE,
+};
+
+/*
+ * IO_TYPE_GRP0 / IO_TYPE_GRP1
+ * MT7987 pins can be divided into two groups:
+ * - PUPD_R0_R1
+ * - PU/PD
+ * Here, we divide pins with PU/PD to be IO_TYPE_GRP0 and those with PUPD_R0_R1
+ * to be IO_TYPE_GRP1.
+ * - PUPD_R0_R1 : IO_TYPE_GRP0
+ * - PU/PD : IO_TYPE_GRP1
+ * DRV_GRP4
+ * For MT7987, thr driving of pins can start from 2mA and increase by 2mA
+ * increments up to 16mA.
+ */
+#define MT7987_TYPE0_PIN(_number, _name) \
+ MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP0)
+
+#define MT7987_TYPE1_PIN(_number, _name) \
+ MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP1)
+
+#define PIN_FIELD_GPIO(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \
+ PIN_FIELD_BASE_CALC(_s_pin, _e_pin, GPIO_BASE, _s_addr, _x_addrs, \
+ _s_bit, _x_bits, 32, 0)
+
+#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
+ _x_bits) \
+ PIN_FIELD_BASE_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, \
+ _s_bit, _x_bits, 32, 0)
+
+#define PINS_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \
+ _x_bits) \
+ PIN_FIELD_BASE_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, \
+ _s_bit, _x_bits, 32, 1)
+
+static const struct mtk_pin_field_calc mt7987_pin_mode_range[] = {
+ PIN_FIELD_GPIO(0, 49, 0x300, 0x10, 0, 4),
+};
+
+static const struct mtk_pin_field_calc mt7987_pin_dir_range[] = {
+ PIN_FIELD_GPIO(0, 49, 0x0, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7987_pin_di_range[] = {
+ PIN_FIELD_GPIO(0, 49, 0x200, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7987_pin_do_range[] = {
+ PIN_FIELD_GPIO(0, 49, 0x100, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7987_pin_ies_range[] = {
+ PIN_FIELD_BASE(0, 0, IOCFG_RT2_BASE, 0x20, 0x10, 3, 1),
+ PIN_FIELD_BASE(1, 1, IOCFG_RT2_BASE, 0x20, 0x10, 2, 1),
+ PIN_FIELD_BASE(2, 2, IOCFG_RT2_BASE, 0x20, 0x10, 11, 1),
+ PIN_FIELD_BASE(3, 3, IOCFG_TL_BASE, 0x20, 0x10, 2, 1),
+ PIN_FIELD_BASE(4, 4, IOCFG_TL_BASE, 0x20, 0x10, 1, 1),
+ PIN_FIELD_BASE(5, 5, IOCFG_TL_BASE, 0x20, 0x10, 3, 1),
+ PIN_FIELD_BASE(6, 6, IOCFG_TL_BASE, 0x20, 0x10, 0, 1),
+ PIN_FIELD_BASE(7, 7, IOCFG_TL_BASE, 0x20, 0x10, 4, 1),
+ PIN_FIELD_BASE(8, 8, IOCFG_RB_BASE, 0x10, 0x10, 2, 1),
+ PIN_FIELD_BASE(9, 9, IOCFG_RB_BASE, 0x10, 0x10, 1, 1),
+ PIN_FIELD_BASE(10, 10, IOCFG_RB_BASE, 0x10, 0x10, 0, 1),
+ PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x10, 0x10, 3, 1),
+ PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x10, 0x10, 4, 1),
+ PIN_FIELD_BASE(13, 13, IOCFG_RT1_BASE, 0x20, 0x10, 0, 1),
+ PIN_FIELD_BASE(14, 14, IOCFG_RT1_BASE, 0x20, 0x10, 15, 1),
+ PIN_FIELD_BASE(15, 15, IOCFG_RT1_BASE, 0x20, 0x10, 3, 1),
+ PIN_FIELD_BASE(16, 16, IOCFG_RT1_BASE, 0x20, 0x10, 7, 1),
+ PIN_FIELD_BASE(17, 17, IOCFG_RT1_BASE, 0x20, 0x10, 6, 1),
+ PIN_FIELD_BASE(18, 18, IOCFG_RT1_BASE, 0x20, 0x10, 4, 1),
+ PIN_FIELD_BASE(19, 19, IOCFG_RT1_BASE, 0x20, 0x10, 5, 1),
+ PIN_FIELD_BASE(20, 20, IOCFG_RT1_BASE, 0x20, 0x10, 8, 1),
+ PIN_FIELD_BASE(21, 21, IOCFG_RT1_BASE, 0x20, 0x10, 9, 1),
+ PIN_FIELD_BASE(22, 22, IOCFG_RT1_BASE, 0x20, 0x10, 12, 1),
+ PIN_FIELD_BASE(23, 23, IOCFG_RT1_BASE, 0x20, 0x10, 11, 1),
+ PIN_FIELD_BASE(24, 24, IOCFG_RT1_BASE, 0x20, 0x10, 10, 1),
+ PIN_FIELD_BASE(25, 25, IOCFG_RT1_BASE, 0x20, 0x10, 13, 1),
+ PIN_FIELD_BASE(26, 26, IOCFG_RT1_BASE, 0x20, 0x10, 14, 1),
+ PIN_FIELD_BASE(27, 27, IOCFG_RT2_BASE, 0x20, 0x10, 9, 1),
+ PIN_FIELD_BASE(28, 28, IOCFG_RT2_BASE, 0x20, 0x10, 7, 1),
+ PIN_FIELD_BASE(29, 29, IOCFG_RT2_BASE, 0x20, 0x10, 8, 1),
+ PIN_FIELD_BASE(30, 30, IOCFG_RT2_BASE, 0x20, 0x10, 10, 1),
+ PIN_FIELD_BASE(31, 31, IOCFG_TL_BASE, 0x20, 0x10, 5, 1),
+ PIN_FIELD_BASE(32, 32, IOCFG_TL_BASE, 0x20, 0x10, 6, 1),
+ PIN_FIELD_BASE(33, 33, IOCFG_LB_BASE, 0x20, 0x10, 2, 1),
+ PIN_FIELD_BASE(34, 34, IOCFG_LB_BASE, 0x20, 0x10, 0, 1),
+ PIN_FIELD_BASE(35, 35, IOCFG_LB_BASE, 0x20, 0x10, 4, 1),
+ PIN_FIELD_BASE(36, 36, IOCFG_LB_BASE, 0x20, 0x10, 3, 1),
+ PIN_FIELD_BASE(37, 37, IOCFG_LB_BASE, 0x20, 0x10, 1, 1),
+ PIN_FIELD_BASE(38, 38, IOCFG_LB_BASE, 0x20, 0x10, 5, 1),
+ PIN_FIELD_BASE(39, 39, IOCFG_RT1_BASE, 0x20, 0x10, 1, 1),
+ PIN_FIELD_BASE(40, 40, IOCFG_RT1_BASE, 0x20, 0x10, 2, 1),
+ PIN_FIELD_BASE(41, 41, IOCFG_RT2_BASE, 0x20, 0x10, 0, 1),
+ PIN_FIELD_BASE(42, 42, IOCFG_RT2_BASE, 0x20, 0x10, 1, 1),
+ PIN_FIELD_BASE(43, 43, IOCFG_RT2_BASE, 0x20, 0x10, 4, 1),
+ PIN_FIELD_BASE(44, 44, IOCFG_RT2_BASE, 0x20, 0x10, 5, 1),
+ PIN_FIELD_BASE(45, 45, IOCFG_RT2_BASE, 0x20, 0x10, 6, 1),
+ PIN_FIELD_BASE(46, 46, IOCFG_TL_BASE, 0x20, 0x10, 9, 1),
+ PIN_FIELD_BASE(47, 47, IOCFG_TL_BASE, 0x20, 0x10, 10, 1),
+ PIN_FIELD_BASE(48, 48, IOCFG_TL_BASE, 0x20, 0x10, 7, 1),
+ PIN_FIELD_BASE(49, 49, IOCFG_TL_BASE, 0x20, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7987_pin_smt_range[] = {
+ PIN_FIELD_BASE(0, 0, IOCFG_RT2_BASE, 0x90, 0x10, 3, 1),
+ PIN_FIELD_BASE(1, 1, IOCFG_RT2_BASE, 0x90, 0x10, 2, 1),
+ PIN_FIELD_BASE(2, 2, IOCFG_RT2_BASE, 0x90, 0x10, 11, 1),
+ PIN_FIELD_BASE(3, 3, IOCFG_TL_BASE, 0x90, 0x10, 2, 1),
+ PIN_FIELD_BASE(4, 4, IOCFG_TL_BASE, 0x90, 0x10, 1, 1),
+ PIN_FIELD_BASE(5, 5, IOCFG_TL_BASE, 0x90, 0x10, 3, 1),
+ PIN_FIELD_BASE(6, 6, IOCFG_TL_BASE, 0x90, 0x10, 0, 1),
+ PIN_FIELD_BASE(7, 7, IOCFG_TL_BASE, 0x90, 0x10, 4, 1),
+ PIN_FIELD_BASE(8, 8, IOCFG_RB_BASE, 0x70, 0x10, 2, 1),
+ PIN_FIELD_BASE(9, 9, IOCFG_RB_BASE, 0x70, 0x10, 1, 1),
+ PIN_FIELD_BASE(10, 10, IOCFG_RB_BASE, 0x70, 0x10, 0, 1),
+ PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x70, 0x10, 3, 1),
+ PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x70, 0x10, 4, 1),
+ PIN_FIELD_BASE(13, 13, IOCFG_RT1_BASE, 0xA0, 0x10, 0, 1),
+ PIN_FIELD_BASE(14, 14, IOCFG_RT1_BASE, 0xA0, 0x10, 15, 1),
+ PIN_FIELD_BASE(15, 15, IOCFG_RT1_BASE, 0xA0, 0x10, 3, 1),
+ PIN_FIELD_BASE(16, 16, IOCFG_RT1_BASE, 0xA0, 0x10, 7, 1),
+ PIN_FIELD_BASE(17, 17, IOCFG_RT1_BASE, 0xA0, 0x10, 6, 1),
+ PIN_FIELD_BASE(18, 18, IOCFG_RT1_BASE, 0xA0, 0x10, 4, 1),
+ PIN_FIELD_BASE(19, 19, IOCFG_RT1_BASE, 0xA0, 0x10, 5, 1),
+ PIN_FIELD_BASE(20, 20, IOCFG_RT1_BASE, 0xA0, 0x10, 8, 1),
+ PIN_FIELD_BASE(21, 21, IOCFG_RT1_BASE, 0xA0, 0x10, 9, 1),
+ PIN_FIELD_BASE(22, 22, IOCFG_RT1_BASE, 0xA0, 0x10, 12, 1),
+ PIN_FIELD_BASE(23, 23, IOCFG_RT1_BASE, 0xA0, 0x10, 11, 1),
+ PIN_FIELD_BASE(24, 24, IOCFG_RT1_BASE, 0xA0, 0x10, 10, 1),
+ PIN_FIELD_BASE(25, 25, IOCFG_RT1_BASE, 0xA0, 0x10, 13, 1),
+ PIN_FIELD_BASE(26, 26, IOCFG_RT1_BASE, 0xA0, 0x10, 14, 1),
+ PIN_FIELD_BASE(27, 27, IOCFG_RT2_BASE, 0x90, 0x10, 9, 1),
+ PIN_FIELD_BASE(28, 28, IOCFG_RT2_BASE, 0x90, 0x10, 7, 1),
+ PIN_FIELD_BASE(29, 29, IOCFG_RT2_BASE, 0x90, 0x10, 8, 1),
+ PIN_FIELD_BASE(30, 30, IOCFG_RT2_BASE, 0x90, 0x10, 10, 1),
+ PIN_FIELD_BASE(31, 31, IOCFG_TL_BASE, 0x90, 0x10, 5, 1),
+ PIN_FIELD_BASE(32, 32, IOCFG_TL_BASE, 0x90, 0x10, 6, 1),
+ PIN_FIELD_BASE(33, 33, IOCFG_LB_BASE, 0x60, 0x10, 2, 1),
+ PIN_FIELD_BASE(34, 34, IOCFG_LB_BASE, 0x60, 0x10, 0, 1),
+ PIN_FIELD_BASE(35, 35, IOCFG_LB_BASE, 0x60, 0x10, 4, 1),
+ PIN_FIELD_BASE(36, 36, IOCFG_LB_BASE, 0x60, 0x10, 3, 1),
+ PIN_FIELD_BASE(37, 37, IOCFG_LB_BASE, 0x60, 0x10, 1, 1),
+ PIN_FIELD_BASE(38, 38, IOCFG_LB_BASE, 0x60, 0x10, 5, 1),
+ PIN_FIELD_BASE(39, 39, IOCFG_RT1_BASE, 0xA0, 0x10, 1, 1),
+ PIN_FIELD_BASE(40, 40, IOCFG_RT1_BASE, 0xA0, 0x10, 2, 1),
+ PIN_FIELD_BASE(41, 41, IOCFG_RT2_BASE, 0x90, 0x10, 0, 1),
+ PIN_FIELD_BASE(42, 42, IOCFG_RT2_BASE, 0x90, 0x10, 1, 1),
+ PIN_FIELD_BASE(43, 43, IOCFG_RT2_BASE, 0x90, 0x10, 4, 1),
+ PIN_FIELD_BASE(44, 44, IOCFG_RT2_BASE, 0x90, 0x10, 5, 1),
+ PIN_FIELD_BASE(45, 45, IOCFG_RT2_BASE, 0x90, 0x10, 6, 1),
+ PIN_FIELD_BASE(46, 46, IOCFG_TL_BASE, 0x90, 0x10, 9, 1),
+ PIN_FIELD_BASE(47, 47, IOCFG_TL_BASE, 0x90, 0x10, 10, 1),
+ PIN_FIELD_BASE(48, 48, IOCFG_TL_BASE, 0x90, 0x10, 7, 1),
+ PIN_FIELD_BASE(49, 49, IOCFG_TL_BASE, 0x90, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7987_pin_pu_range[] = {
+ PIN_FIELD_BASE(33, 33, IOCFG_LB_BASE, 0x40, 0x10, 2, 1),
+ PIN_FIELD_BASE(34, 34, IOCFG_LB_BASE, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(35, 35, IOCFG_LB_BASE, 0x40, 0x10, 4, 1),
+ PIN_FIELD_BASE(36, 36, IOCFG_LB_BASE, 0x40, 0x10, 3, 1),
+ PIN_FIELD_BASE(37, 37, IOCFG_LB_BASE, 0x40, 0x10, 1, 1),
+ PIN_FIELD_BASE(38, 38, IOCFG_LB_BASE, 0x40, 0x10, 5, 1),
+};
+
+static const struct mtk_pin_field_calc mt7987_pin_pd_range[] = {
+ PIN_FIELD_BASE(33, 33, IOCFG_LB_BASE, 0x30, 0x10, 2, 1),
+ PIN_FIELD_BASE(34, 34, IOCFG_LB_BASE, 0x30, 0x10, 0, 1),
+ PIN_FIELD_BASE(35, 35, IOCFG_LB_BASE, 0x30, 0x10, 4, 1),
+ PIN_FIELD_BASE(36, 36, IOCFG_LB_BASE, 0x30, 0x10, 3, 1),
+ PIN_FIELD_BASE(37, 37, IOCFG_LB_BASE, 0x30, 0x10, 1, 1),
+ PIN_FIELD_BASE(38, 38, IOCFG_LB_BASE, 0x30, 0x10, 5, 1),
+};
+
+static const struct mtk_pin_field_calc mt7987_pin_drv_range[] = {
+ PIN_FIELD_BASE(0, 0, IOCFG_RT2_BASE, 0x0, 0x10, 9, 3),
+ PIN_FIELD_BASE(1, 1, IOCFG_RT2_BASE, 0x0, 0x10, 6, 3),
+ PIN_FIELD_BASE(2, 2, IOCFG_RT2_BASE, 0x10, 0x10, 3, 3),
+ PIN_FIELD_BASE(3, 3, IOCFG_TL_BASE, 0x0, 0x10, 6, 3),
+ PIN_FIELD_BASE(4, 4, IOCFG_TL_BASE, 0x0, 0x10, 3, 3),
+ PIN_FIELD_BASE(5, 5, IOCFG_TL_BASE, 0x0, 0x10, 9, 3),
+ PIN_FIELD_BASE(6, 6, IOCFG_TL_BASE, 0x0, 0x10, 0, 3),
+ PIN_FIELD_BASE(7, 7, IOCFG_TL_BASE, 0x0, 0x10, 12, 3),
+ PIN_FIELD_BASE(8, 8, IOCFG_RB_BASE, 0x0, 0x10, 6, 3),
+ PIN_FIELD_BASE(9, 9, IOCFG_RB_BASE, 0x0, 0x10, 3, 3),
+ PIN_FIELD_BASE(10, 10, IOCFG_RB_BASE, 0x0, 0x10, 0, 3),
+ PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x0, 0x10, 9, 3),
+ PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x0, 0x10, 12, 3),
+ PIN_FIELD_BASE(13, 13, IOCFG_RT1_BASE, 0x0, 0x10, 0, 3),
+ PIN_FIELD_BASE(14, 14, IOCFG_RT1_BASE, 0x10, 0x10, 15, 3),
+ PIN_FIELD_BASE(15, 15, IOCFG_RT1_BASE, 0x0, 0x10, 9, 3),
+ PIN_FIELD_BASE(16, 16, IOCFG_RT1_BASE, 0x0, 0x10, 21, 3),
+ PIN_FIELD_BASE(17, 17, IOCFG_RT1_BASE, 0x0, 0x10, 18, 3),
+ PIN_FIELD_BASE(18, 18, IOCFG_RT1_BASE, 0x0, 0x10, 12, 3),
+ PIN_FIELD_BASE(19, 19, IOCFG_RT1_BASE, 0x0, 0x10, 15, 3),
+ PIN_FIELD_BASE(20, 20, IOCFG_RT1_BASE, 0x0, 0x10, 24, 3),
+ PIN_FIELD_BASE(21, 21, IOCFG_RT1_BASE, 0x0, 0x10, 27, 3),
+ PIN_FIELD_BASE(22, 22, IOCFG_RT1_BASE, 0x10, 0x10, 6, 3),
+ PIN_FIELD_BASE(23, 23, IOCFG_RT1_BASE, 0x10, 0x10, 3, 3),
+ PIN_FIELD_BASE(24, 24, IOCFG_RT1_BASE, 0x10, 0x10, 0, 3),
+ PIN_FIELD_BASE(25, 25, IOCFG_RT1_BASE, 0x10, 0x10, 9, 3),
+ PIN_FIELD_BASE(26, 26, IOCFG_RT1_BASE, 0x10, 0x10, 12, 3),
+ PIN_FIELD_BASE(27, 27, IOCFG_RT2_BASE, 0x0, 0x10, 27, 3),
+ PIN_FIELD_BASE(28, 28, IOCFG_RT2_BASE, 0x0, 0x10, 21, 3),
+ PIN_FIELD_BASE(29, 29, IOCFG_RT2_BASE, 0x0, 0x10, 24, 3),
+ PIN_FIELD_BASE(30, 30, IOCFG_RT2_BASE, 0x10, 0x10, 0, 3),
+ PIN_FIELD_BASE(31, 31, IOCFG_TL_BASE, 0x0, 0x10, 15, 3),
+ PIN_FIELD_BASE(32, 32, IOCFG_TL_BASE, 0x0, 0x10, 18, 3),
+ PIN_FIELD_BASE(33, 33, IOCFG_LB_BASE, 0x0, 0x10, 6, 3),
+ PIN_FIELD_BASE(34, 34, IOCFG_LB_BASE, 0x0, 0x10, 0, 3),
+ PIN_FIELD_BASE(35, 35, IOCFG_LB_BASE, 0x0, 0x10, 12, 3),
+ PIN_FIELD_BASE(36, 36, IOCFG_LB_BASE, 0x0, 0x10, 9, 3),
+ PIN_FIELD_BASE(37, 37, IOCFG_LB_BASE, 0x0, 0x10, 3, 3),
+ PIN_FIELD_BASE(38, 38, IOCFG_LB_BASE, 0x0, 0x10, 15, 3),
+ PIN_FIELD_BASE(39, 39, IOCFG_RT1_BASE, 0x0, 0x10, 3, 3),
+ PIN_FIELD_BASE(40, 40, IOCFG_RT1_BASE, 0x0, 0x10, 6, 3),
+ PIN_FIELD_BASE(41, 41, IOCFG_RT2_BASE, 0x0, 0x10, 0, 3),
+ PIN_FIELD_BASE(42, 42, IOCFG_RT2_BASE, 0x0, 0x10, 3, 3),
+ PIN_FIELD_BASE(43, 43, IOCFG_RT2_BASE, 0x0, 0x10, 12, 3),
+ PIN_FIELD_BASE(44, 44, IOCFG_RT2_BASE, 0x0, 0x10, 15, 3),
+ PIN_FIELD_BASE(45, 45, IOCFG_RT2_BASE, 0x0, 0x10, 18, 3),
+ PIN_FIELD_BASE(46, 46, IOCFG_TL_BASE, 0x0, 0x10, 27, 3),
+ PIN_FIELD_BASE(47, 47, IOCFG_TL_BASE, 0x10, 0x10, 0, 3),
+ PIN_FIELD_BASE(48, 48, IOCFG_TL_BASE, 0x0, 0x10, 21, 3),
+ PIN_FIELD_BASE(49, 49, IOCFG_TL_BASE, 0x0, 0x10, 24, 3),
+};
+
+static const struct mtk_pin_field_calc mt7987_pin_pupd_range[] = {
+ PIN_FIELD_BASE(0, 0, IOCFG_RT2_BASE, 0x30, 0x10, 3, 1),
+ PIN_FIELD_BASE(1, 1, IOCFG_RT2_BASE, 0x30, 0x10, 2, 1),
+ PIN_FIELD_BASE(2, 2, IOCFG_RT2_BASE, 0x30, 0x10, 11, 1),
+ PIN_FIELD_BASE(3, 3, IOCFG_TL_BASE, 0x30, 0x10, 2, 1),
+ PIN_FIELD_BASE(4, 4, IOCFG_TL_BASE, 0x30, 0x10, 1, 1),
+ PIN_FIELD_BASE(5, 5, IOCFG_TL_BASE, 0x30, 0x10, 3, 1),
+ PIN_FIELD_BASE(6, 6, IOCFG_TL_BASE, 0x30, 0x10, 0, 1),
+ PIN_FIELD_BASE(7, 7, IOCFG_TL_BASE, 0x30, 0x10, 4, 1),
+ PIN_FIELD_BASE(8, 8, IOCFG_RB_BASE, 0x20, 0x10, 2, 1),
+ PIN_FIELD_BASE(9, 9, IOCFG_RB_BASE, 0x20, 0x10, 1, 1),
+ PIN_FIELD_BASE(10, 10, IOCFG_RB_BASE, 0x20, 0x10, 0, 1),
+ PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x20, 0x10, 3, 1),
+ PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x20, 0x10, 4, 1),
+ PIN_FIELD_BASE(13, 13, IOCFG_RT1_BASE, 0x30, 0x10, 0, 1),
+ PIN_FIELD_BASE(14, 14, IOCFG_RT1_BASE, 0x30, 0x10, 15, 1),
+ PIN_FIELD_BASE(15, 15, IOCFG_RT1_BASE, 0x30, 0x10, 3, 1),
+ PIN_FIELD_BASE(16, 16, IOCFG_RT1_BASE, 0x30, 0x10, 7, 1),
+ PIN_FIELD_BASE(17, 17, IOCFG_RT1_BASE, 0x30, 0x10, 6, 1),
+ PIN_FIELD_BASE(18, 18, IOCFG_RT1_BASE, 0x30, 0x10, 4, 1),
+ PIN_FIELD_BASE(19, 19, IOCFG_RT1_BASE, 0x30, 0x10, 5, 1),
+ PIN_FIELD_BASE(20, 20, IOCFG_RT1_BASE, 0x30, 0x10, 8, 1),
+ PIN_FIELD_BASE(21, 21, IOCFG_RT1_BASE, 0x30, 0x10, 9, 1),
+ PIN_FIELD_BASE(22, 22, IOCFG_RT1_BASE, 0x30, 0x10, 12, 1),
+ PIN_FIELD_BASE(23, 23, IOCFG_RT1_BASE, 0x30, 0x10, 11, 1),
+ PIN_FIELD_BASE(24, 24, IOCFG_RT1_BASE, 0x30, 0x10, 10, 1),
+ PIN_FIELD_BASE(25, 25, IOCFG_RT1_BASE, 0x30, 0x10, 13, 1),
+ PIN_FIELD_BASE(26, 26, IOCFG_RT1_BASE, 0x30, 0x10, 14, 1),
+ PIN_FIELD_BASE(27, 27, IOCFG_RT2_BASE, 0x30, 0x10, 9, 1),
+ PIN_FIELD_BASE(28, 28, IOCFG_RT2_BASE, 0x30, 0x10, 7, 1),
+ PIN_FIELD_BASE(29, 29, IOCFG_RT2_BASE, 0x30, 0x10, 8, 1),
+ PIN_FIELD_BASE(30, 30, IOCFG_RT2_BASE, 0x30, 0x10, 10, 1),
+ PIN_FIELD_BASE(31, 31, IOCFG_TL_BASE, 0x30, 0x10, 5, 1),
+ PIN_FIELD_BASE(32, 32, IOCFG_TL_BASE, 0x30, 0x10, 6, 1),
+
+ PIN_FIELD_BASE(39, 39, IOCFG_RT1_BASE, 0x30, 0x10, 1, 1),
+ PIN_FIELD_BASE(40, 40, IOCFG_RT1_BASE, 0x30, 0x10, 2, 1),
+ PIN_FIELD_BASE(41, 41, IOCFG_RT2_BASE, 0x30, 0x10, 0, 1),
+ PIN_FIELD_BASE(42, 42, IOCFG_RT2_BASE, 0x30, 0x10, 1, 1),
+ PIN_FIELD_BASE(43, 43, IOCFG_RT2_BASE, 0x30, 0x10, 4, 1),
+ PIN_FIELD_BASE(44, 44, IOCFG_RT2_BASE, 0x30, 0x10, 5, 1),
+ PIN_FIELD_BASE(45, 45, IOCFG_RT2_BASE, 0x30, 0x10, 6, 1),
+ PIN_FIELD_BASE(46, 46, IOCFG_TL_BASE, 0x30, 0x10, 9, 1),
+ PIN_FIELD_BASE(47, 47, IOCFG_TL_BASE, 0x30, 0x10, 10, 1),
+ PIN_FIELD_BASE(48, 48, IOCFG_TL_BASE, 0x30, 0x10, 7, 1),
+ PIN_FIELD_BASE(49, 49, IOCFG_TL_BASE, 0x30, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7987_pin_r0_range[] = {
+ PIN_FIELD_BASE(0, 0, IOCFG_RT2_BASE, 0x40, 0x10, 3, 1),
+ PIN_FIELD_BASE(1, 1, IOCFG_RT2_BASE, 0x40, 0x10, 2, 1),
+ PIN_FIELD_BASE(2, 2, IOCFG_RT2_BASE, 0x40, 0x10, 11, 1),
+ PIN_FIELD_BASE(3, 3, IOCFG_TL_BASE, 0x40, 0x10, 2, 1),
+ PIN_FIELD_BASE(4, 4, IOCFG_TL_BASE, 0x40, 0x10, 1, 1),
+ PIN_FIELD_BASE(5, 5, IOCFG_TL_BASE, 0x40, 0x10, 3, 1),
+ PIN_FIELD_BASE(6, 6, IOCFG_TL_BASE, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(7, 7, IOCFG_TL_BASE, 0x40, 0x10, 4, 1),
+ PIN_FIELD_BASE(8, 8, IOCFG_RB_BASE, 0x30, 0x10, 2, 1),
+ PIN_FIELD_BASE(9, 9, IOCFG_RB_BASE, 0x30, 0x10, 1, 1),
+ PIN_FIELD_BASE(10, 10, IOCFG_RB_BASE, 0x30, 0x10, 0, 1),
+ PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x30, 0x10, 3, 1),
+ PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x30, 0x10, 4, 1),
+ PIN_FIELD_BASE(13, 13, IOCFG_RT1_BASE, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(14, 14, IOCFG_RT1_BASE, 0x40, 0x10, 15, 1),
+ PIN_FIELD_BASE(15, 15, IOCFG_RT1_BASE, 0x40, 0x10, 3, 1),
+ PIN_FIELD_BASE(16, 16, IOCFG_RT1_BASE, 0x40, 0x10, 7, 1),
+ PIN_FIELD_BASE(17, 17, IOCFG_RT1_BASE, 0x40, 0x10, 6, 1),
+ PIN_FIELD_BASE(18, 18, IOCFG_RT1_BASE, 0x40, 0x10, 4, 1),
+ PIN_FIELD_BASE(19, 19, IOCFG_RT1_BASE, 0x40, 0x10, 5, 1),
+ PIN_FIELD_BASE(20, 20, IOCFG_RT1_BASE, 0x40, 0x10, 8, 1),
+ PIN_FIELD_BASE(21, 21, IOCFG_RT1_BASE, 0x40, 0x10, 9, 1),
+ PIN_FIELD_BASE(22, 22, IOCFG_RT1_BASE, 0x40, 0x10, 12, 1),
+ PIN_FIELD_BASE(23, 23, IOCFG_RT1_BASE, 0x40, 0x10, 11, 1),
+ PIN_FIELD_BASE(24, 24, IOCFG_RT1_BASE, 0x40, 0x10, 10, 1),
+ PIN_FIELD_BASE(25, 25, IOCFG_RT1_BASE, 0x40, 0x10, 13, 1),
+ PIN_FIELD_BASE(26, 26, IOCFG_RT1_BASE, 0x40, 0x10, 14, 1),
+ PIN_FIELD_BASE(27, 27, IOCFG_RT2_BASE, 0x40, 0x10, 9, 1),
+ PIN_FIELD_BASE(28, 28, IOCFG_RT2_BASE, 0x40, 0x10, 7, 1),
+ PIN_FIELD_BASE(29, 29, IOCFG_RT2_BASE, 0x40, 0x10, 8, 1),
+ PIN_FIELD_BASE(30, 30, IOCFG_RT2_BASE, 0x40, 0x10, 10, 1),
+ PIN_FIELD_BASE(31, 31, IOCFG_TL_BASE, 0x40, 0x10, 5, 1),
+ PIN_FIELD_BASE(32, 32, IOCFG_TL_BASE, 0x40, 0x10, 6, 1),
+
+ PIN_FIELD_BASE(39, 39, IOCFG_RT1_BASE, 0x40, 0x10, 1, 1),
+ PIN_FIELD_BASE(40, 40, IOCFG_RT1_BASE, 0x40, 0x10, 2, 1),
+ PIN_FIELD_BASE(41, 41, IOCFG_RT2_BASE, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(42, 42, IOCFG_RT2_BASE, 0x40, 0x10, 1, 1),
+ PIN_FIELD_BASE(43, 43, IOCFG_RT2_BASE, 0x40, 0x10, 4, 1),
+ PIN_FIELD_BASE(44, 44, IOCFG_RT2_BASE, 0x40, 0x10, 5, 1),
+ PIN_FIELD_BASE(45, 45, IOCFG_RT2_BASE, 0x40, 0x10, 6, 1),
+ PIN_FIELD_BASE(46, 46, IOCFG_TL_BASE, 0x40, 0x10, 9, 1),
+ PIN_FIELD_BASE(47, 47, IOCFG_TL_BASE, 0x40, 0x10, 10, 1),
+ PIN_FIELD_BASE(48, 48, IOCFG_TL_BASE, 0x40, 0x10, 7, 1),
+ PIN_FIELD_BASE(49, 49, IOCFG_TL_BASE, 0x40, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7987_pin_r1_range[] = {
+ PIN_FIELD_BASE(0, 0, IOCFG_RT2_BASE, 0x50, 0x10, 3, 1),
+ PIN_FIELD_BASE(1, 1, IOCFG_RT2_BASE, 0x50, 0x10, 2, 1),
+ PIN_FIELD_BASE(2, 2, IOCFG_RT2_BASE, 0x50, 0x10, 11, 1),
+ PIN_FIELD_BASE(3, 3, IOCFG_TL_BASE, 0x50, 0x10, 2, 1),
+ PIN_FIELD_BASE(4, 4, IOCFG_TL_BASE, 0x50, 0x10, 1, 1),
+ PIN_FIELD_BASE(5, 5, IOCFG_TL_BASE, 0x50, 0x10, 3, 1),
+ PIN_FIELD_BASE(6, 6, IOCFG_TL_BASE, 0x50, 0x10, 0, 1),
+ PIN_FIELD_BASE(7, 7, IOCFG_TL_BASE, 0x50, 0x10, 4, 1),
+ PIN_FIELD_BASE(8, 8, IOCFG_RB_BASE, 0x40, 0x10, 2, 1),
+ PIN_FIELD_BASE(9, 9, IOCFG_RB_BASE, 0x40, 0x10, 1, 1),
+ PIN_FIELD_BASE(10, 10, IOCFG_RB_BASE, 0x40, 0x10, 0, 1),
+ PIN_FIELD_BASE(11, 11, IOCFG_RB_BASE, 0x40, 0x10, 3, 1),
+ PIN_FIELD_BASE(12, 12, IOCFG_RB_BASE, 0x40, 0x10, 4, 1),
+ PIN_FIELD_BASE(13, 13, IOCFG_RT1_BASE, 0x50, 0x10, 0, 1),
+ PIN_FIELD_BASE(14, 14, IOCFG_RT1_BASE, 0x50, 0x10, 15, 1),
+ PIN_FIELD_BASE(15, 15, IOCFG_RT1_BASE, 0x50, 0x10, 3, 1),
+ PIN_FIELD_BASE(16, 16, IOCFG_RT1_BASE, 0x50, 0x10, 7, 1),
+ PIN_FIELD_BASE(17, 17, IOCFG_RT1_BASE, 0x50, 0x10, 6, 1),
+ PIN_FIELD_BASE(18, 18, IOCFG_RT1_BASE, 0x50, 0x10, 4, 1),
+ PIN_FIELD_BASE(19, 19, IOCFG_RT1_BASE, 0x50, 0x10, 5, 1),
+ PIN_FIELD_BASE(20, 20, IOCFG_RT1_BASE, 0x50, 0x10, 8, 1),
+ PIN_FIELD_BASE(21, 21, IOCFG_RT1_BASE, 0x50, 0x10, 9, 1),
+ PIN_FIELD_BASE(22, 22, IOCFG_RT1_BASE, 0x50, 0x10, 12, 1),
+ PIN_FIELD_BASE(23, 23, IOCFG_RT1_BASE, 0x50, 0x10, 11, 1),
+ PIN_FIELD_BASE(24, 24, IOCFG_RT1_BASE, 0x50, 0x10, 10, 1),
+ PIN_FIELD_BASE(25, 25, IOCFG_RT1_BASE, 0x50, 0x10, 13, 1),
+ PIN_FIELD_BASE(26, 26, IOCFG_RT1_BASE, 0x50, 0x10, 14, 1),
+ PIN_FIELD_BASE(27, 27, IOCFG_RT2_BASE, 0x50, 0x10, 9, 1),
+ PIN_FIELD_BASE(28, 28, IOCFG_RT2_BASE, 0x50, 0x10, 7, 1),
+ PIN_FIELD_BASE(29, 29, IOCFG_RT2_BASE, 0x50, 0x10, 8, 1),
+ PIN_FIELD_BASE(30, 30, IOCFG_RT2_BASE, 0x50, 0x10, 10, 1),
+ PIN_FIELD_BASE(31, 31, IOCFG_TL_BASE, 0x50, 0x10, 5, 1),
+ PIN_FIELD_BASE(32, 32, IOCFG_TL_BASE, 0x50, 0x10, 6, 1),
+
+ PIN_FIELD_BASE(39, 39, IOCFG_RT1_BASE, 0x50, 0x10, 1, 1),
+ PIN_FIELD_BASE(40, 40, IOCFG_RT1_BASE, 0x50, 0x10, 2, 1),
+ PIN_FIELD_BASE(41, 41, IOCFG_RT2_BASE, 0x50, 0x10, 0, 1),
+ PIN_FIELD_BASE(42, 42, IOCFG_RT2_BASE, 0x50, 0x10, 1, 1),
+ PIN_FIELD_BASE(43, 43, IOCFG_RT2_BASE, 0x50, 0x10, 4, 1),
+ PIN_FIELD_BASE(44, 44, IOCFG_RT2_BASE, 0x50, 0x10, 5, 1),
+ PIN_FIELD_BASE(45, 45, IOCFG_RT2_BASE, 0x50, 0x10, 6, 1),
+ PIN_FIELD_BASE(46, 46, IOCFG_TL_BASE, 0x50, 0x10, 9, 1),
+ PIN_FIELD_BASE(47, 47, IOCFG_TL_BASE, 0x50, 0x10, 10, 1),
+ PIN_FIELD_BASE(48, 48, IOCFG_TL_BASE, 0x50, 0x10, 7, 1),
+ PIN_FIELD_BASE(49, 49, IOCFG_TL_BASE, 0x50, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_reg_calc mt7987_reg_cals[] = {
+ [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7987_pin_mode_range),
+ [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7987_pin_dir_range),
+ [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7987_pin_di_range),
+ [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7987_pin_do_range),
+ [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7987_pin_smt_range),
+ [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7987_pin_ies_range),
+ [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7987_pin_pu_range),
+ [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7987_pin_pd_range),
+ [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7987_pin_drv_range),
+ [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7987_pin_pupd_range),
+ [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7987_pin_r0_range),
+ [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7987_pin_r1_range),
+};
+
+static const struct mtk_pin_desc mt7987_pins[] = {
+ MT7987_TYPE0_PIN(0, "GPIO_WPS"),
+ MT7987_TYPE0_PIN(1, "GPIO_RESET"),
+ MT7987_TYPE0_PIN(2, "SYS_WATCHDOG"),
+ MT7987_TYPE0_PIN(3, "JTAG_JTDO"),
+ MT7987_TYPE0_PIN(4, "JTAG_JTDI"),
+ MT7987_TYPE0_PIN(5, "JTAG_JTMS"),
+ MT7987_TYPE0_PIN(6, "JTAG_JTCLK"),
+ MT7987_TYPE0_PIN(7, "JTAG_JTRST_N"),
+ MT7987_TYPE0_PIN(8, "PCM_DTX_I2S_DOUT"),
+ MT7987_TYPE0_PIN(9, "PCM_DRX_I2S_DIN"),
+ MT7987_TYPE0_PIN(10, "PCM_CLK_I2S_BCLK"),
+ MT7987_TYPE0_PIN(11, "PCM_FS_I2S_LRCK"),
+ MT7987_TYPE0_PIN(12, "PCM_MCK_I2S_MCLK"),
+ MT7987_TYPE0_PIN(13, "PWM0"),
+ MT7987_TYPE0_PIN(14, "USB_VBUS"),
+ MT7987_TYPE0_PIN(15, "SPI0_CLK"),
+ MT7987_TYPE0_PIN(16, "SPI0_MOSI"),
+ MT7987_TYPE0_PIN(17, "SPI0_MISO"),
+ MT7987_TYPE0_PIN(18, "SPI0_CS"),
+ MT7987_TYPE0_PIN(19, "SPI0_HOLD"),
+ MT7987_TYPE0_PIN(20, "SPI0_WP"),
+ MT7987_TYPE0_PIN(21, "SPI1_CLK"),
+ MT7987_TYPE0_PIN(22, "SPI1_MOSI"),
+ MT7987_TYPE0_PIN(23, "SPI1_MISO"),
+ MT7987_TYPE0_PIN(24, "SPI1_CS"),
+ MT7987_TYPE0_PIN(25, "SPI2_CLK"),
+ MT7987_TYPE0_PIN(26, "SPI2_MOSI"),
+ MT7987_TYPE0_PIN(27, "SPI2_MISO"),
+ MT7987_TYPE0_PIN(28, "SPI2_CS"),
+ MT7987_TYPE0_PIN(29, "SPI2_HOLD"),
+ MT7987_TYPE0_PIN(30, "SPI2_WP"),
+ MT7987_TYPE0_PIN(31, "UART0_RXD"),
+ MT7987_TYPE0_PIN(32, "UART0_TXD"),
+ MT7987_TYPE1_PIN(33, "PCIE_PERESET_N_0"),
+ MT7987_TYPE1_PIN(34, "PCIE_CLK_REQ_0"),
+ MT7987_TYPE1_PIN(35, "PCIE_WAKE_N_0"),
+ MT7987_TYPE1_PIN(36, "PCIE_PERESET_N_1"),
+ MT7987_TYPE1_PIN(37, "PCIE_CLK_REQ_1"),
+ MT7987_TYPE1_PIN(38, "PCIE_WAKE_N_1"),
+ MT7987_TYPE0_PIN(39, "SMI_MDC"),
+ MT7987_TYPE0_PIN(40, "SMI_MDIO"),
+ MT7987_TYPE0_PIN(41, "GBE_INT"),
+ MT7987_TYPE0_PIN(42, "GBE_RESET"),
+ MT7987_TYPE0_PIN(43, "I2C_SCLK"),
+ MT7987_TYPE0_PIN(44, "I2C_SDATA"),
+ MT7987_TYPE0_PIN(45, "2P5G_LED0"),
+ MT7987_TYPE0_PIN(46, "UART1_RXD"),
+ MT7987_TYPE0_PIN(47, "UART1_TXD"),
+ MT7987_TYPE0_PIN(48, "UART1_CTS"),
+ MT7987_TYPE0_PIN(49, "UART1_RTS"),
+};
+
+/* watchdog */
+static const int mt7987_watchdog_pins[] = {2};
+static const int mt7987_watchdog_funcs[] = {1};
+
+/* jtag */
+static const int mt7987_jtag_pins[] = {3, 4, 5, 6, 7};
+static const int mt7987_jtag_funcs[] = {1, 1, 1, 1, 1};
+
+/* pcm */
+static const int mt7987_pcm0_0_pins[] = {3, 4, 5, 6, 7};
+static const int mt7987_pcm0_0_funcs[] = {2, 2, 2, 2, 2};
+
+static const int mt7987_pcm0_1_pins[] = {8, 9, 10, 11, 12};
+static const int mt7987_pcm0_1_funcs[] = {1, 1, 1, 1, 1};
+
+/* uart */
+static const int mt7987_uart0_pins[] = {31, 32};
+static const int mt7987_uart0_funcs[] = {1, 1};
+
+static const int mt7987_uart1_0_pins[] = {3, 4, 5, 6};
+static const int mt7987_uart1_0_funcs[] = {3, 3, 3, 3};
+
+static const int mt7987_uart1_1_pins[] = {21, 22, 23, 24};
+static const int mt7987_uart1_1_funcs[] = {3, 3, 3, 3};
+
+static const int mt7987_uart1_2_pins[] = {46, 47, 48, 49};
+static const int mt7987_uart1_2_funcs[] = {1, 1, 1, 1};
+
+static const int mt7987_uart2_0_pins[] = {8, 9, 10, 11};
+static const int mt7987_uart2_0_funcs[] = {2, 2, 2, 2};
+
+static const int mt7987_uart2_1_pins[] = {25, 26, 27, 28};
+static const int mt7987_uart2_1_funcs[] = {2, 2, 2, 2};
+
+/* pwm */
+static const int mt7987_pwm0_pins[] = {13};
+static const int mt7987_pwm0_funcs[] = {1};
+
+static const int mt7987_pwm1_0_pins[] = {7};
+static const int mt7987_pwm1_0_funcs[] = {3};
+
+static const int mt7987_pwm1_1_pins[] = {43};
+static const int mt7987_pwm1_1_funcs[] = {2};
+
+static const int mt7987_pwm2_0_pins[] = {12};
+static const int mt7987_pwm2_0_funcs[] = {2};
+
+static const int mt7987_pwm2_1_pins[] = {44};
+static const int mt7987_pwm2_1_funcs[] = {2};
+
+/* vbus */
+static const int mt7987_drv_vbus_p1_pins[] = {14};
+static const int mt7987_drv_vbus_p1_funcs[] = {1};
+
+static const int mt7987_drv_vbus_pins[] = {48};
+static const int mt7987_drv_vbus_funcs[] = {3};
+
+/* 2p5gbe_led */
+static const int mt7987_2p5gbe_led0_pins[] = {45};
+static const int mt7987_2p5gbe_led0_funcs[] = {1};
+
+static const int mt7987_2p5gbe_led1_0_pins[] = {13};
+static const int mt7987_2p5gbe_led1_0_funcs[] = {2};
+
+static const int mt7987_2p5gbe_led1_1_pins[] = {49};
+static const int mt7987_2p5gbe_led1_1_funcs[] = {3};
+
+/* mdc, mdio */
+static const int mt7987_2p5g_ext_mdc_mdio_pins[] = {23, 24};
+static const int mt7987_2p5g_ext_mdc_mdio_funcs[] = {4, 4};
+
+static const int mt7987_mdc_mdio_pins[] = {39, 40};
+static const int mt7987_mdc_mdio_funcs[] = {1, 1};
+
+/* spi */
+static const int mt7987_spi0_pins[] = {15, 16, 17, 18};
+static const int mt7987_spi0_funcs[] = {1, 1, 1, 1};
+
+static const int mt7987_spi0_wp_hold_pins[] = {19, 20};
+static const int mt7987_spi0_wp_hold_funcs[] = {1, 1};
+
+static const int mt7987_spi1_pins[] = {21, 22, 23, 24};
+static const int mt7987_spi1_funcs[] = {1, 1, 1, 1};
+
+static const int mt7987_spi1_1_pins[] = {46, 47, 48, 49};
+static const int mt7987_spi1_1_funcs[] = {2, 2, 2, 2};
+
+static const int mt7987_spi2_pins[] = {25, 26, 27, 28};
+static const int mt7987_spi2_funcs[] = {1, 1, 1, 1};
+
+static const int mt7987_spi2_wp_hold_pins[] = {29, 30};
+static const int mt7987_spi2_wp_hold_funcs[] = {1, 1};
+
+/* emmc */
+static const int mt7987_emmc_45_pins[] = {14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
+static const int mt7987_emmc_45_funcs[] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
+
+/* sd */
+static const int mt7987_sd_pins[] = {15, 16, 17, 18, 23, 24};
+static const int mt7987_sd_funcs[] = {2, 2, 2, 2, 2, 2};
+
+/* i2c */
+static const int mt7987_i2c0_0_pins[] = {29, 30};
+static const int mt7987_i2c0_0_funcs[] = {2, 2};
+
+static const int mt7987_i2c0_1_pins[] = {39, 40};
+static const int mt7987_i2c0_1_funcs[] = {2, 2};
+
+static const int mt7987_i2c0_2_pins[] = {43, 44};
+static const int mt7987_i2c0_2_funcs[] = {1, 1};
+
+/* pcie */
+static const int mt7987_pcie0_pereset_pins[] = {33};
+static const int mt7987_pcie0_pereset_funcs[] = {1};
+
+static const int mt7987_pcie0_clkreq_pins[] = {34};
+static const int mt7987_pcie0_clkreq_funcs[] = {1};
+
+static const int mt7987_pcie0_wake_pins[] = {35};
+static const int mt7987_pcie0_wake_funcs[] = {1};
+
+static const int mt7987_pcie1_pereset_pins[] = {36};
+static const int mt7987_pcie1_pereset_funcs[] = {1};
+
+static const int mt7987_pcie1_clkreq_pins[] = {37};
+static const int mt7987_pcie1_clkreq_funcs[] = {1};
+
+static const int mt7987_pcie1_wake_pins[] = {38};
+static const int mt7987_pcie1_wake_funcs[] = {1};
+
+static const int mt7987_pcie_phy_i2c_pins[] = {43, 44};
+static const int mt7987_pcie_phy_i2c_funcs[] = {3, 3};
+
+/* snfi */
+static const int mt7987_snfi_pins[] = {25, 26, 27, 28, 29, 30};
+static const int mt7987_snfi_funcs[] = {3, 3, 3, 3, 3, 3};
+
+/*
+ * - int hsgmii :
+ * For pin41 and pin46, they now can only be used as gpio mode for polling
+ * event. Hence, there's no need to open their pinctrl setting.
+ * - dfd, udi :
+ * Due to dfd & udi functions are only used as detection pins for cpu during
+ * dvt testing stage, we also remove their pinctrl setting.
+ */
+
+static const struct mtk_group_desc mt7987_groups[] = {
+ PINCTRL_PIN_GROUP("watchdog", mt7987_watchdog),
+ PINCTRL_PIN_GROUP("jtag", mt7987_jtag),
+ PINCTRL_PIN_GROUP("pcm0_0", mt7987_pcm0_0),
+ PINCTRL_PIN_GROUP("pcm0_1", mt7987_pcm0_1),
+ PINCTRL_PIN_GROUP("uart0", mt7987_uart0),
+ PINCTRL_PIN_GROUP("uart1_0", mt7987_uart1_0),
+ PINCTRL_PIN_GROUP("uart1_1", mt7987_uart1_1),
+ PINCTRL_PIN_GROUP("uart1_2", mt7987_uart1_2),
+ PINCTRL_PIN_GROUP("uart2_0", mt7987_uart2_0),
+ PINCTRL_PIN_GROUP("uart2_1", mt7987_uart2_1),
+ PINCTRL_PIN_GROUP("pwm0", mt7987_pwm0),
+ PINCTRL_PIN_GROUP("pwm1_0", mt7987_pwm1_0),
+ PINCTRL_PIN_GROUP("pwm1_1", mt7987_pwm1_1),
+ PINCTRL_PIN_GROUP("pwm2_0", mt7987_pwm2_0),
+ PINCTRL_PIN_GROUP("pwm2_1", mt7987_pwm2_1),
+ PINCTRL_PIN_GROUP("drv_vbus_p1", mt7987_drv_vbus_p1),
+ PINCTRL_PIN_GROUP("drv_vbus", mt7987_drv_vbus),
+ PINCTRL_PIN_GROUP("2p5gbe_led0", mt7987_2p5gbe_led0),
+ PINCTRL_PIN_GROUP("2p5gbe_led1_0", mt7987_2p5gbe_led1_0),
+ PINCTRL_PIN_GROUP("2p5gbe_led1_1", mt7987_2p5gbe_led1_1),
+ PINCTRL_PIN_GROUP("2p5g_ext_mdc_mdio", mt7987_2p5g_ext_mdc_mdio),
+ PINCTRL_PIN_GROUP("mdc_mdio", mt7987_mdc_mdio),
+ PINCTRL_PIN_GROUP("spi0", mt7987_spi0),
+ PINCTRL_PIN_GROUP("spi0_wp_hold", mt7987_spi0_wp_hold),
+ PINCTRL_PIN_GROUP("spi1", mt7987_spi1),
+ PINCTRL_PIN_GROUP("spi1_1", mt7987_spi1_1),
+ PINCTRL_PIN_GROUP("spi2", mt7987_spi2),
+ PINCTRL_PIN_GROUP("spi2_wp_hold", mt7987_spi2_wp_hold),
+ PINCTRL_PIN_GROUP("emmc_45", mt7987_emmc_45),
+ PINCTRL_PIN_GROUP("sd", mt7987_sd),
+ PINCTRL_PIN_GROUP("i2c0_0", mt7987_i2c0_0),
+ PINCTRL_PIN_GROUP("i2c0_1", mt7987_i2c0_1),
+ PINCTRL_PIN_GROUP("i2c0_2", mt7987_i2c0_2),
+ PINCTRL_PIN_GROUP("pcie_phy_i2c", mt7987_pcie_phy_i2c),
+ PINCTRL_PIN_GROUP("pcie0_pereset", mt7987_pcie0_pereset),
+ PINCTRL_PIN_GROUP("pcie0_clkreq", mt7987_pcie0_clkreq),
+ PINCTRL_PIN_GROUP("pcie0_wake", mt7987_pcie0_wake),
+ PINCTRL_PIN_GROUP("pcie1_pereset", mt7987_pcie1_pereset),
+ PINCTRL_PIN_GROUP("pcie1_clkreq", mt7987_pcie1_clkreq),
+ PINCTRL_PIN_GROUP("pcie1_wake", mt7987_pcie1_wake),
+ PINCTRL_PIN_GROUP("snfi", mt7987_snfi),
+};
+
+static const struct mtk_io_type_desc mt7987_io_type_desc[] = {
+ [IO_TYPE_GRP0] = {
+ .name = "18OD33",
+ .bias_set = mtk_pinconf_bias_set_pupd_r1_r0,
+ .drive_set = mtk_pinconf_drive_set_v1,
+ .input_enable = mtk_pinconf_input_enable_v1,
+ },
+ [IO_TYPE_GRP1] = {
+ .name = "18A01",
+ .bias_set = mtk_pinconf_bias_set_pu_pd,
+ .drive_set = mtk_pinconf_drive_set_v1,
+ .input_enable = mtk_pinconf_input_enable_v1,
+ },
+};
+
+static const char *const mt7987_wdt_groups[] = {"watchdog",};
+static const char *const mt7987_jtag_groups[] = {"jtag",};
+static const char *const mt7987_pcm_groups[] = {"pcm0_0", "pcm0_1"};
+static const char *const mt7987_uart_groups[] = {"uart0", "uart1_0", "uart1_1",
+ "uart1_2", "uart2_0", "uart2_1",};
+static const char *const mt7987_pwm_groups[] = {"pwm0", "pwm1_0", "pwm1_1", "pwm2_0",
+ "pwm2_1",};
+static const char *const mt7987_usb_groups[] = {"drv_vbus_p1", "drv_vbus",};
+static const char *const mt7987_led_groups[] = {"2p5gbe_led0", "2p5gbe_led1_0",
+ "2p5gbe_led1_1",};
+static const char *const mt7987_ethernet_groups[] = {"2p5g_ext_mdc_mdio", "mdc_mdio",};
+static const char *const mt7987_spi_groups[] = {"spi0", "spi0_wp_hold", "spi1",
+ "spi1_1", "spi2", "spi2_wp_hold",};
+static const char *const mt7987_flash_groups[] = {"emmc_45", "snfi", "sd",};
+static const char *const mt7987_i2c_groups[] = {"i2c0_0", "i2c0_1", "i2c0_2",};
+static const char *const mt7987_pcie_groups[] = {"pcie_phy_i2c", "pcie0_pereset",
+ "pcie0_clkreq", "pcie0_wake",
+ "pcie1_pereset", "pcie1_clkreq",
+ "pcie1_wake",};
+
+static const struct mtk_function_desc mt7987_functions[] = {
+ {"wdt", mt7987_wdt_groups, ARRAY_SIZE(mt7987_wdt_groups)},
+ {"jtag", mt7987_jtag_groups, ARRAY_SIZE(mt7987_jtag_groups)},
+ {"pcm", mt7987_pcm_groups, ARRAY_SIZE(mt7987_pcm_groups)},
+ {"uart", mt7987_uart_groups, ARRAY_SIZE(mt7987_uart_groups)},
+ {"pwm", mt7987_pwm_groups, ARRAY_SIZE(mt7987_pwm_groups)},
+ {"usb", mt7987_usb_groups, ARRAY_SIZE(mt7987_usb_groups)},
+ {"led", mt7987_led_groups, ARRAY_SIZE(mt7987_led_groups)},
+ {"eth", mt7987_ethernet_groups, ARRAY_SIZE(mt7987_ethernet_groups)},
+ {"spi", mt7987_spi_groups, ARRAY_SIZE(mt7987_spi_groups)},
+ {"flash", mt7987_flash_groups, ARRAY_SIZE(mt7987_flash_groups)},
+ {"i2c", mt7987_i2c_groups, ARRAY_SIZE(mt7987_i2c_groups)},
+ {"pcie", mt7987_pcie_groups, ARRAY_SIZE(mt7987_pcie_groups)},
+};
+
+static const char *const mt7987_pinctrl_register_base_names[] = {
+ "gpio", "iocfg_rb", "iocfg_lb", "iocfg_rt1", "iocfg_rt2", "iocfg_tl",
+};
+
+static const struct mtk_pinctrl_soc mt7987_data = {
+ .name = "mt7987_pinctrl",
+ .reg_cal = mt7987_reg_cals,
+ .pins = mt7987_pins,
+ .npins = ARRAY_SIZE(mt7987_pins),
+ .grps = mt7987_groups,
+ .ngrps = ARRAY_SIZE(mt7987_groups),
+ .funcs = mt7987_functions,
+ .nfuncs = ARRAY_SIZE(mt7987_functions),
+ .io_type = mt7987_io_type_desc,
+ .ntype = ARRAY_SIZE(mt7987_io_type_desc),
+ .gpio_mode = 0,
+ .base_names = mt7987_pinctrl_register_base_names,
+ .nbase_names = ARRAY_SIZE(mt7987_pinctrl_register_base_names),
+ .base_calc = 1,
+};
+
+static int mtk_pinctrl_mt7987_probe(struct udevice *dev)
+{
+ return mtk_pinctrl_common_probe(dev, &mt7987_data);
+}
+
+static const struct udevice_id mt7987_pctrl_match[] = {
+ {.compatible = "mediatek,mt7987-pinctrl"},
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(mt7987_pinctrl) = {
+ .name = "mt7987_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = mt7987_pctrl_match,
+ .ops = &mtk_pinctrl_ops,
+ .bind = mtk_pinctrl_common_bind,
+ .probe = mtk_pinctrl_mt7987_probe,
+ .priv_auto = sizeof(struct mtk_pinctrl_priv),
+};
diff --git a/include/configs/mt7987.h b/include/configs/mt7987.h
new file mode 100644
index 00000000000..18ed3c7a55b
--- /dev/null
+++ b/include/configs/mt7987.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Configuration for MediaTek MT7987 SoC
+ *
+ * Copyright (C) 2025 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#ifndef __MT7987_H
+#define __MT7987_H
+
+#define CFG_MAX_MEM_MAPPED 0xC0000000
+
+#endif
diff --git a/include/dt-bindings/clock/mediatek,mt7987-clk.h b/include/dt-bindings/clock/mediatek,mt7987-clk.h
new file mode 100644
index 00000000000..c7472ef9ebb
--- /dev/null
+++ b/include/dt-bindings/clock/mediatek,mt7987-clk.h
@@ -0,0 +1,206 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2024 MediaTek Inc.
+ * Author: Lu Tang <Lu.Tang@mediatek.com>
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT7987_H
+#define _DT_BINDINGS_CLK_MT7987_H
+
+/* INFRACFG */
+
+#define CLK_INFRA_MUX_UART0_SEL 0
+#define CLK_INFRA_MUX_UART1_SEL 1
+#define CLK_INFRA_MUX_UART2_SEL 2
+#define CLK_INFRA_MUX_SPI0_SEL 3
+#define CLK_INFRA_MUX_SPI1_SEL 4
+#define CLK_INFRA_MUX_SPI2_BCK_SEL 5
+#define CLK_INFRA_PWM_BCK_SEL 6
+#define CLK_INFRA_PCIE_GFMUX_TL_O_P0_SEL 7
+#define CLK_INFRA_PCIE_GFMUX_TL_O_P1_SEL 8
+#define CLK_INFRA_66M_GPT_BCK 9
+#define CLK_INFRA_66M_PWM_HCK 10
+#define CLK_INFRA_66M_PWM_BCK 11
+#define CLK_INFRA_133M_CQDMA_BCK 12
+#define CLK_INFRA_66M_AUD_SLV_BCK 13
+#define CLK_INFRA_AUD_26M 14
+#define CLK_INFRA_AUD_L 15
+#define CLK_INFRA_AUD_AUD 16
+#define CLK_INFRA_AUD_EG2 17
+#define CLK_INFRA_DRAMC_F26M 18
+#define CLK_INFRA_133M_DBG_ACKM 19
+#define CLK_INFRA_66M_AP_DMA_BCK 20
+#define CLK_INFRA_MSDC200_SRC 21
+#define CLK_INFRA_66M_SEJ_BCK 22
+#define CLK_INFRA_PRE_CK_SEJ_F13M 23
+#define CLK_INFRA_66M_TRNG 24
+#define CLK_INFRA_26M_THERM_SYSTEM 25
+#define CLK_INFRA_I2C_BCK 26
+#define CLK_INFRA_66M_UART0_PCK 27
+#define CLK_INFRA_66M_UART1_PCK 28
+#define CLK_INFRA_66M_UART2_PCK 29
+#define CLK_INFRA_52M_UART0_CK 30
+#define CLK_INFRA_52M_UART1_CK 31
+#define CLK_INFRA_52M_UART2_CK 32
+#define CLK_INFRA_NFI 33
+#define CLK_INFRA_66M_NFI_HCK 34
+#define CLK_INFRA_104M_SPI0 35
+#define CLK_INFRA_104M_SPI1 36
+#define CLK_INFRA_104M_SPI2_BCK 37
+#define CLK_INFRA_66M_SPI0_HCK 38
+#define CLK_INFRA_66M_SPI1_HCK 39
+#define CLK_INFRA_66M_SPI2_HCK 40
+#define CLK_INFRA_66M_FLASHIF_AXI 41
+#define CLK_INFRA_RTC 42
+#define CLK_INFRA_26M_ADC_BCK 43
+#define CLK_INFRA_RC_ADC 44
+#define CLK_INFRA_MSDC400 45
+#define CLK_INFRA_MSDC2_HCK 46
+#define CLK_INFRA_133M_MSDC_0_HCK 47
+#define CLK_INFRA_66M_MSDC_0_HCK 48
+#define CLK_INFRA_133M_CPUM_BCK 49
+#define CLK_INFRA_BIST2FPC 50
+#define CLK_INFRA_I2C_X16W_MCK_CK_P1 51
+#define CLK_INFRA_I2C_X16W_PCK_CK_P1 52
+#define CLK_INFRA_133M_USB_HCK 53
+#define CLK_INFRA_133M_USB_HCK_CK_P1 54
+#define CLK_INFRA_66M_USB_HCK 55
+#define CLK_INFRA_66M_USB_HCK_CK_P1 56
+#define CLK_INFRA_USB_SYS_CK_P1 57
+#define CLK_INFRA_USB_CK_P1 58
+#define CLK_INFRA_USB_FRMCNT_CK_P1 59
+#define CLK_INFRA_USB_PIPE_CK_P1 60
+#define CLK_INFRA_USB_UTMI_CK_P1 61
+#define CLK_INFRA_USB_XHCI_CK_P1 62
+#define CLK_INFRA_PCIE_GFMUX_TL_P0 63
+#define CLK_INFRA_PCIE_GFMUX_TL_P1 64
+#define CLK_INFRA_PCIE_PIPE_P0 65
+#define CLK_INFRA_PCIE_PIPE_P1 66
+#define CLK_INFRA_133M_PCIE_CK_P0 67
+#define CLK_INFRA_133M_PCIE_CK_P1 68
+#define CLK_INFRA_PCIE_PERI_26M_CK_P0 69
+#define CLK_INFRA_PCIE_PERI_26M_CK_P1 70
+#define CLK_INFRA_NR_CLK 71
+
+/* TOPCKGEN */
+
+#define CLK_TOP_CB_M_D2 0
+#define CLK_TOP_CB_M_D3 1
+#define CLK_TOP_M_D3_D2 2
+#define CLK_TOP_CB_M_D4 3
+#define CLK_TOP_CB_M_D8 4
+#define CLK_TOP_M_D8_D2 5
+#define CLK_TOP_CB_APLL2_D4 6
+#define CLK_TOP_CB_NET1_D3 7
+#define CLK_TOP_CB_NET1_D4 8
+#define CLK_TOP_CB_NET1_D5 9
+#define CLK_TOP_NET1_D5_D2 10
+#define CLK_TOP_NET1_D5_D4 11
+#define CLK_TOP_CB_NET1_D7 12
+#define CLK_TOP_NET1_D7_D2 13
+#define CLK_TOP_NET1_D7_D4 14
+#define CLK_TOP_NET1_D8_D2 15
+#define CLK_TOP_NET1_D8_D4 16
+#define CLK_TOP_NET1_D8_D8 17
+#define CLK_TOP_NET1_D8_D16 18
+#define CLK_TOP_CB_NET2_D2 19
+#define CLK_TOP_CB_NET2_D4 20
+#define CLK_TOP_NET2_D4_D4 21
+#define CLK_TOP_NET2_D4_D8 22
+#define CLK_TOP_CB_NET2_D6 23
+#define CLK_TOP_NET2_D7_D2 24
+#define CLK_TOP_CB_NET2_D8 25
+#define CLK_TOP_MSDC_D2 26
+#define CLK_TOP_CB_CKSQ_40M 27
+#define CLK_TOP_CKSQ_40M_D2 28
+#define CLK_TOP_CB_RTC_32K 29
+#define CLK_TOP_CB_RTC_32P7K 30
+#define CLK_TOP_NETSYS_SEL 31
+#define CLK_TOP_NETSYS_500M_SEL 32
+#define CLK_TOP_NETSYS_2X_SEL 33
+#define CLK_TOP_ETH_GMII_SEL 34
+#define CLK_TOP_EIP_SEL 35
+#define CLK_TOP_AXI_INFRA_SEL 36
+#define CLK_TOP_UART_SEL 37
+#define CLK_TOP_EMMC_250M_SEL 38
+#define CLK_TOP_EMMC_400M_SEL 39
+#define CLK_TOP_SPI_SEL 40
+#define CLK_TOP_SPIM_MST_SEL 41
+#define CLK_TOP_NFI_SEL 42
+#define CLK_TOP_PWM_SEL 43
+#define CLK_TOP_I2C_SEL 44
+#define CLK_TOP_PCIE_MBIST_250M_SEL 45
+#define CLK_TOP_PEXTP_TL_SEL 46
+#define CLK_TOP_PEXTP_TL_P1_SEL 47
+#define CLK_TOP_USB_SYS_P1_SEL 48
+#define CLK_TOP_USB_XHCI_P1_SEL 49
+#define CLK_TOP_AUD_SEL 50
+#define CLK_TOP_A1SYS_SEL 51
+#define CLK_TOP_AUD_L_SEL 52
+#define CLK_TOP_A_TUNER_SEL 53
+#define CLK_TOP_USB_PHY_SEL 54
+#define CLK_TOP_SGM_0_SEL 55
+#define CLK_TOP_SGM_SBUS_0_SEL 56
+#define CLK_TOP_SGM_1_SEL 57
+#define CLK_TOP_SGM_SBUS_1_SEL 58
+#define CLK_TOP_SYSAXI_SEL 59
+#define CLK_TOP_SYSAPB_SEL 60
+#define CLK_TOP_ETH_REFCK_50M_SEL 61
+#define CLK_TOP_ETH_SYS_200M_SEL 62
+#define CLK_TOP_ETH_SYS_SEL 63
+#define CLK_TOP_ETH_XGMII_SEL 64
+#define CLK_TOP_DRAMC_SEL 65
+#define CLK_TOP_DRAMC_MD32_SEL 66
+#define CLK_TOP_INFRA_F26M_SEL 67
+#define CLK_TOP_PEXTP_P0_SEL 68
+#define CLK_TOP_PEXTP_P1_SEL 69
+#define CLK_TOP_DA_XTP_GLB_P0_SEL 70
+#define CLK_TOP_DA_XTP_GLB_P1_SEL 71
+#define CLK_TOP_CKM_SEL 72
+#define CLK_TOP_DA_CKM_XTAL_SEL 73
+#define CLK_TOP_PEXTP_SEL 74
+#define CLK_TOP_ETH_MII_SEL 75
+#define CLK_TOP_EMMC_200M_SEL 76
+#define CLK_TOP_AUD_I2S_M 77
+#define CLK_TOP_NR_CLK 78
+
+/* APMIXEDSYS */
+
+#define CLK_APMIXED_MPLL 0
+#define CLK_APMIXED_APLL2 1
+#define CLK_APMIXED_NET1PLL 2
+#define CLK_APMIXED_NET2PLL 3
+#define CLK_APMIXED_WEDMCUPLL 4
+#define CLK_APMIXED_SGMPLL 5
+#define CLK_APMIXED_ARM_LL 6
+#define CLK_APMIXED_MSDCPLL 7
+#define CLK_APMIXED_NR_CLK 8
+
+/* MCUSYS */
+
+#define CLK_MCU_BUS_DIV_SEL 0
+#define CLK_MCU_NR_CLK 1
+
+/* SGMIISYS_0 */
+
+#define CLK_SGM0_TX_EN 0
+#define CLK_SGM0_RX_EN 1
+#define CLK_SGMII0_NR_CLK 2
+
+/* SGMIISYS_1 */
+
+#define CLK_SGM1_TX_EN 0
+#define CLK_SGM1_RX_EN 1
+#define CLK_SGMII1_NR_CLK 2
+
+/* ETHDMA */
+
+#define CLK_ETHDMA_FE_EN 0
+#define CLK_ETHDMA_GP2_EN 1
+#define CLK_ETHDMA_GP1_EN 2
+#define CLK_ETHDMA_GP3_EN 3
+#define CLK_ETHDMA_NR_CLK 4
+
+#endif /* _DT_BINDINGS_CLK_MT7987_H */
+