mediatek: add mt7986 soc support to the target
authorSam Shih <sam.shih@mediatek.com>
Sun, 10 Apr 2022 12:49:09 +0000 (20:49 +0800)
committerDaniel Golle <daniel@makrotopia.org>
Sun, 28 Aug 2022 19:33:15 +0000 (20:33 +0100)
It will be supported by the new filogic subtarget

Signed-off-by: Sam Shih <sam.shih@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
25 files changed:
target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts [new file with mode: 0644]
target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nor.dts [new file with mode: 0644]
target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts [new file with mode: 0644]
target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986a.dtsi [new file with mode: 0644]
target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts [new file with mode: 0644]
target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986b.dtsi [new file with mode: 0644]
target/linux/mediatek/files-5.15/drivers/clk/mediatek/clk-mt7986-apmixed.c [new file with mode: 0644]
target/linux/mediatek/files-5.15/drivers/clk/mediatek/clk-mt7986-eth.c [new file with mode: 0644]
target/linux/mediatek/files-5.15/drivers/clk/mediatek/clk-mt7986-infracfg.c [new file with mode: 0644]
target/linux/mediatek/files-5.15/drivers/clk/mediatek/clk-mt7986-topckgen.c [new file with mode: 0644]
target/linux/mediatek/files-5.15/drivers/pinctrl/mediatek/pinctrl-mt7986.c [new file with mode: 0644]
target/linux/mediatek/files-5.15/include/dt-bindings/clock/mt7986-clk.h [new file with mode: 0644]
target/linux/mediatek/files-5.15/include/dt-bindings/reset/mt7986-resets.h [new file with mode: 0644]
target/linux/mediatek/mt7622/config-5.15
target/linux/mediatek/mt7623/config-5.15
target/linux/mediatek/mt7629/config-5.15
target/linux/mediatek/patches-5.15/210-pinctrl-mediatek-add-support-for-MT7986-SoC.patch [new file with mode: 0644]
target/linux/mediatek/patches-5.15/211-clk-mediatek-Add-API-for-clock-resource-recycle.patch [new file with mode: 0644]
target/linux/mediatek/patches-5.15/212-clk-mediatek-add-mt7986-clock-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-5.15/213-spi-mediatek-add-mt7986-spi-support [new file with mode: 0644]
target/linux/mediatek/patches-5.15/320-mmc-mediatek-add-support-for-MT7986-SoC.patch [new file with mode: 0644]
target/linux/mediatek/patches-5.15/405-mt7986-trng-add-rng-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-5.15/920-watchdog-add-mt7986-assert.patch [new file with mode: 0644]
target/linux/mediatek/patches-5.15/921-mt7986-add-mmc-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-5.15/922-PCI-mediatek-gen3-change-driver-name-to-mtk-pcie-gen.patch [new file with mode: 0644]

diff --git a/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts b/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nand.dts
new file mode 100644 (file)
index 0000000..72b8923
--- /dev/null
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+
+/dts-v1/;
+/plugin/;
+
+/ {
+        compatible = "mediatek,mt7986a-spim-snand-rfb";
+
+        fragment@0 {
+               target-path = "/soc/spi@1100a000";
+                __overlay__ {
+                       status = "okay";
+                       spi_nand: spi_nand@0 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "spi-nand";
+                               reg = <1>;
+                               spi-max-frequency = <10000000>;
+                               spi-tx-buswidth = <4>;
+                               spi-rx-buswidth = <4>;
+
+                               partitions {
+                                       compatible = "fixed-partitions";
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+                                       partition@0 {
+                                               label = "BL2";
+                                               reg = <0x00000 0x0100000>;
+                                               read-only;
+                                       };
+                                       partition@100000 {
+                                               label = "u-boot-env";
+                                               reg = <0x0100000 0x0080000>;
+                                       };
+                                       factory: partition@180000 {
+                                               label = "Factory";
+                                               reg = <0x180000 0x0200000>;
+                                       };
+                                       partition@380000 {
+                                               label = "FIP";
+                                               reg = <0x380000 0x0200000>;
+                                       };
+                                       partition@580000 {
+                                               label = "ubi";
+                                               reg = <0x580000 0x4000000>;
+                                       };
+                               };
+                       };
+               };
+        };
+};
diff --git a/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nor.dts b/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986a-rfb-spim-nor.dts
new file mode 100644 (file)
index 0000000..b847e48
--- /dev/null
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+
+/dts-v1/;
+/plugin/;
+
+/ {
+        compatible = "mediatek,mt7986a-snor-rfb";
+
+        fragment@0 {
+               target-path = "/soc/spi@1100a000";
+               __overlay__ {
+                       status = "okay";
+                       spi_nor: spi_nor@0 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "jedec,spi-nor";
+                               reg = <0>;
+                               spi-max-frequency = <52000000>;
+                               spi-tx-buswidth = <4>;
+                               spi-rx-buswidth = <4>;
+                               partitions {
+                                       compatible = "fixed-partitions";
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+
+                                       partition@00000 {
+                                               label = "BL2";
+                                               reg = <0x00000 0x0040000>;
+                                       };
+                                       partition@40000 {
+                                               label = "u-boot-env";
+                                               reg = <0x40000 0x0010000>;
+                                       };
+                                       factory: partition@50000 {
+                                               label = "Factory";
+                                               reg = <0x50000 0x00B0000>;
+                                       };
+                                       partition@100000 {
+                                               label = "FIP";
+                                               reg = <0x100000 0x0080000>;
+                                       };
+                                       partition@180000 {
+                                               label = "firmware";
+                                               reg = <0x180000 0xE00000>;
+                                       };
+                               };
+                       };
+               };
+        };
+};
diff --git a/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts b/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
new file mode 100644 (file)
index 0000000..41ae5f1
--- /dev/null
@@ -0,0 +1,378 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7986a.dtsi"
+
+/ {
+       model = "MediaTek MT7986a RFB";
+       compatible = "mediatek,mt7986a-rfb";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory {
+               reg = <0 0x40000000 0 0x40000000>;
+       };
+
+       reg_1p8v: regulator-1p8v {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-1.8V";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       reg_3p3v: regulator-3p3v {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-3.3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       reg_5v: regulator-5v {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+};
+
+&eth {
+       status = "okay";
+
+       gmac0: mac@0 {
+               compatible = "mediatek,eth-mac";
+               reg = <0>;
+               phy-mode = "2500base-x";
+
+               fixed-link {
+                       speed = <2500>;
+                       full-duplex;
+                       pause;
+               };
+       };
+
+       gmac1: mac@1 {
+               compatible = "mediatek,eth-mac";
+               reg = <1>;
+               phy-mode = "2500base-x";
+
+               fixed-link {
+                       speed = <2500>;
+                       full-duplex;
+                       pause;
+               };
+       };
+
+       mdio: mdio-bus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+};
+
+&wmac {
+       status = "okay";
+       pinctrl-names = "default", "dbdc";
+       pinctrl-0 = <&wf_2g_5g_pins>;
+       pinctrl-1 = <&wf_dbdc_pins>;
+};
+
+&mdio {
+       phy5: phy@5 {
+               compatible = "ethernet-phy-id67c9.de0a";
+               reg = <5>;
+               reset-gpios = <&pio 6 1>;
+               reset-deassert-us = <20000>;
+               phy-mode = "2500base-x";
+       };
+
+       phy6: phy@6 {
+               compatible = "ethernet-phy-id67c9.de0a";
+               reg = <6>;
+               phy-mode = "2500base-x";
+       };
+
+       switch: switch@0 {
+               compatible = "mediatek,mt7531";
+               reg = <31>;
+               reset-gpios = <&pio 5 0>;
+       };
+};
+
+&crypto {
+       status = "okay";
+};
+
+&mmc0 {
+       pinctrl-names = "default", "state_uhs";
+       pinctrl-0 = <&mmc0_pins_default>;
+       pinctrl-1 = <&mmc0_pins_uhs>;
+       bus-width = <8>;
+       max-frequency = <200000000>;
+       cap-mmc-highspeed;
+       mmc-hs200-1_8v;
+       mmc-hs400-1_8v;
+       hs400-ds-delay = <0x14014>;
+       vmmc-supply = <&reg_3p3v>;
+       vqmmc-supply = <&reg_1p8v>;
+       non-removable;
+       no-sd;
+       no-sdio;
+       status = "okay";
+};
+
+&pcie {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie_pins>;
+       status = "okay";
+};
+
+&pcie_phy {
+       status = "okay";
+};
+
+&pio {
+       mmc0_pins_default: mmc0-pins {
+               mux {
+                       function = "emmc";
+                       groups = "emmc_51";
+               };
+               conf-cmd-dat {
+                       pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
+                              "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
+                              "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
+                       input-enable;
+                       drive-strength = <4>;
+                       mediatek,pull-up-adv = <1>;     /* pull-up 10K */
+               };
+               conf-clk {
+                       pins = "EMMC_CK";
+                       drive-strength = <6>;
+                       mediatek,pull-down-adv = <2>;   /* pull-down 50K */
+               };
+               conf-ds {
+                       pins = "EMMC_DSL";
+                       mediatek,pull-down-adv = <2>;   /* pull-down 50K */
+               };
+               conf-rst {
+                       pins = "EMMC_RSTB";
+                       drive-strength = <4>;
+                       mediatek,pull-up-adv = <1>;     /* pull-up 10K */
+               };
+       };
+
+       mmc0_pins_uhs: mmc0-uhs-pins {
+               mux {
+                       function = "emmc";
+                       groups = "emmc_51";
+               };
+               conf-cmd-dat {
+                       pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2",
+                              "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5",
+                              "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD";
+                       input-enable;
+                       drive-strength = <4>;
+                       mediatek,pull-up-adv = <1>;     /* pull-up 10K */
+               };
+               conf-clk {
+                       pins = "EMMC_CK";
+                       drive-strength = <6>;
+                       mediatek,pull-down-adv = <2>;   /* pull-down 50K */
+               };
+               conf-ds {
+                       pins = "EMMC_DSL";
+                       mediatek,pull-down-adv = <2>;   /* pull-down 50K */
+               };
+               conf-rst {
+                       pins = "EMMC_RSTB";
+                       drive-strength = <4>;
+                       mediatek,pull-up-adv = <1>;     /* pull-up 10K */
+               };
+       };
+
+       pcie_pins: pcie-pins {
+               mux {
+                       function = "pcie";
+                       groups = "pcie_clk", "pcie_wake", "pcie_pereset";
+               };
+       };
+
+       spic_pins_g2: spic-pins-29-to-32 {
+               mux {
+                       function = "spi";
+                       groups = "spi1_2";
+               };
+       };
+
+       spi_flash_pins: spi-flash-pins-33-to-38 {
+               mux {
+                       function = "spi";
+                       groups = "spi0", "spi0_wp_hold";
+               };
+               conf-pu {
+                       pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+                       drive-strength = <8>;
+                       mediatek,pull-up-adv = <0>;     /* bias-disable */
+               };
+               conf-pd {
+                       pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+                       drive-strength = <8>;
+                       mediatek,pull-down-adv = <0>;   /* bias-disable */
+               };
+       };
+
+       uart1_pins: uart1-pins {
+               mux {
+                       function = "uart";
+                       groups = "uart1";
+               };
+       };
+
+       uart2_pins: uart2-pins {
+               mux {
+                       function = "uart";
+                       groups = "uart2";
+               };
+       };
+
+       wf_2g_5g_pins: wf_2g_5g-pins {
+               mux {
+                       function = "wifi";
+                       groups = "wf_2g", "wf_5g";
+               };
+               conf {
+                       pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
+                              "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
+                              "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
+                              "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
+                              "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
+                              "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
+                              "WF1_TOP_CLK", "WF1_TOP_DATA";
+                       drive-strength = <4>;
+               };
+       };
+
+       wf_dbdc_pins: wf_dbdc-pins {
+               mux {
+                       function = "wifi";
+                       groups = "wf_dbdc";
+               };
+               conf {
+                       pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
+                              "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
+                              "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
+                              "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
+                              "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
+                              "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
+                              "WF1_TOP_CLK", "WF1_TOP_DATA";
+                       drive-strength = <4>;
+               };
+       };
+};
+
+&spi0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi_flash_pins>;
+       cs-gpios = <0>, <0>;
+       #address-cells = <1>;
+       #size-cells = <0>;
+       status = "disabled";
+};
+
+&spi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spic_pins_g2>;
+       status = "okay";
+
+       proslic_spi: proslic_spi@0 {
+               compatible = "silabs,proslic_spi";
+               reg = <0>;
+               spi-max-frequency = <10000000>;
+               spi-cpha = <1>;
+               spi-cpol = <1>;
+               channel_count = <1>;
+               debug_level = <4>;       /* 1 = TRC, 2 = DBG, 4 = ERR */
+               reset_gpio = <&pio 7 0>;
+               ig,enable-spi = <1>;     /* 1: Enable, 0: Disable */
+       };
+};
+
+&switch {
+       ports {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               port@0 {
+                       reg = <0>;
+                       label = "lan0";
+               };
+
+               port@1 {
+                       reg = <1>;
+                       label = "lan1";
+               };
+
+               port@2 {
+                       reg = <2>;
+                       label = "lan2";
+               };
+
+               port@3 {
+                       reg = <3>;
+                       label = "lan3";
+               };
+
+               port@6 {
+                       reg = <6>;
+                       label = "cpu";
+                       ethernet = <&gmac0>;
+                       phy-mode = "2500base-x";
+
+                       fixed-link {
+                               speed = <2500>;
+                               full-duplex;
+                               pause;
+                       };
+               };
+       };
+};
+
+&ssusb {
+       vusb33-supply = <&reg_3p3v>;
+       vbus-supply = <&reg_5v>;
+       status = "okay";
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+       status = "okay";
+};
+
+&usb_phy {
+       status = "okay";
+};
diff --git a/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
new file mode 100644 (file)
index 0000000..ae90c10
--- /dev/null
@@ -0,0 +1,465 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+#include <dt-bindings/clock/mt7986-clk.h>
+#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/mt7986-resets.h>
+
+/ {
+       interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       clk40m: oscillator@0 {
+               compatible = "fixed-clock";
+               clock-frequency = <40000000>;
+               #clock-cells = <0>;
+               clock-output-names = "clkxtal";
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       enable-method = "psci";
+                       reg = <0x0>;
+                       #cooling-cells = <2>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       enable-method = "psci";
+                       reg = <0x1>;
+                       #cooling-cells = <2>;
+               };
+
+               cpu2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       enable-method = "psci";
+                       reg = <0x2>;
+                       #cooling-cells = <2>;
+               };
+
+               cpu3: cpu@3 {
+                       device_type = "cpu";
+                       enable-method = "psci";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x3>;
+                       #cooling-cells = <2>;
+               };
+       };
+
+       psci {
+               compatible  = "arm,psci-0.2";
+               method      = "smc";
+       };
+
+       reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               /* 64 KiB reserved for ramoops/pstore */
+               ramoops@42ff0000 {
+                       compatible = "ramoops";
+                       reg = <0 0x42ff0000 0 0x10000>;
+                       record-size = <0x1000>;
+               };
+
+               /* 192 KiB reserved for ARM Trusted Firmware (BL31) */
+               secmon_reserved: secmon@43000000 {
+                       reg = <0 0x43000000 0 0x30000>;
+                       no-map;
+               };
+
+               wmcpu_emi: wmcpu-reserved@4fc00000 {
+                       no-map;
+                       reg = <0 0x4fc00000 0 0x00100000>;
+               };
+       };
+
+       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 {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               compatible = "simple-bus";
+               ranges;
+
+               gic: interrupt-controller@c000000 {
+                       compatible = "arm,gic-v3";
+                       #interrupt-cells = <3>;
+                       interrupt-parent = <&gic>;
+                       interrupt-controller;
+                       reg = <0 0x0c000000 0 0x10000>,  /* GICD */
+                             <0 0x0c080000 0 0x80000>,  /* GICR */
+                             <0 0x0c400000 0 0x2000>,   /* GICC */
+                             <0 0x0c410000 0 0x1000>,   /* GICH */
+                             <0 0x0c420000 0 0x2000>;   /* GICV */
+                       interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
+               infracfg: infracfg@10001000 {
+                       compatible = "mediatek,mt7986-infracfg", "syscon";
+                       reg = <0 0x10001000 0 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               topckgen: topckgen@1001b000 {
+                       compatible = "mediatek,mt7986-topckgen", "syscon";
+                       reg = <0 0x1001B000 0 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               watchdog: watchdog@1001c000 {
+                       compatible = "mediatek,mt7986-wdt",
+                                    "mediatek,mt6589-wdt";
+                       reg = <0 0x1001c000 0 0x1000>;
+                       interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+                       #reset-cells = <1>;
+               };
+
+               pio: pinctrl@1001f000 {
+                       compatible = "mediatek,mt7986a-pinctrl";
+                       reg = <0 0x1001f000 0 0x1000>,
+                             <0 0x11c30000 0 0x1000>,
+                             <0 0x11c40000 0 0x1000>,
+                             <0 0x11e20000 0 0x1000>,
+                             <0 0x11e30000 0 0x1000>,
+                             <0 0x11f00000 0 0x1000>,
+                             <0 0x11f10000 0 0x1000>,
+                             <0 0x1000b000 0 0x1000>;
+                       reg-names = "gpio", "iocfg_rt", "iocfg_rb", "iocfg_lt",
+                                   "iocfg_lb", "iocfg_tr", "iocfg_tl", "eint";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       gpio-ranges = <&pio 0 0 100>;
+                       interrupt-controller;
+                       interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-parent = <&gic>;
+                       #interrupt-cells = <2>;
+               };
+
+               apmixedsys: apmixedsys@1001e000 {
+                       compatible = "mediatek,mt7986-apmixedsys";
+                       reg = <0 0x1001E000 0 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               sgmiisys0: syscon@10060000 {
+                       compatible = "mediatek,mt7986-sgmiisys_0",
+                                    "syscon";
+                       reg = <0 0x10060000 0 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               sgmiisys1: syscon@10070000 {
+                       compatible = "mediatek,mt7986-sgmiisys_1",
+                                    "syscon";
+                       reg = <0 0x10070000 0 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               trng: trng@1020f000 {
+                       compatible = "mediatek,mt7986-rng";
+                       reg = <0 0x1020f000 0 0x100>;
+                       clocks = <&infracfg CLK_INFRA_TRNG_CK>;
+                       clock-names = "rng";
+                       status = "okay";
+               };
+
+               crypto: crypto@10320000 {
+                       compatible = "inside-secure,safexcel-eip97";
+                       reg = <0 0x10320000 0 0x40000>;
+                       interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "ring0", "ring1", "ring2", "ring3";
+                       clocks = <&infracfg CLK_INFRA_EIP97_CK>;
+                       clock-names = "infra_eip97_ck";
+                       assigned-clocks = <&topckgen CLK_TOP_EIP_B_SEL>;
+                       assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>;
+                       status = "disabled";
+               };
+
+               uart0: serial@11002000 {
+                       compatible = "mediatek,mt7986-uart",
+                                    "mediatek,mt6577-uart";
+                       reg = <0 0x11002000 0 0x400>;
+                       interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&infracfg CLK_INFRA_UART0_SEL>,
+                                <&infracfg CLK_INFRA_UART0_CK>;
+                       clock-names = "baud", "bus";
+                       assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
+                                         <&infracfg CLK_INFRA_UART0_SEL>;
+                       assigned-clock-parents = <&topckgen CLK_TOP_XTAL>,
+                                                <&topckgen CLK_TOP_UART_SEL>;
+                       status = "disabled";
+               };
+
+               uart1: serial@11003000 {
+                       compatible = "mediatek,mt7986-uart",
+                                    "mediatek,mt6577-uart";
+                       reg = <0 0x11003000 0 0x400>;
+                       interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&infracfg CLK_INFRA_UART1_SEL>,
+                                <&infracfg CLK_INFRA_UART1_CK>;
+                       clock-names = "baud", "bus";
+                       assigned-clocks = <&infracfg CLK_INFRA_UART1_SEL>;
+                       assigned-clock-parents = <&topckgen CLK_TOP_F26M_SEL>;
+                       status = "disabled";
+               };
+
+               uart2: serial@11004000 {
+                       compatible = "mediatek,mt7986-uart",
+                                    "mediatek,mt6577-uart";
+                       reg = <0 0x11004000 0 0x400>;
+                       interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&infracfg CLK_INFRA_UART2_SEL>,
+                                <&infracfg CLK_INFRA_UART2_CK>;
+                       clock-names = "baud", "bus";
+                       assigned-clocks = <&infracfg CLK_INFRA_UART2_SEL>;
+                       assigned-clock-parents = <&topckgen CLK_TOP_F26M_SEL>;
+                       status = "disabled";
+               };
+
+               spi0: spi@1100a000 {
+                       compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
+                       reg = <0 0x1100a000 0 0x100>;
+                       interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&topckgen CLK_TOP_MPLL_D2>,
+                                <&topckgen CLK_TOP_SPI_SEL>,
+                                <&infracfg CLK_INFRA_SPI0_CK>,
+                                <&infracfg CLK_INFRA_SPI0_HCK_CK>;
+                       clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
+                       status = "disabled";
+               };
+
+               spi1: spi@1100b000 {
+                       compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
+                       reg = <0 0x1100b000 0 0x100>;
+                       interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&topckgen CLK_TOP_MPLL_D2>,
+                                <&topckgen CLK_TOP_SPIM_MST_SEL>,
+                                <&infracfg CLK_INFRA_SPI1_CK>,
+                                <&infracfg CLK_INFRA_SPI1_HCK_CK>;
+                       clock-names = "parent-clk", "sel-clk", "spi-clk", "hclk";
+                       status = "disabled";
+               };
+
+               ssusb: usb@11200000 {
+                       compatible = "mediatek,mt7986-xhci",
+                                    "mediatek,mtk-xhci";
+                       reg = <0 0x11200000 0 0x2e00>,
+                             <0 0x11203e00 0 0x0100>;
+                       reg-names = "mac", "ippc";
+                       interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&infracfg CLK_INFRA_IUSB_SYS_CK>,
+                                <&topckgen CLK_TOP_U2U3_XHCI_SEL>,
+                                <&infracfg CLK_INFRA_IUSB_CK>,
+                                <&infracfg CLK_INFRA_IUSB_133_CK>,
+                                <&infracfg CLK_INFRA_IUSB_66M_CK>;
+                       clock-names = "sys_ck",
+                                     "xhci_ck",
+                                     "ref_ck",
+                                     "mcu_ck",
+                                     "dma_ck";
+                       phys = <&u2port0 PHY_TYPE_USB2>,
+                              <&u3port0 PHY_TYPE_USB3>,
+                              <&u2port1 PHY_TYPE_USB2>;
+                       status = "disabled";
+               };
+
+               mmc0: mmc@11230000 {
+                       compatible = "mediatek,mt7986-mmc";
+                       reg = <0 0x11230000 0 0x1000>,
+                             <0 0x11c20000 0 0x1000>;
+                       interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&infracfg CLK_INFRA_MSDC_CK>,
+                                <&infracfg CLK_INFRA_MSDC_HCK_CK>,
+                                <&infracfg CLK_INFRA_MSDC_66M_CK>,
+                                <&infracfg CLK_INFRA_MSDC_133M_CK>;
+                       clock-names = "source", "hclk", "axi_cg", "ahb_cg";
+                       assigned-clocks = <&topckgen CLK_TOP_EMMC_416M_SEL>,
+                                         <&topckgen CLK_TOP_EMMC_250M_SEL>;
+                       assigned-clock-parents = <&apmixedsys CLK_APMIXED_MPLL>,
+                                                <&topckgen CLK_TOP_NET1PLL_D5_D2>;
+                       status = "disabled";
+               };
+
+               pcie: pcie@11280000 {
+                       compatible = "mediatek,mt7986-pcie",
+                                    "mediatek,mt8192-pcie";
+                       device_type = "pci";
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       reg = <0x00 0x11280000 0x00 0x4000>;
+                       reg-names = "pcie-mac";
+                       interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+                       bus-range = <0x00 0xff>;
+                       ranges = <0x82000000 0x00 0x20000000 0x00
+                                 0x20000000 0x00 0x10000000>;
+                       clocks = <&infracfg CLK_INFRA_PCIE_SEL>,
+                                <&infracfg CLK_INFRA_IPCIE_CK>,
+                                <&infracfg CLK_INFRA_IPCIE_PIPE_CK>,
+                                <&infracfg CLK_INFRA_IPCIER_CK>,
+                                <&infracfg CLK_INFRA_IPCIEB_CK>;
+                       status = "disabled";
+
+                       phys = <&pcie_port PHY_TYPE_PCIE>;
+                       phy-names = "pcie-phy";
+
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 0x7>;
+                       interrupt-map = <0 0 0 1 &pcie_intc 0>,
+                                       <0 0 0 2 &pcie_intc 1>,
+                                       <0 0 0 3 &pcie_intc 2>,
+                                       <0 0 0 4 &pcie_intc 3>;
+                       pcie_intc: interrupt-controller {
+                               #address-cells = <0>;
+                               #interrupt-cells = <1>;
+                               interrupt-controller;
+                       };
+               };
+
+               pcie_phy: t-phy@11c00000 {
+                       compatible = "mediatek,mt7986-tphy",
+                                    "mediatek,generic-tphy-v2";
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+                       status = "disabled";
+
+                       pcie_port: pcie-phy@11c00000 {
+                               reg = <0 0x11c00000 0 0x20000>;
+                               clocks = <&clk40m>;
+                               clock-names = "ref";
+                               #phy-cells = <1>;
+                       };
+               };
+
+               usb_phy: t-phy@11e10000 {
+                       compatible = "mediatek,mt7986-tphy",
+                                    "mediatek,generic-tphy-v2";
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+                       status = "disabled";
+
+                       u2port0: usb-phy@11e10000 {
+                               reg = <0 0x11e10000 0 0x700>;
+                               clocks = <&topckgen CLK_TOP_DA_U2_REFSEL>,
+                                        <&topckgen CLK_TOP_DA_U2_CK_1P_SEL>;
+                               clock-names = "ref", "da_ref";
+                               #phy-cells = <1>;
+                       };
+
+                       u3port0: usb-phy@11e10700 {
+                               reg = <0 0x11e10700 0 0x900>;
+                               clocks = <&topckgen CLK_TOP_USB3_PHY_SEL>;
+                               clock-names = "ref";
+                               #phy-cells = <1>;
+                       };
+
+                       u2port1: usb-phy@11e11000 {
+                               reg = <0 0x11e11000 0 0x700>;
+                               clocks = <&topckgen CLK_TOP_DA_U2_REFSEL>,
+                                        <&topckgen CLK_TOP_DA_U2_CK_1P_SEL>;
+                               clock-names = "ref", "da_ref";
+                               #phy-cells = <1>;
+                       };
+               };
+
+               ethsys: syscon@15000000 {
+                        #address-cells = <1>;
+                        #size-cells = <1>;
+                        compatible = "mediatek,mt7986-ethsys_ck",
+                                     "syscon";
+                        reg = <0 0x15000000 0 0x1000>;
+                        #clock-cells = <1>;
+                        #reset-cells = <1>;
+               };
+
+               eth: ethernet@15100000 {
+                       compatible = "mediatek,mt7986-eth";
+                       reg = <0 0x15100000 0 0x80000>;
+                       interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ethsys CLK_ETH_FE_EN>,
+                                <&ethsys CLK_ETH_GP2_EN>,
+                                <&ethsys CLK_ETH_GP1_EN>,
+                                <&ethsys CLK_ETH_WOCPU1_EN>,
+                                <&ethsys CLK_ETH_WOCPU0_EN>,
+                                <&sgmiisys0 CLK_SGMII0_TX250M_EN>,
+                                <&sgmiisys0 CLK_SGMII0_RX250M_EN>,
+                                <&sgmiisys0 CLK_SGMII0_CDR_REF>,
+                                <&sgmiisys0 CLK_SGMII0_CDR_FB>,
+                                <&sgmiisys1 CLK_SGMII1_TX250M_EN>,
+                                <&sgmiisys1 CLK_SGMII1_RX250M_EN>,
+                                <&sgmiisys1 CLK_SGMII1_CDR_REF>,
+                                <&sgmiisys1 CLK_SGMII1_CDR_FB>,
+                                <&topckgen CLK_TOP_NETSYS_SEL>,
+                                <&topckgen CLK_TOP_NETSYS_500M_SEL>;
+                       clock-names = "fe", "gp2", "gp1", "wocpu1", "wocpu0",
+                                     "sgmii_tx250m", "sgmii_rx250m",
+                                     "sgmii_cdr_ref", "sgmii_cdr_fb",
+                                     "sgmii2_tx250m", "sgmii2_rx250m",
+                                     "sgmii2_cdr_ref", "sgmii2_cdr_fb",
+                                     "netsys0", "netsys1";
+                       assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
+                                         <&topckgen CLK_TOP_SGM_325M_SEL>;
+                       assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
+                                                <&apmixedsys CLK_APMIXED_SGMPLL>;
+                       mediatek,ethsys = <&ethsys>;
+                       mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
+                       #reset-cells = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               consys: consys@10000000 {
+                       compatible = "mediatek,mt7986-consys";
+                       reg = <0 0x10000000 0 0x8600000>;
+                       memory-region = <&wmcpu_emi>;
+               };
+
+               wmac: wmac@18000000 {
+                       compatible = "mediatek,mt7986-wmac", "mediatek,wbsys";
+                       resets = <&watchdog MT7986_TOPRGU_CONSYS_RST>;
+                       reset-names = "consys";
+                       reg = <0 0x18000000 0 0x1000000>,
+                             <0 0x10003000 0 0x1000>,
+                             <0 0x11d10000 0 0x1000>;
+                       interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&topckgen CLK_TOP_CONN_MCUSYS_SEL>,
+                                <&topckgen CLK_TOP_AP2CNN_HOST_SEL>;
+                       clock-names = "mcu", "ap2conn";
+                       memory-region = <&wmcpu_emi>;
+                       status = "disabled";
+               };
+       };
+
+};
diff --git a/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts b/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
new file mode 100644 (file)
index 0000000..52b6c15
--- /dev/null
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7986b.dtsi"
+
+/ {
+       model = "MediaTek MT7986b RFB";
+       compatible = "mediatek,mt7986b-rfb";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory {
+               reg = <0 0x40000000 0 0x40000000>;
+       };
+
+       reg_3p3v: regulator-3p3v {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-3.3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       reg_5v: regulator-5v {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+};
+
+&ssusb {
+       vusb33-supply = <&reg_3p3v>;
+       vbus-supply = <&reg_5v>;
+       status = "okay";
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&usb_phy {
+       status = "okay";
+};
+
+&wmac {
+       status = "okay";
+       pinctrl-names = "default", "dbdc";
+       pinctrl-0 = <&wf_2g_5g_pins>;
+       pinctrl-1 = <&wf_dbdc_pins>;
+};
+
+&eth {
+       status = "okay";
+
+       gmac0: mac@0 {
+               compatible = "mediatek,eth-mac";
+               reg = <0>;
+               phy-mode = "2500base-x";
+
+               fixed-link {
+                       speed = <2500>;
+                       full-duplex;
+                       pause;
+               };
+       };
+
+       gmac1: mac@1 {
+               compatible = "mediatek,eth-mac";
+               reg = <1>;
+               phy-mode = "2500base-x";
+
+               fixed-link {
+                       speed = <2500>;
+                       full-duplex;
+                       pause;
+               };
+       };
+
+       mdio: mdio-bus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               phy5: phy@5 {
+                       compatible = "ethernet-phy-id67c9.de0a";
+                       reg = <5>;
+                       reset-gpios = <&pio 6 1>;
+                       reset-deassert-us = <20000>;
+                       phy-mode = "2500base-x";
+               };
+
+               phy6: phy@6 {
+                       compatible = "ethernet-phy-id67c9.de0a";
+                       reg = <6>;
+                       phy-mode = "2500base-x";
+               };
+
+               switch@0 {
+                       compatible = "mediatek,mt7531";
+                       reg = <31>;
+                       reset-gpios = <&pio 5 0>;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       label = "lan0";
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       label = "lan1";
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       label = "lan2";
+                               };
+
+                               port@3 {
+                                       reg = <3>;
+                                       label = "lan3";
+                               };
+
+                               port@6 {
+                                       reg = <6>;
+                                       label = "cpu";
+                                       ethernet = <&gmac0>;
+                                       phy-mode = "2500base-x";
+
+                                       fixed-link {
+                                               speed = <2500>;
+                                               full-duplex;
+                                               pause;
+                                       };
+                               };
+                       };
+               };
+       };
+};
+
+&crypto {
+       status = "okay";
+};
+
+&pio {
+       wf_2g_5g_pins: wf_2g_5g-pins {
+               mux {
+                       function = "wifi";
+                       groups = "wf_2g", "wf_5g";
+               };
+               conf {
+                       pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
+                              "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
+                              "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
+                              "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
+                              "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
+                              "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
+                              "WF1_TOP_CLK", "WF1_TOP_DATA";
+                       drive-strength = <4>;
+               };
+       };
+
+       wf_dbdc_pins: wf_dbdc-pins {
+               mux {
+                       function = "wifi";
+                       groups = "wf_dbdc";
+               };
+               conf {
+                       pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
+                              "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
+                              "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
+                              "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
+                              "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
+                              "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
+                              "WF1_TOP_CLK", "WF1_TOP_DATA";
+                       drive-strength = <4>;
+               };
+       };
+};
diff --git a/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986b.dtsi b/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
new file mode 100644 (file)
index 0000000..23923b9
--- /dev/null
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Sam.Shih <sam.shih@mediatek.com>
+ */
+
+#include "mt7986a.dtsi"
+
+&pio {
+       compatible = "mediatek,mt7986b-pinctrl";
+       gpio-ranges = <&pio 0 0 41>, <&pio 66 66 35>;
+};
diff --git a/target/linux/mediatek/files-5.15/drivers/clk/mediatek/clk-mt7986-apmixed.c b/target/linux/mediatek/files-5.15/drivers/clk/mediatek/clk-mt7986-apmixed.c
new file mode 100644 (file)
index 0000000..76c8ebd
--- /dev/null
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-1.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ * Author: Wenzhen Yu <wenzhen.yu@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "clk-mtk.h"
+#include "clk-gate.h"
+#include "clk-mux.h"
+
+#include <dt-bindings/clock/mt7986-clk.h>
+#include <linux/clk.h>
+
+#define MT7986_PLL_FMAX (2500UL * MHZ)
+#define CON0_MT7986_RST_BAR BIT(27)
+
+#define PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,       \
+                _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift,         \
+                _div_table, _parent_name)                                     \
+       {                                                                      \
+               .id = _id, .name = _name, .reg = _reg, .pwr_reg = _pwr_reg,    \
+               .en_mask = _en_mask, .flags = _flags,                          \
+               .rst_bar_mask = CON0_MT7986_RST_BAR, .fmax = MT7986_PLL_FMAX,  \
+               .pcwbits = _pcwbits, .pd_reg = _pd_reg, .pd_shift = _pd_shift, \
+               .tuner_reg = _tuner_reg, .pcw_reg = _pcw_reg,                  \
+               .pcw_shift = _pcw_shift, .div_table = _div_table,              \
+               .parent_name = _parent_name,                                   \
+       }
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg,   \
+           _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift)                       \
+       PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,       \
+                _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, NULL,   \
+                "clkxtal")
+
+static const struct mtk_pll_data plls[] = {
+       PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0200, 0x020C, 0x00000001, 0, 32,
+           0x0200, 4, 0, 0x0204, 0),
+       PLL(CLK_APMIXED_NET2PLL, "net2pll", 0x0210, 0x021C, 0x00000001, 0, 32,
+           0x0210, 4, 0, 0x0214, 0),
+       PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0220, 0x022C, 0x00000001, 0, 32,
+           0x0220, 4, 0, 0x0224, 0),
+       PLL(CLK_APMIXED_SGMPLL, "sgmpll", 0x0230, 0x023c, 0x00000001, 0, 32,
+           0x0230, 4, 0, 0x0234, 0),
+       PLL(CLK_APMIXED_WEDMCUPLL, "wedmcupll", 0x0240, 0x024c, 0x00000001, 0,
+           32, 0x0240, 4, 0, 0x0244, 0),
+       PLL(CLK_APMIXED_NET1PLL, "net1pll", 0x0250, 0x025c, 0x00000001, 0, 32,
+           0x0250, 4, 0, 0x0254, 0),
+       PLL(CLK_APMIXED_MPLL, "mpll", 0x0260, 0x0270, 0x00000001, 0, 32, 0x0260,
+           4, 0, 0x0264, 0),
+       PLL(CLK_APMIXED_APLL2, "apll2", 0x0278, 0x0288, 0x00000001, 0, 32,
+           0x0278, 4, 0, 0x027c, 0),
+};
+
+static const struct of_device_id of_match_clk_mt7986_apmixed[] = {
+       { .compatible = "mediatek,mt7986-apmixedsys", },
+       {}
+};
+
+static int clk_mt7986_apmixed_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(ARRAY_SIZE(plls));
+       if (!clk_data)
+               return -ENOMEM;
+
+       mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+
+       clk_prepare_enable(clk_data->clks[CLK_APMIXED_ARMPLL]);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r) {
+               pr_err("%s(): could not register clock provider: %d\n",
+                      __func__, r);
+               goto free_apmixed_data;
+       }
+       return r;
+
+free_apmixed_data:
+       mtk_free_clk_data(clk_data);
+       return r;
+}
+
+static struct platform_driver clk_mt7986_apmixed_drv = {
+       .probe = clk_mt7986_apmixed_probe,
+       .driver = {
+               .name = "clk-mt7986-apmixed",
+               .of_match_table = of_match_clk_mt7986_apmixed,
+       },
+};
+builtin_platform_driver(clk_mt7986_apmixed_drv);
diff --git a/target/linux/mediatek/files-5.15/drivers/clk/mediatek/clk-mt7986-eth.c b/target/linux/mediatek/files-5.15/drivers/clk/mediatek/clk-mt7986-eth.c
new file mode 100644 (file)
index 0000000..495d023
--- /dev/null
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ * Author: Wenzhen Yu <wenzhen.yu@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt7986-clk.h>
+
+static const struct mtk_gate_regs sgmii0_cg_regs = {
+       .set_ofs = 0xe4,
+       .clr_ofs = 0xe4,
+       .sta_ofs = 0xe4,
+};
+
+#define GATE_SGMII0(_id, _name, _parent, _shift)                               \
+       {                                                                      \
+               .id = _id, .name = _name, .parent_name = _parent,              \
+               .regs = &sgmii0_cg_regs, .shift = _shift,                      \
+               .ops = &mtk_clk_gate_ops_no_setclr_inv,                        \
+       }
+
+static const struct mtk_gate sgmii0_clks[] __initconst = {
+       GATE_SGMII0(CLK_SGMII0_TX250M_EN, "sgmii0_tx250m_en", "top_xtal", 2),
+       GATE_SGMII0(CLK_SGMII0_RX250M_EN, "sgmii0_rx250m_en", "top_xtal", 3),
+       GATE_SGMII0(CLK_SGMII0_CDR_REF, "sgmii0_cdr_ref", "top_xtal", 4),
+       GATE_SGMII0(CLK_SGMII0_CDR_FB, "sgmii0_cdr_fb", "top_xtal", 5),
+};
+
+static const struct mtk_gate_regs sgmii1_cg_regs = {
+       .set_ofs = 0xe4,
+       .clr_ofs = 0xe4,
+       .sta_ofs = 0xe4,
+};
+
+#define GATE_SGMII1(_id, _name, _parent, _shift)                               \
+       {                                                                      \
+               .id = _id, .name = _name, .parent_name = _parent,              \
+               .regs = &sgmii1_cg_regs, .shift = _shift,                      \
+               .ops = &mtk_clk_gate_ops_no_setclr_inv,                        \
+       }
+
+static const struct mtk_gate sgmii1_clks[] __initconst = {
+       GATE_SGMII1(CLK_SGMII1_TX250M_EN, "sgmii1_tx250m_en", "top_xtal", 2),
+       GATE_SGMII1(CLK_SGMII1_RX250M_EN, "sgmii1_rx250m_en", "top_xtal", 3),
+       GATE_SGMII1(CLK_SGMII1_CDR_REF, "sgmii1_cdr_ref", "top_xtal", 4),
+       GATE_SGMII1(CLK_SGMII1_CDR_FB, "sgmii1_cdr_fb", "top_xtal", 5),
+};
+
+static const struct mtk_gate_regs eth_cg_regs = {
+       .set_ofs = 0x30,
+       .clr_ofs = 0x30,
+       .sta_ofs = 0x30,
+};
+
+#define GATE_ETH(_id, _name, _parent, _shift)                                  \
+       {                                                                      \
+               .id = _id, .name = _name, .parent_name = _parent,              \
+               .regs = &eth_cg_regs, .shift = _shift,                         \
+               .ops = &mtk_clk_gate_ops_no_setclr_inv,                        \
+       }
+
+static const struct mtk_gate eth_clks[] __initconst = {
+       GATE_ETH(CLK_ETH_FE_EN, "eth_fe_en", "netsys_2x_sel", 6),
+       GATE_ETH(CLK_ETH_GP2_EN, "eth_gp2_en", "sgm_325m_sel", 7),
+       GATE_ETH(CLK_ETH_GP1_EN, "eth_gp1_en", "sgm_325m_sel", 8),
+       GATE_ETH(CLK_ETH_WOCPU1_EN, "eth_wocpu1_en", "netsys_mcu_sel", 14),
+       GATE_ETH(CLK_ETH_WOCPU0_EN, "eth_wocpu0_en", "netsys_mcu_sel", 15),
+};
+
+static void __init mtk_sgmiisys_0_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii0_clks));
+
+       mtk_clk_register_gates(node, sgmii0_clks, ARRAY_SIZE(sgmii0_clks),
+                              clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                      __func__, r);
+}
+CLK_OF_DECLARE(mtk_sgmiisys_0, "mediatek,mt7986-sgmiisys_0",
+              mtk_sgmiisys_0_init);
+
+static void __init mtk_sgmiisys_1_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii1_clks));
+
+       mtk_clk_register_gates(node, sgmii1_clks, ARRAY_SIZE(sgmii1_clks),
+                              clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                      __func__, r);
+}
+CLK_OF_DECLARE(mtk_sgmiisys_1, "mediatek,mt7986-sgmiisys_1",
+              mtk_sgmiisys_1_init);
+
+static void __init mtk_ethsys_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(ARRAY_SIZE(eth_clks));
+
+       mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks), clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                      __func__, r);
+}
+CLK_OF_DECLARE(mtk_ethsys, "mediatek,mt7986-ethsys_ck", mtk_ethsys_init);
diff --git a/target/linux/mediatek/files-5.15/drivers/clk/mediatek/clk-mt7986-infracfg.c b/target/linux/mediatek/files-5.15/drivers/clk/mediatek/clk-mt7986-infracfg.c
new file mode 100644 (file)
index 0000000..3be168c
--- /dev/null
@@ -0,0 +1,224 @@
+// SPDX-License-Identifier: GPL-1.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ * Author: Wenzhen Yu <wenzhen.yu@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "clk-mtk.h"
+#include "clk-gate.h"
+#include "clk-mux.h"
+
+#include <dt-bindings/clock/mt7986-clk.h>
+#include <linux/clk.h>
+
+static DEFINE_SPINLOCK(mt7986_clk_lock);
+
+static const struct mtk_fixed_factor infra_divs[] = {
+       FACTOR(CLK_INFRA_SYSAXI_D2, "infra_sysaxi_d2", "sysaxi_sel", 1, 2),
+};
+
+static const char *const infra_uart_parent[] __initconst = { "csw_f26m_sel",
+                                                            "uart_sel" };
+
+static const char *const infra_spi_parents[] __initconst = { "i2c_sel",
+                                                            "spi_sel" };
+
+static const char *const infra_pwm_bsel_parents[] __initconst = {
+       "top_rtc_32p7k", "csw_f26m_sel", "infra_sysaxi_d2", "pwm_sel"
+};
+
+static const char *const infra_pcie_parents[] __initconst = {
+       "top_rtc_32p7k", "csw_f26m_sel", "top_xtal", "pextp_tl_ck_sel"
+};
+
+static const struct mtk_mux infra_muxes[] = {
+       /* MODULE_CLK_SEL_0 */
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART0_SEL, "infra_uart0_sel",
+                            infra_uart_parent, 0x0018, 0x0010, 0x0014, 0, 1,
+                            -1, -1, -1),
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART1_SEL, "infra_uart1_sel",
+                            infra_uart_parent, 0x0018, 0x0010, 0x0014, 1, 1,
+                            -1, -1, -1),
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART2_SEL, "infra_uart2_sel",
+                            infra_uart_parent, 0x0018, 0x0010, 0x0014, 2, 1,
+                            -1, -1, -1),
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI0_SEL, "infra_spi0_sel",
+                            infra_spi_parents, 0x0018, 0x0010, 0x0014, 4, 1,
+                            -1, -1, -1),
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI1_SEL, "infra_spi1_sel",
+                            infra_spi_parents, 0x0018, 0x0010, 0x0014, 5, 1,
+                            -1, -1, -1),
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM1_SEL, "infra_pwm1_sel",
+                            infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 9,
+                            2, -1, -1, -1),
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM2_SEL, "infra_pwm2_sel",
+                            infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 11,
+                            2, -1, -1, -1),
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_BSEL, "infra_pwm_bsel",
+                            infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 13,
+                            2, -1, -1, -1),
+       /* MODULE_CLK_SEL_1 */
+       MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_SEL, "infra_pcie_sel",
+                            infra_pcie_parents, 0x0028, 0x0020, 0x0024, 0, 2,
+                            -1, -1, -1),
+};
+
+static const struct mtk_gate_regs infra0_cg_regs = {
+       .set_ofs = 0x40,
+       .clr_ofs = 0x44,
+       .sta_ofs = 0x48,
+};
+
+static const struct mtk_gate_regs infra1_cg_regs = {
+       .set_ofs = 0x50,
+       .clr_ofs = 0x54,
+       .sta_ofs = 0x58,
+};
+
+static const struct mtk_gate_regs infra2_cg_regs = {
+       .set_ofs = 0x60,
+       .clr_ofs = 0x64,
+       .sta_ofs = 0x68,
+};
+
+#define GATE_INFRA0(_id, _name, _parent, _shift)                               \
+       {                                                                      \
+               .id = _id, .name = _name, .parent_name = _parent,              \
+               .regs = &infra0_cg_regs, .shift = _shift,                      \
+               .ops = &mtk_clk_gate_ops_setclr,                               \
+       }
+
+#define GATE_INFRA1(_id, _name, _parent, _shift)                               \
+       {                                                                      \
+               .id = _id, .name = _name, .parent_name = _parent,              \
+               .regs = &infra1_cg_regs, .shift = _shift,                      \
+               .ops = &mtk_clk_gate_ops_setclr,                               \
+       }
+
+#define GATE_INFRA2(_id, _name, _parent, _shift)                               \
+       {                                                                      \
+               .id = _id, .name = _name, .parent_name = _parent,              \
+               .regs = &infra2_cg_regs, .shift = _shift,                      \
+               .ops = &mtk_clk_gate_ops_setclr,                               \
+       }
+
+static const struct mtk_gate infra_clks[] = {
+       /* INFRA0 */
+       GATE_INFRA0(CLK_INFRA_GPT_STA, "infra_gpt_sta", "infra_sysaxi_d2", 0),
+       GATE_INFRA0(CLK_INFRA_PWM_HCK, "infra_pwm_hck", "infra_sysaxi_d2", 1),
+       GATE_INFRA0(CLK_INFRA_PWM_STA, "infra_pwm_sta", "infra_pwm_bsel", 2),
+       GATE_INFRA0(CLK_INFRA_PWM1_CK, "infra_pwm1", "infra_pwm1_sel", 3),
+       GATE_INFRA0(CLK_INFRA_PWM2_CK, "infra_pwm2", "infra_pwm2_sel", 4),
+       GATE_INFRA0(CLK_INFRA_CQ_DMA_CK, "infra_cq_dma", "sysaxi_sel", 6),
+       GATE_INFRA0(CLK_INFRA_EIP97_CK, "infra_eip97", "eip_b_sel", 7),
+       GATE_INFRA0(CLK_INFRA_AUD_BUS_CK, "infra_aud_bus", "sysaxi_sel", 8),
+       GATE_INFRA0(CLK_INFRA_AUD_26M_CK, "infra_aud_26m", "csw_f26m_sel", 9),
+       GATE_INFRA0(CLK_INFRA_AUD_L_CK, "infra_aud_l", "aud_l_sel", 10),
+       GATE_INFRA0(CLK_INFRA_AUD_AUD_CK, "infra_aud_aud", "a1sys_sel", 11),
+       GATE_INFRA0(CLK_INFRA_AUD_EG2_CK, "infra_aud_eg2", "a_tuner_sel", 13),
+       GATE_INFRA0(CLK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", "csw_f26m_sel",
+                   14),
+       GATE_INFRA0(CLK_INFRA_DBG_CK, "infra_dbg", "infra_sysaxi_d2", 15),
+       GATE_INFRA0(CLK_INFRA_AP_DMA_CK, "infra_ap_dma", "infra_sysaxi_d2", 16),
+       GATE_INFRA0(CLK_INFRA_SEJ_CK, "infra_sej", "infra_sysaxi_d2", 24),
+       GATE_INFRA0(CLK_INFRA_SEJ_13M_CK, "infra_sej_13m", "csw_f26m_sel", 25),
+       GATE_INFRA0(CLK_INFRA_TRNG_CK, "infra_trng", "sysaxi_sel", 26),
+       /* INFRA1 */
+       GATE_INFRA1(CLK_INFRA_THERM_CK, "infra_therm", "csw_f26m_sel", 0),
+       GATE_INFRA1(CLK_INFRA_I2C0_CK, "infra_i2c0", "i2c_sel", 1),
+       GATE_INFRA1(CLK_INFRA_UART0_CK, "infra_uart0", "infra_uart0_sel", 2),
+       GATE_INFRA1(CLK_INFRA_UART1_CK, "infra_uart1", "infra_uart1_sel", 3),
+       GATE_INFRA1(CLK_INFRA_UART2_CK, "infra_uart2", "infra_uart2_sel", 4),
+       GATE_INFRA1(CLK_INFRA_NFI1_CK, "infra_nfi1", "nfi1x_sel", 8),
+       GATE_INFRA1(CLK_INFRA_SPINFI1_CK, "infra_spinfi1", "spinfi_sel", 9),
+       GATE_INFRA1(CLK_INFRA_NFI_HCK_CK, "infra_nfi_hck", "infra_sysaxi_d2",
+                   10),
+       GATE_INFRA1(CLK_INFRA_SPI0_CK, "infra_spi0", "infra_spi0_sel", 11),
+       GATE_INFRA1(CLK_INFRA_SPI1_CK, "infra_spi1", "infra_spi1_sel", 12),
+       GATE_INFRA1(CLK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", "infra_sysaxi_d2",
+                   13),
+       GATE_INFRA1(CLK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", "infra_sysaxi_d2",
+                   14),
+       GATE_INFRA1(CLK_INFRA_FRTC_CK, "infra_frtc", "top_rtc_32k", 15),
+       GATE_INFRA1(CLK_INFRA_MSDC_CK, "infra_msdc", "emmc_416m_sel", 16),
+       GATE_INFRA1(CLK_INFRA_MSDC_HCK_CK, "infra_msdc_hck", "emmc_250m_sel",
+                   17),
+       GATE_INFRA1(CLK_INFRA_MSDC_133M_CK, "infra_msdc_133m", "sysaxi_sel",
+                   18),
+       GATE_INFRA1(CLK_INFRA_MSDC_66M_CK, "infra_msdc_66m", "infra_sysaxi_d2",
+                   19),
+       GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m", "csw_f26m_sel", 20),
+       GATE_INFRA1(CLK_INFRA_ADC_FRC_CK, "infra_adc_frc", "csw_f26m_sel", 21),
+       GATE_INFRA1(CLK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", "nfi1x_sel", 23),
+       /* INFRA2 */
+       GATE_INFRA2(CLK_INFRA_IUSB_133_CK, "infra_iusb_133", "sysaxi_sel", 0),
+       GATE_INFRA2(CLK_INFRA_IUSB_66M_CK, "infra_iusb_66m", "infra_sysaxi_d2",
+                   1),
+       GATE_INFRA2(CLK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", "u2u3_sys_sel", 2),
+       GATE_INFRA2(CLK_INFRA_IUSB_CK, "infra_iusb", "u2u3_sel", 3),
+       GATE_INFRA2(CLK_INFRA_IPCIE_CK, "infra_ipcie", "pextp_tl_ck_sel", 12),
+       GATE_INFRA2(CLK_INFRA_IPCIE_PIPE_CK, "infra_ipcie_pipe", "top_xtal",
+                   13),
+       GATE_INFRA2(CLK_INFRA_IPCIER_CK, "infra_ipcier", "csw_f26m_sel", 14),
+       GATE_INFRA2(CLK_INFRA_IPCIEB_CK, "infra_ipcieb", "sysaxi_sel", 15),
+};
+
+static int clk_mt7986_infracfg_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       int r;
+       void __iomem *base;
+       int nr = ARRAY_SIZE(infra_divs) + ARRAY_SIZE(infra_muxes) +
+                ARRAY_SIZE(infra_clks);
+
+       base = of_iomap(node, 0);
+       if (!base) {
+               pr_err("%s(): ioremap failed\n", __func__);
+               return -ENOMEM;
+       }
+
+       clk_data = mtk_alloc_clk_data(nr);
+
+       if (!clk_data)
+               return -ENOMEM;
+
+       mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
+       mtk_clk_register_muxes(infra_muxes, ARRAY_SIZE(infra_muxes), node,
+                              &mt7986_clk_lock, clk_data);
+       mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+                              clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r) {
+               pr_err("%s(): could not register clock provider: %d\n",
+                      __func__, r);
+               goto free_infracfg_data;
+       }
+       return r;
+
+free_infracfg_data:
+       mtk_free_clk_data(clk_data);
+       return r;
+
+}
+
+static const struct of_device_id of_match_clk_mt7986_infracfg[] = {
+       { .compatible = "mediatek,mt7986-infracfg", },
+       {}
+};
+
+static struct platform_driver clk_mt7986_infracfg_drv = {
+       .probe = clk_mt7986_infracfg_probe,
+       .driver = {
+               .name = "clk-mt7986-infracfg",
+               .of_match_table = of_match_clk_mt7986_infracfg,
+       },
+};
+builtin_platform_driver(clk_mt7986_infracfg_drv);
diff --git a/target/linux/mediatek/files-5.15/drivers/clk/mediatek/clk-mt7986-topckgen.c b/target/linux/mediatek/files-5.15/drivers/clk/mediatek/clk-mt7986-topckgen.c
new file mode 100644 (file)
index 0000000..8550e2b
--- /dev/null
@@ -0,0 +1,342 @@
+// SPDX-License-Identifier: GPL-1.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ * Author: Wenzhen Yu <wenzhen.yu@mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "clk-mtk.h"
+#include "clk-gate.h"
+#include "clk-mux.h"
+
+#include <dt-bindings/clock/mt7986-clk.h>
+#include <linux/clk.h>
+
+static DEFINE_SPINLOCK(mt7986_clk_lock);
+
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+       FIXED_CLK(CLK_TOP_XTAL, "top_xtal", "clkxtal", 40000000),
+       FIXED_CLK(CLK_TOP_JTAG, "top_jtag", "clkxtal", 50000000),
+};
+
+static const struct mtk_fixed_factor top_divs[] = {
+       /* XTAL */
+       FACTOR(CLK_TOP_XTAL_D2, "top_xtal_d2", "top_xtal", 1, 2),
+       FACTOR(CLK_TOP_RTC_32K, "top_rtc_32k", "top_xtal", 1, 1250),
+       FACTOR(CLK_TOP_RTC_32P7K, "top_rtc_32p7k", "top_xtal", 1, 1220),
+       /* MPLL */
+       FACTOR(CLK_TOP_MPLL_D2, "top_mpll_d2", "mpll", 1, 2),
+       FACTOR(CLK_TOP_MPLL_D4, "top_mpll_d4", "mpll", 1, 4),
+       FACTOR(CLK_TOP_MPLL_D8, "top_mpll_d8", "mpll", 1, 8),
+       FACTOR(CLK_TOP_MPLL_D8_D2, "top_mpll_d8_d2", "mpll", 1, 16),
+       FACTOR(CLK_TOP_MPLL_D3_D2, "top_mpll_d3_d2", "mpll", 1, 6),
+       /* MMPLL */
+       FACTOR(CLK_TOP_MMPLL_D2, "top_mmpll_d2", "mmpll", 1, 2),
+       FACTOR(CLK_TOP_MMPLL_D4, "top_mmpll_d4", "mmpll", 1, 4),
+       FACTOR(CLK_TOP_MMPLL_D8, "top_mmpll_d8", "mmpll", 1, 8),
+       FACTOR(CLK_TOP_MMPLL_D8_D2, "top_mmpll_d8_d2", "mmpll", 1, 16),
+       FACTOR(CLK_TOP_MMPLL_D3_D8, "top_mmpll_d3_d8", "mmpll", 1, 24),
+       FACTOR(CLK_TOP_MMPLL_U2PHY, "top_mmpll_u2phy", "mmpll", 1, 30),
+       /* APLL2 */
+       FACTOR(CLK_TOP_APLL2_D4, "top_apll2_d4", "apll2", 1, 4),
+       /* NET1PLL */
+       FACTOR(CLK_TOP_NET1PLL_D4, "top_net1pll_d4", "net1pll", 1, 4),
+       FACTOR(CLK_TOP_NET1PLL_D5, "top_net1pll_d5", "net1pll", 1, 5),
+       FACTOR(CLK_TOP_NET1PLL_D5_D2, "top_net1pll_d5_d2", "net1pll", 1, 10),
+       FACTOR(CLK_TOP_NET1PLL_D5_D4, "top_net1pll_d5_d4", "net1pll", 1, 20),
+       FACTOR(CLK_TOP_NET1PLL_D8_D2, "top_net1pll_d8_d2", "net1pll", 1, 16),
+       FACTOR(CLK_TOP_NET1PLL_D8_D4, "top_net1pll_d8_d4", "net1pll", 1, 32),
+       /* NET2PLL */
+       FACTOR(CLK_TOP_NET2PLL_D4, "top_net2pll_d4", "net2pll", 1, 4),
+       FACTOR(CLK_TOP_NET2PLL_D4_D2, "top_net2pll_d4_d2", "net2pll", 1, 8),
+       FACTOR(CLK_TOP_NET2PLL_D3_D2, "top_net2pll_d3_d2", "net2pll", 1, 2),
+       /* WEDMCUPLL */
+       FACTOR(CLK_TOP_WEDMCUPLL_D5_D2, "top_wedmcupll_d5_d2", "wedmcupll", 1,
+              10),
+};
+
+static const char *const nfi1x_parents[] __initconst = { "top_xtal",
+                                                        "top_mmpll_d8",
+                                                        "top_net1pll_d8_d2",
+                                                        "top_net2pll_d3_d2",
+                                                        "top_mpll_d4",
+                                                        "top_mmpll_d8_d2",
+                                                        "top_wedmcupll_d5_d2",
+                                                        "top_mpll_d8" };
+
+static const char *const spinfi_parents[] __initconst = {
+       "top_xtal_d2",     "top_xtal",  "top_net1pll_d5_d4",
+       "top_mpll_d4",     "top_mmpll_d8_d2", "top_wedmcupll_d5_d2",
+       "top_mmpll_d3_d8", "top_mpll_d8"
+};
+
+static const char *const spi_parents[] __initconst = {
+       "top_xtal",       "top_mpll_d2",        "top_mmpll_d8",
+       "top_net1pll_d8_d2", "top_net2pll_d3_d2",  "top_net1pll_d5_d4",
+       "top_mpll_d4",       "top_wedmcupll_d5_d2"
+};
+
+static const char *const uart_parents[] __initconst = { "top_xtal",
+                                                       "top_mpll_d8",
+                                                       "top_mpll_d8_d2" };
+
+static const char *const pwm_parents[] __initconst = {
+       "top_xtal", "top_net1pll_d8_d2", "top_net1pll_d5_d4", "top_mpll_d4"
+};
+
+static const char *const i2c_parents[] __initconst = {
+       "top_xtal", "top_net1pll_d5_d4", "top_mpll_d4", "top_net1pll_d8_d4"
+};
+
+static const char *const pextp_tl_ck_parents[] __initconst = {
+       "top_xtal", "top_net1pll_d5_d4", "top_net2pll_d4_d2", "top_rtc_32k"
+};
+
+static const char *const emmc_250m_parents[] __initconst = {
+       "top_xtal", "top_net1pll_d5_d2"
+};
+
+static const char *const emmc_416m_parents[] __initconst = { "top_xtal",
+                                                            "mpll" };
+
+static const char *const f_26m_adc_parents[] __initconst = { "top_xtal",
+                                                            "top_mpll_d8_d2" };
+
+static const char *const dramc_md32_parents[] __initconst = { "top_xtal",
+                                                             "top_mpll_d2" };
+
+static const char *const sysaxi_parents[] __initconst = { "top_xtal",
+                                                         "top_net1pll_d8_d2",
+                                                         "top_net2pll_d4" };
+
+static const char *const sysapb_parents[] __initconst = { "top_xtal",
+                                                         "top_mpll_d3_d2",
+                                                         "top_net2pll_d4_d2" };
+
+static const char *const arm_db_main_parents[] __initconst = {
+       "top_xtal", "top_net2pll_d3_d2"
+};
+
+static const char *const arm_db_jtsel_parents[] __initconst = { "top_jtag",
+                                                               "top_xtal" };
+
+static const char *const netsys_parents[] __initconst = { "top_xtal",
+                                                         "top_mmpll_d4" };
+
+static const char *const netsys_500m_parents[] __initconst = {
+       "top_xtal", "top_net1pll_d5"
+};
+
+static const char *const netsys_mcu_parents[] __initconst = {
+       "top_xtal", "wedmcupll", "top_mmpll_d2", "top_net1pll_d4",
+       "top_net1pll_d5"
+};
+
+static const char *const netsys_2x_parents[] __initconst = {
+       "top_xtal", "net2pll", "wedmcupll", "top_mmpll_d2"
+};
+
+static const char *const sgm_325m_parents[] __initconst = { "top_xtal",
+                                                           "sgmpll" };
+
+static const char *const sgm_reg_parents[] __initconst = {
+       "top_xtal", "top_net1pll_d8_d4"
+};
+
+static const char *const a1sys_parents[] __initconst = { "top_xtal",
+                                                        "top_apll2_d4" };
+
+static const char *const conn_mcusys_parents[] __initconst = { "top_xtal",
+                                                              "top_mmpll_d2" };
+
+static const char *const eip_b_parents[] __initconst = { "top_xtal",
+                                                        "net2pll" };
+
+static const char *const aud_l_parents[] __initconst = { "top_xtal", "apll2",
+                                                        "top_mpll_d8_d2" };
+
+static const char *const a_tuner_parents[] __initconst = { "top_xtal",
+                                                          "top_apll2_d4",
+                                                          "top_mpll_d8_d2" };
+
+static const char *const u2u3_sys_parents[] __initconst = {
+       "top_xtal", "top_net1pll_d5_d4"
+};
+
+static const char *const da_u2_refsel_parents[] __initconst = {
+       "top_xtal", "top_mmpll_u2phy"
+};
+
+static const struct mtk_mux top_muxes[] = {
+       /* CLK_CFG_0 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents,
+                            0x000, 0x004, 0x008, 0, 3, 7, 0x1C0, 0),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents,
+                            0x000, 0x004, 0x008, 8, 3, 15, 0x1C0, 1),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x000,
+                            0x004, 0x008, 16, 3, 23, 0x1C0, 2),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents,
+                            0x000, 0x004, 0x008, 24, 3, 31, 0x1C0, 3),
+       /* CLK_CFG_1 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x010,
+                            0x014, 0x018, 0, 2, 7, 0x1C0, 4),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x010,
+                            0x014, 0x018, 8, 2, 15, 0x1C0, 5),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x010,
+                            0x014, 0x018, 16, 2, 23, 0x1C0, 6),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel",
+                            pextp_tl_ck_parents, 0x010, 0x014, 0x018, 24, 2,
+                            31, 0x1C0, 7),
+       /* CLK_CFG_2 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_250M_SEL, "emmc_250m_sel",
+                            emmc_250m_parents, 0x020, 0x024, 0x028, 0, 1, 7,
+                            0x1C0, 8),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_416M_SEL, "emmc_416m_sel",
+                            emmc_416m_parents, 0x020, 0x024, 0x028, 8, 1, 15,
+                            0x1C0, 9),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_F_26M_ADC_SEL, "f_26m_adc_sel",
+                            f_26m_adc_parents, 0x020, 0x024, 0x028, 16, 1, 23,
+                            0x1C0, 10),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DRAMC_SEL, "dramc_sel", f_26m_adc_parents,
+                            0x020, 0x024, 0x028, 24, 1, 31, 0x1C0, 11),
+       /* CLK_CFG_3 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel",
+                            dramc_md32_parents, 0x030, 0x034, 0x038, 0, 1, 7,
+                            0x1C0, 12),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents,
+                            0x030, 0x034, 0x038, 8, 2, 15, 0x1C0, 13),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents,
+                            0x030, 0x034, 0x038, 16, 2, 23, 0x1C0, 14),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel",
+                            arm_db_main_parents, 0x030, 0x034, 0x038, 24, 1,
+                            31, 0x1C0, 15),
+       /* CLK_CFG_4 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_ARM_DB_JTSEL, "arm_db_jtsel",
+                            arm_db_jtsel_parents, 0x040, 0x044, 0x048, 0, 1, 7,
+                            0x1C0, 16),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents,
+                            0x040, 0x044, 0x048, 8, 1, 15, 0x1C0, 17),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_500M_SEL, "netsys_500m_sel",
+                            netsys_500m_parents, 0x040, 0x044, 0x048, 16, 1,
+                            23, 0x1C0, 18),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel",
+                            netsys_mcu_parents, 0x040, 0x044, 0x048, 24, 3, 31,
+                            0x1C0, 19),
+       /* CLK_CFG_5 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_2X_SEL, "netsys_2x_sel",
+                            netsys_2x_parents, 0x050, 0x054, 0x058, 0, 2, 7,
+                            0x1C0, 20),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_325M_SEL, "sgm_325m_sel",
+                            sgm_325m_parents, 0x050, 0x054, 0x058, 8, 1, 15,
+                            0x1C0, 21),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel",
+                            sgm_reg_parents, 0x050, 0x054, 0x058, 16, 1, 23,
+                            0x1C0, 22),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents,
+                            0x050, 0x054, 0x058, 24, 1, 31, 0x1C0, 23),
+       /* CLK_CFG_6 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_CONN_MCUSYS_SEL, "conn_mcusys_sel",
+                            conn_mcusys_parents, 0x060, 0x064, 0x068, 0, 1, 7,
+                            0x1C0, 24),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_EIP_B_SEL, "eip_b_sel", eip_b_parents,
+                            0x060, 0x064, 0x068, 8, 1, 15, 0x1C0, 25),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_PCIE_PHY_SEL, "pcie_phy_sel",
+                            f_26m_adc_parents, 0x060, 0x064, 0x068, 16, 1, 23,
+                            0x1C0, 26),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_USB3_PHY_SEL, "usb3_phy_sel",
+                            f_26m_adc_parents, 0x060, 0x064, 0x068, 24, 1, 31,
+                            0x1C0, 27),
+       /* CLK_CFG_7 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_F26M_SEL, "csw_f26m_sel",
+                            f_26m_adc_parents, 0x070, 0x074, 0x078, 0, 1, 7,
+                            0x1C0, 28),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents,
+                            0x070, 0x074, 0x078, 8, 2, 15, 0x1C0, 29),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_A_TUNER_SEL, "a_tuner_sel",
+                            a_tuner_parents, 0x070, 0x074, 0x078, 16, 2, 23,
+                            0x1C0, 30),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_SEL, "u2u3_sel", f_26m_adc_parents,
+                            0x070, 0x074, 0x078, 24, 1, 31, 0x1C4, 0),
+       /* CLK_CFG_8 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel",
+                            u2u3_sys_parents, 0x080, 0x084, 0x088, 0, 1, 7,
+                            0x1C4, 1),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel",
+                            u2u3_sys_parents, 0x080, 0x084, 0x088, 8, 1, 15,
+                            0x1C4, 2),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_U2_REFSEL, "da_u2_refsel",
+                            da_u2_refsel_parents, 0x080, 0x084, 0x088, 16, 1,
+                            23, 0x1C4, 3),
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_U2_CK_1P_SEL, "da_u2_ck_1p_sel",
+                            da_u2_refsel_parents, 0x080, 0x084, 0x088, 24, 1,
+                            31, 0x1C4, 4),
+       /* CLK_CFG_9 */
+       MUX_GATE_CLR_SET_UPD(CLK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel",
+                            sgm_reg_parents, 0x090, 0x094, 0x098, 0, 1, 7,
+                            0x1C4, 5),
+};
+
+static int clk_mt7986_topckgen_probe(struct platform_device *pdev)
+{
+       struct clk_onecell_data *clk_data;
+       struct device_node *node = pdev->dev.of_node;
+       int r;
+       void __iomem *base;
+       int nr = ARRAY_SIZE(top_fixed_clks) + ARRAY_SIZE(top_divs) +
+                ARRAY_SIZE(top_muxes);
+
+       base = of_iomap(node, 0);
+       if (!base) {
+               pr_err("%s(): ioremap failed\n", __func__);
+               return -ENOMEM;
+       }
+
+       clk_data = mtk_alloc_clk_data(nr);
+       if (!clk_data)
+               return -ENOMEM;
+
+       mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
+                                   clk_data);
+       mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+       mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes), node,
+                              &mt7986_clk_lock, clk_data);
+
+       clk_prepare_enable(clk_data->clks[CLK_TOP_SYSAXI_SEL]);
+       clk_prepare_enable(clk_data->clks[CLK_TOP_SYSAPB_SEL]);
+       clk_prepare_enable(clk_data->clks[CLK_TOP_DRAMC_SEL]);
+       clk_prepare_enable(clk_data->clks[CLK_TOP_DRAMC_MD32_SEL]);
+       clk_prepare_enable(clk_data->clks[CLK_TOP_F26M_SEL]);
+       clk_prepare_enable(clk_data->clks[CLK_TOP_SGM_REG_SEL]);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r) {
+               pr_err("%s(): could not register clock provider: %d\n",
+                      __func__, r);
+               goto free_topckgen_data;
+       }
+       return r;
+
+free_topckgen_data:
+       mtk_free_clk_data(clk_data);
+       return r;
+}
+
+static const struct of_device_id of_match_clk_mt7986_topckgen[] = {
+       { .compatible = "mediatek,mt7986-topckgen", },
+       {}
+};
+
+static struct platform_driver clk_mt7986_topckgen_drv = {
+       .probe = clk_mt7986_topckgen_probe,
+       .driver = {
+               .name = "clk-mt7986-topckgen",
+               .of_match_table = of_match_clk_mt7986_topckgen,
+       },
+};
+builtin_platform_driver(clk_mt7986_topckgen_drv);
diff --git a/target/linux/mediatek/files-5.15/drivers/pinctrl/mediatek/pinctrl-mt7986.c b/target/linux/mediatek/files-5.15/drivers/pinctrl/mediatek/pinctrl-mt7986.c
new file mode 100644 (file)
index 0000000..05a34e7
--- /dev/null
@@ -0,0 +1,933 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The MT7986 driver based on Linux generic pinctrl binding.
+ *
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#include "pinctrl-moore.h"
+
+#define MT7986_PIN(_number, _name) MTK_PIN(_number, _name, 0, _number, DRV_GRP4)
+#define MT7986_NOT_BALLOUT_PIN(_number) { .number = _number, .name = NULL }
+
+#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,     \
+                       _x_bits)        \
+               PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit,      \
+                       _x_bits, 32, 0)
+
+/**
+ * enum - Locking variants of the iocfg bases
+ *
+ * MT7986 have multiple bases to program pin configuration listed as the below:
+ * iocfg_rt:0x11c30000, iocfg_rb:0x11c40000, iocfg_lt:0x11e20000,
+ * iocfg_lb:0x11e30000, iocfg_tr:0x11f00000, iocfg_tl:0x11f10000,
+ * _i_based could be used to indicate what base the pin should be mapped into.
+ *
+ * Each iocfg register base control different group of pads on the SoC
+ *
+ *
+ *  chip carrier
+ *
+ *      A  B  C  D  E  F  G  H
+ *    +------------------------+
+ *  8 | o  o  o  o  o  o  o  o |
+ *  7 | o  o  o  o  o  o  o  o |
+ *  6 | o  o  o  o  o  o  o  o |
+ *  5 | o  o  o  o  o  o  o  o |
+ *  4 | o  o  o  o  o  o  o  o |
+ *  3 | o  o  o  o  o  o  o  o |
+ *  2 | o  o  o  o  o  o  o  o |
+ *  1 | o  o  o  o  o  o  o  o |
+ *    +------------------------+
+ *
+ *  inside Chip carrier
+ *
+ *      A  B  C  D  E  F  G  H
+ *    +------------------------+
+ *  8 |                        |
+ *  7 |        TL  TR          |
+ *  6 |      +---------+       |
+ *  5 |   LT |         | RT    |
+ *  4 |      |         |       |
+ *  3 |   LB |         | RB    |
+ *  2 |      +---------+       |
+ *  1 |                        |
+ *    +------------------------+
+ *
+ */
+
+enum {
+       GPIO_BASE,
+       IOCFG_RT_BASE,
+       IOCFG_RB_BASE,
+       IOCFG_LT_BASE,
+       IOCFG_LB_BASE,
+       IOCFG_TR_BASE,
+       IOCFG_TL_BASE,
+};
+
+static const char *const mt7986_pinctrl_register_base_names[] = {
+       "gpio", "iocfg_rt", "iocfg_rb", "iocfg_lt", "iocfg_lb", "iocfg_tr",
+       "iocfg_tl",
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_mode_range[] = {
+       PIN_FIELD(0, 100, 0x300, 0x10, 0, 4),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_dir_range[] = {
+       PIN_FIELD(0, 100, 0x0, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_di_range[] = {
+       PIN_FIELD(0, 100, 0x200, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_do_range[] = {
+       PIN_FIELD(0, 100, 0x100, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_ies_range[] = {
+       PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x40, 0x10, 17, 1),
+       PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x20, 0x10, 10, 1),
+       PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x20, 0x10, 0, 1),
+       PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x40, 0x10, 0, 1),
+       PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x20, 0x10, 0, 1),
+       PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x40, 0x10, 8, 1),
+       PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x40, 0x10, 2, 1),
+       PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x30, 0x10, 12, 1),
+       PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x30, 0x10, 18, 1),
+       PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x30, 0x10, 17, 1),
+       PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x30, 0x10, 15, 1),
+       PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x30, 0x10, 19, 1),
+       PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x30, 0x10, 23, 1),
+       PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x30, 0x10, 22, 1),
+       PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x30, 0x10, 21, 1),
+       PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x20, 0x10, 4, 1),
+       PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x20, 0x10, 8, 1),
+       PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x20, 0x10, 7, 1),
+       PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x20, 0x10, 5, 1),
+       PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x20, 0x10, 9, 1),
+       PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x40, 0x10, 18, 1),
+       PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x40, 0x10, 12, 1),
+       PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x40, 0x10, 22, 1),
+       PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x40, 0x10, 20, 1),
+       PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x40, 0x10, 26, 1),
+       PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x40, 0x10, 24, 1),
+       PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x30, 0x10, 2, 1),
+       PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x30, 0x10, 1, 1),
+       PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x30, 0x10, 0, 1),
+       PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x30, 0x10, 10, 1),
+       PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x40, 0x10, 15, 1),
+       PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x40, 0x10, 14, 1),
+       PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x40, 0x10, 13, 1),
+       PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x40, 0x10, 16, 1),
+       PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x20, 0x10, 2, 1),
+       PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x30, 0x10, 1, 1),
+       PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x30, 0x10, 0, 1),
+       PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x30, 0x10, 16, 1),
+       PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x30, 0x10, 14, 1),
+       PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x30, 0x10, 4, 1),
+       PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x30, 0x10, 6, 1),
+       PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x30, 0x10, 2, 1),
+       PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x30, 0x10, 9, 1),
+       PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x30, 0x10, 5, 1),
+       PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x30, 0x10, 1, 1),
+       PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x30, 0x10, 0, 1),
+       PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x30, 0x10, 14, 1),
+       PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x30, 0x10, 12, 1),
+       PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x30, 0x10, 4, 1),
+       PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x30, 0x10, 2, 1),
+       PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x30, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_smt_range[] = {
+       PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0xf0, 0x10, 17, 1),
+       PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x90, 0x10, 10, 1),
+       PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x90, 0x10, 0, 1),
+       PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0xf0, 0x10, 0, 1),
+       PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x90, 0x10, 0, 1),
+       PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0xf0, 0x10, 8, 1),
+       PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0xf0, 0x10, 2, 1),
+       PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0xc0, 0x10, 12, 1),
+       PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0xc0, 0x10, 18, 1),
+       PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0xc0, 0x10, 17, 1),
+       PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0xc0, 0x10, 15, 1),
+       PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0xc0, 0x10, 19, 1),
+       PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0xc0, 0x10, 23, 1),
+       PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0xc0, 0x10, 22, 1),
+       PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0xc0, 0x10, 21, 1),
+       PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x90, 0x10, 4, 1),
+       PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x90, 0x10, 8, 1),
+       PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x90, 0x10, 7, 1),
+       PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x90, 0x10, 5, 1),
+       PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x90, 0x10, 9, 1),
+       PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0xf0, 0x10, 18, 1),
+       PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0xf0, 0x10, 12, 1),
+       PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0xf0, 0x10, 22, 1),
+       PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0xf0, 0x10, 20, 1),
+       PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0xf0, 0x10, 26, 1),
+       PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0xf0, 0x10, 24, 1),
+       PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0xc0, 0x10, 2, 1),
+       PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0xc0, 0x10, 1, 1),
+       PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0xc0, 0x10, 0, 1),
+       PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0xc0, 0x10, 10, 1),
+       PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0xf0, 0x10, 15, 1),
+       PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0xf0, 0x10, 14, 1),
+       PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0xf0, 0x10, 13, 1),
+       PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0xf0, 0x10, 16, 1),
+       PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x90, 0x10, 2, 1),
+       PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x80, 0x10, 1, 1),
+       PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x80, 0x10, 0, 1),
+       PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x80, 0x10, 16, 1),
+       PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x80, 0x10, 14, 1),
+       PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x80, 0x10, 4, 1),
+       PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x80, 0x10, 6, 1),
+       PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x80, 0x10, 2, 1),
+       PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x80, 0x10, 9, 1),
+       PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x80, 0x10, 5, 1),
+       PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x70, 0x10, 1, 1),
+       PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x70, 0x10, 0, 1),
+       PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x70, 0x10, 14, 1),
+       PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x70, 0x10, 12, 1),
+       PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x70, 0x10, 4, 1),
+       PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x70, 0x10, 2, 1),
+       PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x70, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_pu_range[] = {
+       PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x50, 0x10, 1, 1),
+       PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x50, 0x10, 0, 1),
+       PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x50, 0x10, 16, 1),
+       PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x50, 0x10, 14, 1),
+       PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x50, 0x10, 4, 1),
+       PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x50, 0x10, 6, 1),
+       PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x50, 0x10, 2, 1),
+       PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x50, 0x10, 9, 1),
+       PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x50, 0x10, 5, 1),
+       PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x50, 0x10, 1, 1),
+       PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x50, 0x10, 0, 1),
+       PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x50, 0x10, 14, 1),
+       PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x50, 0x10, 12, 1),
+       PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x50, 0x10, 4, 1),
+       PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x50, 0x10, 2, 1),
+       PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x50, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_pd_range[] = {
+       PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x40, 0x10, 1, 1),
+       PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x40, 0x10, 0, 1),
+       PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x40, 0x10, 16, 1),
+       PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x40, 0x10, 14, 1),
+       PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x40, 0x10, 4, 1),
+       PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x40, 0x10, 6, 1),
+       PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x40, 0x10, 2, 1),
+       PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x40, 0x10, 9, 1),
+       PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x40, 0x10, 5, 1),
+       PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x40, 0x10, 1, 1),
+       PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x40, 0x10, 0, 1),
+       PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x40, 0x10, 14, 1),
+       PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x40, 0x10, 12, 1),
+       PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x40, 0x10, 4, 1),
+       PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x40, 0x10, 2, 1),
+       PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x40, 0x10, 8, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_drv_range[] = {
+       PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x10, 0x10, 21, 3),
+       PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x10, 0x10, 0, 3),
+       PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x00, 0x10, 0, 1),
+       PIN_FIELD_BASE(5, 5, IOCFG_RB_BASE, 0x00, 0x10, 0, 3),
+       PIN_FIELD_BASE(6, 6, IOCFG_RB_BASE, 0x00, 0x10, 21, 3),
+       PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x00, 0x10, 0, 3),
+       PIN_FIELD_BASE(11, 12, IOCFG_RB_BASE, 0x00, 0x10, 24, 3),
+       PIN_FIELD_BASE(13, 14, IOCFG_RB_BASE, 0x10, 0x10, 0, 3),
+       PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x00, 0x10, 3, 3),
+       PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x10, 0x10, 6, 3),
+       PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x10, 0x10, 24, 3),
+       PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x10, 0x10, 21, 3),
+       PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x10, 0x10, 15, 3),
+       PIN_FIELD_BASE(28, 28, IOCFG_RT_BASE, 0x10, 0x10, 27, 3),
+       PIN_FIELD_BASE(29, 29, IOCFG_RT_BASE, 0x20, 0x10, 0, 3),
+       PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x20, 0x10, 9, 3),
+       PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x20, 0x10, 6, 3),
+       PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x20, 0x10, 3, 3),
+       PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x00, 0x10, 12, 3),
+       PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x00, 0x10, 24, 3),
+       PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x00, 0x10, 21, 3),
+       PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x00, 0x10, 15, 3),
+       PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x00, 0x10, 27, 3),
+       PIN_FIELD_BASE(39, 39, IOCFG_RB_BASE, 0x10, 0x10, 27, 3),
+       PIN_FIELD_BASE(40, 40, IOCFG_RB_BASE, 0x20, 0x10, 0, 3),
+       PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x10, 0x10, 6, 3),
+       PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x20, 0x10, 9, 3),
+       PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x20, 0x10, 3, 3),
+       PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x20, 0x10, 21, 3),
+       PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x20, 0x10, 15, 3),
+       PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x00, 0x10, 6, 3),
+       PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x00, 0x10, 3, 3),
+       PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x00, 0x10, 0, 3),
+       PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x10, 0x10, 0, 3),
+       PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x10, 0x10, 15, 3),
+       PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x10, 0x10, 12, 3),
+       PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x10, 0x10, 9, 3),
+       PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x10, 0x10, 18, 3),
+       PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x00, 0x10, 2, 3),
+       PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x00, 0x10, 3, 3),
+       PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x00, 0x10, 0, 3),
+       PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x10, 0x10, 18, 3),
+       PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x10, 0x10, 12, 3),
+       PIN_FIELD_BASE(74, 77, IOCFG_TR_BASE, 0x00, 0x10, 15, 3),
+       PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x00, 0x10, 6, 3),
+       PIN_FIELD_BASE(80, 80, IOCFG_TR_BASE, 0x00, 0x10, 27, 3),
+       PIN_FIELD_BASE(81, 84, IOCFG_TR_BASE, 0x10, 0x10, 0, 3),
+       PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x00, 0x10, 12, 3),
+       PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x00, 0x10, 3, 3),
+       PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x00, 0x10, 0, 3),
+       PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x10, 0x10, 12, 3),
+       PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x10, 0x10, 6, 3),
+       PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x00, 0x10, 12, 3),
+       PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x00, 0x10, 6, 3),
+       PIN_FIELD_BASE(97, 98, IOCFG_TL_BASE, 0x00, 0x10, 24, 3),
+       PIN_FIELD_BASE(99, 100, IOCFG_TL_BASE, 0x10, 0x10, 2, 3),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_pupd_range[] = {
+       PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x60, 0x10, 17, 1),
+       PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x30, 0x10, 10, 1),
+       PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x40, 0x10, 0, 1),
+       PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x60, 0x10, 0, 1),
+       PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x30, 0x10, 0, 1),
+       PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x60, 0x10, 8, 1),
+       PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x60, 0x10, 2, 1),
+       PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x40, 0x10, 12, 1),
+       PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x40, 0x10, 18, 1),
+       PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x40, 0x10, 17, 1),
+       PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x40, 0x10, 15, 1),
+       PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x40, 0x10, 19, 1),
+       PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x40, 0x10, 23, 1),
+       PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x40, 0x10, 22, 1),
+       PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x40, 0x10, 21, 1),
+       PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x30, 0x10, 4, 1),
+       PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x30, 0x10, 8, 1),
+       PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x30, 0x10, 7, 1),
+       PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x30, 0x10, 5, 1),
+       PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x30, 0x10, 9, 1),
+       PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x60, 0x10, 18, 1),
+       PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x60, 0x10, 12, 1),
+       PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x60, 0x10, 22, 1),
+       PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x60, 0x10, 20, 1),
+       PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x60, 0x10, 26, 1),
+       PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x60, 0x10, 24, 1),
+       PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x40, 0x10, 2, 1),
+       PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x40, 0x10, 1, 1),
+       PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x40, 0x10, 0, 1),
+       PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x40, 0x10, 10, 1),
+       PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x60, 0x10, 15, 1),
+       PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x60, 0x10, 14, 1),
+       PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x60, 0x10, 13, 1),
+       PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x60, 0x10, 16, 1),
+       PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x40, 0x10, 2, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_r0_range[] = {
+       PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x70, 0x10, 17, 1),
+       PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x40, 0x10, 10, 1),
+       PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x50, 0x10, 0, 1),
+       PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x70, 0x10, 0, 1),
+       PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x40, 0x10, 0, 1),
+       PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x70, 0x10, 8, 1),
+       PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x70, 0x10, 2, 1),
+       PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x50, 0x10, 12, 1),
+       PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x50, 0x10, 18, 1),
+       PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x50, 0x10, 17, 1),
+       PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x50, 0x10, 15, 1),
+       PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x50, 0x10, 19, 1),
+       PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x50, 0x10, 23, 1),
+       PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x50, 0x10, 22, 1),
+       PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x50, 0x10, 21, 1),
+       PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x40, 0x10, 4, 1),
+       PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x40, 0x10, 8, 1),
+       PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x40, 0x10, 7, 1),
+       PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x40, 0x10, 5, 1),
+       PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x40, 0x10, 9, 1),
+       PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x70, 0x10, 18, 1),
+       PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x70, 0x10, 12, 1),
+       PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x70, 0x10, 22, 1),
+       PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x70, 0x10, 20, 1),
+       PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x70, 0x10, 26, 1),
+       PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x70, 0x10, 24, 1),
+       PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x50, 0x10, 2, 1),
+       PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x50, 0x10, 1, 1),
+       PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x50, 0x10, 0, 1),
+       PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x50, 0x10, 10, 1),
+       PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x70, 0x10, 15, 1),
+       PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x70, 0x10, 14, 1),
+       PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x70, 0x10, 13, 1),
+       PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x70, 0x10, 16, 1),
+       PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x50, 0x10, 2, 1),
+};
+
+static const struct mtk_pin_field_calc mt7986_pin_r1_range[] = {
+       PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x80, 0x10, 17, 1),
+       PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x50, 0x10, 10, 1),
+       PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x60, 0x10, 0, 1),
+       PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x80, 0x10, 0, 1),
+       PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x50, 0x10, 0, 1),
+       PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x80, 0x10, 8, 1),
+       PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x80, 0x10, 2, 1),
+       PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x60, 0x10, 12, 1),
+       PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x60, 0x10, 18, 1),
+       PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x60, 0x10, 17, 1),
+       PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x60, 0x10, 15, 1),
+       PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x60, 0x10, 19, 1),
+       PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x60, 0x10, 23, 1),
+       PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x60, 0x10, 22, 1),
+       PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x60, 0x10, 21, 1),
+       PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x50, 0x10, 4, 1),
+       PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x50, 0x10, 8, 1),
+       PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x50, 0x10, 7, 1),
+       PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x50, 0x10, 5, 1),
+       PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x50, 0x10, 9, 1),
+       PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x80, 0x10, 18, 1),
+       PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x80, 0x10, 12, 1),
+       PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x80, 0x10, 22, 1),
+       PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x80, 0x10, 20, 1),
+       PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x80, 0x10, 26, 1),
+       PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x80, 0x10, 24, 1),
+       PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x60, 0x10, 2, 1),
+       PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x60, 0x10, 1, 1),
+       PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x60, 0x10, 0, 1),
+       PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x60, 0x10, 10, 1),
+       PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x80, 0x10, 15, 1),
+       PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x80, 0x10, 14, 1),
+       PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x80, 0x10, 13, 1),
+       PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x80, 0x10, 16, 1),
+       PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x60, 0x10, 2, 1),
+};
+
+static const struct mtk_pin_reg_calc mt7986_reg_cals[] = {
+       [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7986_pin_mode_range),
+       [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7986_pin_dir_range),
+       [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7986_pin_di_range),
+       [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7986_pin_do_range),
+       [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7986_pin_smt_range),
+       [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7986_pin_ies_range),
+       [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7986_pin_drv_range),
+       [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7986_pin_pu_range),
+       [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7986_pin_pd_range),
+       [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7986_pin_pupd_range),
+       [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7986_pin_r0_range),
+       [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7986_pin_r1_range),
+};
+
+static const struct mtk_pin_desc mt7986a_pins[] = {
+       MT7986_PIN(0, "SYS_WATCHDOG"),
+       MT7986_PIN(1, "WF2G_LED"),
+       MT7986_PIN(2, "WF5G_LED"),
+       MT7986_PIN(3, "I2C_SCL"),
+       MT7986_PIN(4, "I2C_SDA"),
+       MT7986_PIN(5, "GPIO_0"),
+       MT7986_PIN(6, "GPIO_1"),
+       MT7986_PIN(7, "GPIO_2"),
+       MT7986_PIN(8, "GPIO_3"),
+       MT7986_PIN(9, "GPIO_4"),
+       MT7986_PIN(10, "GPIO_5"),
+       MT7986_PIN(11, "GPIO_6"),
+       MT7986_PIN(12, "GPIO_7"),
+       MT7986_PIN(13, "GPIO_8"),
+       MT7986_PIN(14, "GPIO_9"),
+       MT7986_PIN(15, "GPIO_10"),
+       MT7986_PIN(16, "GPIO_11"),
+       MT7986_PIN(17, "GPIO_12"),
+       MT7986_PIN(18, "GPIO_13"),
+       MT7986_PIN(19, "GPIO_14"),
+       MT7986_PIN(20, "GPIO_15"),
+       MT7986_PIN(21, "PWM0"),
+       MT7986_PIN(22, "PWM1"),
+       MT7986_PIN(23, "SPI0_CLK"),
+       MT7986_PIN(24, "SPI0_MOSI"),
+       MT7986_PIN(25, "SPI0_MISO"),
+       MT7986_PIN(26, "SPI0_CS"),
+       MT7986_PIN(27, "SPI0_HOLD"),
+       MT7986_PIN(28, "SPI0_WP"),
+       MT7986_PIN(29, "SPI1_CLK"),
+       MT7986_PIN(30, "SPI1_MOSI"),
+       MT7986_PIN(31, "SPI1_MISO"),
+       MT7986_PIN(32, "SPI1_CS"),
+       MT7986_PIN(33, "SPI2_CLK"),
+       MT7986_PIN(34, "SPI2_MOSI"),
+       MT7986_PIN(35, "SPI2_MISO"),
+       MT7986_PIN(36, "SPI2_CS"),
+       MT7986_PIN(37, "SPI2_HOLD"),
+       MT7986_PIN(38, "SPI2_WP"),
+       MT7986_PIN(39, "UART0_RXD"),
+       MT7986_PIN(40, "UART0_TXD"),
+       MT7986_PIN(41, "PCIE_PERESET_N"),
+       MT7986_PIN(42, "UART1_RXD"),
+       MT7986_PIN(43, "UART1_TXD"),
+       MT7986_PIN(44, "UART1_CTS"),
+       MT7986_PIN(45, "UART1_RTS"),
+       MT7986_PIN(46, "UART2_RXD"),
+       MT7986_PIN(47, "UART2_TXD"),
+       MT7986_PIN(48, "UART2_CTS"),
+       MT7986_PIN(49, "UART2_RTS"),
+       MT7986_PIN(50, "EMMC_DATA_0"),
+       MT7986_PIN(51, "EMMC_DATA_1"),
+       MT7986_PIN(52, "EMMC_DATA_2"),
+       MT7986_PIN(53, "EMMC_DATA_3"),
+       MT7986_PIN(54, "EMMC_DATA_4"),
+       MT7986_PIN(55, "EMMC_DATA_5"),
+       MT7986_PIN(56, "EMMC_DATA_6"),
+       MT7986_PIN(57, "EMMC_DATA_7"),
+       MT7986_PIN(58, "EMMC_CMD"),
+       MT7986_PIN(59, "EMMC_CK"),
+       MT7986_PIN(60, "EMMC_DSL"),
+       MT7986_PIN(61, "EMMC_RSTB"),
+       MT7986_PIN(62, "PCM_DTX"),
+       MT7986_PIN(63, "PCM_DRX"),
+       MT7986_PIN(64, "PCM_CLK"),
+       MT7986_PIN(65, "PCM_FS"),
+       MT7986_PIN(66, "MT7531_INT"),
+       MT7986_PIN(67, "SMI_MDC"),
+       MT7986_PIN(68, "SMI_MDIO"),
+       MT7986_PIN(69, "WF0_DIG_RESETB"),
+       MT7986_PIN(70, "WF0_CBA_RESETB"),
+       MT7986_PIN(71, "WF0_XO_REQ"),
+       MT7986_PIN(72, "WF0_TOP_CLK"),
+       MT7986_PIN(73, "WF0_TOP_DATA"),
+       MT7986_PIN(74, "WF0_HB1"),
+       MT7986_PIN(75, "WF0_HB2"),
+       MT7986_PIN(76, "WF0_HB3"),
+       MT7986_PIN(77, "WF0_HB4"),
+       MT7986_PIN(78, "WF0_HB0"),
+       MT7986_PIN(79, "WF0_HB0_B"),
+       MT7986_PIN(80, "WF0_HB5"),
+       MT7986_PIN(81, "WF0_HB6"),
+       MT7986_PIN(82, "WF0_HB7"),
+       MT7986_PIN(83, "WF0_HB8"),
+       MT7986_PIN(84, "WF0_HB9"),
+       MT7986_PIN(85, "WF0_HB10"),
+       MT7986_PIN(86, "WF1_DIG_RESETB"),
+       MT7986_PIN(87, "WF1_CBA_RESETB"),
+       MT7986_PIN(88, "WF1_XO_REQ"),
+       MT7986_PIN(89, "WF1_TOP_CLK"),
+       MT7986_PIN(90, "WF1_TOP_DATA"),
+       MT7986_PIN(91, "WF1_HB1"),
+       MT7986_PIN(92, "WF1_HB2"),
+       MT7986_PIN(93, "WF1_HB3"),
+       MT7986_PIN(94, "WF1_HB4"),
+       MT7986_PIN(95, "WF1_HB0"),
+       MT7986_PIN(96, "WF1_HB0_B"),
+       MT7986_PIN(97, "WF1_HB5"),
+       MT7986_PIN(98, "WF1_HB6"),
+       MT7986_PIN(99, "WF1_HB7"),
+       MT7986_PIN(100, "WF1_HB8"),
+};
+
+static const struct mtk_pin_desc mt7986b_pins[] = {
+       MT7986_PIN(0, "SYS_WATCHDOG"),
+       MT7986_PIN(1, "WF2G_LED"),
+       MT7986_PIN(2, "WF5G_LED"),
+       MT7986_PIN(3, "I2C_SCL"),
+       MT7986_PIN(4, "I2C_SDA"),
+       MT7986_PIN(5, "GPIO_0"),
+       MT7986_PIN(6, "GPIO_1"),
+       MT7986_PIN(7, "GPIO_2"),
+       MT7986_PIN(8, "GPIO_3"),
+       MT7986_PIN(9, "GPIO_4"),
+       MT7986_PIN(10, "GPIO_5"),
+       MT7986_PIN(11, "GPIO_6"),
+       MT7986_PIN(12, "GPIO_7"),
+       MT7986_PIN(13, "GPIO_8"),
+       MT7986_PIN(14, "GPIO_9"),
+       MT7986_PIN(15, "GPIO_10"),
+       MT7986_PIN(16, "GPIO_11"),
+       MT7986_PIN(17, "GPIO_12"),
+       MT7986_PIN(18, "GPIO_13"),
+       MT7986_PIN(19, "GPIO_14"),
+       MT7986_PIN(20, "GPIO_15"),
+       MT7986_PIN(21, "PWM0"),
+       MT7986_PIN(22, "PWM1"),
+       MT7986_PIN(23, "SPI0_CLK"),
+       MT7986_PIN(24, "SPI0_MOSI"),
+       MT7986_PIN(25, "SPI0_MISO"),
+       MT7986_PIN(26, "SPI0_CS"),
+       MT7986_PIN(27, "SPI0_HOLD"),
+       MT7986_PIN(28, "SPI0_WP"),
+       MT7986_PIN(29, "SPI1_CLK"),
+       MT7986_PIN(30, "SPI1_MOSI"),
+       MT7986_PIN(31, "SPI1_MISO"),
+       MT7986_PIN(32, "SPI1_CS"),
+       MT7986_PIN(33, "SPI2_CLK"),
+       MT7986_PIN(34, "SPI2_MOSI"),
+       MT7986_PIN(35, "SPI2_MISO"),
+       MT7986_PIN(36, "SPI2_CS"),
+       MT7986_PIN(37, "SPI2_HOLD"),
+       MT7986_PIN(38, "SPI2_WP"),
+       MT7986_PIN(39, "UART0_RXD"),
+       MT7986_PIN(40, "UART0_TXD"),
+       MT7986_NOT_BALLOUT_PIN(41),
+       MT7986_NOT_BALLOUT_PIN(42),
+       MT7986_NOT_BALLOUT_PIN(43),
+       MT7986_NOT_BALLOUT_PIN(44),
+       MT7986_NOT_BALLOUT_PIN(45),
+       MT7986_NOT_BALLOUT_PIN(46),
+       MT7986_NOT_BALLOUT_PIN(47),
+       MT7986_NOT_BALLOUT_PIN(48),
+       MT7986_NOT_BALLOUT_PIN(49),
+       MT7986_NOT_BALLOUT_PIN(50),
+       MT7986_NOT_BALLOUT_PIN(51),
+       MT7986_NOT_BALLOUT_PIN(52),
+       MT7986_NOT_BALLOUT_PIN(53),
+       MT7986_NOT_BALLOUT_PIN(54),
+       MT7986_NOT_BALLOUT_PIN(55),
+       MT7986_NOT_BALLOUT_PIN(56),
+       MT7986_NOT_BALLOUT_PIN(57),
+       MT7986_NOT_BALLOUT_PIN(58),
+       MT7986_NOT_BALLOUT_PIN(59),
+       MT7986_NOT_BALLOUT_PIN(60),
+       MT7986_NOT_BALLOUT_PIN(61),
+       MT7986_NOT_BALLOUT_PIN(62),
+       MT7986_NOT_BALLOUT_PIN(63),
+       MT7986_NOT_BALLOUT_PIN(64),
+       MT7986_NOT_BALLOUT_PIN(65),
+       MT7986_PIN(66, "MT7531_INT"),
+       MT7986_PIN(67, "SMI_MDC"),
+       MT7986_PIN(68, "SMI_MDIO"),
+       MT7986_PIN(69, "WF0_DIG_RESETB"),
+       MT7986_PIN(70, "WF0_CBA_RESETB"),
+       MT7986_PIN(71, "WF0_XO_REQ"),
+       MT7986_PIN(72, "WF0_TOP_CLK"),
+       MT7986_PIN(73, "WF0_TOP_DATA"),
+       MT7986_PIN(74, "WF0_HB1"),
+       MT7986_PIN(75, "WF0_HB2"),
+       MT7986_PIN(76, "WF0_HB3"),
+       MT7986_PIN(77, "WF0_HB4"),
+       MT7986_PIN(78, "WF0_HB0"),
+       MT7986_PIN(79, "WF0_HB0_B"),
+       MT7986_PIN(80, "WF0_HB5"),
+       MT7986_PIN(81, "WF0_HB6"),
+       MT7986_PIN(82, "WF0_HB7"),
+       MT7986_PIN(83, "WF0_HB8"),
+       MT7986_PIN(84, "WF0_HB9"),
+       MT7986_PIN(85, "WF0_HB10"),
+       MT7986_PIN(86, "WF1_DIG_RESETB"),
+       MT7986_PIN(87, "WF1_CBA_RESETB"),
+       MT7986_PIN(88, "WF1_XO_REQ"),
+       MT7986_PIN(89, "WF1_TOP_CLK"),
+       MT7986_PIN(90, "WF1_TOP_DATA"),
+       MT7986_PIN(91, "WF1_HB1"),
+       MT7986_PIN(92, "WF1_HB2"),
+       MT7986_PIN(93, "WF1_HB3"),
+       MT7986_PIN(94, "WF1_HB4"),
+       MT7986_PIN(95, "WF1_HB0"),
+       MT7986_PIN(96, "WF1_HB0_B"),
+       MT7986_PIN(97, "WF1_HB5"),
+       MT7986_PIN(98, "WF1_HB6"),
+       MT7986_PIN(99, "WF1_HB7"),
+       MT7986_PIN(100, "WF1_HB8"),
+};
+
+/* List all groups consisting of these pins dedicated to the enablement of
+ * certain hardware block and the corresponding mode for all of the pins.
+ * The hardware probably has multiple combinations of these pinouts.
+ */
+
+static int mt7986_watchdog_pins[] = { 0, };
+static int mt7986_watchdog_funcs[] = { 1, };
+
+static int mt7986_wifi_led_pins[] = { 1, 2, };
+static int mt7986_wifi_led_funcs[] = { 1, 1, };
+
+static int mt7986_i2c_pins[] = { 3, 4, };
+static int mt7986_i2c_funcs[] = { 1, 1, };
+
+static int mt7986_uart1_0_pins[] = { 7, 8, 9, 10, };
+static int mt7986_uart1_0_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_spi1_0_pins[] = { 11, 12, 13, 14, };
+static int mt7986_spi1_0_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_pwm1_1_pins[] = { 20, };
+static int mt7986_pwm1_1_funcs[] = { 2, };
+
+static int mt7986_pwm0_pins[] = { 21, };
+static int mt7986_pwm0_funcs[] = { 1, };
+
+static int mt7986_pwm1_0_pins[] = { 22, };
+static int mt7986_pwm1_0_funcs[] = { 1, };
+
+static int mt7986_emmc_45_pins[] = {
+       22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, };
+static int mt7986_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
+
+static int mt7986_snfi_pins[] = { 23, 24, 25, 26, 27, 28, };
+static int mt7986_snfi_funcs[] = { 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_spi1_1_pins[] = { 23, 24, 25, 26, };
+static int mt7986_spi1_1_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_uart1_1_pins[] = { 23, 24, 25, 26, };
+static int mt7986_uart1_1_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7986_spi1_2_pins[] = { 29, 30, 31, 32, };
+static int mt7986_spi1_2_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_uart1_2_pins[] = { 29, 30, 31, 32, };
+static int mt7986_uart1_2_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_uart2_0_pins[] = { 29, 30, 31, 32, };
+static int mt7986_uart2_0_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7986_spi0_pins[] = { 33, 34, 35, 36, };
+static int mt7986_spi0_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_spi0_wp_hold_pins[] = { 37, 38, };
+static int mt7986_spi0_wp_hold_funcs[] = { 1, 1, };
+
+static int mt7986_uart2_1_pins[] = { 33, 34, 35, 36, };
+static int mt7986_uart2_1_funcs[] = { 3, 3, 3, 3, };
+
+static int mt7986_uart1_3_rx_tx_pins[] = { 35, 36, };
+static int mt7986_uart1_3_rx_tx_funcs[] = { 2, 2, };
+
+static int mt7986_uart1_3_cts_rts_pins[] = { 37, 38, };
+static int mt7986_uart1_3_cts_rts_funcs[] = { 2, 2, };
+
+static int mt7986_spi1_3_pins[] = { 33, 34, 35, 36, };
+static int mt7986_spi1_3_funcs[] = { 4, 4, 4, 4, };
+
+static int mt7986_uart0_pins[] = { 39, 40, };
+static int mt7986_uart0_funcs[] = { 1, 1, };
+
+static int mt7986_pcie_reset_pins[] = { 41, };
+static int mt7986_pcie_reset_funcs[] = { 1, };
+
+static int mt7986_uart1_pins[] = { 42, 43, 44, 45, };
+static int mt7986_uart1_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_uart2_pins[] = { 46, 47, 48, 49, };
+static int mt7986_uart2_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_emmc_51_pins[] = {
+       50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, };
+static int mt7986_emmc_51_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_pcm_pins[] = { 62, 63, 64, 65, };
+static int mt7986_pcm_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_i2s_pins[] = { 62, 63, 64, 65, };
+static int mt7986_i2s_funcs[] = { 1, 1, 1, 1, };
+
+static int mt7986_switch_int_pins[] = { 66, };
+static int mt7986_switch_int_funcs[] = { 1, };
+
+static int mt7986_mdc_mdio_pins[] = { 67, 68, };
+static int mt7986_mdc_mdio_funcs[] = { 1, 1, };
+
+static int mt7986_wf_2g_pins[] = {74, 75, 76, 77, 78, 79, 80, 81, 82, 83, };
+static int mt7986_wf_2g_funcs[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_wf_5g_pins[] = {91, 92, 93, 94, 95, 96, 97, 98, 99, 100, };
+static int mt7986_wf_5g_funcs[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+static int mt7986_wf_dbdc_pins[] = {
+       74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, };
+static int mt7986_wf_dbdc_funcs[] = {
+       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
+
+static int mt7986_pcie_clk_pins[] = { 9, };
+static int mt7986_pcie_clk_funcs[] = { 1, };
+
+static int mt7986_pcie_wake_pins[] = { 10, };
+static int mt7986_pcie_wake_funcs[] = { 1, };
+
+static int mt7986_jtag_pins[] = { 11, 12, 13, 14, 15};
+static int mt7986_jtag_funcs[] = { 1, 1, 1, 1, 1};
+
+static const struct group_desc mt7986_groups[] = {
+       PINCTRL_PIN_GROUP("watchdog", mt7986_watchdog),
+       PINCTRL_PIN_GROUP("wifi_led", mt7986_wifi_led),
+       PINCTRL_PIN_GROUP("i2c", mt7986_i2c),
+       PINCTRL_PIN_GROUP("uart1_0", mt7986_uart1_0),
+       PINCTRL_PIN_GROUP("pcie_clk", mt7986_pcie_clk),
+       PINCTRL_PIN_GROUP("pcie_wake", mt7986_pcie_wake),
+       PINCTRL_PIN_GROUP("spi1_0", mt7986_spi1_0),
+       PINCTRL_PIN_GROUP("pwm1_1", mt7986_pwm1_1),
+       PINCTRL_PIN_GROUP("pwm0", mt7986_pwm0),
+       PINCTRL_PIN_GROUP("pwm1_0", mt7986_pwm1_0),
+       PINCTRL_PIN_GROUP("emmc_45", mt7986_emmc_45),
+       PINCTRL_PIN_GROUP("snfi", mt7986_snfi),
+       PINCTRL_PIN_GROUP("spi1_1", mt7986_spi1_1),
+       PINCTRL_PIN_GROUP("uart1_1", mt7986_uart1_1),
+       PINCTRL_PIN_GROUP("spi1_2", mt7986_spi1_2),
+       PINCTRL_PIN_GROUP("uart1_2", mt7986_uart1_2),
+       PINCTRL_PIN_GROUP("uart2_0", mt7986_uart2_0),
+       PINCTRL_PIN_GROUP("spi0", mt7986_spi0),
+       PINCTRL_PIN_GROUP("spi0_wp_hold", mt7986_spi0_wp_hold),
+       PINCTRL_PIN_GROUP("uart2_1", mt7986_uart2_1),
+       PINCTRL_PIN_GROUP("uart1_3_rx_tx", mt7986_uart1_3_rx_tx),
+       PINCTRL_PIN_GROUP("uart1_3_cts_rts", mt7986_uart1_3_cts_rts),
+       PINCTRL_PIN_GROUP("spi1_3", mt7986_spi1_3),
+       PINCTRL_PIN_GROUP("uart0", mt7986_uart0),
+       PINCTRL_PIN_GROUP("switch_int", mt7986_switch_int),
+       PINCTRL_PIN_GROUP("mdc_mdio", mt7986_mdc_mdio),
+       PINCTRL_PIN_GROUP("pcie_pereset", mt7986_pcie_reset),
+       PINCTRL_PIN_GROUP("uart1", mt7986_uart1),
+       PINCTRL_PIN_GROUP("uart2", mt7986_uart2),
+       PINCTRL_PIN_GROUP("emmc_51", mt7986_emmc_51),
+       PINCTRL_PIN_GROUP("pcm", mt7986_pcm),
+       PINCTRL_PIN_GROUP("i2s", mt7986_i2s),
+       PINCTRL_PIN_GROUP("wf_2g", mt7986_wf_2g),
+       PINCTRL_PIN_GROUP("wf_5g", mt7986_wf_5g),
+       PINCTRL_PIN_GROUP("wf_dbdc", mt7986_wf_dbdc),
+       PINCTRL_PIN_GROUP("jtag", mt7986_jtag),
+};
+
+/* Joint those groups owning the same capability in user point of view which
+ * allows that people tend to use through the device tree.
+ */
+
+static const char *mt7986_audio_groups[] = { "pcm", "i2s" };
+static const char *mt7986_emmc_groups[] = {
+       "emmc_45", "emmc_51", };
+static const char *mt7986_ethernet_groups[] = {
+       "switch_int", "mdc_mdio", };
+static const char *mt7986_i2c_groups[] = { "i2c", };
+static const char *mt7986_led_groups[] = { "wifi_led", };
+static const char *mt7986_flash_groups[] = { "snfi", };
+static const char *mt7986_pcie_groups[] = {
+       "pcie_clk", "pcie_wake", "pcie_pereset" };
+static const char *mt7986_pwm_groups[] = { "pwm0", "pwm1_0", "pwm1_1", };
+static const char *mt7986_spi_groups[] = {
+       "spi0", "spi0_wp_hold", "spi1_0", "spi1_1", "spi1_2", "spi1_3", };
+static const char *mt7986_uart_groups[] = {
+       "uart1_0", "uart1_1", "uart1_2", "uart1_3_rx_tx", "uart1_3_cts_rts",
+       "uart2_0", "uart2_1", "uart0", "uart1", "uart2",
+};
+static const char *mt7986_wdt_groups[] = { "watchdog", };
+static const char *mt7986_wf_groups[] = { "wf_2g", "wf_5g", "wf_dbdc", };
+static const char *mt7986_jtag_groups[] = { "jtag", };
+
+static const struct function_desc mt7986_functions[] = {
+       {"audio", mt7986_audio_groups, ARRAY_SIZE(mt7986_audio_groups)},
+       {"emmc", mt7986_emmc_groups, ARRAY_SIZE(mt7986_emmc_groups)},
+       {"eth", mt7986_ethernet_groups, ARRAY_SIZE(mt7986_ethernet_groups)},
+       {"i2c", mt7986_i2c_groups, ARRAY_SIZE(mt7986_i2c_groups)},
+       {"led", mt7986_led_groups, ARRAY_SIZE(mt7986_led_groups)},
+       {"flash", mt7986_flash_groups, ARRAY_SIZE(mt7986_flash_groups)},
+       {"pcie", mt7986_pcie_groups, ARRAY_SIZE(mt7986_pcie_groups)},
+       {"pwm", mt7986_pwm_groups, ARRAY_SIZE(mt7986_pwm_groups)},
+       {"spi", mt7986_spi_groups, ARRAY_SIZE(mt7986_spi_groups)},
+       {"uart", mt7986_uart_groups, ARRAY_SIZE(mt7986_uart_groups)},
+       {"watchdog", mt7986_wdt_groups, ARRAY_SIZE(mt7986_wdt_groups)},
+       {"wifi", mt7986_wf_groups, ARRAY_SIZE(mt7986_wf_groups)},
+       {"jtag", mt7986_jtag_groups, ARRAY_SIZE(mt7986_jtag_groups)},
+};
+
+static const struct mtk_eint_hw mt7986a_eint_hw = {
+       .port_mask = 7,
+       .ports = 7,
+       .ap_num = ARRAY_SIZE(mt7986a_pins),
+       .db_cnt = 16,
+};
+
+static const struct mtk_eint_hw mt7986b_eint_hw = {
+       .port_mask = 7,
+       .ports = 7,
+       .ap_num = ARRAY_SIZE(mt7986b_pins),
+       .db_cnt = 16,
+};
+
+static struct mtk_pin_soc mt7986a_data = {
+       .reg_cal = mt7986_reg_cals,
+       .pins = mt7986a_pins,
+       .npins = ARRAY_SIZE(mt7986a_pins),
+       .grps = mt7986_groups,
+       .ngrps = ARRAY_SIZE(mt7986_groups),
+       .funcs = mt7986_functions,
+       .nfuncs = ARRAY_SIZE(mt7986_functions),
+       .eint_hw = &mt7986a_eint_hw,
+       .gpio_m = 0,
+       .ies_present = false,
+       .base_names = mt7986_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
+       .bias_set_combo = mtk_pinconf_bias_set_combo,
+       .bias_get_combo = mtk_pinconf_bias_get_combo,
+       .drive_set = mtk_pinconf_drive_set_rev1,
+       .drive_get = mtk_pinconf_drive_get_rev1,
+       .adv_pull_get = mtk_pinconf_adv_pull_get,
+       .adv_pull_set = mtk_pinconf_adv_pull_set,
+};
+
+static struct mtk_pin_soc mt7986b_data = {
+       .reg_cal = mt7986_reg_cals,
+       .pins = mt7986b_pins,
+       .npins = ARRAY_SIZE(mt7986b_pins),
+       .grps = mt7986_groups,
+       .ngrps = ARRAY_SIZE(mt7986_groups),
+       .funcs = mt7986_functions,
+       .nfuncs = ARRAY_SIZE(mt7986_functions),
+       .eint_hw = &mt7986b_eint_hw,
+       .gpio_m = 0,
+       .ies_present = false,
+       .base_names = mt7986_pinctrl_register_base_names,
+       .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names),
+       .bias_set_combo = mtk_pinconf_bias_set_combo,
+       .bias_get_combo = mtk_pinconf_bias_get_combo,
+       .drive_set = mtk_pinconf_drive_set_rev1,
+       .drive_get = mtk_pinconf_drive_get_rev1,
+       .adv_pull_get = mtk_pinconf_adv_pull_get,
+       .adv_pull_set = mtk_pinconf_adv_pull_set,
+};
+
+static const struct of_device_id mt7986a_pinctrl_of_match[] = {
+       {.compatible = "mediatek,mt7986a-pinctrl",},
+       {}
+};
+
+static const struct of_device_id mt7986b_pinctrl_of_match[] = {
+       {.compatible = "mediatek,mt7986b-pinctrl",},
+       {}
+};
+
+static int mt7986a_pinctrl_probe(struct platform_device *pdev)
+{
+       return mtk_moore_pinctrl_probe(pdev, &mt7986a_data);
+}
+
+static int mt7986b_pinctrl_probe(struct platform_device *pdev)
+{
+       return mtk_moore_pinctrl_probe(pdev, &mt7986b_data);
+}
+
+static struct platform_driver mt7986a_pinctrl_driver = {
+       .driver = {
+               .name = "mt7986a-pinctrl",
+               .of_match_table = mt7986a_pinctrl_of_match,
+       },
+       .probe = mt7986a_pinctrl_probe,
+};
+
+static struct platform_driver mt7986b_pinctrl_driver = {
+       .driver = {
+               .name = "mt7986b-pinctrl",
+               .of_match_table = mt7986b_pinctrl_of_match,
+       },
+       .probe = mt7986b_pinctrl_probe,
+};
+
+static int __init mt7986a_pinctrl_init(void)
+{
+       return platform_driver_register(&mt7986a_pinctrl_driver);
+}
+
+static int __init mt7986b_pinctrl_init(void)
+{
+       return platform_driver_register(&mt7986b_pinctrl_driver);
+}
+
+arch_initcall(mt7986a_pinctrl_init);
+arch_initcall(mt7986b_pinctrl_init);
diff --git a/target/linux/mediatek/files-5.15/include/dt-bindings/clock/mt7986-clk.h b/target/linux/mediatek/files-5.15/include/dt-bindings/clock/mt7986-clk.h
new file mode 100644 (file)
index 0000000..5a9b169
--- /dev/null
@@ -0,0 +1,169 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT7986_H
+#define _DT_BINDINGS_CLK_MT7986_H
+
+/* APMIXEDSYS */
+
+#define CLK_APMIXED_ARMPLL             0
+#define CLK_APMIXED_NET2PLL            1
+#define CLK_APMIXED_MMPLL              2
+#define CLK_APMIXED_SGMPLL             3
+#define CLK_APMIXED_WEDMCUPLL          4
+#define CLK_APMIXED_NET1PLL            5
+#define CLK_APMIXED_MPLL               6
+#define CLK_APMIXED_APLL2              7
+
+/* TOPCKGEN */
+
+#define CLK_TOP_XTAL                   0
+#define CLK_TOP_XTAL_D2                        1
+#define CLK_TOP_RTC_32K                        2
+#define CLK_TOP_RTC_32P7K              3
+#define CLK_TOP_MPLL_D2                        4
+#define CLK_TOP_MPLL_D4                        5
+#define CLK_TOP_MPLL_D8                        6
+#define CLK_TOP_MPLL_D8_D2             7
+#define CLK_TOP_MPLL_D3_D2             8
+#define CLK_TOP_MMPLL_D2               9
+#define CLK_TOP_MMPLL_D4               10
+#define CLK_TOP_MMPLL_D8               11
+#define CLK_TOP_MMPLL_D8_D2            12
+#define CLK_TOP_MMPLL_D3_D8            13
+#define CLK_TOP_MMPLL_U2PHY            14
+#define CLK_TOP_APLL2_D4               15
+#define CLK_TOP_NET1PLL_D4             16
+#define CLK_TOP_NET1PLL_D5             17
+#define CLK_TOP_NET1PLL_D5_D2          18
+#define CLK_TOP_NET1PLL_D5_D4          19
+#define CLK_TOP_NET1PLL_D8_D2          20
+#define CLK_TOP_NET1PLL_D8_D4          21
+#define CLK_TOP_NET2PLL_D4             22
+#define CLK_TOP_NET2PLL_D4_D2          23
+#define CLK_TOP_NET2PLL_D3_D2          24
+#define CLK_TOP_WEDMCUPLL_D5_D2                25
+#define CLK_TOP_NFI1X_SEL              26
+#define CLK_TOP_SPINFI_SEL             27
+#define CLK_TOP_SPI_SEL                        28
+#define CLK_TOP_SPIM_MST_SEL           29
+#define CLK_TOP_UART_SEL               30
+#define CLK_TOP_PWM_SEL                        31
+#define CLK_TOP_I2C_SEL                        32
+#define CLK_TOP_PEXTP_TL_SEL           33
+#define CLK_TOP_EMMC_250M_SEL          34
+#define CLK_TOP_EMMC_416M_SEL          35
+#define CLK_TOP_F_26M_ADC_SEL          36
+#define CLK_TOP_DRAMC_SEL              37
+#define CLK_TOP_DRAMC_MD32_SEL         38
+#define CLK_TOP_SYSAXI_SEL             39
+#define CLK_TOP_SYSAPB_SEL             40
+#define CLK_TOP_ARM_DB_MAIN_SEL                41
+#define CLK_TOP_ARM_DB_JTSEL           42
+#define CLK_TOP_NETSYS_SEL             43
+#define CLK_TOP_NETSYS_500M_SEL                44
+#define CLK_TOP_NETSYS_MCU_SEL         45
+#define CLK_TOP_NETSYS_2X_SEL          46
+#define CLK_TOP_SGM_325M_SEL           47
+#define CLK_TOP_SGM_REG_SEL            48
+#define CLK_TOP_A1SYS_SEL              49
+#define CLK_TOP_CONN_MCUSYS_SEL                50
+#define CLK_TOP_EIP_B_SEL              51
+#define CLK_TOP_PCIE_PHY_SEL           52
+#define CLK_TOP_USB3_PHY_SEL           53
+#define CLK_TOP_F26M_SEL               54
+#define CLK_TOP_AUD_L_SEL              55
+#define CLK_TOP_A_TUNER_SEL            56
+#define CLK_TOP_U2U3_SEL               57
+#define CLK_TOP_U2U3_SYS_SEL           58
+#define CLK_TOP_U2U3_XHCI_SEL          59
+#define CLK_TOP_DA_U2_REFSEL           60
+#define CLK_TOP_DA_U2_CK_1P_SEL                61
+#define CLK_TOP_AP2CNN_HOST_SEL                62
+#define CLK_TOP_JTAG                   63
+
+/* INFRACFG */
+
+#define CLK_INFRA_SYSAXI_D2            0
+#define CLK_INFRA_UART0_SEL            1
+#define CLK_INFRA_UART1_SEL            2
+#define CLK_INFRA_UART2_SEL            3
+#define CLK_INFRA_SPI0_SEL             4
+#define CLK_INFRA_SPI1_SEL             5
+#define CLK_INFRA_PWM1_SEL             6
+#define CLK_INFRA_PWM2_SEL             7
+#define CLK_INFRA_PWM_BSEL             8
+#define CLK_INFRA_PCIE_SEL             9
+#define CLK_INFRA_GPT_STA              10
+#define CLK_INFRA_PWM_HCK              11
+#define CLK_INFRA_PWM_STA              12
+#define CLK_INFRA_PWM1_CK              13
+#define CLK_INFRA_PWM2_CK              14
+#define CLK_INFRA_CQ_DMA_CK            15
+#define CLK_INFRA_EIP97_CK             16
+#define CLK_INFRA_AUD_BUS_CK           17
+#define CLK_INFRA_AUD_26M_CK           18
+#define CLK_INFRA_AUD_L_CK             19
+#define CLK_INFRA_AUD_AUD_CK           20
+#define CLK_INFRA_AUD_EG2_CK           21
+#define CLK_INFRA_DRAMC_26M_CK         22
+#define CLK_INFRA_DBG_CK               23
+#define CLK_INFRA_AP_DMA_CK            24
+#define CLK_INFRA_SEJ_CK               25
+#define CLK_INFRA_SEJ_13M_CK           26
+#define CLK_INFRA_THERM_CK             27
+#define CLK_INFRA_I2C0_CK              28
+#define CLK_INFRA_UART0_CK             29
+#define CLK_INFRA_UART1_CK             30
+#define CLK_INFRA_UART2_CK             31
+#define CLK_INFRA_NFI1_CK              32
+#define CLK_INFRA_SPINFI1_CK           33
+#define CLK_INFRA_NFI_HCK_CK           34
+#define CLK_INFRA_SPI0_CK              35
+#define CLK_INFRA_SPI1_CK              36
+#define CLK_INFRA_SPI0_HCK_CK          37
+#define CLK_INFRA_SPI1_HCK_CK          38
+#define CLK_INFRA_FRTC_CK              39
+#define CLK_INFRA_MSDC_CK              40
+#define CLK_INFRA_MSDC_HCK_CK          41
+#define CLK_INFRA_MSDC_133M_CK         42
+#define CLK_INFRA_MSDC_66M_CK          43
+#define CLK_INFRA_ADC_26M_CK           44
+#define CLK_INFRA_ADC_FRC_CK           45
+#define CLK_INFRA_FBIST2FPC_CK         46
+#define CLK_INFRA_IUSB_133_CK          47
+#define CLK_INFRA_IUSB_66M_CK          48
+#define CLK_INFRA_IUSB_SYS_CK          49
+#define CLK_INFRA_IUSB_CK              50
+#define CLK_INFRA_IPCIE_CK             51
+#define CLK_INFRA_IPCIE_PIPE_CK                52
+#define CLK_INFRA_IPCIER_CK            53
+#define CLK_INFRA_IPCIEB_CK            54
+#define CLK_INFRA_TRNG_CK              55
+
+/* SGMIISYS_0 */
+
+#define CLK_SGMII0_TX250M_EN           0
+#define CLK_SGMII0_RX250M_EN           1
+#define CLK_SGMII0_CDR_REF             2
+#define CLK_SGMII0_CDR_FB              3
+
+/* SGMIISYS_1 */
+
+#define CLK_SGMII1_TX250M_EN           0
+#define CLK_SGMII1_RX250M_EN           1
+#define CLK_SGMII1_CDR_REF             2
+#define CLK_SGMII1_CDR_FB              3
+
+/* ETHSYS */
+
+#define CLK_ETH_FE_EN                  0
+#define CLK_ETH_GP2_EN                 1
+#define CLK_ETH_GP1_EN                 2
+#define CLK_ETH_WOCPU1_EN              3
+#define CLK_ETH_WOCPU0_EN              4
+
+#endif /* _DT_BINDINGS_CLK_MT7986_H */
diff --git a/target/linux/mediatek/files-5.15/include/dt-bindings/reset/mt7986-resets.h b/target/linux/mediatek/files-5.15/include/dt-bindings/reset/mt7986-resets.h
new file mode 100644 (file)
index 0000000..1bdfe34
--- /dev/null
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2021 MediaTek Inc. */
+
+#ifndef _DT_BINDINGS_RESET_MT7986
+#define _DT_BINDINGS_RESET_MT7986
+
+#define MT7986_TOPRGU_CONSYS_RST       23
+#define MT7986_TOPRGU_SW_RST_NUM       32
+
+#endif  /* _DT_BINDINGS_RESET_MT7986 */
index 978994abbc9ee19dd239ad7325f6e14bcf90475d..47464eb40fb5c321f008b95569df0324454be863 100644 (file)
@@ -70,6 +70,7 @@ CONFIG_COMMON_CLK_MT7622=y
 CONFIG_COMMON_CLK_MT7622_AUDSYS=y
 CONFIG_COMMON_CLK_MT7622_ETHSYS=y
 CONFIG_COMMON_CLK_MT7622_HIFSYS=y
+# CONFIG_COMMON_CLK_MT7986 is not set
 # CONFIG_COMMON_CLK_MT8173 is not set
 CONFIG_COMMON_CLK_MT8183=y
 # CONFIG_COMMON_CLK_MT8183_AUDIOSYS is not set
@@ -334,6 +335,7 @@ CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_MT6765 is not set
 # CONFIG_PINCTRL_MT6797 is not set
 CONFIG_PINCTRL_MT7622=y
+# CONFIG_PINCTRL_MT7986 is not set
 # CONFIG_PINCTRL_MT8173 is not set
 # CONFIG_PINCTRL_MT8183 is not set
 CONFIG_PINCTRL_MT8516=y
index 3b64eccc0596d6f59e49e58101045210de0d8ec6..215bd2186c02d09d353dc8c5a2893047f57913d3 100644 (file)
@@ -67,6 +67,7 @@ CONFIG_COMMON_CLK_MT2701_MMSYS=y
 CONFIG_COMMON_CLK_MT2701_VDECSYS=y
 # CONFIG_COMMON_CLK_MT7622 is not set
 # CONFIG_COMMON_CLK_MT7629 is not set
+# CONFIG_COMMON_CLK_MT7986 is not set
 # CONFIG_COMMON_CLK_MT8135 is not set
 # CONFIG_COMMON_CLK_MT8173 is not set
 CONFIG_COMMON_CLK_MT8516=y
@@ -428,6 +429,7 @@ CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MT2701=y
 CONFIG_PINCTRL_MT6397=y
 CONFIG_PINCTRL_MT7623=y
+# CONFIG_PINCTRL_MT7986 is not set
 CONFIG_PINCTRL_MTK=y
 CONFIG_PINCTRL_MTK_MOORE=y
 CONFIG_PINCTRL_MTK_V2=y
index 592f28babf2d00a40ac952a102960ae2441cc2b2..010151d4b39e1e3b64d0a530cf2e30e04e609c6f 100644 (file)
@@ -51,6 +51,7 @@ CONFIG_COMMON_CLK_MEDIATEK=y
 CONFIG_COMMON_CLK_MT7629=y
 CONFIG_COMMON_CLK_MT7629_ETHSYS=y
 CONFIG_COMMON_CLK_MT7629_HIFSYS=y
+# CONFIG_COMMON_CLK_MT7986 is not set
 # CONFIG_COMMON_CLK_MT8135 is not set
 # CONFIG_COMMON_CLK_MT8173 is not set
 CONFIG_COMMON_CLK_MT8516=y
@@ -238,6 +239,7 @@ CONFIG_PHY_MTK_TPHY=y
 # CONFIG_PHY_MTK_XSPHY is not set
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MT7629=y
+# CONFIG_PINCTRL_MT7986 is not set
 CONFIG_PINCTRL_MTK_MOORE=y
 CONFIG_PINCTRL_MTK_V2=y
 CONFIG_PM=y
diff --git a/target/linux/mediatek/patches-5.15/210-pinctrl-mediatek-add-support-for-MT7986-SoC.patch b/target/linux/mediatek/patches-5.15/210-pinctrl-mediatek-add-support-for-MT7986-SoC.patch
new file mode 100644 (file)
index 0000000..0761e1d
--- /dev/null
@@ -0,0 +1,26 @@
+--- a/drivers/pinctrl/mediatek/Kconfig
++++ b/drivers/pinctrl/mediatek/Kconfig
+@@ -120,6 +120,13 @@ config PINCTRL_MT7622
+       default ARM64 && ARCH_MEDIATEK
+       select PINCTRL_MTK_MOORE
++config PINCTRL_MT7986
++      bool "Mediatek MT7986 pin control"
++      depends on OF
++      depends on ARM64 || COMPILE_TEST
++      default ARM64 && ARCH_MEDIATEK
++      select PINCTRL_MTK_MOORE
++
+ config PINCTRL_MT8167
+       bool "Mediatek MT8167 pin control"
+       depends on OF
+--- a/drivers/pinctrl/mediatek/Makefile
++++ b/drivers/pinctrl/mediatek/Makefile
+@@ -17,6 +17,7 @@ obj-$(CONFIG_PINCTRL_MT6797) += pinctrl-
+ obj-$(CONFIG_PINCTRL_MT7622)  += pinctrl-mt7622.o
+ obj-$(CONFIG_PINCTRL_MT7623)  += pinctrl-mt7623.o
+ obj-$(CONFIG_PINCTRL_MT7629)  += pinctrl-mt7629.o
++obj-$(CONFIG_PINCTRL_MT7986)  += pinctrl-mt7986.o
+ obj-$(CONFIG_PINCTRL_MT8167)  += pinctrl-mt8167.o
+ obj-$(CONFIG_PINCTRL_MT8173)  += pinctrl-mt8173.o
+ obj-$(CONFIG_PINCTRL_MT8183)  += pinctrl-mt8183.o
diff --git a/target/linux/mediatek/patches-5.15/211-clk-mediatek-Add-API-for-clock-resource-recycle.patch b/target/linux/mediatek/patches-5.15/211-clk-mediatek-Add-API-for-clock-resource-recycle.patch
new file mode 100644 (file)
index 0000000..15de8aa
--- /dev/null
@@ -0,0 +1,28 @@
+--- a/drivers/clk/mediatek/clk-mtk.c
++++ b/drivers/clk/mediatek/clk-mtk.c
+@@ -43,6 +43,15 @@ err_out:
+       return NULL;
+ }
++void mtk_free_clk_data(struct clk_onecell_data *clk_data)
++{
++      if (!clk_data)
++              return;
++
++      kfree(clk_data->clks);
++      kfree(clk_data);
++}
++
+ void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
+               int num, struct clk_onecell_data *clk_data)
+ {
+--- a/drivers/clk/mediatek/clk-mtk.h
++++ b/drivers/clk/mediatek/clk-mtk.h
+@@ -202,6 +202,7 @@ void mtk_clk_register_dividers(const str
+                               struct clk_onecell_data *clk_data);
+ struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num);
++void mtk_free_clk_data(struct clk_onecell_data *clk_data);
+ #define HAVE_RST_BAR  BIT(0)
+ #define PLL_AO                BIT(1)
diff --git a/target/linux/mediatek/patches-5.15/212-clk-mediatek-add-mt7986-clock-support.patch b/target/linux/mediatek/patches-5.15/212-clk-mediatek-add-mt7986-clock-support.patch
new file mode 100644 (file)
index 0000000..8e2365a
--- /dev/null
@@ -0,0 +1,39 @@
+--- a/drivers/clk/mediatek/Kconfig
++++ b/drivers/clk/mediatek/Kconfig
+@@ -344,6 +344,23 @@ config COMMON_CLK_MT7629_HIFSYS
+         This driver supports MediaTek MT7629 HIFSYS clocks providing
+         to PCI-E and USB.
++config COMMON_CLK_MT7986
++      bool "Clock driver for MediaTek MT7986"
++      depends on ARCH_MEDIATEK || COMPILE_TEST
++      select COMMON_CLK_MEDIATEK
++      default ARCH_MEDIATEK
++      help
++        This driver supports MediaTek MT7986 basic clocks and clocks
++        required for various periperals found on MediaTek.
++
++config COMMON_CLK_MT7986_ETHSYS
++      bool "Clock driver for MediaTek MT7986 ETHSYS"
++      depends on COMMON_CLK_MT7986
++      default COMMON_CLK_MT7986
++      help
++        This driver add support for clocks for Ethernet and SGMII
++        required on MediaTek MT7986 SoC.
++
+ config COMMON_CLK_MT8135
+       bool "Clock driver for MediaTek MT8135"
+       depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
+--- a/drivers/clk/mediatek/Makefile
++++ b/drivers/clk/mediatek/Makefile
+@@ -46,6 +46,10 @@ obj-$(CONFIG_COMMON_CLK_MT7622_AUDSYS) +
+ obj-$(CONFIG_COMMON_CLK_MT7629) += clk-mt7629.o
+ obj-$(CONFIG_COMMON_CLK_MT7629_ETHSYS) += clk-mt7629-eth.o
+ obj-$(CONFIG_COMMON_CLK_MT7629_HIFSYS) += clk-mt7629-hif.o
++obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-apmixed.o
++obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-topckgen.o
++obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-infracfg.o
++obj-$(CONFIG_COMMON_CLK_MT7986_ETHSYS) += clk-mt7986-eth.o
+ obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
+ obj-$(CONFIG_COMMON_CLK_MT8167) += clk-mt8167.o
+ obj-$(CONFIG_COMMON_CLK_MT8167_AUDSYS) += clk-mt8167-aud.o
diff --git a/target/linux/mediatek/patches-5.15/213-spi-mediatek-add-mt7986-spi-support b/target/linux/mediatek/patches-5.15/213-spi-mediatek-add-mt7986-spi-support
new file mode 100644 (file)
index 0000000..f10d57a
--- /dev/null
@@ -0,0 +1,917 @@
+From 7d99750f96fc6904d54affebdc8c9b0bfae1e9e8 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Sun, 17 Apr 2022 11:40:22 +0800
+Subject: [PATCH] spi: mediatek: backport document and driver to support mt7986
+ spi design
+
+this patch add the support of ipm design and upgrade devicetree binding
+
+The patch is comming from following threads
+- https://lore.kernel.org/all/20220315032411.2826-1-leilk.liu@mediatek.com/
+- https://lore.kernel.org/all/20220401071616.8874-1-leilk.liu@mediatek.com/
+
+Signed-off-by: Sam Shih <sam.shih@mediatek.com>
+---
+ .../bindings/spi/mediatek,spi-mt65xx.yaml     | 111 ++++
+ drivers/spi/spi-mt65xx.c                      | 509 ++++++++++++++++--
+ 2 files changed, 572 insertions(+), 48 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
+@@ -0,0 +1,111 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/spi/mediatek,spi-mt65xx.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: SPI Bus controller for MediaTek ARM SoCs
++
++maintainers:
++  - Leilk Liu <leilk.liu@mediatek.com>
++
++allOf:
++  - $ref: "/schemas/spi/spi-controller.yaml#"
++
++properties:
++  compatible:
++    oneOf:
++      - items:
++          - enum:
++              - mediatek,mt7629-spi
++          - const: mediatek,mt7622-spi
++      - items:
++          - enum:
++              - mediatek,mt8516-spi
++          - const: mediatek,mt2712-spi
++      - items:
++          - enum:
++              - mediatek,mt6779-spi
++              - mediatek,mt8186-spi
++              - mediatek,mt8192-spi
++              - mediatek,mt8195-spi
++          - const: mediatek,mt6765-spi
++      - items:
++          - enum:
++              - mediatek,mt7986-spi-ipm
++          - const: mediatek,spi-ipm
++      - items:
++          - enum:
++              - mediatek,mt2701-spi
++              - mediatek,mt2712-spi
++              - mediatek,mt6589-spi
++              - mediatek,mt6765-spi
++              - mediatek,mt6893-spi
++              - mediatek,mt7622-spi
++              - mediatek,mt8135-spi
++              - mediatek,mt8173-spi
++              - mediatek,mt8183-spi
++
++  reg:
++    maxItems: 1
++
++  interrupts:
++    maxItems: 1
++
++  clocks:
++    minItems: 3
++    items:
++      - description: clock used for the parent clock
++      - description: clock used for the muxes clock
++      - description: clock used for the clock gate
++      - description: clock used for the AHB bus, this clock is optional
++
++  clock-names:
++    minItems: 3
++    items:
++      - const: parent-clk
++      - const: sel-clk
++      - const: spi-clk
++      - const: hclk
++
++  mediatek,pad-select:
++    $ref: /schemas/types.yaml#/definitions/uint32-array
++    minItems: 1
++    maxItems: 4
++    items:
++      enum: [0, 1, 2, 3]
++    description:
++      specify which pins group(ck/mi/mo/cs) spi controller used.
++      This is an array.
++
++required:
++  - compatible
++  - reg
++  - interrupts
++  - clocks
++  - clock-names
++  - '#address-cells'
++  - '#size-cells'
++
++unevaluatedProperties: false
++
++examples:
++  - |
++    #include <dt-bindings/clock/mt8173-clk.h>
++    #include <dt-bindings/gpio/gpio.h>
++    #include <dt-bindings/interrupt-controller/arm-gic.h>
++    #include <dt-bindings/interrupt-controller/irq.h>
++
++    spi@1100a000 {
++      compatible = "mediatek,mt8173-spi";
++      #address-cells = <1>;
++      #size-cells = <0>;
++      reg = <0x1100a000 0x1000>;
++      interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
++      clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
++               <&topckgen CLK_TOP_SPI_SEL>,
++               <&pericfg CLK_PERI_SPI0>;
++      clock-names = "parent-clk", "sel-clk", "spi-clk";
++      cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72 GPIO_ACTIVE_LOW>;
++      mediatek,pad-select = <1>, <0>;
++    };
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -12,11 +12,12 @@
+ #include <linux/ioport.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
+-#include <linux/of_gpio.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/platform_device.h>
+ #include <linux/platform_data/spi-mt65xx.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/spi/spi.h>
++#include <linux/spi/spi-mem.h>
+ #include <linux/dma-mapping.h>
+ #define SPI_CFG0_REG                      0x0000
+@@ -31,6 +32,7 @@
+ #define SPI_CFG2_REG                      0x0028
+ #define SPI_TX_SRC_REG_64                 0x002c
+ #define SPI_RX_DST_REG_64                 0x0030
++#define SPI_CFG3_IPM_REG                  0x0040
+ #define SPI_CFG0_SCK_HIGH_OFFSET          0
+ #define SPI_CFG0_SCK_LOW_OFFSET           8
+@@ -51,6 +53,7 @@
+ #define SPI_CFG1_CS_IDLE_MASK             0xff
+ #define SPI_CFG1_PACKET_LOOP_MASK         0xff00
+ #define SPI_CFG1_PACKET_LENGTH_MASK       0x3ff0000
++#define SPI_CFG1_IPM_PACKET_LENGTH_MASK   GENMASK(31, 16)
+ #define SPI_CFG2_SCK_HIGH_OFFSET          0
+ #define SPI_CFG2_SCK_LOW_OFFSET           16
+@@ -71,6 +74,24 @@
+ #define SPI_CMD_TX_ENDIAN            BIT(15)
+ #define SPI_CMD_FINISH_IE            BIT(16)
+ #define SPI_CMD_PAUSE_IE             BIT(17)
++#define SPI_CMD_IPM_NONIDLE_MODE     BIT(19)
++#define SPI_CMD_IPM_SPIM_LOOP        BIT(21)
++#define SPI_CMD_IPM_GET_TICKDLY_OFFSET    22
++
++#define SPI_CMD_IPM_GET_TICKDLY_MASK  GENMASK(24, 22)
++
++#define PIN_MODE_CFG(x)       ((x) / 2)
++
++#define SPI_CFG3_IPM_HALF_DUPLEX_DIR          BIT(2)
++#define SPI_CFG3_IPM_HALF_DUPLEX_EN           BIT(3)
++#define SPI_CFG3_IPM_XMODE_EN                 BIT(4)
++#define SPI_CFG3_IPM_NODATA_FLAG              BIT(5)
++#define SPI_CFG3_IPM_CMD_BYTELEN_OFFSET               8
++#define SPI_CFG3_IPM_ADDR_BYTELEN_OFFSET      12
++
++#define SPI_CFG3_IPM_CMD_PIN_MODE_MASK                GENMASK(1, 0)
++#define SPI_CFG3_IPM_CMD_BYTELEN_MASK         GENMASK(11, 8)
++#define SPI_CFG3_IPM_ADDR_BYTELEN_MASK                GENMASK(15, 12)
+ #define MT8173_SPI_MAX_PAD_SEL 3
+@@ -81,6 +102,9 @@
+ #define MTK_SPI_MAX_FIFO_SIZE 32U
+ #define MTK_SPI_PACKET_SIZE 1024
++#define MTK_SPI_IPM_PACKET_SIZE SZ_64K
++#define MTK_SPI_IPM_PACKET_LOOP SZ_256
++
+ #define MTK_SPI_32BITS_MASK  (0xffffffff)
+ #define DMA_ADDR_EXT_BITS (36)
+@@ -96,6 +120,8 @@ struct mtk_spi_compatible {
+       bool dma_ext;
+       /* some IC no need unprepare SPI clk */
+       bool no_need_unprepare;
++      /* IPM design adjust and extend register to support more features */
++      bool ipm_design;
+ };
+ struct mtk_spi {
+@@ -103,7 +129,7 @@ struct mtk_spi {
+       u32 state;
+       int pad_num;
+       u32 *pad_sel;
+-      struct clk *parent_clk, *sel_clk, *spi_clk;
++      struct clk *parent_clk, *sel_clk, *spi_clk, *spi_hclk;
+       struct spi_transfer *cur_transfer;
+       u32 xfer_len;
+       u32 num_xfered;
+@@ -111,6 +137,11 @@ struct mtk_spi {
+       u32 tx_sgl_len, rx_sgl_len;
+       const struct mtk_spi_compatible *dev_comp;
+       u32 spi_clk_hz;
++      struct completion spimem_done;
++      bool use_spimem;
++      struct device *dev;
++      dma_addr_t tx_dma;
++      dma_addr_t rx_dma;
+ };
+ static const struct mtk_spi_compatible mtk_common_compat;
+@@ -119,6 +150,12 @@ static const struct mtk_spi_compatible m
+       .must_tx = true,
+ };
++static const struct mtk_spi_compatible mtk_ipm_compat = {
++      .enhance_timing = true,
++      .dma_ext = true,
++      .ipm_design = true,
++};
++
+ static const struct mtk_spi_compatible mt6765_compat = {
+       .need_pad_sel = true,
+       .must_tx = true,
+@@ -160,6 +197,9 @@ static const struct mtk_chip_config mtk_
+ };
+ static const struct of_device_id mtk_spi_of_match[] = {
++      { .compatible = "mediatek,spi-ipm",
++              .data = (void *)&mtk_ipm_compat,
++      },
+       { .compatible = "mediatek,mt2701-spi",
+               .data = (void *)&mtk_common_compat,
+       },
+@@ -278,12 +318,11 @@ static int mtk_spi_set_hw_cs_timing(stru
+       return 0;
+ }
+-static int mtk_spi_prepare_message(struct spi_master *master,
+-                                 struct spi_message *msg)
++static int mtk_spi_hw_init(struct spi_master *master,
++                         struct spi_device *spi)
+ {
+       u16 cpha, cpol;
+       u32 reg_val;
+-      struct spi_device *spi = msg->spi;
+       struct mtk_chip_config *chip_config = spi->controller_data;
+       struct mtk_spi *mdata = spi_master_get_devdata(master);
+@@ -291,6 +330,15 @@ static int mtk_spi_prepare_message(struc
+       cpol = spi->mode & SPI_CPOL ? 1 : 0;
+       reg_val = readl(mdata->base + SPI_CMD_REG);
++      if (mdata->dev_comp->ipm_design) {
++              /* SPI transfer without idle time until packet length done */
++              reg_val |= SPI_CMD_IPM_NONIDLE_MODE;
++              if (spi->mode & SPI_LOOP)
++                      reg_val |= SPI_CMD_IPM_SPIM_LOOP;
++              else
++                      reg_val &= ~SPI_CMD_IPM_SPIM_LOOP;
++      }
++
+       if (cpha)
+               reg_val |= SPI_CMD_CPHA;
+       else
+@@ -348,23 +396,39 @@ static int mtk_spi_prepare_message(struc
+                      mdata->base + SPI_PAD_SEL_REG);
+       /* tick delay */
+-      reg_val = readl(mdata->base + SPI_CFG1_REG);
+       if (mdata->dev_comp->enhance_timing) {
+-              reg_val &= ~SPI_CFG1_GET_TICK_DLY_MASK;
+-              reg_val |= ((chip_config->tick_delay & 0x7)
+-                          << SPI_CFG1_GET_TICK_DLY_OFFSET);
++              if (mdata->dev_comp->ipm_design) {
++                      reg_val = readl(mdata->base + SPI_CMD_REG);
++                      reg_val &= ~SPI_CMD_IPM_GET_TICKDLY_MASK;
++                      reg_val |= ((chip_config->tick_delay & 0x7)
++                                  << SPI_CMD_IPM_GET_TICKDLY_OFFSET);
++                      writel(reg_val, mdata->base + SPI_CMD_REG);
++              } else {
++                      reg_val = readl(mdata->base + SPI_CFG1_REG);
++                      reg_val &= ~SPI_CFG1_GET_TICK_DLY_MASK;
++                      reg_val |= ((chip_config->tick_delay & 0x7)
++                                  << SPI_CFG1_GET_TICK_DLY_OFFSET);
++                      writel(reg_val, mdata->base + SPI_CFG1_REG);
++              }
+       } else {
++              reg_val = readl(mdata->base + SPI_CFG1_REG);
+               reg_val &= ~SPI_CFG1_GET_TICK_DLY_MASK_V1;
+               reg_val |= ((chip_config->tick_delay & 0x3)
+                           << SPI_CFG1_GET_TICK_DLY_OFFSET_V1);
++              writel(reg_val, mdata->base + SPI_CFG1_REG);
+       }
+-      writel(reg_val, mdata->base + SPI_CFG1_REG);
+       /* set hw cs timing */
+       mtk_spi_set_hw_cs_timing(spi);
+       return 0;
+ }
++static int mtk_spi_prepare_message(struct spi_master *master,
++                                 struct spi_message *msg)
++{
++      return mtk_spi_hw_init(master, msg->spi);
++}
++
+ static void mtk_spi_set_cs(struct spi_device *spi, bool enable)
+ {
+       u32 reg_val;
+@@ -386,13 +450,13 @@ static void mtk_spi_set_cs(struct spi_de
+ }
+ static void mtk_spi_prepare_transfer(struct spi_master *master,
+-                                   struct spi_transfer *xfer)
++                                   u32 speed_hz)
+ {
+       u32 div, sck_time, reg_val;
+       struct mtk_spi *mdata = spi_master_get_devdata(master);
+-      if (xfer->speed_hz < mdata->spi_clk_hz / 2)
+-              div = DIV_ROUND_UP(mdata->spi_clk_hz, xfer->speed_hz);
++      if (speed_hz < mdata->spi_clk_hz / 2)
++              div = DIV_ROUND_UP(mdata->spi_clk_hz, speed_hz);
+       else
+               div = 1;
+@@ -423,12 +487,24 @@ static void mtk_spi_setup_packet(struct
+       u32 packet_size, packet_loop, reg_val;
+       struct mtk_spi *mdata = spi_master_get_devdata(master);
+-      packet_size = min_t(u32, mdata->xfer_len, MTK_SPI_PACKET_SIZE);
++      if (mdata->dev_comp->ipm_design)
++              packet_size = min_t(u32,
++                                  mdata->xfer_len,
++                                  MTK_SPI_IPM_PACKET_SIZE);
++      else
++              packet_size = min_t(u32,
++                                  mdata->xfer_len,
++                                  MTK_SPI_PACKET_SIZE);
++
+       packet_loop = mdata->xfer_len / packet_size;
+       reg_val = readl(mdata->base + SPI_CFG1_REG);
+-      reg_val &= ~(SPI_CFG1_PACKET_LENGTH_MASK | SPI_CFG1_PACKET_LOOP_MASK);
++      if (mdata->dev_comp->ipm_design)
++              reg_val &= ~SPI_CFG1_IPM_PACKET_LENGTH_MASK;
++      else
++              reg_val &= ~SPI_CFG1_PACKET_LENGTH_MASK;
+       reg_val |= (packet_size - 1) << SPI_CFG1_PACKET_LENGTH_OFFSET;
++      reg_val &= ~SPI_CFG1_PACKET_LOOP_MASK;
+       reg_val |= (packet_loop - 1) << SPI_CFG1_PACKET_LOOP_OFFSET;
+       writel(reg_val, mdata->base + SPI_CFG1_REG);
+ }
+@@ -523,7 +599,7 @@ static int mtk_spi_fifo_transfer(struct
+       mdata->cur_transfer = xfer;
+       mdata->xfer_len = min(MTK_SPI_MAX_FIFO_SIZE, xfer->len);
+       mdata->num_xfered = 0;
+-      mtk_spi_prepare_transfer(master, xfer);
++      mtk_spi_prepare_transfer(master, xfer->speed_hz);
+       mtk_spi_setup_packet(master);
+       if (xfer->tx_buf) {
+@@ -556,7 +632,7 @@ static int mtk_spi_dma_transfer(struct s
+       mdata->cur_transfer = xfer;
+       mdata->num_xfered = 0;
+-      mtk_spi_prepare_transfer(master, xfer);
++      mtk_spi_prepare_transfer(master, xfer->speed_hz);
+       cmd = readl(mdata->base + SPI_CMD_REG);
+       if (xfer->tx_buf)
+@@ -591,6 +667,19 @@ static int mtk_spi_transfer_one(struct s
+                               struct spi_device *spi,
+                               struct spi_transfer *xfer)
+ {
++      struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
++      u32 reg_val = 0;
++
++      /* prepare xfer direction and duplex mode */
++      if (mdata->dev_comp->ipm_design) {
++              if (!xfer->tx_buf || !xfer->rx_buf) {
++                      reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_EN;
++                      if (xfer->rx_buf)
++                              reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_DIR;
++              }
++              writel(reg_val, mdata->base + SPI_CFG3_IPM_REG);
++      }
++
+       if (master->can_dma(master, spi, xfer))
+               return mtk_spi_dma_transfer(master, spi, xfer);
+       else
+@@ -614,8 +703,9 @@ static int mtk_spi_setup(struct spi_devi
+       if (!spi->controller_data)
+               spi->controller_data = (void *)&mtk_default_chip_info;
+-      if (mdata->dev_comp->need_pad_sel && gpio_is_valid(spi->cs_gpio))
+-              gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH));
++      if (mdata->dev_comp->need_pad_sel && spi->cs_gpiod)
++              /* CS de-asserted, gpiolib will handle inversion */
++              gpiod_direction_output(spi->cs_gpiod, 0);
+       return 0;
+ }
+@@ -633,6 +723,12 @@ static irqreturn_t mtk_spi_interrupt(int
+       else
+               mdata->state = MTK_SPI_IDLE;
++      /* SPI-MEM ops */
++      if (mdata->use_spimem) {
++              complete(&mdata->spimem_done);
++              return IRQ_HANDLED;
++      }
++
+       if (!master->can_dma(master, NULL, trans)) {
+               if (trans->rx_buf) {
+                       cnt = mdata->xfer_len / 4;
+@@ -716,6 +812,274 @@ static irqreturn_t mtk_spi_interrupt(int
+       return IRQ_HANDLED;
+ }
++static int mtk_spi_mem_adjust_op_size(struct spi_mem *mem,
++                                    struct spi_mem_op *op)
++{
++      int opcode_len;
++
++      if (op->data.dir != SPI_MEM_NO_DATA) {
++              opcode_len = 1 + op->addr.nbytes + op->dummy.nbytes;
++              if (opcode_len + op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE) {
++                      op->data.nbytes = MTK_SPI_IPM_PACKET_SIZE - opcode_len;
++                      /* force data buffer dma-aligned. */
++                      op->data.nbytes -= op->data.nbytes % 4;
++              }
++      }
++
++      return 0;
++}
++
++static bool mtk_spi_mem_supports_op(struct spi_mem *mem,
++                                  const struct spi_mem_op *op)
++{
++      if (!spi_mem_default_supports_op(mem, op))
++              return false;
++
++      if (op->addr.nbytes && op->dummy.nbytes &&
++          op->addr.buswidth != op->dummy.buswidth)
++              return false;
++
++      if (op->addr.nbytes + op->dummy.nbytes > 16)
++              return false;
++
++      if (op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE) {
++              if (op->data.nbytes / MTK_SPI_IPM_PACKET_SIZE >
++                  MTK_SPI_IPM_PACKET_LOOP ||
++                  op->data.nbytes % MTK_SPI_IPM_PACKET_SIZE != 0)
++                      return false;
++      }
++
++      return true;
++}
++
++static void mtk_spi_mem_setup_dma_xfer(struct spi_master *master,
++                                     const struct spi_mem_op *op)
++{
++      struct mtk_spi *mdata = spi_master_get_devdata(master);
++
++      writel((u32)(mdata->tx_dma & MTK_SPI_32BITS_MASK),
++             mdata->base + SPI_TX_SRC_REG);
++#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
++      if (mdata->dev_comp->dma_ext)
++              writel((u32)(mdata->tx_dma >> 32),
++                     mdata->base + SPI_TX_SRC_REG_64);
++#endif
++
++      if (op->data.dir == SPI_MEM_DATA_IN) {
++              writel((u32)(mdata->rx_dma & MTK_SPI_32BITS_MASK),
++                     mdata->base + SPI_RX_DST_REG);
++#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
++              if (mdata->dev_comp->dma_ext)
++                      writel((u32)(mdata->rx_dma >> 32),
++                             mdata->base + SPI_RX_DST_REG_64);
++#endif
++      }
++}
++
++static int mtk_spi_transfer_wait(struct spi_mem *mem,
++                               const struct spi_mem_op *op)
++{
++      struct mtk_spi *mdata = spi_master_get_devdata(mem->spi->master);
++      /*
++       * For each byte we wait for 8 cycles of the SPI clock.
++       * Since speed is defined in Hz and we want milliseconds,
++       * so it should be 8 * 1000.
++       */
++      u64 ms = 8000LL;
++
++      if (op->data.dir == SPI_MEM_NO_DATA)
++              ms *= 32; /* prevent we may get 0 for short transfers. */
++      else
++              ms *= op->data.nbytes;
++      ms = div_u64(ms, mem->spi->max_speed_hz);
++      ms += ms + 1000; /* 1s tolerance */
++
++      if (ms > UINT_MAX)
++              ms = UINT_MAX;
++
++      if (!wait_for_completion_timeout(&mdata->spimem_done,
++                                       msecs_to_jiffies(ms))) {
++              dev_err(mdata->dev, "spi-mem transfer timeout\n");
++              return -ETIMEDOUT;
++      }
++
++      return 0;
++}
++
++static int mtk_spi_mem_exec_op(struct spi_mem *mem,
++                             const struct spi_mem_op *op)
++{
++      struct mtk_spi *mdata = spi_master_get_devdata(mem->spi->master);
++      u32 reg_val, nio, tx_size;
++      char *tx_tmp_buf, *rx_tmp_buf;
++      int ret = 0;
++
++      mdata->use_spimem = true;
++      reinit_completion(&mdata->spimem_done);
++
++      mtk_spi_reset(mdata);
++      mtk_spi_hw_init(mem->spi->master, mem->spi);
++      mtk_spi_prepare_transfer(mem->spi->master, mem->spi->max_speed_hz);
++
++      reg_val = readl(mdata->base + SPI_CFG3_IPM_REG);
++      /* opcode byte len */
++      reg_val &= ~SPI_CFG3_IPM_CMD_BYTELEN_MASK;
++      reg_val |= 1 << SPI_CFG3_IPM_CMD_BYTELEN_OFFSET;
++
++      /* addr & dummy byte len */
++      reg_val &= ~SPI_CFG3_IPM_ADDR_BYTELEN_MASK;
++      if (op->addr.nbytes || op->dummy.nbytes)
++              reg_val |= (op->addr.nbytes + op->dummy.nbytes) <<
++                          SPI_CFG3_IPM_ADDR_BYTELEN_OFFSET;
++
++      /* data byte len */
++      if (op->data.dir == SPI_MEM_NO_DATA) {
++              reg_val |= SPI_CFG3_IPM_NODATA_FLAG;
++              writel(0, mdata->base + SPI_CFG1_REG);
++      } else {
++              reg_val &= ~SPI_CFG3_IPM_NODATA_FLAG;
++              mdata->xfer_len = op->data.nbytes;
++              mtk_spi_setup_packet(mem->spi->master);
++      }
++
++      if (op->addr.nbytes || op->dummy.nbytes) {
++              if (op->addr.buswidth == 1 || op->dummy.buswidth == 1)
++                      reg_val |= SPI_CFG3_IPM_XMODE_EN;
++              else
++                      reg_val &= ~SPI_CFG3_IPM_XMODE_EN;
++      }
++
++      if (op->addr.buswidth == 2 ||
++          op->dummy.buswidth == 2 ||
++          op->data.buswidth == 2)
++              nio = 2;
++      else if (op->addr.buswidth == 4 ||
++               op->dummy.buswidth == 4 ||
++               op->data.buswidth == 4)
++              nio = 4;
++      else
++              nio = 1;
++
++      reg_val &= ~SPI_CFG3_IPM_CMD_PIN_MODE_MASK;
++      reg_val |= PIN_MODE_CFG(nio);
++
++      reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_EN;
++      if (op->data.dir == SPI_MEM_DATA_IN)
++              reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_DIR;
++      else
++              reg_val &= ~SPI_CFG3_IPM_HALF_DUPLEX_DIR;
++      writel(reg_val, mdata->base + SPI_CFG3_IPM_REG);
++
++      tx_size = 1 + op->addr.nbytes + op->dummy.nbytes;
++      if (op->data.dir == SPI_MEM_DATA_OUT)
++              tx_size += op->data.nbytes;
++
++      tx_size = max_t(u32, tx_size, 32);
++
++      tx_tmp_buf = kzalloc(tx_size, GFP_KERNEL | GFP_DMA);
++      if (!tx_tmp_buf) {
++              mdata->use_spimem = false;
++              return -ENOMEM;
++      }
++
++      tx_tmp_buf[0] = op->cmd.opcode;
++
++      if (op->addr.nbytes) {
++              int i;
++
++              for (i = 0; i < op->addr.nbytes; i++)
++                      tx_tmp_buf[i + 1] = op->addr.val >>
++                                      (8 * (op->addr.nbytes - i - 1));
++      }
++
++      if (op->dummy.nbytes)
++              memset(tx_tmp_buf + op->addr.nbytes + 1,
++                     0xff,
++                     op->dummy.nbytes);
++
++      if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT)
++              memcpy(tx_tmp_buf + op->dummy.nbytes + op->addr.nbytes + 1,
++                     op->data.buf.out,
++                     op->data.nbytes);
++
++      mdata->tx_dma = dma_map_single(mdata->dev, tx_tmp_buf,
++                                     tx_size, DMA_TO_DEVICE);
++      if (dma_mapping_error(mdata->dev, mdata->tx_dma)) {
++              ret = -ENOMEM;
++              goto err_exit;
++      }
++
++      if (op->data.dir == SPI_MEM_DATA_IN) {
++              if (!IS_ALIGNED((size_t)op->data.buf.in, 4)) {
++                      rx_tmp_buf = kzalloc(op->data.nbytes,
++                                           GFP_KERNEL | GFP_DMA);
++                      if (!rx_tmp_buf) {
++                              ret = -ENOMEM;
++                              goto unmap_tx_dma;
++                      }
++              } else {
++                      rx_tmp_buf = op->data.buf.in;
++              }
++
++              mdata->rx_dma = dma_map_single(mdata->dev,
++                                             rx_tmp_buf,
++                                             op->data.nbytes,
++                                             DMA_FROM_DEVICE);
++              if (dma_mapping_error(mdata->dev, mdata->rx_dma)) {
++                      ret = -ENOMEM;
++                      goto kfree_rx_tmp_buf;
++              }
++      }
++
++      reg_val = readl(mdata->base + SPI_CMD_REG);
++      reg_val |= SPI_CMD_TX_DMA;
++      if (op->data.dir == SPI_MEM_DATA_IN)
++              reg_val |= SPI_CMD_RX_DMA;
++      writel(reg_val, mdata->base + SPI_CMD_REG);
++
++      mtk_spi_mem_setup_dma_xfer(mem->spi->master, op);
++
++      mtk_spi_enable_transfer(mem->spi->master);
++
++      /* Wait for the interrupt. */
++      ret = mtk_spi_transfer_wait(mem, op);
++      if (ret)
++              goto unmap_rx_dma;
++
++      /* spi disable dma */
++      reg_val = readl(mdata->base + SPI_CMD_REG);
++      reg_val &= ~SPI_CMD_TX_DMA;
++      if (op->data.dir == SPI_MEM_DATA_IN)
++              reg_val &= ~SPI_CMD_RX_DMA;
++      writel(reg_val, mdata->base + SPI_CMD_REG);
++
++unmap_rx_dma:
++      if (op->data.dir == SPI_MEM_DATA_IN) {
++              dma_unmap_single(mdata->dev, mdata->rx_dma,
++                               op->data.nbytes, DMA_FROM_DEVICE);
++              if (!IS_ALIGNED((size_t)op->data.buf.in, 4))
++                      memcpy(op->data.buf.in, rx_tmp_buf, op->data.nbytes);
++      }
++kfree_rx_tmp_buf:
++      if (op->data.dir == SPI_MEM_DATA_IN &&
++          !IS_ALIGNED((size_t)op->data.buf.in, 4))
++              kfree(rx_tmp_buf);
++unmap_tx_dma:
++      dma_unmap_single(mdata->dev, mdata->tx_dma,
++                       tx_size, DMA_TO_DEVICE);
++err_exit:
++      kfree(tx_tmp_buf);
++      mdata->use_spimem = false;
++
++      return ret;
++}
++
++static const struct spi_controller_mem_ops mtk_spi_mem_ops = {
++      .adjust_op_size = mtk_spi_mem_adjust_op_size,
++      .supports_op = mtk_spi_mem_supports_op,
++      .exec_op = mtk_spi_mem_exec_op,
++};
++
+ static int mtk_spi_probe(struct platform_device *pdev)
+ {
+       struct spi_master *master;
+@@ -739,6 +1103,7 @@ static int mtk_spi_probe(struct platform
+       master->can_dma = mtk_spi_can_dma;
+       master->setup = mtk_spi_setup;
+       master->set_cs_timing = mtk_spi_set_hw_cs_timing;
++      master->use_gpio_descriptors = true;
+       of_id = of_match_node(mtk_spi_of_match, pdev->dev.of_node);
+       if (!of_id) {
+@@ -755,6 +1120,14 @@ static int mtk_spi_probe(struct platform
+       if (mdata->dev_comp->must_tx)
+               master->flags = SPI_MASTER_MUST_TX;
++      if (mdata->dev_comp->ipm_design)
++              master->mode_bits |= SPI_LOOP;
++
++      if (mdata->dev_comp->ipm_design) {
++              mdata->dev = &pdev->dev;
++              master->mem_ops = &mtk_spi_mem_ops;
++              init_completion(&mdata->spimem_done);
++      }
+       if (mdata->dev_comp->need_pad_sel) {
+               mdata->pad_num = of_property_count_u32_elems(
+@@ -831,25 +1204,40 @@ static int mtk_spi_probe(struct platform
+               goto err_put_master;
+       }
++      mdata->spi_hclk = devm_clk_get_optional(&pdev->dev, "hclk");
++      if (IS_ERR(mdata->spi_hclk)) {
++              ret = PTR_ERR(mdata->spi_hclk);
++              dev_err(&pdev->dev, "failed to get hclk: %d\n", ret);
++              goto err_put_master;
++      }
++
++      ret = clk_prepare_enable(mdata->spi_hclk);
++      if (ret < 0) {
++              dev_err(&pdev->dev, "failed to enable hclk (%d)\n", ret);
++              goto err_put_master;
++      }
++
+       ret = clk_prepare_enable(mdata->spi_clk);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to enable spi_clk (%d)\n", ret);
+-              goto err_put_master;
++              goto err_disable_spi_hclk;
+       }
+       ret = clk_set_parent(mdata->sel_clk, mdata->parent_clk);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to clk_set_parent (%d)\n", ret);
+-              clk_disable_unprepare(mdata->spi_clk);
+-              goto err_put_master;
++              goto err_disable_spi_clk;
+       }
+       mdata->spi_clk_hz = clk_get_rate(mdata->spi_clk);
+-      if (mdata->dev_comp->no_need_unprepare)
++      if (mdata->dev_comp->no_need_unprepare) {
+               clk_disable(mdata->spi_clk);
+-      else
++              clk_disable(mdata->spi_hclk);
++      } else {
+               clk_disable_unprepare(mdata->spi_clk);
++              clk_disable_unprepare(mdata->spi_hclk);
++      }
+       pm_runtime_enable(&pdev->dev);
+@@ -862,25 +1250,12 @@ static int mtk_spi_probe(struct platform
+                       goto err_disable_runtime_pm;
+               }
+-              if (!master->cs_gpios && master->num_chipselect > 1) {
++              if (!master->cs_gpiods && master->num_chipselect > 1) {
+                       dev_err(&pdev->dev,
+                               "cs_gpios not specified and num_chipselect > 1\n");
+                       ret = -EINVAL;
+                       goto err_disable_runtime_pm;
+               }
+-
+-              if (master->cs_gpios) {
+-                      for (i = 0; i < master->num_chipselect; i++) {
+-                              ret = devm_gpio_request(&pdev->dev,
+-                                                      master->cs_gpios[i],
+-                                                      dev_name(&pdev->dev));
+-                              if (ret) {
+-                                      dev_err(&pdev->dev,
+-                                              "can't get CS GPIO %i\n", i);
+-                                      goto err_disable_runtime_pm;
+-                              }
+-                      }
+-              }
+       }
+       if (mdata->dev_comp->dma_ext)
+@@ -902,6 +1277,10 @@ static int mtk_spi_probe(struct platform
+ err_disable_runtime_pm:
+       pm_runtime_disable(&pdev->dev);
++err_disable_spi_clk:
++      clk_disable_unprepare(mdata->spi_clk);
++err_disable_spi_hclk:
++      clk_disable_unprepare(mdata->spi_hclk);
+ err_put_master:
+       spi_master_put(master);
+@@ -917,8 +1296,10 @@ static int mtk_spi_remove(struct platfor
+       mtk_spi_reset(mdata);
+-      if (mdata->dev_comp->no_need_unprepare)
++      if (mdata->dev_comp->no_need_unprepare) {
+               clk_unprepare(mdata->spi_clk);
++              clk_unprepare(mdata->spi_hclk);
++      }
+       return 0;
+ }
+@@ -934,8 +1315,10 @@ static int mtk_spi_suspend(struct device
+       if (ret)
+               return ret;
+-      if (!pm_runtime_suspended(dev))
++      if (!pm_runtime_suspended(dev)) {
+               clk_disable_unprepare(mdata->spi_clk);
++              clk_disable_unprepare(mdata->spi_hclk);
++      }
+       return ret;
+ }
+@@ -952,11 +1335,20 @@ static int mtk_spi_resume(struct device
+                       dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
+                       return ret;
+               }
++
++              ret = clk_prepare_enable(mdata->spi_hclk);
++              if (ret < 0) {
++                      dev_err(dev, "failed to enable spi_hclk (%d)\n", ret);
++                      clk_disable_unprepare(mdata->spi_clk);
++                      return ret;
++              }
+       }
+       ret = spi_master_resume(master);
+-      if (ret < 0)
++      if (ret < 0) {
+               clk_disable_unprepare(mdata->spi_clk);
++              clk_disable_unprepare(mdata->spi_hclk);
++      }
+       return ret;
+ }
+@@ -968,10 +1360,13 @@ static int mtk_spi_runtime_suspend(struc
+       struct spi_master *master = dev_get_drvdata(dev);
+       struct mtk_spi *mdata = spi_master_get_devdata(master);
+-      if (mdata->dev_comp->no_need_unprepare)
++      if (mdata->dev_comp->no_need_unprepare) {
+               clk_disable(mdata->spi_clk);
+-      else
++              clk_disable(mdata->spi_hclk);
++      } else {
+               clk_disable_unprepare(mdata->spi_clk);
++              clk_disable_unprepare(mdata->spi_hclk);
++      }
+       return 0;
+ }
+@@ -982,13 +1377,31 @@ static int mtk_spi_runtime_resume(struct
+       struct mtk_spi *mdata = spi_master_get_devdata(master);
+       int ret;
+-      if (mdata->dev_comp->no_need_unprepare)
++      if (mdata->dev_comp->no_need_unprepare) {
+               ret = clk_enable(mdata->spi_clk);
+-      else
++              if (ret < 0) {
++                      dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
++                      return ret;
++              }
++              ret = clk_enable(mdata->spi_hclk);
++              if (ret < 0) {
++                      dev_err(dev, "failed to enable spi_hclk (%d)\n", ret);
++                      clk_disable(mdata->spi_clk);
++                      return ret;
++              }
++      } else {
+               ret = clk_prepare_enable(mdata->spi_clk);
+-      if (ret < 0) {
+-              dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
+-              return ret;
++              if (ret < 0) {
++                      dev_err(dev, "failed to prepare_enable spi_clk (%d)\n", ret);
++                      return ret;
++              }
++
++              ret = clk_prepare_enable(mdata->spi_hclk);
++              if (ret < 0) {
++                      dev_err(dev, "failed to prepare_enable spi_hclk (%d)\n", ret);
++                      clk_disable_unprepare(mdata->spi_clk);
++                      return ret;
++              }
+       }
+       return 0;
diff --git a/target/linux/mediatek/patches-5.15/320-mmc-mediatek-add-support-for-MT7986-SoC.patch b/target/linux/mediatek/patches-5.15/320-mmc-mediatek-add-support-for-MT7986-SoC.patch
new file mode 100644 (file)
index 0000000..56ffa73
--- /dev/null
@@ -0,0 +1,44 @@
+From 1a7963e9843f6f1e4b02a30926d20b314c03e4df Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Sat, 25 Jun 2022 02:10:13 +0800
+Subject: [PATCH] mmc: mediatek: add support for MT7986 SoC
+
+Adding mt7986 own characteristics and of_device_id to have support
+of MT7986 SoC.
+
+Signed-off-by: Sam Shih <sam.shih@mediatek.com>
+Change-Id: I07cf8406cbe8c1a7114b304f35fc3e689e512e5a
+---
+ drivers/mmc/host/mtk-sd.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/mmc/host/mtk-sd.c
++++ b/drivers/mmc/host/mtk-sd.c
+@@ -540,6 +540,19 @@ static const struct mtk_mmc_compatible m
+       .support_64g = false,
+ };
++static const struct mtk_mmc_compatible mt7986_compat = {
++      .clk_div_bits = 12,
++      .recheck_sdio_irq = true,
++      .hs400_tune = false,
++      .pad_tune_reg = MSDC_PAD_TUNE0,
++      .async_fifo = true,
++      .data_tune = true,
++      .busy_check = true,
++      .stop_clk_fix = true,
++      .enhance_rx = true,
++      .support_64g = true,
++};
++
+ static const struct mtk_mmc_compatible mt8516_compat = {
+       .clk_div_bits = 12,
+       .recheck_sdio_irq = true,
+@@ -584,6 +597,7 @@ static const struct of_device_id msdc_of
+       { .compatible = "mediatek,mt2701-mmc", .data = &mt2701_compat},
+       { .compatible = "mediatek,mt2712-mmc", .data = &mt2712_compat},
+       { .compatible = "mediatek,mt7622-mmc", .data = &mt7622_compat},
++      { .compatible = "mediatek,mt7986-mmc", .data = &mt7986_compat},
+       { .compatible = "mediatek,mt8516-mmc", .data = &mt8516_compat},
+       { .compatible = "mediatek,mt7620-mmc", .data = &mt7620_compat},
+       { .compatible = "mediatek,mt6779-mmc", .data = &mt6779_compat},
diff --git a/target/linux/mediatek/patches-5.15/405-mt7986-trng-add-rng-support.patch b/target/linux/mediatek/patches-5.15/405-mt7986-trng-add-rng-support.patch
new file mode 100644 (file)
index 0000000..332f17b
--- /dev/null
@@ -0,0 +1,41 @@
+From f6ba5e17bee38f8ffe118c47fbfef3cf90eb87ff Mon Sep 17 00:00:00 2001
+From: "Mingming.Su" <Mingming.Su@mediatek.com>
+Date: Wed, 30 Jun 2021 16:59:32 +0800
+Subject: [PATCH] mt7986: trng: add rng support
+
+1. Add trng compatible name for MT7986
+2. Fix mtk_rng_wait_ready() function
+
+Signed-off-by: Mingming.Su <Mingming.Su@mediatek.com>
+---
+ drivers/char/hw_random/mtk-rng.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/hw_random/mtk-rng.c
++++ b/drivers/char/hw_random/mtk-rng.c
+@@ -22,7 +22,7 @@
+ #define RNG_AUTOSUSPEND_TIMEOUT               100
+ #define USEC_POLL                     2
+-#define TIMEOUT_POLL                  20
++#define TIMEOUT_POLL                  60
+ #define RNG_CTRL                      0x00
+ #define RNG_EN                                BIT(0)
+@@ -77,7 +77,7 @@ static bool mtk_rng_wait_ready(struct hw
+               readl_poll_timeout_atomic(priv->base + RNG_CTRL, ready,
+                                         ready & RNG_READY, USEC_POLL,
+                                         TIMEOUT_POLL);
+-      return !!ready;
++      return !!(ready & RNG_READY);
+ }
+ static int mtk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+@@ -179,6 +179,7 @@ static const struct dev_pm_ops mtk_rng_p
+ #endif        /* CONFIG_PM */
+ static const struct of_device_id mtk_rng_match[] = {
++      { .compatible = "mediatek,mt7986-rng" },
+       { .compatible = "mediatek,mt7623-rng" },
+       {},
+ };
diff --git a/target/linux/mediatek/patches-5.15/920-watchdog-add-mt7986-assert.patch b/target/linux/mediatek/patches-5.15/920-watchdog-add-mt7986-assert.patch
new file mode 100644 (file)
index 0000000..6991614
--- /dev/null
@@ -0,0 +1,57 @@
+--- a/drivers/watchdog/mtk_wdt.c
++++ b/drivers/watchdog/mtk_wdt.c
+@@ -9,6 +9,7 @@
+  * Based on sunxi_wdt.c
+  */
++#include <dt-bindings/reset/mt7986-resets.h>
+ #include <dt-bindings/reset-controller/mt2712-resets.h>
+ #include <dt-bindings/reset-controller/mt8183-resets.h>
+ #include <dt-bindings/reset-controller/mt8192-resets.h>
+@@ -65,6 +66,7 @@ struct mtk_wdt_dev {
+       void __iomem *wdt_base;
+       spinlock_t lock; /* protects WDT_SWSYSRST reg */
+       struct reset_controller_dev rcdev;
++      bool disable_wdt_extrst;
+ };
+ struct mtk_wdt_data {
+@@ -87,6 +89,10 @@ static const struct mtk_wdt_data mt8195_
+       .toprgu_sw_rst_num = MT8195_TOPRGU_SW_RST_NUM,
+ };
++static const struct mtk_wdt_data mt7986_data = {
++      .toprgu_sw_rst_num = MT7986_TOPRGU_SW_RST_NUM,
++};
++
+ static int toprgu_reset_update(struct reset_controller_dev *rcdev,
+                              unsigned long id, bool assert)
+ {
+@@ -256,6 +262,8 @@ static int mtk_wdt_start(struct watchdog
+               reg |= (WDT_MODE_IRQ_EN | WDT_MODE_DUAL_EN);
+       else
+               reg &= ~(WDT_MODE_IRQ_EN | WDT_MODE_DUAL_EN);
++      if (mtk_wdt->disable_wdt_extrst)
++              reg &= ~WDT_MODE_EXRST_EN;
+       reg |= (WDT_MODE_EN | WDT_MODE_KEY);
+       iowrite32(reg, wdt_base + WDT_MODE);
+@@ -381,6 +389,10 @@ static int mtk_wdt_probe(struct platform
+               if (err)
+                       return err;
+       }
++
++      mtk_wdt->disable_wdt_extrst =
++              of_property_read_bool(dev->of_node, "mediatek,disable-extrst");
++
+       return 0;
+ }
+@@ -414,6 +426,7 @@ static const struct of_device_id mtk_wdt
+       { .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data },
+       { .compatible = "mediatek,mt8192-wdt", .data = &mt8192_data },
+       { .compatible = "mediatek,mt8195-wdt", .data = &mt8195_data },
++      { .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data },
+       { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, mtk_wdt_dt_ids);
diff --git a/target/linux/mediatek/patches-5.15/921-mt7986-add-mmc-support.patch b/target/linux/mediatek/patches-5.15/921-mt7986-add-mmc-support.patch
new file mode 100644 (file)
index 0000000..18b6e97
--- /dev/null
@@ -0,0 +1,47 @@
+From 0f8a0dd620b2fb5f9c852844ce5f445bb0bd6d52 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Wed, 4 May 2022 10:27:43 +0800
+Subject: [PATCH 5/5] mediatek: add mt7986a mmc support
+
+Add mt7986a boot mmc support
+
+Signed-off-by: Sam Shih <sam.shih@mediatek.com>
+---
+ ...-mmc-mediatek-add-mt7986-mmc-support.patch | 31 +++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+ create mode 100644 target/linux/mediatek/patches-5.15/0704-mmc-mediatek-add-mt7986-mmc-support.patch
+
+--- /dev/null
++++ b/target/linux/mediatek/patches-5.15/0704-mmc-mediatek-add-mt7986-mmc-support.patch
+@@ -0,0 +1,31 @@
++diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
++index 1ac9201..a32349c 100644
++--- a/drivers/mmc/host/mtk-sd.c
+++++ b/drivers/mmc/host/mtk-sd.c
++@@ -540,6 +540,18 @@ static const struct mtk_mmc_compatible mt7622_compat = {
++      .support_64g = false,
++ };
++ 
+++static const struct mtk_mmc_compatible mt7986_compat = {
+++    .clk_div_bits = 12,
+++    .hs400_tune = false,
+++    .pad_tune_reg = MSDC_PAD_TUNE0,
+++    .async_fifo = true,
+++    .data_tune = true,
+++    .busy_check = true,
+++    .stop_clk_fix = true,
+++    .enhance_rx = true,
+++    .support_64g = true,
+++};
+++
++ static const struct mtk_mmc_compatible mt8516_compat = {
++      .clk_div_bits = 12,
++      .recheck_sdio_irq = true,
++@@ -584,6 +596,7 @@ static const struct of_device_id msdc_of_ids[] = {
++      { .compatible = "mediatek,mt2701-mmc", .data = &mt2701_compat},
++      { .compatible = "mediatek,mt2712-mmc", .data = &mt2712_compat},
++      { .compatible = "mediatek,mt7622-mmc", .data = &mt7622_compat},
+++     { .compatible = "mediatek,mt7986-mmc", .data = &mt7986_compat},
++      { .compatible = "mediatek,mt8516-mmc", .data = &mt8516_compat},
++      { .compatible = "mediatek,mt7620-mmc", .data = &mt7620_compat},
++      { .compatible = "mediatek,mt6779-mmc", .data = &mt6779_compat},
diff --git a/target/linux/mediatek/patches-5.15/922-PCI-mediatek-gen3-change-driver-name-to-mtk-pcie-gen.patch b/target/linux/mediatek/patches-5.15/922-PCI-mediatek-gen3-change-driver-name-to-mtk-pcie-gen.patch
new file mode 100644 (file)
index 0000000..44aed22
--- /dev/null
@@ -0,0 +1,20 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 4 May 2022 12:03:42 +0200
+Subject: [PATCH] PCI: mediatek-gen3: change driver name to mtk-pcie-gen3
+
+This allows it to coexist with the other mtk pcie driver in the same kernel
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/pci/controller/pcie-mediatek-gen3.c
++++ b/drivers/pci/controller/pcie-mediatek-gen3.c
+@@ -1025,7 +1025,7 @@ static struct platform_driver mtk_pcie_d
+       .probe = mtk_pcie_probe,
+       .remove = mtk_pcie_remove,
+       .driver = {
+-              .name = "mtk-pcie",
++              .name = "mtk-pcie-gen3",
+               .of_match_table = mtk_pcie_of_match,
+               .pm = &mtk_pcie_pm_ops,
+       },