aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mediatek/patches-4.4
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mediatek/patches-4.4')
-rw-r--r--target/linux/mediatek/patches-4.4/0001-NET-multi-phy-support.patch60
-rw-r--r--target/linux/mediatek/patches-4.4/0002-soc-mediatek-Separate-scpsys-driver-common-code.patch681
-rw-r--r--target/linux/mediatek/patches-4.4/0003-soc-mediatek-Init-MT8173-scpsys-driver-earlier.patch38
-rw-r--r--target/linux/mediatek/patches-4.4/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch50
-rw-r--r--target/linux/mediatek/patches-4.4/0005-soc-mediatek-Add-MT2701-MT7623-scpsys-driver.patch214
-rw-r--r--target/linux/mediatek/patches-4.4/0006-clk-mediatek-Refine-the-makefile-to-support-multiple.patch71
-rw-r--r--target/linux/mediatek/patches-4.4/0007-dt-bindings-ARM-Mediatek-Document-bindings-for-MT270.patch198
-rw-r--r--target/linux/mediatek/patches-4.4/0008-clk-mediatek-Add-dt-bindings-for-MT2701-clocks.patch505
-rw-r--r--target/linux/mediatek/patches-4.4/0009-clk-mediatek-Add-MT2701-clock-support.patch1449
-rw-r--r--target/linux/mediatek/patches-4.4/0010-reset-mediatek-mt2701-reset-controller-dt-binding-fi.patch99
-rw-r--r--target/linux/mediatek/patches-4.4/0011-reset-mediatek-mt2701-reset-driver.patch41
-rw-r--r--target/linux/mediatek/patches-4.4/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch34
-rw-r--r--target/linux/mediatek/patches-4.4/0013-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt2.patch36
-rw-r--r--target/linux/mediatek/patches-4.4/0014-pinctrl-dt-bindings-Add-pinfunc-header-file-for-mt27.patch3812
-rw-r--r--target/linux/mediatek/patches-4.4/0015-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt7.patch555
-rw-r--r--target/linux/mediatek/patches-4.4/0016-pinctrl-dt-bindings-Add-pinctrl-file-for-mt7623.patch2394
-rw-r--r--target/linux/mediatek/patches-4.4/0017-clk-add-hifsys-reset.patch54
-rw-r--r--target/linux/mediatek/patches-4.4/0018-dt-bindings-Add-a-binding-for-Mediatek-xHCI-host-con.patch75
-rw-r--r--target/linux/mediatek/patches-4.4/0019-xhci-mediatek-support-MTK-xHCI-host-controller.patch1547
-rw-r--r--target/linux/mediatek/patches-4.4/0020-arm64-dts-mediatek-add-xHCI-usb-phy-for-mt8173.patch114
-rw-r--r--target/linux/mediatek/patches-4.4/0021-Document-DT-Add-bindings-for-mediatek-MT7623-SoC-Pla.patch64
-rw-r--r--target/linux/mediatek/patches-4.4/0022-soc-mediatek-add-compat-string-for-mt7623-to-scpsys.patch26
-rw-r--r--target/linux/mediatek/patches-4.4/0023-ARM-dts-mediatek-add-MT7623-basic-support.patch1038
-rw-r--r--target/linux/mediatek/patches-4.4/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch160
-rw-r--r--target/linux/mediatek/patches-4.4/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch710
-rw-r--r--target/linux/mediatek/patches-4.4/0026-scpsys-various-fixes.patch65
-rw-r--r--target/linux/mediatek/patches-4.4/0027-soc-mediatek-PMIC-wrap-Clear-the-vldclr-if-state-mac.patch74
-rw-r--r--target/linux/mediatek/patches-4.4/0028-ARM-mediatek-add-MT7623-smp-bringup-code.patch41
-rw-r--r--target/linux/mediatek/patches-4.4/0029-soc-mediatek-PMIC-wrap-clear-the-STAUPD_TRIG-bit-of-.patch63
-rw-r--r--target/linux/mediatek/patches-4.4/0030-ARM-mediatek-add-mt2701-smp-bringup-code.patch28
-rw-r--r--target/linux/mediatek/patches-4.4/0031-dt-bindings-ARM-Mediatek-add-MT2701-7623-string-to-t.patch28
-rw-r--r--target/linux/mediatek/patches-4.4/0032-soc-mediatek-PMIC-wrap-don-t-duplicate-the-wrapper-d.patch98
-rw-r--r--target/linux/mediatek/patches-4.4/0033-soc-mediatek-PMIC-wrap-add-wrapper-callbacks-for-ini.patch127
-rw-r--r--target/linux/mediatek/patches-4.4/0034-soc-mediatek-PMIC-wrap-split-SoC-specific-init-into-.patch127
-rw-r--r--target/linux/mediatek/patches-4.4/0035-soc-mediatek-PMIC-wrap-WRAP_INT_EN-needs-a-different.patch53
-rw-r--r--target/linux/mediatek/patches-4.4/0036-soc-mediatek-PMIC-wrap-SPI_WRITE-needs-a-different-b.patch66
-rw-r--r--target/linux/mediatek/patches-4.4/0037-soc-mediatek-PMIC-wrap-move-wdt_src-into-the-pmic_wr.patch66
-rw-r--r--target/linux/mediatek/patches-4.4/0038-soc-mediatek-PMIC-wrap-remove-pwrap_is_mt8135-and-pw.patch118
-rw-r--r--target/linux/mediatek/patches-4.4/0039-soc-mediatek-PMIC-wrap-add-a-slave-specific-struct.patch301
-rw-r--r--target/linux/mediatek/patches-4.4/0040-soc-mediatek-PMIC-wrap-add-mt6323-slave-support.patch98
-rw-r--r--target/linux/mediatek/patches-4.4/0041-soc-mediatek-PMIC-wrap-add-MT2701-7623-support.patch237
-rw-r--r--target/linux/mediatek/patches-4.4/0042-dt-bindings-mfd-Add-bindings-for-the-MediaTek-MT6323.patch55
-rw-r--r--target/linux/mediatek/patches-4.4/0043-mfd-mt6397-int_con-and-int_status-may-vary-in-locati.patch104
-rw-r--r--target/linux/mediatek/patches-4.4/0044-mfd-mt6397-add-support-for-different-Slave-types.patch105
-rw-r--r--target/linux/mediatek/patches-4.4/0045-mfd-mt6397-add-MT6323-support-to-MT6397-driver.patch530
-rw-r--r--target/linux/mediatek/patches-4.4/0046-regulator-Add-document-for-MT6323-regulator.patch260
-rw-r--r--target/linux/mediatek/patches-4.4/0047-regulator-mt6323-Add-support-for-MT6323-regulator.patch551
-rw-r--r--target/linux/mediatek/patches-4.4/0048-net-next-mediatek-document-MediaTek-SoC-ethernet-bin.patch103
-rw-r--r--target/linux/mediatek/patches-4.4/0049-net-next-mediatek-add-support-for-MT7623-ethernet.patch2271
-rw-r--r--target/linux/mediatek/patches-4.4/0050-net-next-mediatek-add-Kconfig-and-Makefile.patch78
-rw-r--r--target/linux/mediatek/patches-4.4/0051-net-next-mediatek-add-an-entry-to-MAINTAINERS.patch34
-rw-r--r--target/linux/mediatek/patches-4.4/0052-net-out-of-tree-fixes.patch2409
-rw-r--r--target/linux/mediatek/patches-4.4/0053-dont-disable-clocks.patch25
53 files changed, 22140 insertions, 0 deletions
diff --git a/target/linux/mediatek/patches-4.4/0001-NET-multi-phy-support.patch b/target/linux/mediatek/patches-4.4/0001-NET-multi-phy-support.patch
new file mode 100644
index 0000000000..8917ac328f
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0001-NET-multi-phy-support.patch
@@ -0,0 +1,60 @@
+From c30a296646a42302065ba452abe95b0b4b550883 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 27 Jul 2014 09:38:50 +0100
+Subject: [PATCH 01/53] NET: multi phy support
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/net/phy/phy.c | 9 ++++++---
+ include/linux/phy.h | 1 +
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
+index 47cd306..f69d12f 100644
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -844,7 +844,8 @@ void phy_state_machine(struct work_struct *work)
+ /* If the link is down, give up on negotiation for now */
+ if (!phydev->link) {
+ phydev->state = PHY_NOLINK;
+- netif_carrier_off(phydev->attached_dev);
++ if (!phydev->no_auto_carrier_off)
++ netif_carrier_off(phydev->attached_dev);
+ phydev->adjust_link(phydev->attached_dev);
+ break;
+ }
+@@ -927,7 +928,8 @@ void phy_state_machine(struct work_struct *work)
+ netif_carrier_on(phydev->attached_dev);
+ } else {
+ phydev->state = PHY_NOLINK;
+- netif_carrier_off(phydev->attached_dev);
++ if (!phydev->no_auto_carrier_off)
++ netif_carrier_off(phydev->attached_dev);
+ }
+
+ phydev->adjust_link(phydev->attached_dev);
+@@ -939,7 +941,8 @@ void phy_state_machine(struct work_struct *work)
+ case PHY_HALTED:
+ if (phydev->link) {
+ phydev->link = 0;
+- netif_carrier_off(phydev->attached_dev);
++ if (!phydev->no_auto_carrier_off)
++ netif_carrier_off(phydev->attached_dev);
+ phydev->adjust_link(phydev->attached_dev);
+ do_suspend = true;
+ }
+diff --git a/include/linux/phy.h b/include/linux/phy.h
+index 05fde31..276ab8a 100644
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -377,6 +377,7 @@ struct phy_device {
+ bool is_pseudo_fixed_link;
+ bool has_fixups;
+ bool suspended;
++ bool no_auto_carrier_off;
+
+ enum phy_state state;
+
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0002-soc-mediatek-Separate-scpsys-driver-common-code.patch b/target/linux/mediatek/patches-4.4/0002-soc-mediatek-Separate-scpsys-driver-common-code.patch
new file mode 100644
index 0000000000..53781dc3be
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0002-soc-mediatek-Separate-scpsys-driver-common-code.patch
@@ -0,0 +1,681 @@
+From 2c93328ed05061a50e3bd4111379dbcf6946d3ac Mon Sep 17 00:00:00 2001
+From: James Liao <jamesjj.liao@mediatek.com>
+Date: Wed, 30 Dec 2015 14:41:43 +0800
+Subject: [PATCH 02/53] soc: mediatek: Separate scpsys driver common code
+
+Separate scpsys driver common code to mtk-scpsys.c, and move MT8173
+platform code to mtk-scpsys-mt8173.c.
+
+Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
+---
+ drivers/soc/mediatek/Kconfig | 13 +-
+ drivers/soc/mediatek/Makefile | 1 +
+ drivers/soc/mediatek/mtk-scpsys-mt8173.c | 179 ++++++++++++++++++
+ drivers/soc/mediatek/mtk-scpsys.c | 301 ++++++++----------------------
+ drivers/soc/mediatek/mtk-scpsys.h | 54 ++++++
+ 5 files changed, 320 insertions(+), 228 deletions(-)
+ create mode 100644 drivers/soc/mediatek/mtk-scpsys-mt8173.c
+ create mode 100644 drivers/soc/mediatek/mtk-scpsys.h
+
+diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
+index 0a4ea80..eca6fb7 100644
+--- a/drivers/soc/mediatek/Kconfig
++++ b/drivers/soc/mediatek/Kconfig
+@@ -22,11 +22,20 @@ config MTK_PMIC_WRAP
+
+ config MTK_SCPSYS
+ bool "MediaTek SCPSYS Support"
+- depends on ARCH_MEDIATEK || COMPILE_TEST
+- default ARM64 && ARCH_MEDIATEK
+ select REGMAP
+ select MTK_INFRACFG
+ select PM_GENERIC_DOMAINS if PM
+ help
+ Say yes here to add support for the MediaTek SCPSYS power domain
+ driver.
++
++config MTK_SCPSYS_MT8173
++ bool "MediaTek MT8173 SCPSYS Support"
++ depends on ARCH_MEDIATEK || COMPILE_TEST
++ select MTK_SCPSYS
++ default ARCH_MEDIATEK
++ help
++ Say yes here to add support for the MT8173 SCPSYS power domain
++ driver.
++ The System Control Processor System (SCPSYS) has several power
++ management related tasks in the system.
+diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
+index 12998b0..3b22baa 100644
+--- a/drivers/soc/mediatek/Makefile
++++ b/drivers/soc/mediatek/Makefile
+@@ -1,3 +1,4 @@
+ obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
+ obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
+ obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
++obj-$(CONFIG_MTK_SCPSYS_MT8173) += mtk-scpsys-mt8173.o
+diff --git a/drivers/soc/mediatek/mtk-scpsys-mt8173.c b/drivers/soc/mediatek/mtk-scpsys-mt8173.c
+new file mode 100644
+index 0000000..3c7b569
+--- /dev/null
++++ b/drivers/soc/mediatek/mtk-scpsys-mt8173.c
+@@ -0,0 +1,179 @@
++/*
++ * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++#include <linux/mfd/syscon.h>
++#include <linux/module.h>
++#include <linux/of_device.h>
++#include <linux/pm_domain.h>
++#include <linux/soc/mediatek/infracfg.h>
++#include <dt-bindings/power/mt8173-power.h>
++
++#include "mtk-scpsys.h"
++
++#define SPM_VDE_PWR_CON 0x0210
++#define SPM_MFG_PWR_CON 0x0214
++#define SPM_VEN_PWR_CON 0x0230
++#define SPM_ISP_PWR_CON 0x0238
++#define SPM_DIS_PWR_CON 0x023c
++#define SPM_VEN2_PWR_CON 0x0298
++#define SPM_AUDIO_PWR_CON 0x029c
++#define SPM_MFG_2D_PWR_CON 0x02c0
++#define SPM_MFG_ASYNC_PWR_CON 0x02c4
++#define SPM_USB_PWR_CON 0x02cc
++
++#define PWR_STATUS_DISP BIT(3)
++#define PWR_STATUS_MFG BIT(4)
++#define PWR_STATUS_ISP BIT(5)
++#define PWR_STATUS_VDEC BIT(7)
++#define PWR_STATUS_VENC_LT BIT(20)
++#define PWR_STATUS_VENC BIT(21)
++#define PWR_STATUS_MFG_2D BIT(22)
++#define PWR_STATUS_MFG_ASYNC BIT(23)
++#define PWR_STATUS_AUDIO BIT(24)
++#define PWR_STATUS_USB BIT(25)
++
++static const struct scp_domain_data scp_domain_data[] __initconst = {
++ [MT8173_POWER_DOMAIN_VDEC] = {
++ .name = "vdec",
++ .sta_mask = PWR_STATUS_VDEC,
++ .ctl_offs = SPM_VDE_PWR_CON,
++ .sram_pdn_bits = GENMASK(11, 8),
++ .sram_pdn_ack_bits = GENMASK(12, 12),
++ .clk_id = {CLK_MM},
++ },
++ [MT8173_POWER_DOMAIN_VENC] = {
++ .name = "venc",
++ .sta_mask = PWR_STATUS_VENC,
++ .ctl_offs = SPM_VEN_PWR_CON,
++ .sram_pdn_bits = GENMASK(11, 8),
++ .sram_pdn_ack_bits = GENMASK(15, 12),
++ .clk_id = {CLK_MM, CLK_VENC},
++ },
++ [MT8173_POWER_DOMAIN_ISP] = {
++ .name = "isp",
++ .sta_mask = PWR_STATUS_ISP,
++ .ctl_offs = SPM_ISP_PWR_CON,
++ .sram_pdn_bits = GENMASK(11, 8),
++ .sram_pdn_ack_bits = GENMASK(13, 12),
++ .clk_id = {CLK_MM},
++ },
++ [MT8173_POWER_DOMAIN_MM] = {
++ .name = "mm",
++ .sta_mask = PWR_STATUS_DISP,
++ .ctl_offs = SPM_DIS_PWR_CON,
++ .sram_pdn_bits = GENMASK(11, 8),
++ .sram_pdn_ack_bits = GENMASK(12, 12),
++ .clk_id = {CLK_MM},
++ .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
++ MT8173_TOP_AXI_PROT_EN_MM_M1,
++ },
++ [MT8173_POWER_DOMAIN_VENC_LT] = {
++ .name = "venc_lt",
++ .sta_mask = PWR_STATUS_VENC_LT,
++ .ctl_offs = SPM_VEN2_PWR_CON,
++ .sram_pdn_bits = GENMASK(11, 8),
++ .sram_pdn_ack_bits = GENMASK(15, 12),
++ .clk_id = {CLK_MM, CLK_VENC_LT},
++ },
++ [MT8173_POWER_DOMAIN_AUDIO] = {
++ .name = "audio",
++ .sta_mask = PWR_STATUS_AUDIO,
++ .ctl_offs = SPM_AUDIO_PWR_CON,
++ .sram_pdn_bits = GENMASK(11, 8),
++ .sram_pdn_ack_bits = GENMASK(15, 12),
++ .clk_id = {CLK_NONE},
++ },
++ [MT8173_POWER_DOMAIN_USB] = {
++ .name = "usb",
++ .sta_mask = PWR_STATUS_USB,
++ .ctl_offs = SPM_USB_PWR_CON,
++ .sram_pdn_bits = GENMASK(11, 8),
++ .sram_pdn_ack_bits = GENMASK(15, 12),
++ .clk_id = {CLK_NONE},
++ .active_wakeup = true,
++ },
++ [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
++ .name = "mfg_async",
++ .sta_mask = PWR_STATUS_MFG_ASYNC,
++ .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
++ .sram_pdn_bits = GENMASK(11, 8),
++ .sram_pdn_ack_bits = 0,
++ .clk_id = {CLK_MFG},
++ },
++ [MT8173_POWER_DOMAIN_MFG_2D] = {
++ .name = "mfg_2d",
++ .sta_mask = PWR_STATUS_MFG_2D,
++ .ctl_offs = SPM_MFG_2D_PWR_CON,
++ .sram_pdn_bits = GENMASK(11, 8),
++ .sram_pdn_ack_bits = GENMASK(13, 12),
++ .clk_id = {CLK_NONE},
++ },
++ [MT8173_POWER_DOMAIN_MFG] = {
++ .name = "mfg",
++ .sta_mask = PWR_STATUS_MFG,
++ .ctl_offs = SPM_MFG_PWR_CON,
++ .sram_pdn_bits = GENMASK(13, 8),
++ .sram_pdn_ack_bits = GENMASK(21, 16),
++ .clk_id = {CLK_NONE},
++ .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
++ MT8173_TOP_AXI_PROT_EN_MFG_M0 |
++ MT8173_TOP_AXI_PROT_EN_MFG_M1 |
++ MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
++ },
++};
++
++#define NUM_DOMAINS ARRAY_SIZE(scp_domain_data)
++
++static int __init scpsys_probe(struct platform_device *pdev)
++{
++ struct scp *scp;
++ struct genpd_onecell_data *pd_data;
++ int ret;
++
++ scp = init_scp(pdev, scp_domain_data, NUM_DOMAINS);
++ if (IS_ERR(scp))
++ return PTR_ERR(scp);
++
++ mtk_register_power_domains(pdev, scp, NUM_DOMAINS);
++
++ pd_data = &scp->pd_data;
++
++ ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
++ pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
++ if (ret && IS_ENABLED(CONFIG_PM))
++ dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
++
++ ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D],
++ pd_data->domains[MT8173_POWER_DOMAIN_MFG]);
++ if (ret && IS_ENABLED(CONFIG_PM))
++ dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
++
++ return 0;
++}
++
++static const struct of_device_id of_scpsys_match_tbl[] = {
++ {
++ .compatible = "mediatek,mt8173-scpsys",
++ }, {
++ /* sentinel */
++ }
++};
++
++static struct platform_driver scpsys_drv = {
++ .driver = {
++ .name = "mtk-scpsys-mt8173",
++ .owner = THIS_MODULE,
++ .of_match_table = of_match_ptr(of_scpsys_match_tbl),
++ },
++};
++
++module_platform_driver_probe(scpsys_drv, scpsys_probe);
+diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
+index 4d4203c..a0943c5 100644
+--- a/drivers/soc/mediatek/mtk-scpsys.c
++++ b/drivers/soc/mediatek/mtk-scpsys.c
+@@ -11,28 +11,14 @@
+ * GNU General Public License for more details.
+ */
+ #include <linux/clk.h>
+-#include <linux/delay.h>
+ #include <linux/io.h>
+-#include <linux/kernel.h>
+ #include <linux/mfd/syscon.h>
+-#include <linux/module.h>
+-#include <linux/of_device.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_domain.h>
+-#include <linux/regmap.h>
+ #include <linux/soc/mediatek/infracfg.h>
+-#include <dt-bindings/power/mt8173-power.h>
+-
+-#define SPM_VDE_PWR_CON 0x0210
+-#define SPM_MFG_PWR_CON 0x0214
+-#define SPM_VEN_PWR_CON 0x0230
+-#define SPM_ISP_PWR_CON 0x0238
+-#define SPM_DIS_PWR_CON 0x023c
+-#define SPM_VEN2_PWR_CON 0x0298
+-#define SPM_AUDIO_PWR_CON 0x029c
+-#define SPM_MFG_2D_PWR_CON 0x02c0
+-#define SPM_MFG_ASYNC_PWR_CON 0x02c4
+-#define SPM_USB_PWR_CON 0x02cc
++
++#include "mtk-scpsys.h"
++
+ #define SPM_PWR_STATUS 0x060c
+ #define SPM_PWR_STATUS_2ND 0x0610
+
+@@ -42,153 +28,6 @@
+ #define PWR_ON_2ND_BIT BIT(3)
+ #define PWR_CLK_DIS_BIT BIT(4)
+
+-#define PWR_STATUS_DISP BIT(3)
+-#define PWR_STATUS_MFG BIT(4)
+-#define PWR_STATUS_ISP BIT(5)
+-#define PWR_STATUS_VDEC BIT(7)
+-#define PWR_STATUS_VENC_LT BIT(20)
+-#define PWR_STATUS_VENC BIT(21)
+-#define PWR_STATUS_MFG_2D BIT(22)
+-#define PWR_STATUS_MFG_ASYNC BIT(23)
+-#define PWR_STATUS_AUDIO BIT(24)
+-#define PWR_STATUS_USB BIT(25)
+-
+-enum clk_id {
+- MT8173_CLK_NONE,
+- MT8173_CLK_MM,
+- MT8173_CLK_MFG,
+- MT8173_CLK_VENC,
+- MT8173_CLK_VENC_LT,
+- MT8173_CLK_MAX,
+-};
+-
+-#define MAX_CLKS 2
+-
+-struct scp_domain_data {
+- const char *name;
+- u32 sta_mask;
+- int ctl_offs;
+- u32 sram_pdn_bits;
+- u32 sram_pdn_ack_bits;
+- u32 bus_prot_mask;
+- enum clk_id clk_id[MAX_CLKS];
+- bool active_wakeup;
+-};
+-
+-static const struct scp_domain_data scp_domain_data[] __initconst = {
+- [MT8173_POWER_DOMAIN_VDEC] = {
+- .name = "vdec",
+- .sta_mask = PWR_STATUS_VDEC,
+- .ctl_offs = SPM_VDE_PWR_CON,
+- .sram_pdn_bits = GENMASK(11, 8),
+- .sram_pdn_ack_bits = GENMASK(12, 12),
+- .clk_id = {MT8173_CLK_MM},
+- },
+- [MT8173_POWER_DOMAIN_VENC] = {
+- .name = "venc",
+- .sta_mask = PWR_STATUS_VENC,
+- .ctl_offs = SPM_VEN_PWR_CON,
+- .sram_pdn_bits = GENMASK(11, 8),
+- .sram_pdn_ack_bits = GENMASK(15, 12),
+- .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC},
+- },
+- [MT8173_POWER_DOMAIN_ISP] = {
+- .name = "isp",
+- .sta_mask = PWR_STATUS_ISP,
+- .ctl_offs = SPM_ISP_PWR_CON,
+- .sram_pdn_bits = GENMASK(11, 8),
+- .sram_pdn_ack_bits = GENMASK(13, 12),
+- .clk_id = {MT8173_CLK_MM},
+- },
+- [MT8173_POWER_DOMAIN_MM] = {
+- .name = "mm",
+- .sta_mask = PWR_STATUS_DISP,
+- .ctl_offs = SPM_DIS_PWR_CON,
+- .sram_pdn_bits = GENMASK(11, 8),
+- .sram_pdn_ack_bits = GENMASK(12, 12),
+- .clk_id = {MT8173_CLK_MM},
+- .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
+- MT8173_TOP_AXI_PROT_EN_MM_M1,
+- },
+- [MT8173_POWER_DOMAIN_VENC_LT] = {
+- .name = "venc_lt",
+- .sta_mask = PWR_STATUS_VENC_LT,
+- .ctl_offs = SPM_VEN2_PWR_CON,
+- .sram_pdn_bits = GENMASK(11, 8),
+- .sram_pdn_ack_bits = GENMASK(15, 12),
+- .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC_LT},
+- },
+- [MT8173_POWER_DOMAIN_AUDIO] = {
+- .name = "audio",
+- .sta_mask = PWR_STATUS_AUDIO,
+- .ctl_offs = SPM_AUDIO_PWR_CON,
+- .sram_pdn_bits = GENMASK(11, 8),
+- .sram_pdn_ack_bits = GENMASK(15, 12),
+- .clk_id = {MT8173_CLK_NONE},
+- },
+- [MT8173_POWER_DOMAIN_USB] = {
+- .name = "usb",
+- .sta_mask = PWR_STATUS_USB,
+- .ctl_offs = SPM_USB_PWR_CON,
+- .sram_pdn_bits = GENMASK(11, 8),
+- .sram_pdn_ack_bits = GENMASK(15, 12),
+- .clk_id = {MT8173_CLK_NONE},
+- .active_wakeup = true,
+- },
+- [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
+- .name = "mfg_async",
+- .sta_mask = PWR_STATUS_MFG_ASYNC,
+- .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
+- .sram_pdn_bits = GENMASK(11, 8),
+- .sram_pdn_ack_bits = 0,
+- .clk_id = {MT8173_CLK_MFG},
+- },
+- [MT8173_POWER_DOMAIN_MFG_2D] = {
+- .name = "mfg_2d",
+- .sta_mask = PWR_STATUS_MFG_2D,
+- .ctl_offs = SPM_MFG_2D_PWR_CON,
+- .sram_pdn_bits = GENMASK(11, 8),
+- .sram_pdn_ack_bits = GENMASK(13, 12),
+- .clk_id = {MT8173_CLK_NONE},
+- },
+- [MT8173_POWER_DOMAIN_MFG] = {
+- .name = "mfg",
+- .sta_mask = PWR_STATUS_MFG,
+- .ctl_offs = SPM_MFG_PWR_CON,
+- .sram_pdn_bits = GENMASK(13, 8),
+- .sram_pdn_ack_bits = GENMASK(21, 16),
+- .clk_id = {MT8173_CLK_NONE},
+- .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
+- MT8173_TOP_AXI_PROT_EN_MFG_M0 |
+- MT8173_TOP_AXI_PROT_EN_MFG_M1 |
+- MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
+- },
+-};
+-
+-#define NUM_DOMAINS ARRAY_SIZE(scp_domain_data)
+-
+-struct scp;
+-
+-struct scp_domain {
+- struct generic_pm_domain genpd;
+- struct scp *scp;
+- struct clk *clk[MAX_CLKS];
+- u32 sta_mask;
+- void __iomem *ctl_addr;
+- u32 sram_pdn_bits;
+- u32 sram_pdn_ack_bits;
+- u32 bus_prot_mask;
+- bool active_wakeup;
+-};
+-
+-struct scp {
+- struct scp_domain domains[NUM_DOMAINS];
+- struct genpd_onecell_data pd_data;
+- struct device *dev;
+- void __iomem *base;
+- struct regmap *infracfg;
+-};
+-
+ static int scpsys_domain_is_on(struct scp_domain *scpd)
+ {
+ struct scp *scp = scpd->scp;
+@@ -398,63 +237,89 @@ static bool scpsys_active_wakeup(struct device *dev)
+ return scpd->active_wakeup;
+ }
+
+-static int __init scpsys_probe(struct platform_device *pdev)
++static void init_clks(struct platform_device *pdev, struct clk *clk[CLK_MAX])
++{
++ enum clk_id clk_ids[] = {
++ CLK_MM,
++ CLK_MFG,
++ CLK_VENC,
++ CLK_VENC_LT
++ };
++
++ static const char * const clk_names[] = {
++ "mm",
++ "mfg",
++ "venc",
++ "venc_lt",
++ };
++
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(clk_ids); i++)
++ clk[clk_ids[i]] = devm_clk_get(&pdev->dev, clk_names[i]);
++}
++
++struct scp *init_scp(struct platform_device *pdev,
++ const struct scp_domain_data *scp_domain_data, int num)
+ {
+ struct genpd_onecell_data *pd_data;
+ struct resource *res;
+- int i, j, ret;
++ int i, j;
+ struct scp *scp;
+- struct clk *clk[MT8173_CLK_MAX];
++ struct clk *clk[CLK_MAX];
+
+ scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
+ if (!scp)
+- return -ENOMEM;
++ return ERR_PTR(-ENOMEM);
+
+ scp->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ scp->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(scp->base))
+- return PTR_ERR(scp->base);
+-
+- pd_data = &scp->pd_data;
+-
+- pd_data->domains = devm_kzalloc(&pdev->dev,
+- sizeof(*pd_data->domains) * NUM_DOMAINS, GFP_KERNEL);
+- if (!pd_data->domains)
+- return -ENOMEM;
+-
+- clk[MT8173_CLK_MM] = devm_clk_get(&pdev->dev, "mm");
+- if (IS_ERR(clk[MT8173_CLK_MM]))
+- return PTR_ERR(clk[MT8173_CLK_MM]);
+-
+- clk[MT8173_CLK_MFG] = devm_clk_get(&pdev->dev, "mfg");
+- if (IS_ERR(clk[MT8173_CLK_MFG]))
+- return PTR_ERR(clk[MT8173_CLK_MFG]);
+-
+- clk[MT8173_CLK_VENC] = devm_clk_get(&pdev->dev, "venc");
+- if (IS_ERR(clk[MT8173_CLK_VENC]))
+- return PTR_ERR(clk[MT8173_CLK_VENC]);
+-
+- clk[MT8173_CLK_VENC_LT] = devm_clk_get(&pdev->dev, "venc_lt");
+- if (IS_ERR(clk[MT8173_CLK_VENC_LT]))
+- return PTR_ERR(clk[MT8173_CLK_VENC_LT]);
++ return ERR_CAST(scp->base);
+
+ scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+ "infracfg");
+ if (IS_ERR(scp->infracfg)) {
+ dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n",
+ PTR_ERR(scp->infracfg));
+- return PTR_ERR(scp->infracfg);
++ return ERR_CAST(scp->infracfg);
+ }
+
+- pd_data->num_domains = NUM_DOMAINS;
++ scp->domains = devm_kzalloc(&pdev->dev,
++ sizeof(*scp->domains) * num, GFP_KERNEL);
++ if (!scp->domains)
++ return ERR_PTR(-ENOMEM);
++
++ pd_data = &scp->pd_data;
++
++ pd_data->domains = devm_kzalloc(&pdev->dev,
++ sizeof(*pd_data->domains) * num, GFP_KERNEL);
++ if (!pd_data->domains)
++ return ERR_PTR(-ENOMEM);
+
+- for (i = 0; i < NUM_DOMAINS; i++) {
++ pd_data->num_domains = num;
++
++ init_clks(pdev, clk);
++
++ for (i = 0; i < num; i++) {
+ struct scp_domain *scpd = &scp->domains[i];
+ struct generic_pm_domain *genpd = &scpd->genpd;
+ const struct scp_domain_data *data = &scp_domain_data[i];
+
++ for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) {
++ struct clk *c = clk[data->clk_id[j]];
++
++ if (IS_ERR(c)) {
++ dev_err(&pdev->dev, "%s: clk unavailable\n",
++ data->name);
++ return ERR_CAST(c);
++ }
++
++ scpd->clk[j] = c;
++ }
++
+ pd_data->domains[i] = genpd;
+ scpd->scp = scp;
+
+@@ -464,13 +329,25 @@ static int __init scpsys_probe(struct platform_device *pdev)
+ scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits;
+ scpd->bus_prot_mask = data->bus_prot_mask;
+ scpd->active_wakeup = data->active_wakeup;
+- for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++)
+- scpd->clk[j] = clk[data->clk_id[j]];
+
+ genpd->name = data->name;
+ genpd->power_off = scpsys_power_off;
+ genpd->power_on = scpsys_power_on;
+ genpd->dev_ops.active_wakeup = scpsys_active_wakeup;
++ }
++
++ return scp;
++}
++
++void mtk_register_power_domains(struct platform_device *pdev,
++ struct scp *scp, int num)
++{
++ struct genpd_onecell_data *pd_data;
++ int i, ret;
++
++ for (i = 0; i < num; i++) {
++ struct scp_domain *scpd = &scp->domains[i];
++ struct generic_pm_domain *genpd = &scpd->genpd;
+
+ /*
+ * Initially turn on all domains to make the domains usable
+@@ -489,37 +366,9 @@ static int __init scpsys_probe(struct platform_device *pdev)
+ * valid.
+ */
+
+- ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
+- pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
+- if (ret && IS_ENABLED(CONFIG_PM))
+- dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
+-
+- ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D],
+- pd_data->domains[MT8173_POWER_DOMAIN_MFG]);
+- if (ret && IS_ENABLED(CONFIG_PM))
+- dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
++ pd_data = &scp->pd_data;
+
+ ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
+ if (ret)
+ dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
+-
+- return 0;
+ }
+-
+-static const struct of_device_id of_scpsys_match_tbl[] = {
+- {
+- .compatible = "mediatek,mt8173-scpsys",
+- }, {
+- /* sentinel */
+- }
+-};
+-
+-static struct platform_driver scpsys_drv = {
+- .driver = {
+- .name = "mtk-scpsys",
+- .owner = THIS_MODULE,
+- .of_match_table = of_match_ptr(of_scpsys_match_tbl),
+- },
+-};
+-
+-module_platform_driver_probe(scpsys_drv, scpsys_probe);
+diff --git a/drivers/soc/mediatek/mtk-scpsys.h b/drivers/soc/mediatek/mtk-scpsys.h
+new file mode 100644
+index 0000000..466728d
+--- /dev/null
++++ b/drivers/soc/mediatek/mtk-scpsys.h
+@@ -0,0 +1,54 @@
++#ifndef __DRV_SOC_MTK_H
++#define __DRV_SOC_MTK_H
++
++enum clk_id {
++ CLK_NONE,
++ CLK_MM,
++ CLK_MFG,
++ CLK_VENC,
++ CLK_VENC_LT,
++ CLK_MAX,
++};
++
++#define MAX_CLKS 2
++
++struct scp_domain_data {
++ const char *name;
++ u32 sta_mask;
++ int ctl_offs;
++ u32 sram_pdn_bits;
++ u32 sram_pdn_ack_bits;
++ u32 bus_prot_mask;
++ enum clk_id clk_id[MAX_CLKS];
++ bool active_wakeup;
++};
++
++struct scp;
++
++struct scp_domain {
++ struct generic_pm_domain genpd;
++ struct scp *scp;
++ struct clk *clk[MAX_CLKS];
++ u32 sta_mask;
++ void __iomem *ctl_addr;
++ u32 sram_pdn_bits;
++ u32 sram_pdn_ack_bits;
++ u32 bus_prot_mask;
++ bool active_wakeup;
++};
++
++struct scp {
++ struct scp_domain *domains;
++ struct genpd_onecell_data pd_data;
++ struct device *dev;
++ void __iomem *base;
++ struct regmap *infracfg;
++};
++
++struct scp *init_scp(struct platform_device *pdev,
++ const struct scp_domain_data *scp_domain_data, int num);
++
++void mtk_register_power_domains(struct platform_device *pdev,
++ struct scp *scp, int num);
++
++#endif /* __DRV_SOC_MTK_H */
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0003-soc-mediatek-Init-MT8173-scpsys-driver-earlier.patch b/target/linux/mediatek/patches-4.4/0003-soc-mediatek-Init-MT8173-scpsys-driver-earlier.patch
new file mode 100644
index 0000000000..43ed31c816
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0003-soc-mediatek-Init-MT8173-scpsys-driver-earlier.patch
@@ -0,0 +1,38 @@
+From c359272f86805259c5801385d60fdeea9d629cf9 Mon Sep 17 00:00:00 2001
+From: James Liao <jamesjj.liao@mediatek.com>
+Date: Wed, 30 Dec 2015 14:41:44 +0800
+Subject: [PATCH 03/53] soc: mediatek: Init MT8173 scpsys driver earlier
+
+Some power domain comsumers may init before module_init.
+So the power domain provider (scpsys) need to be initialized
+earlier too.
+
+Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
+---
+ drivers/soc/mediatek/mtk-scpsys-mt8173.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/mediatek/mtk-scpsys-mt8173.c b/drivers/soc/mediatek/mtk-scpsys-mt8173.c
+index 3c7b569..827e696 100644
+--- a/drivers/soc/mediatek/mtk-scpsys-mt8173.c
++++ b/drivers/soc/mediatek/mtk-scpsys-mt8173.c
+@@ -176,4 +176,15 @@ static struct platform_driver scpsys_drv = {
+ },
+ };
+
+-module_platform_driver_probe(scpsys_drv, scpsys_probe);
++static int __init scpsys_drv_init(void)
++{
++ return platform_driver_probe(&scpsys_drv, scpsys_probe);
++}
++
++static void __exit scpsys_drv_exit(void)
++{
++ platform_driver_unregister(&scpsys_drv);
++}
++
++subsys_initcall(scpsys_drv_init);
++module_exit(scpsys_drv_exit);
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch b/target/linux/mediatek/patches-4.4/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch
new file mode 100644
index 0000000000..79f849f3c9
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch
@@ -0,0 +1,50 @@
+From f371844374fff273f817d6c43f679606417af59e Mon Sep 17 00:00:00 2001
+From: Shunli Wang <shunli.wang@mediatek.com>
+Date: Wed, 30 Dec 2015 14:41:45 +0800
+Subject: [PATCH 04/53] soc: mediatek: Add MT2701 power dt-bindings
+
+Add power dt-bindings for MT2701.
+
+Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
+Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
+---
+ include/dt-bindings/power/mt2701-power.h | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+ create mode 100644 include/dt-bindings/power/mt2701-power.h
+
+diff --git a/include/dt-bindings/power/mt2701-power.h b/include/dt-bindings/power/mt2701-power.h
+new file mode 100644
+index 0000000..64cc826
+--- /dev/null
++++ b/include/dt-bindings/power/mt2701-power.h
+@@ -0,0 +1,27 @@
++/*
++ * Copyright (C) 2015 MediaTek Inc.
++ *
++ * This program is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef _DT_BINDINGS_POWER_MT2701_POWER_H
++#define _DT_BINDINGS_POWER_MT2701_POWER_H
++
++#define MT2701_POWER_DOMAIN_CONN 0
++#define MT2701_POWER_DOMAIN_DISP 1
++#define MT2701_POWER_DOMAIN_MFG 2
++#define MT2701_POWER_DOMAIN_VDEC 3
++#define MT2701_POWER_DOMAIN_ISP 4
++#define MT2701_POWER_DOMAIN_BDP 5
++#define MT2701_POWER_DOMAIN_ETH 6
++#define MT2701_POWER_DOMAIN_HIF 7
++#define MT2701_POWER_DOMAIN_IFR_MSC 8
++
++#endif /* _DT_BINDINGS_POWER_MT2701_POWER_H */
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0005-soc-mediatek-Add-MT2701-MT7623-scpsys-driver.patch b/target/linux/mediatek/patches-4.4/0005-soc-mediatek-Add-MT2701-MT7623-scpsys-driver.patch
new file mode 100644
index 0000000000..6bbeecbb00
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0005-soc-mediatek-Add-MT2701-MT7623-scpsys-driver.patch
@@ -0,0 +1,214 @@
+From c6711565985f359d7d3c05f01f081e4c216902de Mon Sep 17 00:00:00 2001
+From: Shunli Wang <shunli.wang@mediatek.com>
+Date: Wed, 30 Dec 2015 14:41:46 +0800
+Subject: [PATCH 05/53] soc: mediatek: Add MT2701/MT7623 scpsys driver
+
+Add scpsys driver for MT2701 and MT7623.
+
+Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
+Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
+---
+ drivers/soc/mediatek/Kconfig | 11 ++
+ drivers/soc/mediatek/Makefile | 1 +
+ drivers/soc/mediatek/mtk-scpsys-mt2701.c | 161 ++++++++++++++++++++++++++++++
+ 3 files changed, 173 insertions(+)
+ create mode 100644 drivers/soc/mediatek/mtk-scpsys-mt2701.c
+
+diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
+index eca6fb7..92cf838 100644
+--- a/drivers/soc/mediatek/Kconfig
++++ b/drivers/soc/mediatek/Kconfig
+@@ -39,3 +39,14 @@ config MTK_SCPSYS_MT8173
+ driver.
+ The System Control Processor System (SCPSYS) has several power
+ management related tasks in the system.
++
++config MTK_SCPSYS_MT2701
++ bool "SCPSYS Support MediaTek MT2701 and MT7623"
++ depends on ARCH_MEDIATEK || COMPILE_TEST
++ select MTK_SCPSYS
++ default ARCH_MEDIATEK
++ help
++ Say yes here to add support for the MT2701/MT7623 SCPSYS power
++ domain driver.
++ The System Control Processor System (SCPSYS) has several power
++ management related tasks in the system.
+diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
+index 3b22baa..822986d 100644
+--- a/drivers/soc/mediatek/Makefile
++++ b/drivers/soc/mediatek/Makefile
+@@ -2,3 +2,4 @@ obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
+ obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
+ obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
+ obj-$(CONFIG_MTK_SCPSYS_MT8173) += mtk-scpsys-mt8173.o
++obj-$(CONFIG_MTK_SCPSYS_MT2701) += mtk-scpsys-mt2701.o
+diff --git a/drivers/soc/mediatek/mtk-scpsys-mt2701.c b/drivers/soc/mediatek/mtk-scpsys-mt2701.c
+new file mode 100644
+index 0000000..339d5b8
+--- /dev/null
++++ b/drivers/soc/mediatek/mtk-scpsys-mt2701.c
+@@ -0,0 +1,161 @@
++/*
++ * Copyright (c) 2015 Mediatek, Shunli Wang <shunli.wang@mediatek.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++#include <linux/mfd/syscon.h>
++#include <linux/module.h>
++#include <linux/of_device.h>
++#include <linux/pm_domain.h>
++#include <linux/soc/mediatek/infracfg.h>
++#include <dt-bindings/power/mt2701-power.h>
++
++#include "mtk-scpsys.h"
++
++#define SPM_VDE_PWR_CON 0x0210
++#define SPM_MFG_PWR_CON 0x0214
++#define SPM_ISP_PWR_CON 0x0238
++#define SPM_DIS_PWR_CON 0x023C
++#define SPM_CONN_PWR_CON 0x0280
++#define SPM_BDP_PWR_CON 0x029C
++#define SPM_ETH_PWR_CON 0x02A0
++#define SPM_HIF_PWR_CON 0x02A4
++#define SPM_IFR_MSC_PWR_CON 0x02A8
++#define SPM_PWR_STATUS 0x060c
++#define SPM_PWR_STATUS_2ND 0x0610
++
++#define CONN_PWR_STA_MASK BIT(1)
++#define DIS_PWR_STA_MASK BIT(3)
++#define MFG_PWR_STA_MASK BIT(4)
++#define ISP_PWR_STA_MASK BIT(5)
++#define VDE_PWR_STA_MASK BIT(7)
++#define BDP_PWR_STA_MASK BIT(14)
++#define ETH_PWR_STA_MASK BIT(15)
++#define HIF_PWR_STA_MASK BIT(16)
++#define IFR_MSC_PWR_STA_MASK BIT(17)
++
++#define MT2701_TOP_AXI_PROT_EN_CONN 0x0104
++#define MT2701_TOP_AXI_PROT_EN_DISP 0x0002
++
++static const struct scp_domain_data scp_domain_data[] = {
++ [MT2701_POWER_DOMAIN_CONN] = {
++ .name = "conn",
++ .sta_mask = CONN_PWR_STA_MASK,
++ .ctl_offs = SPM_CONN_PWR_CON,
++ .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN,
++ .active_wakeup = true,
++ },
++ [MT2701_POWER_DOMAIN_DISP] = {
++ .name = "disp",
++ .sta_mask = DIS_PWR_STA_MASK,
++ .ctl_offs = SPM_DIS_PWR_CON,
++ .sram_pdn_bits = GENMASK(11, 8),
++ .clk_id = {CLK_MM},
++ .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_DISP,
++ .active_wakeup = true,
++ },
++ [MT2701_POWER_DOMAIN_MFG] = {
++ .name = "mfg",
++ .sta_mask = MFG_PWR_STA_MASK,
++ .ctl_offs = SPM_MFG_PWR_CON,
++ .sram_pdn_bits = GENMASK(11, 8),
++ .sram_pdn_ack_bits = GENMASK(12, 12),
++ .active_wakeup = true,
++ },
++ [MT2701_POWER_DOMAIN_VDEC] = {
++ .name = "vdec",
++ .sta_mask = VDE_PWR_STA_MASK,
++ .ctl_offs = SPM_VDE_PWR_CON,
++ .sram_pdn_bits = GENMASK(11, 8),
++ .sram_pdn_ack_bits = GENMASK(12, 12),
++ .clk_id = {CLK_MM},
++ .active_wakeup = true,
++ },
++ [MT2701_POWER_DOMAIN_ISP] = {
++ .name = "isp",
++ .sta_mask = ISP_PWR_STA_MASK,
++ .ctl_offs = SPM_ISP_PWR_CON,
++ .sram_pdn_bits = GENMASK(11, 8),
++ .sram_pdn_ack_bits = GENMASK(13, 12),
++ .active_wakeup = true,
++ },
++ [MT2701_POWER_DOMAIN_BDP] = {
++ .name = "bdp",
++ .sta_mask = BDP_PWR_STA_MASK,
++ .ctl_offs = SPM_BDP_PWR_CON,
++ .sram_pdn_bits = GENMASK(11, 8),
++ .active_wakeup = true,
++ },
++ [MT2701_POWER_DOMAIN_ETH] = {
++ .name = "eth",
++ .sta_mask = ETH_PWR_STA_MASK,
++ .ctl_offs = SPM_ETH_PWR_CON,
++ .sram_pdn_bits = GENMASK(11, 8),
++ .sram_pdn_ack_bits = GENMASK(15, 12),
++ .active_wakeup = true,
++ },
++ [MT2701_POWER_DOMAIN_HIF] = {
++ .name = "hif",
++ .sta_mask = HIF_PWR_STA_MASK,
++ .ctl_offs = SPM_HIF_PWR_CON,
++ .sram_pdn_bits = GENMASK(11, 8),
++ .sram_pdn_ack_bits = GENMASK(15, 12),
++ .active_wakeup = true,
++ },
++ [MT2701_POWER_DOMAIN_IFR_MSC] = {
++ .name = "ifr_msc",
++ .sta_mask = IFR_MSC_PWR_STA_MASK,
++ .ctl_offs = SPM_IFR_MSC_PWR_CON,
++ .active_wakeup = true,
++ },
++};
++
++#define NUM_DOMAINS ARRAY_SIZE(scp_domain_data)
++
++static int __init scpsys_probe(struct platform_device *pdev)
++{
++ struct scp *scp;
++
++ scp = init_scp(pdev, scp_domain_data, NUM_DOMAINS);
++ if (IS_ERR(scp))
++ return PTR_ERR(scp);
++
++ mtk_register_power_domains(pdev, scp, NUM_DOMAINS);
++
++ return 0;
++}
++
++static const struct of_device_id of_scpsys_match_tbl[] = {
++ {
++ .compatible = "mediatek,mt2701-scpsys",
++ }, {
++ /* sentinel */
++ }
++};
++MODULE_DEVICE_TABLE(of, of_scpsys_match_tbl);
++
++static struct platform_driver scpsys_drv = {
++ .driver = {
++ .name = "mtk-scpsys-mt2701",
++ .owner = THIS_MODULE,
++ .of_match_table = of_match_ptr(of_scpsys_match_tbl),
++ },
++ .probe = scpsys_probe,
++};
++
++static int __init scpsys_init(void)
++{
++ return platform_driver_register(&scpsys_drv);
++}
++
++subsys_initcall(scpsys_init);
++
++MODULE_DESCRIPTION("MediaTek MT2701 scpsys driver");
++MODULE_LICENSE("GPL v2");
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0006-clk-mediatek-Refine-the-makefile-to-support-multiple.patch b/target/linux/mediatek/patches-4.4/0006-clk-mediatek-Refine-the-makefile-to-support-multiple.patch
new file mode 100644
index 0000000000..6b00dc2274
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0006-clk-mediatek-Refine-the-makefile-to-support-multiple.patch
@@ -0,0 +1,71 @@
+From 0c39bcd17fa6ce723f56ad3756b4bb36c4690342 Mon Sep 17 00:00:00 2001
+From: James Liao <jamesjj.liao@mediatek.com>
+Date: Tue, 5 Jan 2016 14:30:17 +0800
+Subject: [PATCH 06/53] clk: mediatek: Refine the makefile to support multiple
+ clock drivers
+
+Add a Kconfig to define clock configuration for each SoC, and
+modify the Makefile to build drivers that only selected in config.
+
+Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
+Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
+---
+ drivers/clk/Kconfig | 1 +
+ drivers/clk/mediatek/Kconfig | 23 +++++++++++++++++++++++
+ drivers/clk/mediatek/Makefile | 6 +++---
+ 3 files changed, 27 insertions(+), 3 deletions(-)
+ create mode 100644 drivers/clk/mediatek/Kconfig
+
+diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
+index c3e3a02..b7a37dc 100644
+--- a/drivers/clk/Kconfig
++++ b/drivers/clk/Kconfig
+@@ -198,3 +198,4 @@ source "drivers/clk/mvebu/Kconfig"
+
+ source "drivers/clk/samsung/Kconfig"
+ source "drivers/clk/tegra/Kconfig"
++source "drivers/clk/mediatek/Kconfig"
+diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
+new file mode 100644
+index 0000000..dc224e6
+--- /dev/null
++++ b/drivers/clk/mediatek/Kconfig
+@@ -0,0 +1,23 @@
++#
++# MediaTek SoC drivers
++#
++config COMMON_CLK_MEDIATEK
++ bool
++ ---help---
++ Mediatek SoCs' clock support.
++
++config COMMON_CLK_MT8135
++ bool "Clock driver for Mediatek MT8135"
++ depends on COMMON_CLK
++ select COMMON_CLK_MEDIATEK
++ default ARCH_MEDIATEK
++ ---help---
++ This driver supports Mediatek MT8135 clocks.
++
++config COMMON_CLK_MT8173
++ bool "Clock driver for Mediatek MT8173"
++ depends on COMMON_CLK
++ select COMMON_CLK_MEDIATEK
++ default ARCH_MEDIATEK
++ ---help---
++ This driver supports Mediatek MT8173 clocks.
+diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
+index 95fdfac..32e7222 100644
+--- a/drivers/clk/mediatek/Makefile
++++ b/drivers/clk/mediatek/Makefile
+@@ -1,4 +1,4 @@
+-obj-y += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o
++obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o
+ obj-$(CONFIG_RESET_CONTROLLER) += reset.o
+-obj-y += clk-mt8135.o
+-obj-y += clk-mt8173.o
++obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
++obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0007-dt-bindings-ARM-Mediatek-Document-bindings-for-MT270.patch b/target/linux/mediatek/patches-4.4/0007-dt-bindings-ARM-Mediatek-Document-bindings-for-MT270.patch
new file mode 100644
index 0000000000..3d6bc709cf
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0007-dt-bindings-ARM-Mediatek-Document-bindings-for-MT270.patch
@@ -0,0 +1,198 @@
+From d7e96f87f66c571e9f4171ecd89c656fbd2de89b Mon Sep 17 00:00:00 2001
+From: James Liao <jamesjj.liao@mediatek.com>
+Date: Tue, 5 Jan 2016 14:30:18 +0800
+Subject: [PATCH 07/53] dt-bindings: ARM: Mediatek: Document bindings for
+ MT2701
+
+This patch adds the binding documentation for apmixedsys, bdpsys,
+ethsys, hifsys, imgsys, infracfg, mmsys, pericfg, topckgen and
+vdecsys for Mediatek MT2701.
+
+Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
+---
+ .../bindings/arm/mediatek/mediatek,apmixedsys.txt | 1 +
+ .../bindings/arm/mediatek/mediatek,bdpsys.txt | 22 ++++++++++++++++++++
+ .../bindings/arm/mediatek/mediatek,ethsys.txt | 22 ++++++++++++++++++++
+ .../bindings/arm/mediatek/mediatek,hifsys.txt | 22 ++++++++++++++++++++
+ .../bindings/arm/mediatek/mediatek,imgsys.txt | 1 +
+ .../bindings/arm/mediatek/mediatek,infracfg.txt | 1 +
+ .../bindings/arm/mediatek/mediatek,mmsys.txt | 1 +
+ .../bindings/arm/mediatek/mediatek,pericfg.txt | 1 +
+ .../bindings/arm/mediatek/mediatek,topckgen.txt | 1 +
+ .../bindings/arm/mediatek/mediatek,vdecsys.txt | 1 +
+ 10 files changed, 73 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt
+ create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
+ create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
+
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
+index 936166f..a701e19 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
+@@ -6,6 +6,7 @@ The Mediatek apmixedsys controller provides the PLLs to the system.
+ Required Properties:
+
+ - compatible: Should be:
++ - "mediatek,mt2701-apmixedsys"
+ - "mediatek,mt8135-apmixedsys"
+ - "mediatek,mt8173-apmixedsys"
+ - #clock-cells: Must be 1
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt
+new file mode 100644
+index 0000000..4137196
+--- /dev/null
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt
+@@ -0,0 +1,22 @@
++Mediatek bdpsys controller
++============================
++
++The Mediatek bdpsys controller provides various clocks to the system.
++
++Required Properties:
++
++- compatible: Should be:
++ - "mediatek,mt2701-bdpsys", "syscon"
++- #clock-cells: Must be 1
++
++The bdpsys controller uses the common clk binding from
++Documentation/devicetree/bindings/clock/clock-bindings.txt
++The available clocks are defined in dt-bindings/clock/mt*-clk.h.
++
++Example:
++
++bdpsys: clock-controller@1c000000 {
++ compatible = "mediatek,mt2701-bdpsys", "syscon";
++ reg = <0 0x1c000000 0 0x1000>;
++ #clock-cells = <1>;
++};
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
+new file mode 100644
+index 0000000..768f3a5
+--- /dev/null
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
+@@ -0,0 +1,22 @@
++Mediatek ethsys controller
++============================
++
++The Mediatek ethsys controller provides various clocks to the system.
++
++Required Properties:
++
++- compatible: Should be:
++ - "mediatek,mt2701-ethsys", "syscon"
++- #clock-cells: Must be 1
++
++The ethsys controller uses the common clk binding from
++Documentation/devicetree/bindings/clock/clock-bindings.txt
++The available clocks are defined in dt-bindings/clock/mt*-clk.h.
++
++Example:
++
++ethsys: clock-controller@1b000000 {
++ compatible = "mediatek,mt2701-ethsys", "syscon";
++ reg = <0 0x1b000000 0 0x1000>;
++ #clock-cells = <1>;
++};
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
+new file mode 100644
+index 0000000..b7a39b6
+--- /dev/null
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
+@@ -0,0 +1,22 @@
++Mediatek hifsys controller
++============================
++
++The Mediatek hifsys controller provides various clocks to the system.
++
++Required Properties:
++
++- compatible: Should be:
++ - "mediatek,mt2701-hifsys", "syscon"
++- #clock-cells: Must be 1
++
++The hifsys controller uses the common clk binding from
++Documentation/devicetree/bindings/clock/clock-bindings.txt
++The available clocks are defined in dt-bindings/clock/mt*-clk.h.
++
++Example:
++
++hifsys: clock-controller@1a000000 {
++ compatible = "mediatek,mt2701-hifsys", "syscon";
++ reg = <0 0x1a000000 0 0x1000>;
++ #clock-cells = <1>;
++};
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
+index b1f2ce1..9bda7f7 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
+@@ -6,6 +6,7 @@ The Mediatek imgsys controller provides various clocks to the system.
+ Required Properties:
+
+ - compatible: Should be:
++ - "mediatek,mt2701-imgsys", "syscon"
+ - "mediatek,mt8173-imgsys", "syscon"
+ - #clock-cells: Must be 1
+
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
+index f6cd3e4..2f11a69 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
+@@ -7,6 +7,7 @@ outputs to the system.
+ Required Properties:
+
+ - compatible: Should be:
++ - "mediatek,mt2701-infracfg", "syscon"
+ - "mediatek,mt8135-infracfg", "syscon"
+ - "mediatek,mt8173-infracfg", "syscon"
+ - #clock-cells: Must be 1
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
+index 4385946..c9d9d43 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
+@@ -6,6 +6,7 @@ The Mediatek mmsys controller provides various clocks to the system.
+ Required Properties:
+
+ - compatible: Should be:
++ - "mediatek,mt2701-mmsys", "syscon"
+ - "mediatek,mt8173-mmsys", "syscon"
+ - #clock-cells: Must be 1
+
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
+index f25b854..d3454cd 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
+@@ -7,6 +7,7 @@ outputs to the system.
+ Required Properties:
+
+ - compatible: Should be:
++ - "mediatek,mt2701-pericfg", "syscon"
+ - "mediatek,mt8135-pericfg", "syscon"
+ - "mediatek,mt8173-pericfg", "syscon"
+ - #clock-cells: Must be 1
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
+index f9e9179..602e5bc 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
+@@ -6,6 +6,7 @@ The Mediatek topckgen controller provides various clocks to the system.
+ Required Properties:
+
+ - compatible: Should be:
++ - "mediatek,mt2701-topckgen"
+ - "mediatek,mt8135-topckgen"
+ - "mediatek,mt8173-topckgen"
+ - #clock-cells: Must be 1
+diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
+index 1faacf1..f5b1e7d 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
+@@ -6,6 +6,7 @@ The Mediatek vdecsys controller provides various clocks to the system.
+ Required Properties:
+
+ - compatible: Should be:
++ - "mediatek,mt2701-vdecsys", "syscon"
+ - "mediatek,mt8173-vdecsys", "syscon"
+ - #clock-cells: Must be 1
+
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0008-clk-mediatek-Add-dt-bindings-for-MT2701-clocks.patch b/target/linux/mediatek/patches-4.4/0008-clk-mediatek-Add-dt-bindings-for-MT2701-clocks.patch
new file mode 100644
index 0000000000..0cbe27ddbb
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0008-clk-mediatek-Add-dt-bindings-for-MT2701-clocks.patch
@@ -0,0 +1,505 @@
+From 2fcbc15da2f13164e0851b9c7fae290249f0b44d Mon Sep 17 00:00:00 2001
+From: Shunli Wang <shunli.wang@mediatek.com>
+Date: Tue, 5 Jan 2016 14:30:19 +0800
+Subject: [PATCH 08/53] clk: mediatek: Add dt-bindings for MT2701 clocks
+
+Add MT2701 clock dt-bindings, include topckgen, apmixedsys,
+infracfg, pericfg and subsystem clocks.
+
+Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
+Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
+---
+ include/dt-bindings/clock/mt2701-clk.h | 481 ++++++++++++++++++++++++++++++++
+ 1 file changed, 481 insertions(+)
+ create mode 100644 include/dt-bindings/clock/mt2701-clk.h
+
+diff --git a/include/dt-bindings/clock/mt2701-clk.h b/include/dt-bindings/clock/mt2701-clk.h
+new file mode 100644
+index 0000000..50972d1
+--- /dev/null
++++ b/include/dt-bindings/clock/mt2701-clk.h
+@@ -0,0 +1,481 @@
++/*
++ * Copyright (c) 2014 MediaTek Inc.
++ * Author: Shunli Wang <shunli.wang@mediatek.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef _DT_BINDINGS_CLK_MT2701_H
++#define _DT_BINDINGS_CLK_MT2701_H
++
++/* TOPCKGEN */
++#define CLK_TOP_SYSPLL 1
++#define CLK_TOP_SYSPLL_D2 2
++#define CLK_TOP_SYSPLL_D3 3
++#define CLK_TOP_SYSPLL_D5 4
++#define CLK_TOP_SYSPLL_D7 5
++#define CLK_TOP_SYSPLL1_D2 6
++#define CLK_TOP_SYSPLL1_D4 7
++#define CLK_TOP_SYSPLL1_D8 8
++#define CLK_TOP_SYSPLL1_D16 9
++#define CLK_TOP_SYSPLL2_D2 10
++#define CLK_TOP_SYSPLL2_D4 11
++#define CLK_TOP_SYSPLL2_D8 12
++#define CLK_TOP_SYSPLL3_D2 13
++#define CLK_TOP_SYSPLL3_D4 14
++#define CLK_TOP_SYSPLL4_D2 15
++#define CLK_TOP_SYSPLL4_D4 16
++#define CLK_TOP_UNIVPLL 17
++#define CLK_TOP_UNIVPLL_D2 18
++#define CLK_TOP_UNIVPLL_D3 19
++#define CLK_TOP_UNIVPLL_D5 20
++#define CLK_TOP_UNIVPLL_D7 21
++#define CLK_TOP_UNIVPLL_D26 22
++#define CLK_TOP_UNIVPLL_D52 23
++#define CLK_TOP_UNIVPLL_D108 24
++#define CLK_TOP_USB_PHY48M 25
++#define CLK_TOP_UNIVPLL1_D2 26
++#define CLK_TOP_UNIVPLL1_D4 27
++#define CLK_TOP_UNIVPLL1_D8 28
++#define CLK_TOP_UNIVPLL2_D2 29
++#define CLK_TOP_UNIVPLL2_D4 30
++#define CLK_TOP_UNIVPLL2_D8 31
++#define CLK_TOP_UNIVPLL2_D16 32
++#define CLK_TOP_UNIVPLL2_D32 33
++#define CLK_TOP_UNIVPLL3_D2 34
++#define CLK_TOP_UNIVPLL3_D4 35
++#define CLK_TOP_UNIVPLL3_D8 36
++#define CLK_TOP_MSDCPLL 37
++#define CLK_TOP_MSDCPLL_D2 38
++#define CLK_TOP_MSDCPLL_D4 39
++#define CLK_TOP_MSDCPLL_D8 40
++#define CLK_TOP_MMPLL 41
++#define CLK_TOP_MMPLL_D2 42
++#define CLK_TOP_DMPLL 43
++#define CLK_TOP_DMPLL_D2 44
++#define CLK_TOP_DMPLL_D4 45
++#define CLK_TOP_DMPLL_X2 46
++#define CLK_TOP_TVDPLL 47
++#define CLK_TOP_TVDPLL_D2 48
++#define CLK_TOP_TVDPLL_D4 49
++#define CLK_TOP_TVD2PLL 50
++#define CLK_TOP_TVD2PLL_D2 51
++#define CLK_TOP_HADDS2PLL_98M 52
++#define CLK_TOP_HADDS2PLL_294M 53
++#define CLK_TOP_HADDS2_FB 54
++#define CLK_TOP_MIPIPLL_D2 55
++#define CLK_TOP_MIPIPLL_D4 56
++#define CLK_TOP_HDMIPLL 57
++#define CLK_TOP_HDMIPLL_D2 58
++#define CLK_TOP_HDMIPLL_D3 59
++#define CLK_TOP_HDMI_SCL_RX 60
++#define CLK_TOP_HDMI_0_PIX340M 61
++#define CLK_TOP_HDMI_0_DEEP340M 62
++#define CLK_TOP_HDMI_0_PLL340M 63
++#define CLK_TOP_AUD1PLL_98M 64
++#define CLK_TOP_AUD2PLL_90M 65
++#define CLK_TOP_AUDPLL 66
++#define CLK_TOP_AUDPLL_D4 67
++#define CLK_TOP_AUDPLL_D8 68
++#define CLK_TOP_AUDPLL_D16 69
++#define CLK_TOP_AUDPLL_D24 70
++#define CLK_TOP_ETHPLL_500M 71
++#define CLK_TOP_VDECPLL 72
++#define CLK_TOP_VENCPLL 73
++#define CLK_TOP_MIPIPLL 74
++#define CLK_TOP_ARMPLL_1P3G 75
++
++#define CLK_TOP_MM_SEL 76
++#define CLK_TOP_DDRPHYCFG_SEL 77
++#define CLK_TOP_MEM_SEL 78
++#define CLK_TOP_AXI_SEL 79
++#define CLK_TOP_CAMTG_SEL 80
++#define CLK_TOP_MFG_SEL 81
++#define CLK_TOP_VDEC_SEL 82
++#define CLK_TOP_PWM_SEL 83
++#define CLK_TOP_MSDC30_0_SEL 84
++#define CLK_TOP_USB20_SEL 85
++#define CLK_TOP_SPI0_SEL 86
++#define CLK_TOP_UART_SEL 87
++#define CLK_TOP_AUDINTBUS_SEL 88
++#define CLK_TOP_AUDIO_SEL 89
++#define CLK_TOP_MSDC30_2_SEL 90
++#define CLK_TOP_MSDC30_1_SEL 91
++#define CLK_TOP_DPI1_SEL 92
++#define CLK_TOP_DPI0_SEL 93
++#define CLK_TOP_SCP_SEL 94
++#define CLK_TOP_PMICSPI_SEL 95
++#define CLK_TOP_APLL_SEL 96
++#define CLK_TOP_HDMI_SEL 97
++#define CLK_TOP_TVE_SEL 98
++#define CLK_TOP_EMMC_HCLK_SEL 99
++#define CLK_TOP_NFI2X_SEL 100
++#define CLK_TOP_RTC_SEL 101
++#define CLK_TOP_OSD_SEL 102
++#define CLK_TOP_NR_SEL 103
++#define CLK_TOP_DI_SEL 104
++#define CLK_TOP_FLASH_SEL 105
++#define CLK_TOP_ASM_M_SEL 106
++#define CLK_TOP_ASM_I_SEL 107
++#define CLK_TOP_INTDIR_SEL 108
++#define CLK_TOP_HDMIRX_BIST_SEL 109
++#define CLK_TOP_ETHIF_SEL 110
++#define CLK_TOP_MS_CARD_SEL 111
++#define CLK_TOP_ASM_H_SEL 112
++#define CLK_TOP_SPI1_SEL 113
++#define CLK_TOP_CMSYS_SEL 114
++#define CLK_TOP_MSDC30_3_SEL 115
++#define CLK_TOP_HDMIRX26_24_SEL 116
++#define CLK_TOP_AUD2DVD_SEL 117
++#define CLK_TOP_8BDAC_SEL 118
++#define CLK_TOP_SPI2_SEL 119
++#define CLK_TOP_AUD_MUX1_SEL 120
++#define CLK_TOP_AUD_MUX2_SEL 121
++#define CLK_TOP_AUDPLL_MUX_SEL 122
++#define CLK_TOP_AUD_K1_SRC_SEL 123
++#define CLK_TOP_AUD_K2_SRC_SEL 124
++#define CLK_TOP_AUD_K3_SRC_SEL 125
++#define CLK_TOP_AUD_K4_SRC_SEL 126
++#define CLK_TOP_AUD_K5_SRC_SEL 127
++#define CLK_TOP_AUD_K6_SRC_SEL 128
++#define CLK_TOP_PADMCLK_SEL 129
++#define CLK_TOP_AUD_EXTCK1_DIV 130
++#define CLK_TOP_AUD_EXTCK2_DIV 131
++#define CLK_TOP_AUD_MUX1_DIV 132
++#define CLK_TOP_AUD_MUX2_DIV 133
++#define CLK_TOP_AUD_K1_SRC_DIV 134
++#define CLK_TOP_AUD_K2_SRC_DIV 135
++#define CLK_TOP_AUD_K3_SRC_DIV 136
++#define CLK_TOP_AUD_K4_SRC_DIV 137
++#define CLK_TOP_AUD_K5_SRC_DIV 138
++#define CLK_TOP_AUD_K6_SRC_DIV 139
++#define CLK_TOP_AUD_I2S1_MCLK 140
++#define CLK_TOP_AUD_I2S2_MCLK 141
++#define CLK_TOP_AUD_I2S3_MCLK 142
++#define CLK_TOP_AUD_I2S4_MCLK 143
++#define CLK_TOP_AUD_I2S5_MCLK 144
++#define CLK_TOP_AUD_I2S6_MCLK 145
++#define CLK_TOP_AUD_48K_TIMING 146
++#define CLK_TOP_AUD_44K_TIMING 147
++
++#define CLK_TOP_32K_INTERNAL 148
++#define CLK_TOP_32K_EXTERNAL 149
++#define CLK_TOP_CLK26M_D8 150
++#define CLK_TOP_8BDAC 151
++#define CLK_TOP_WBG_DIG_416M 152
++#define CLK_TOP_DPI 153
++#define CLK_TOP_HDMITX_CLKDIG_CTS 154
++#define CLK_TOP_NR 155
++
++/* APMIXEDSYS */
++
++#define CLK_APMIXED_ARMPLL 1
++#define CLK_APMIXED_MAINPLL 2
++#define CLK_APMIXED_UNIVPLL 3
++#define CLK_APMIXED_MMPLL 4
++#define CLK_APMIXED_MSDCPLL 5
++#define CLK_APMIXED_TVDPLL 6
++#define CLK_APMIXED_AUD1PLL 7
++#define CLK_APMIXED_TRGPLL 8
++#define CLK_APMIXED_ETHPLL 9
++#define CLK_APMIXED_VDECPLL 10
++#define CLK_APMIXED_HADDS2PLL 11
++#define CLK_APMIXED_AUD2PLL 12
++#define CLK_APMIXED_TVD2PLL 13
++#define CLK_APMIXED_NR 14
++
++/* DDRPHY */
++
++#define CLK_DDRPHY_VENCPLL 1
++#define CLK_DDRPHY_NR 2
++
++/* INFRACFG */
++
++#define CLK_INFRA_DBG 1
++#define CLK_INFRA_SMI 2
++#define CLK_INFRA_QAXI_CM4 3
++#define CLK_INFRA_AUD_SPLIN_B 4
++#define CLK_INFRA_AUDIO 5
++#define CLK_INFRA_EFUSE 6
++#define CLK_INFRA_L2C_SRAM 7
++#define CLK_INFRA_M4U 8
++#define CLK_INFRA_CONNMCU 9
++#define CLK_INFRA_TRNG 10
++#define CLK_INFRA_RAMBUFIF 11
++#define CLK_INFRA_CPUM 12
++#define CLK_INFRA_KP 13
++#define CLK_INFRA_CEC 14
++#define CLK_INFRA_IRRX 15
++#define CLK_INFRA_PMICSPI 16
++#define CLK_INFRA_PMICWRAP 17
++#define CLK_INFRA_DDCCI 18
++#define CLK_INFRA_CLK_13M 19
++#define CLK_INFRA_NR 20
++
++/* PERICFG */
++
++#define CLK_PERI_NFI 1
++#define CLK_PERI_THERM 2
++#define CLK_PERI_PWM1 3
++#define CLK_PERI_PWM2 4
++#define CLK_PERI_PWM3 5
++#define CLK_PERI_PWM4 6
++#define CLK_PERI_PWM5 7
++#define CLK_PERI_PWM6 8
++#define CLK_PERI_PWM7 9
++#define CLK_PERI_PWM 10
++#define CLK_PERI_USB0 11
++#define CLK_PERI_USB1 12
++#define CLK_PERI_AP_DMA 13
++#define CLK_PERI_MSDC30_0 14
++#define CLK_PERI_MSDC30_1 15
++#define CLK_PERI_MSDC30_2 16
++#define CLK_PERI_MSDC30_3 17
++#define CLK_PERI_MSDC50_3 18
++#define CLK_PERI_NLI 19
++#define CLK_PERI_UART0 20
++#define CLK_PERI_UART1 21
++#define CLK_PERI_UART2 22
++#define CLK_PERI_UART3 23
++#define CLK_PERI_BTIF 24
++#define CLK_PERI_I2C0 25
++#define CLK_PERI_I2C1 26
++#define CLK_PERI_I2C2 27
++#define CLK_PERI_I2C3 28
++#define CLK_PERI_AUXADC 29
++#define CLK_PERI_SPI0 30
++#define CLK_PERI_ETH 31
++#define CLK_PERI_USB0_MCU 32
++
++#define CLK_PERI_USB1_MCU 33
++#define CLK_PERI_USB_SLV 34
++#define CLK_PERI_GCPU 35
++#define CLK_PERI_NFI_ECC 36
++#define CLK_PERI_NFI_PAD 37
++#define CLK_PERI_FLASH 38
++#define CLK_PERI_HOST89_INT 39
++#define CLK_PERI_HOST89_SPI 40
++#define CLK_PERI_HOST89_DVD 41
++#define CLK_PERI_SPI1 42
++#define CLK_PERI_SPI2 43
++#define CLK_PERI_FCI 44
++
++#define CLK_PERI_UART0_SEL 45
++#define CLK_PERI_UART1_SEL 46
++#define CLK_PERI_UART2_SEL 47
++#define CLK_PERI_UART3_SEL 48
++#define CLK_PERI_NR 49
++
++/* AUDIO */
++
++#define CLK_AUD_AFE 1
++#define CLK_AUD_LRCK_DETECT 2
++#define CLK_AUD_I2S 3
++#define CLK_AUD_APLL_TUNER 4
++#define CLK_AUD_HDMI 5
++#define CLK_AUD_SPDF 6
++#define CLK_AUD_SPDF2 7
++#define CLK_AUD_APLL 8
++#define CLK_AUD_TML 9
++#define CLK_AUD_AHB_IDLE_EXT 10
++#define CLK_AUD_AHB_IDLE_INT 11
++
++#define CLK_AUD_I2SIN1 12
++#define CLK_AUD_I2SIN2 13
++#define CLK_AUD_I2SIN3 14
++#define CLK_AUD_I2SIN4 15
++#define CLK_AUD_I2SIN5 16
++#define CLK_AUD_I2SIN6 17
++#define CLK_AUD_I2SO1 18
++#define CLK_AUD_I2SO2 19
++#define CLK_AUD_I2SO3 20
++#define CLK_AUD_I2SO4 21
++#define CLK_AUD_I2SO5 22
++#define CLK_AUD_I2SO6 23
++#define CLK_AUD_ASRCI1 24
++#define CLK_AUD_ASRCI2 25
++#define CLK_AUD_ASRCO1 26
++#define CLK_AUD_ASRCO2 27
++#define CLK_AUD_ASRC11 28
++#define CLK_AUD_ASRC12 29
++#define CLK_AUD_HDMIRX 30
++#define CLK_AUD_INTDIR 31
++#define CLK_AUD_A1SYS 32
++#define CLK_AUD_A2SYS 33
++#define CLK_AUD_AFE_CONN 34
++#define CLK_AUD_AFE_PCMIF 35
++#define CLK_AUD_AFE_MRGIF 36
++
++#define CLK_AUD_MMIF_UL1 37
++#define CLK_AUD_MMIF_UL2 38
++#define CLK_AUD_MMIF_UL3 39
++#define CLK_AUD_MMIF_UL4 40
++#define CLK_AUD_MMIF_UL5 41
++#define CLK_AUD_MMIF_UL6 42
++#define CLK_AUD_MMIF_DL1 43
++#define CLK_AUD_MMIF_DL2 44
++#define CLK_AUD_MMIF_DL3 45
++#define CLK_AUD_MMIF_DL4 46
++#define CLK_AUD_MMIF_DL5 47
++#define CLK_AUD_MMIF_DL6 48
++#define CLK_AUD_MMIF_DLMCH 49
++#define CLK_AUD_MMIF_ARB1 50
++#define CLK_AUD_MMIF_AWB1 51
++#define CLK_AUD_MMIF_AWB2 52
++#define CLK_AUD_MMIF_DAI 53
++
++#define CLK_AUD_DMIC1 54
++#define CLK_AUD_DMIC2 55
++#define CLK_AUD_ASRCI3 56
++#define CLK_AUD_ASRCI4 57
++#define CLK_AUD_ASRCI5 58
++#define CLK_AUD_ASRCI6 59
++#define CLK_AUD_ASRCO3 60
++#define CLK_AUD_ASRCO4 61
++#define CLK_AUD_ASRCO5 62
++#define CLK_AUD_ASRCO6 63
++#define CLK_AUD_MEM_ASRC1 64
++#define CLK_AUD_MEM_ASRC2 65
++#define CLK_AUD_MEM_ASRC3 66
++#define CLK_AUD_MEM_ASRC4 67
++#define CLK_AUD_MEM_ASRC5 68
++#define CLK_AUD_DSD_ENC 69
++#define CLK_AUD_ASRC_BRG 70
++#define CLK_AUD_NR 71
++
++/* MMSYS */
++
++#define CLK_MM_SMI_COMMON 1
++#define CLK_MM_SMI_LARB0 2
++#define CLK_MM_CMDQ 3
++#define CLK_MM_MUTEX 4
++#define CLK_MM_DISP_COLOR 5
++#define CLK_MM_DISP_BLS 6
++#define CLK_MM_DISP_WDMA 7
++#define CLK_MM_DISP_RDMA 8
++#define CLK_MM_DISP_OVL 9
++#define CLK_MM_MDP_TDSHP 10
++#define CLK_MM_MDP_WROT 11
++#define CLK_MM_MDP_WDMA 12
++#define CLK_MM_MDP_RSZ1 13
++#define CLK_MM_MDP_RSZ0 14
++#define CLK_MM_MDP_RDMA 15
++#define CLK_MM_MDP_BLS_26M 16
++#define CLK_MM_CAM_MDP 17
++#define CLK_MM_FAKE_ENG 18
++#define CLK_MM_MUTEX_32K 19
++#define CLK_MM_DISP_RDMA1 20
++#define CLK_MM_DISP_UFOE 21
++
++#define CLK_MM_DSI_ENGINE 22
++#define CLK_MM_DSI_DIG 23
++#define CLK_MM_DPI_DIGL 24
++#define CLK_MM_DPI_ENGINE 25
++#define CLK_MM_DPI1_DIGL 26
++#define CLK_MM_DPI1_ENGINE 27
++#define CLK_MM_TVE_OUTPUT 28
++#define CLK_MM_TVE_INPUT 29
++#define CLK_MM_HDMI_PIXEL 30
++#define CLK_MM_HDMI_PLL 31
++#define CLK_MM_HDMI_AUDIO 32
++#define CLK_MM_HDMI_SPDIF 33
++#define CLK_MM_TVE_FMM 34
++#define CLK_MM_NR 35
++
++/* IMGSYS */
++
++#define CLK_IMG_SMI_COMM 1
++#define CLK_IMG_RESZ 2
++#define CLK_IMG_JPGDEC 3
++#define CLK_IMG_VENC_LT 4
++#define CLK_IMG_VENC 5
++#define CLK_IMG_NR 6
++
++/* VDEC */
++
++#define CLK_VDEC_CKGEN 1
++#define CLK_VDEC_LARB 2
++#define CLK_VDEC_NR 3
++
++/* HIFSYS */
++
++#define CLK_HIFSYS_USB0PHY 1
++#define CLK_HIFSYS_USB1PHY 2
++#define CLK_HIFSYS_PCIE0 3
++#define CLK_HIFSYS_PCIE1 4
++#define CLK_HIFSYS_PCIE2 5
++#define CLK_HIFSYS_NR 6
++
++/* ETHSYS */
++#define CLK_ETHSYS_HSDMA 1
++#define CLK_ETHSYS_ESW 2
++#define CLK_ETHSYS_GP2 3
++#define CLK_ETHSYS_GP1 4
++#define CLK_ETHSYS_PCM 5
++#define CLK_ETHSYS_GDMA 6
++#define CLK_ETHSYS_I2S 7
++#define CLK_ETHSYS_CRYPTO 8
++#define CLK_ETHSYS_NR 9
++
++/* BDP */
++
++#define CLK_BDP_BRG_BA 1
++#define CLK_BDP_BRG_DRAM 2
++#define CLK_BDP_LARB_DRAM 3
++#define CLK_BDP_WR_VDI_PXL 4
++#define CLK_BDP_WR_VDI_DRAM 5
++#define CLK_BDP_WR_B 6
++#define CLK_BDP_DGI_IN 7
++#define CLK_BDP_DGI_OUT 8
++#define CLK_BDP_FMT_MAST_27 9
++#define CLK_BDP_FMT_B 10
++#define CLK_BDP_OSD_B 11
++#define CLK_BDP_OSD_DRAM 12
++#define CLK_BDP_OSD_AGENT 13
++#define CLK_BDP_OSD_PXL 14
++#define CLK_BDP_RLE_B 15
++#define CLK_BDP_RLE_AGENT 16
++#define CLK_BDP_RLE_DRAM 17
++#define CLK_BDP_F27M 18
++#define CLK_BDP_F27M_VDOUT 19
++#define CLK_BDP_F27_74_74 20
++#define CLK_BDP_F2FS 21
++#define CLK_BDP_F2FS74_148 22
++#define CLK_BDP_FB 23
++#define CLK_BDP_VDO_DRAM 24
++#define CLK_BDP_VDO_2FS 25
++#define CLK_BDP_VDO_B 26
++#define CLK_BDP_WR_DI_PXL 27
++#define CLK_BDP_WR_DI_DRAM 28
++#define CLK_BDP_WR_DI_B 29
++#define CLK_BDP_NR_PXL 30
++#define CLK_BDP_NR_DRAM 31
++#define CLK_BDP_NR_B 32
++
++#define CLK_BDP_RX_F 33
++#define CLK_BDP_RX_X 34
++#define CLK_BDP_RXPDT 35
++#define CLK_BDP_RX_CSCL_N 36
++#define CLK_BDP_RX_CSCL 37
++#define CLK_BDP_RX_DDCSCL_N 38
++#define CLK_BDP_RX_DDCSCL 39
++#define CLK_BDP_RX_VCO 40
++#define CLK_BDP_RX_DP 41
++#define CLK_BDP_RX_P 42
++#define CLK_BDP_RX_M 43
++#define CLK_BDP_RX_PLL 44
++#define CLK_BDP_BRG_RT_B 45
++#define CLK_BDP_BRG_RT_DRAM 46
++#define CLK_BDP_LARBRT_DRAM 47
++#define CLK_BDP_TMDS_SYN 48
++#define CLK_BDP_HDMI_MON 49
++#define CLK_BDP_NR 50
++
++#endif /* _DT_BINDINGS_CLK_MT2701_H */
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0009-clk-mediatek-Add-MT2701-clock-support.patch b/target/linux/mediatek/patches-4.4/0009-clk-mediatek-Add-MT2701-clock-support.patch
new file mode 100644
index 0000000000..f9670e45f6
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0009-clk-mediatek-Add-MT2701-clock-support.patch
@@ -0,0 +1,1449 @@
+From f2c07eaa2df52f9acac9ffc3457d3d81079dd723 Mon Sep 17 00:00:00 2001
+From: Shunli Wang <shunli.wang@mediatek.com>
+Date: Tue, 5 Jan 2016 14:30:20 +0800
+Subject: [PATCH 09/53] clk: mediatek: Add MT2701 clock support
+
+Add MT2701 clock support, include topckgen, apmixedsys,
+infracfg, pericfg and subsystem clocks.
+
+Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
+Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
+---
+ drivers/clk/mediatek/Kconfig | 8 +
+ drivers/clk/mediatek/Makefile | 1 +
+ drivers/clk/mediatek/clk-gate.c | 56 ++
+ drivers/clk/mediatek/clk-gate.h | 2 +
+ drivers/clk/mediatek/clk-mt2701.c | 1210 +++++++++++++++++++++++++++++++++++++
+ drivers/clk/mediatek/clk-mtk.c | 25 +
+ drivers/clk/mediatek/clk-mtk.h | 35 +-
+ 7 files changed, 1334 insertions(+), 3 deletions(-)
+ create mode 100644 drivers/clk/mediatek/clk-mt2701.c
+
+diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
+index dc224e6..6c7cdc0 100644
+--- a/drivers/clk/mediatek/Kconfig
++++ b/drivers/clk/mediatek/Kconfig
+@@ -6,6 +6,14 @@ config COMMON_CLK_MEDIATEK
+ ---help---
+ Mediatek SoCs' clock support.
+
++config COMMON_CLK_MT2701
++ bool "Clock driver for Mediatek MT2701 and MT7623"
++ depends on COMMON_CLK
++ select COMMON_CLK_MEDIATEK
++ default ARCH_MEDIATEK
++ ---help---
++ This driver supports Mediatek MT2701 and MT7623 clocks.
++
+ config COMMON_CLK_MT8135
+ bool "Clock driver for Mediatek MT8135"
+ depends on COMMON_CLK
+diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
+index 32e7222..5b2b91b 100644
+--- a/drivers/clk/mediatek/Makefile
++++ b/drivers/clk/mediatek/Makefile
+@@ -1,4 +1,5 @@
+ obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o
+ obj-$(CONFIG_RESET_CONTROLLER) += reset.o
++obj-$(CONFIG_COMMON_CLK_MT2701) += clk-mt2701.o
+ obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
+ obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o
+diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
+index 576bdb7..38badb4 100644
+--- a/drivers/clk/mediatek/clk-gate.c
++++ b/drivers/clk/mediatek/clk-gate.c
+@@ -61,6 +61,26 @@ static void mtk_cg_clr_bit(struct clk_hw *hw)
+ regmap_write(cg->regmap, cg->clr_ofs, BIT(cg->bit));
+ }
+
++static void mtk_cg_set_bit_no_setclr(struct clk_hw *hw)
++{
++ struct mtk_clk_gate *cg = to_clk_gate(hw);
++ u32 val;
++
++ regmap_read(cg->regmap, cg->sta_ofs, &val);
++ val |= BIT(cg->bit);
++ regmap_write(cg->regmap, cg->sta_ofs, val);
++}
++
++static void mtk_cg_clr_bit_no_setclr(struct clk_hw *hw)
++{
++ struct mtk_clk_gate *cg = to_clk_gate(hw);
++ u32 val;
++
++ regmap_read(cg->regmap, cg->sta_ofs, &val);
++ val &= ~(BIT(cg->bit));
++ regmap_write(cg->regmap, cg->sta_ofs, val);
++}
++
+ static int mtk_cg_enable(struct clk_hw *hw)
+ {
+ mtk_cg_clr_bit(hw);
+@@ -85,6 +105,30 @@ static void mtk_cg_disable_inv(struct clk_hw *hw)
+ mtk_cg_clr_bit(hw);
+ }
+
++static int mtk_cg_enable_no_setclr(struct clk_hw *hw)
++{
++ mtk_cg_clr_bit_no_setclr(hw);
++
++ return 0;
++}
++
++static void mtk_cg_disable_no_setclr(struct clk_hw *hw)
++{
++ mtk_cg_set_bit_no_setclr(hw);
++}
++
++static int mtk_cg_enable_inv_no_setclr(struct clk_hw *hw)
++{
++ mtk_cg_set_bit_no_setclr(hw);
++
++ return 0;
++}
++
++static void mtk_cg_disable_inv_no_setclr(struct clk_hw *hw)
++{
++ mtk_cg_clr_bit_no_setclr(hw);
++}
++
+ const struct clk_ops mtk_clk_gate_ops_setclr = {
+ .is_enabled = mtk_cg_bit_is_cleared,
+ .enable = mtk_cg_enable,
+@@ -97,6 +141,18 @@ const struct clk_ops mtk_clk_gate_ops_setclr_inv = {
+ .disable = mtk_cg_disable_inv,
+ };
+
++const struct clk_ops mtk_clk_gate_ops_no_setclr = {
++ .is_enabled = mtk_cg_bit_is_cleared,
++ .enable = mtk_cg_enable_no_setclr,
++ .disable = mtk_cg_disable_no_setclr,
++};
++
++const struct clk_ops mtk_clk_gate_ops_no_setclr_inv = {
++ .is_enabled = mtk_cg_bit_is_set,
++ .enable = mtk_cg_enable_inv_no_setclr,
++ .disable = mtk_cg_disable_inv_no_setclr,
++};
++
+ struct clk * __init mtk_clk_register_gate(
+ const char *name,
+ const char *parent_name,
+diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h
+index 11e25c9..7f7ef34 100644
+--- a/drivers/clk/mediatek/clk-gate.h
++++ b/drivers/clk/mediatek/clk-gate.h
+@@ -36,6 +36,8 @@ static inline struct mtk_clk_gate *to_clk_gate(struct clk_hw *hw)
+
+ extern const struct clk_ops mtk_clk_gate_ops_setclr;
+ extern const struct clk_ops mtk_clk_gate_ops_setclr_inv;
++extern const struct clk_ops mtk_clk_gate_ops_no_setclr;
++extern const struct clk_ops mtk_clk_gate_ops_no_setclr_inv;
+
+ struct clk *mtk_clk_register_gate(
+ const char *name,
+diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c
+new file mode 100644
+index 0000000..2f521f4
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-mt2701.c
+@@ -0,0 +1,1210 @@
++/*
++ * Copyright (c) 2014 MediaTek Inc.
++ * Author: Shunli Wang <shunli.wang@mediatek.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/clk.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++
++#include "clk-mtk.h"
++#include "clk-gate.h"
++
++#include <dt-bindings/clock/mt2701-clk.h>
++
++static DEFINE_SPINLOCK(lock);
++
++static const struct mtk_fixed_clk top_fixed_clks[] __initconst = {
++ FIXED_CLK(CLK_TOP_DPI, "dpi_ck", "clk26m", 108 * MHZ),
++ FIXED_CLK(CLK_TOP_DMPLL, "dmpll_ck", "clk26m", 400 * MHZ),
++ FIXED_CLK(CLK_TOP_VENCPLL, "vencpll_ck", "clk26m", 295750000),
++ FIXED_CLK(CLK_TOP_HDMI_0_PIX340M, "hdmi_0_pix340m", "clk26m", 340 * MHZ),
++ FIXED_CLK(CLK_TOP_HDMI_0_DEEP340M, "hdmi_0_deep340m", "clk26m", 340 * MHZ),
++ FIXED_CLK(CLK_TOP_HDMI_0_PLL340M, "hdmi_0_pll340m", "clk26m", 340 * MHZ),
++ FIXED_CLK(CLK_TOP_HDMITX_CLKDIG_CTS, "hdmitx_dig_cts", "clk26m", 300 * MHZ),
++ FIXED_CLK(CLK_TOP_HADDS2_FB, "hadds2_fbclk", "clk26m", 27 * MHZ),
++ FIXED_CLK(CLK_TOP_WBG_DIG_416M, "wbg_dig_ck_416m", "clk26m", 416 * MHZ),
++};
++
++static const struct mtk_fixed_factor top_fixed_divs[] __initconst = {
++ FACTOR(CLK_TOP_SYSPLL, "syspll_ck", "mainpll", 1, 1),
++ FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2),
++ FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1, 3),
++ FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5),
++ FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll", 1, 7),
++ FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "syspll_d2", 1, 2),
++ FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "syspll_d2", 1, 4),
++ FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "syspll_d2", 1, 8),
++ FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "syspll_d2", 1, 16),
++ FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "syspll_d3", 1, 2),
++ FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "syspll_d3", 1, 4),
++ FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "syspll_d3", 1, 8),
++ FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "syspll_d5", 1, 2),
++ FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "syspll_d5", 1, 4),
++ FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "syspll_d7", 1, 2),
++ FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "syspll_d7", 1, 4),
++
++ FACTOR(CLK_TOP_UNIVPLL, "univpll_ck", "univpll", 1, 1),
++ FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
++ FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
++ FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
++ FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7),
++ FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll", 1, 26),
++ FACTOR(CLK_TOP_UNIVPLL_D52, "univpll_d52", "univpll", 1, 52),
++ FACTOR(CLK_TOP_UNIVPLL_D108, "univpll_d108", "univpll", 1, 108),
++ FACTOR(CLK_TOP_USB_PHY48M, "USB_PHY48M_CK", "univpll", 1, 26),
++ FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_d2", 1, 2),
++ FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_d2", 1, 4),
++ FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_d2", 1, 8),
++ FACTOR(CLK_TOP_8BDAC, "8bdac_ck", "univpll_d2", 1, 1),
++ FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_d3", 1, 2),
++ FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_d3", 1, 4),
++ FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_d3", 1, 8),
++ FACTOR(CLK_TOP_UNIVPLL2_D16, "univpll2_d16", "univpll_d3", 1, 16),
++ FACTOR(CLK_TOP_UNIVPLL2_D32, "univpll2_d32", "univpll_d3", 1, 32),
++ FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll_d5", 1, 2),
++ FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll_d5", 1, 4),
++ FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univpll_d5", 1, 8),
++
++ FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1),
++ FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
++ FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4),
++ FACTOR(CLK_TOP_MSDCPLL_D8, "msdcpll_d8", "msdcpll", 1, 8),
++
++ FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1, 1),
++ FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
++
++ FACTOR(CLK_TOP_DMPLL_D2, "dmpll_d2", "dmpll_ck", 1, 2),
++ FACTOR(CLK_TOP_DMPLL_D4, "dmpll_d4", "dmpll_ck", 1, 4),
++ FACTOR(CLK_TOP_DMPLL_X2, "dmpll_x2", "dmpll_ck", 1, 1),
++
++ FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll", 1, 1),
++ FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll", 1, 2),
++ FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4),
++
++ FACTOR(CLK_TOP_VDECPLL, "vdecpll_ck", "vdecpll", 1, 1),
++ FACTOR(CLK_TOP_TVD2PLL, "tvd2pll_ck", "tvd2pll", 1, 1),
++ FACTOR(CLK_TOP_TVD2PLL_D2, "tvd2pll_d2", "tvd2pll", 1, 2),
++
++ FACTOR(CLK_TOP_MIPIPLL, "mipipll", "dpi_ck", 1, 1),
++ FACTOR(CLK_TOP_MIPIPLL_D2, "mipipll_d2", "dpi_ck", 1, 2),
++ FACTOR(CLK_TOP_MIPIPLL_D4, "mipipll_d4", "dpi_ck", 1, 4),
++
++ FACTOR(CLK_TOP_HDMIPLL, "hdmipll_ck", "hdmitx_dig_cts", 1, 1),
++ FACTOR(CLK_TOP_HDMIPLL_D2, "hdmipll_d2", "hdmitx_dig_cts", 1, 2),
++ FACTOR(CLK_TOP_HDMIPLL_D3, "hdmipll_d3", "hdmitx_dig_cts", 1, 3),
++
++ FACTOR(CLK_TOP_ARMPLL_1P3G, "armpll_1p3g_ck", "armpll", 1, 1),
++
++ FACTOR(CLK_TOP_AUDPLL, "audpll", "audpll_sel", 1, 1),
++ FACTOR(CLK_TOP_AUDPLL_D4, "audpll_d4", "audpll_sel", 1, 4),
++ FACTOR(CLK_TOP_AUDPLL_D8, "audpll_d8", "audpll_sel", 1, 8),
++ FACTOR(CLK_TOP_AUDPLL_D16, "audpll_d16", "audpll_sel", 1, 16),
++ FACTOR(CLK_TOP_AUDPLL_D24, "audpll_d24", "audpll_sel", 1, 24),
++
++ FACTOR(CLK_TOP_AUD1PLL_98M, "aud1pll_98m_ck", "aud1pll", 1, 3),
++ FACTOR(CLK_TOP_AUD2PLL_90M, "aud2pll_90m_ck", "aud2pll", 1, 3),
++ FACTOR(CLK_TOP_HADDS2PLL_98M, "hadds2pll_98m", "hadds2pll", 1, 3),
++ FACTOR(CLK_TOP_HADDS2PLL_294M, "hadds2pll_294m", "hadds2pll", 1, 1),
++ FACTOR(CLK_TOP_ETHPLL_500M, "ethpll_500m_ck", "ethpll", 1, 1),
++ FACTOR(CLK_TOP_CLK26M_D8, "clk26m_d8", "clk26m", 1, 8),
++ FACTOR(CLK_TOP_32K_INTERNAL, "32k_internal", "clk26m", 1, 793),
++ FACTOR(CLK_TOP_32K_EXTERNAL, "32k_external", "rtc32k", 1, 1),
++};
++
++static const char * const axi_parents[] __initconst = {
++ "clk26m",
++ "syspll1_d2",
++ "syspll_d5",
++ "syspll1_d4",
++ "univpll_d5",
++ "univpll2_d2",
++ "mmpll_d2",
++ "dmpll_d2"
++};
++
++static const char * const mem_parents[] __initconst = {
++ "clk26m",
++ "dmpll_ck"
++};
++
++static const char * const ddrphycfg_parents[] __initconst = {
++ "clk26m",
++ "syspll1_d8"
++};
++
++static const char * const mm_parents[] __initconst = {
++ "clk26m",
++ "vencpll_ck",
++ "syspll1_d2",
++ "syspll1_d4",
++ "univpll_d5",
++ "univpll1_d2",
++ "univpll2_d2",
++ "dmpll_ck"
++};
++
++static const char * const pwm_parents[] __initconst = {
++ "clk26m",
++ "univpll2_d4",
++ "univpll3_d2",
++ "univpll1_d4",
++};
++
++static const char * const vdec_parents[] __initconst = {
++ "clk26m",
++ "vdecpll_ck",
++ "syspll_d5",
++ "syspll1_d4",
++ "univpll_d5",
++ "univpll2_d2",
++ "vencpll_ck",
++ "msdcpll_d2",
++ "mmpll_d2"
++};
++
++static const char * const mfg_parents[] __initconst = {
++ "clk26m",
++ "mmpll_ck",
++ "dmpll_x2_ck",
++ "msdcpll_ck",
++ "clk26m",
++ "syspll_d3",
++ "univpll_d3",
++ "univpll1_d2"
++};
++
++static const char * const camtg_parents[] __initconst = {
++ "clk26m",
++ "univpll_d26",
++ "univpll2_d2",
++ "syspll3_d2",
++ "syspll3_d4",
++ "msdcpll_d2",
++ "mmpll_d2"
++};
++
++static const char * const uart_parents[] __initconst = {
++ "clk26m",
++ "univpll2_d8"
++};
++
++static const char * const spi_parents[] __initconst = {
++ "clk26m",
++ "syspll3_d2",
++ "syspll4_d2",
++ "univpll2_d4",
++ "univpll1_d8"
++};
++
++static const char * const usb20_parents[] __initconst = {
++ "clk26m",
++ "univpll1_d8",
++ "univpll3_d4"
++};
++
++static const char * const msdc30_parents[] __initconst = {
++ "clk26m",
++ "msdcpll_d2",
++ "syspll2_d2",
++ "syspll1_d4",
++ "univpll1_d4",
++ "univpll2_d4"
++};
++
++static const char * const audio_parents[] __initconst = {
++ "clk26m",
++ "syspll1_d16"
++};
++
++static const char * const aud_intbus_parents[] __initconst = {
++ "clk26m",
++ "syspll1_d4",
++ "syspll3_d2",
++ "syspll4_d2",
++ "univpll3_d2",
++ "univpll2_d4"
++};
++
++static const char * const pmicspi_parents[] __initconst = {
++ "clk26m",
++ "syspll1_d8",
++ "syspll2_d4",
++ "syspll4_d2",
++ "syspll3_d4",
++ "syspll2_d8",
++ "syspll1_d16",
++ "univpll3_d4",
++ "univpll_d26",
++ "dmpll_d2",
++ "dmpll_d4"
++};
++
++static const char * const scp_parents[] __initconst = {
++ "clk26m",
++ "syspll1_d8",
++ "dmpll_d2",
++ "dmpll_d4"
++};
++
++static const char * const dpi0_parents[] __initconst = {
++ "clk26m",
++ "mipipll",
++ "mipipll_d2",
++ "mipipll_d4",
++ "clk26m",
++ "tvdpll_ck",
++ "tvdpll_d2",
++ "tvdpll_d4"
++};
++
++static const char * const dpi1_parents[] __initconst = {
++ "clk26m",
++ "tvdpll_ck",
++ "tvdpll_d2",
++ "tvdpll_d4"
++};
++
++static const char * const tve_parents[] __initconst = {
++ "clk26m",
++ "mipipll",
++ "mipipll_d2",
++ "mipipll_d4",
++ "clk26m",
++ "tvdpll_ck",
++ "tvdpll_d2",
++ "tvdpll_d4"
++};
++
++static const char * const hdmi_parents[] __initconst = {
++ "clk26m",
++ "hdmipll_ck",
++ "hdmipll_d2",
++ "hdmipll_d3"
++};
++
++static const char * const apll_parents[] __initconst = {
++ "clk26m",
++ "audpll",
++ "audpll_d4",
++ "audpll_d8",
++ "audpll_d16",
++ "audpll_d24",
++ "clk26m",
++ "clk26m"
++};
++
++static const char * const rtc_parents[] __initconst = {
++ "32k_internal",
++ "32k_external",
++ "clk26m",
++ "univpll3_d8"
++};
++
++static const char * const nfi2x_parents[] __initconst = {
++ "clk26m",
++ "syspll2_d2",
++ "syspll_d7",
++ "univpll3_d2",
++ "syspll2_d4",
++ "univpll3_d4",
++ "syspll4_d4",
++ "clk26m"
++};
++
++static const char * const emmc_hclk_parents[] __initconst = {
++ "clk26m",
++ "syspll1_d2",
++ "syspll1_d4",
++ "syspll2_d2"
++};
++
++static const char * const flash_parents[] __initconst = {
++ "clk26m_d8",
++ "clk26m",
++ "syspll2_d8",
++ "syspll3_d4",
++ "univpll3_d4",
++ "syspll4_d2",
++ "syspll2_d4",
++ "univpll2_d4"
++};
++
++static const char * const di_parents[] __initconst = {
++ "clk26m",
++ "tvd2pll_ck",
++ "tvd2pll_d2",
++ "clk26m"
++};
++
++static const char * const nr_osd_parents[] __initconst = {
++ "clk26m",
++ "vencpll_ck",
++ "syspll1_d2",
++ "syspll1_d4",
++ "univpll_d5",
++ "univpll1_d2",
++ "univpll2_d2",
++ "dmpll_ck"
++};
++
++static const char * const hdmirx_bist_parents[] __initconst = {
++ "clk26m",
++ "syspll_d3",
++ "clk26m",
++ "syspll1_d16",
++ "syspll4_d2",
++ "syspll1_d4",
++ "vencpll_ck",
++ "clk26m"
++};
++
++static const char * const intdir_parents[] __initconst = {
++ "clk26m",
++ "mmpll_ck",
++ "syspll_d2",
++ "univpll_d2"
++};
++
++static const char * const asm_parents[] __initconst = {
++ "clk26m",
++ "univpll2_d4",
++ "univpll2_d2",
++ "syspll_d5"
++};
++
++static const char * const ms_card_parents[] __initconst = {
++ "clk26m",
++ "univpll3_d8",
++ "syspll4_d4"
++};
++
++static const char * const ethif_parents[] __initconst = {
++ "clk26m",
++ "syspll1_d2",
++ "syspll_d5",
++ "syspll1_d4",
++ "univpll_d5",
++ "univpll1_d2",
++ "dmpll_ck",
++ "dmpll_d2"
++};
++
++static const char * const hdmirx_parents[] __initconst = {
++ "clk26m",
++ "univpll_d52"
++};
++
++static const char * const cmsys_parents[] __initconst = {
++ "clk26m",
++ "syspll1_d2",
++ "univpll1_d2",
++ "univpll_d5",
++ "syspll_d5",
++ "syspll2_d2",
++ "syspll1_d4",
++ "syspll3_d2",
++ "syspll2_d4",
++ "syspll1_d8",
++ "clk26m",
++ "clk26m",
++ "clk26m",
++ "clk26m",
++ "clk26m"
++};
++
++static const char * const clk_8bdac_parents[] __initconst = {
++ "clkrtc_int",
++ "8bdac_ck_pre",
++ "clk26m",
++ "clk26m"
++};
++
++static const char * const aud2dvd_parents[] __initconst = {
++ "a1sys_hp_ck",
++ "a2sys_hp_ck"
++};
++
++static const char * const padmclk_parents[] __initconst = {
++ "clk26m",
++ "univpll_d26",
++ "univpll_d52",
++ "univpll_d108",
++ "univpll2_d8",
++ "univpll2_d16",
++ "univpll2_d32"
++};
++
++static const char * const aud_mux_parents[] __initconst = {
++ "clk26m",
++ "aud1pll_98m_ck",
++ "aud2pll_90m_ck",
++ "hadds2pll_98m",
++ "audio_ext1_ck",
++ "audio_ext2_ck"
++};
++
++static const char * const aud_src_parents[] __initconst = {
++ "aud_mux1_sel",
++ "aud_mux2_sel"
++};
++
++static const char * const cpu_parents[] __initconst = {
++ "clk26m",
++ "armpll",
++ "mainpll",
++ "mmpll"
++};
++
++static const struct mtk_composite top_muxes[] __initconst = {
++ MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
++ 0x0040, 0, 3, INVALID_MUX_GATE_BIT),
++ MUX_GATE(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x0040, 8, 1, 15),
++ MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents, 0x0040, 16, 1, 23),
++ MUX_GATE(CLK_TOP_MM_SEL, "mm_sel", mm_parents, 0x0040, 24, 3, 31),
++
++ MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x0050, 0, 2, 7),
++ MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x0050, 8, 4, 15),
++ MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0050, 16, 3, 23),
++ MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x0050, 24, 3, 31),
++ MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x0060, 0, 1, 7),
++
++ MUX_GATE(CLK_TOP_SPI0_SEL, "spi0_sel", spi_parents, 0x0060, 8, 3, 15),
++ MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x0060, 16, 2, 23),
++ MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_parents, 0x0060, 24, 3, 31),
++
++ MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_parents, 0x0070, 0, 3, 7),
++ MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_parents, 0x0070, 8, 3, 15),
++ MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", msdc30_parents, 0x0070, 16, 1, 23),
++ MUX_GATE(CLK_TOP_AUDINTBUS_SEL, "aud_intbus_sel", aud_intbus_parents, 0x0070, 24, 3, 31),
++
++ MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x0080, 0, 4, 7),
++ MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, 0x0080, 8, 2, 15),
++ MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents, 0x0080, 16, 3, 23),
++ MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0080, 24, 2, 31),
++
++ MUX_GATE(CLK_TOP_TVE_SEL, "tve_sel", tve_parents, 0x0090, 0, 3, 7),
++ MUX_GATE(CLK_TOP_HDMI_SEL, "hdmi_sel", hdmi_parents, 0x0090, 8, 2, 15),
++ MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", apll_parents, 0x0090, 16, 3, 23),
++
++ MUX_GATE(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents, 0x00A0, 0, 2, 7),
++ MUX_GATE(CLK_TOP_NFI2X_SEL, "nfi2x_sel", nfi2x_parents, 0x00A0, 8, 3, 15),
++ MUX_GATE(CLK_TOP_EMMC_HCLK_SEL, "emmc_hclk_sel", emmc_hclk_parents, 0x00A0, 24, 2, 31),
++
++ MUX_GATE(CLK_TOP_FLASH_SEL, "flash_sel", flash_parents, 0x00B0, 0, 3, 7),
++ MUX_GATE(CLK_TOP_DI_SEL, "di_sel", di_parents, 0x00B0, 8, 2, 15),
++ MUX_GATE(CLK_TOP_NR_SEL, "nr_sel", nr_osd_parents, 0x00B0, 16, 3, 23),
++ MUX_GATE(CLK_TOP_OSD_SEL, "osd_sel", nr_osd_parents, 0x00B0, 24, 3, 31),
++
++ MUX_GATE(CLK_TOP_HDMIRX_BIST_SEL, "hdmirx_bist_sel", hdmirx_bist_parents, 0x00C0, 0, 3, 7),
++ MUX_GATE(CLK_TOP_INTDIR_SEL, "intdir_sel", intdir_parents, 0x00C0, 8, 2, 15),
++ MUX_GATE(CLK_TOP_ASM_I_SEL, "asm_i_sel", asm_parents, 0x00C0, 16, 2, 23),
++ MUX_GATE(CLK_TOP_ASM_M_SEL, "asm_m_sel", asm_parents, 0x00C0, 24, 3, 31),
++
++ MUX_GATE(CLK_TOP_ASM_H_SEL, "asm_h_sel", asm_parents, 0x00D0, 0, 2, 7),
++ MUX_GATE(CLK_TOP_MS_CARD_SEL, "ms_card_sel", ms_card_parents, 0x00D0, 16, 2, 23),
++ MUX_GATE(CLK_TOP_ETHIF_SEL, "ethif_sel", ethif_parents, 0x00D0, 24, 3, 31),
++
++ MUX_GATE(CLK_TOP_HDMIRX26_24_SEL, "hdmirx26_24_sel", hdmirx_parents, 0x00E0, 0, 1, 7),
++ MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_parents, 0x00E0, 8, 3, 15),
++ MUX_GATE(CLK_TOP_CMSYS_SEL, "cmsys_sel", cmsys_parents, 0x00E0, 16, 4, 23),
++
++ MUX_GATE(CLK_TOP_SPI1_SEL, "spi2_sel", spi_parents, 0x00E0, 24, 3, 31),
++ MUX_GATE(CLK_TOP_SPI2_SEL, "spi1_sel", spi_parents, 0x00F0, 0, 3, 7),
++ MUX_GATE(CLK_TOP_8BDAC_SEL, "8bdac_sel", clk_8bdac_parents, 0x00F0, 8, 2, 15),
++ MUX_GATE(CLK_TOP_AUD2DVD_SEL, "aud2dvd_sel", aud2dvd_parents, 0x00F0, 16, 1, 23),
++
++ MUX(CLK_TOP_PADMCLK_SEL, "padmclk_sel", padmclk_parents, 0x0100, 0, 3),
++
++ MUX(CLK_TOP_AUD_MUX1_SEL, "aud_mux1_sel", aud_mux_parents, 0x012c, 0, 3),
++ MUX(CLK_TOP_AUD_MUX2_SEL, "aud_mux2_sel", aud_mux_parents, 0x012c, 3, 3),
++ MUX(CLK_TOP_AUDPLL_MUX_SEL, "audpll_sel", aud_mux_parents, 0x012c, 6, 3),
++ MUX_GATE(CLK_TOP_AUD_K1_SRC_SEL, "aud_k1_src_sel", aud_src_parents, 0x012c, 15, 1, 23),
++ MUX_GATE(CLK_TOP_AUD_K2_SRC_SEL, "aud_k2_src_sel", aud_src_parents, 0x012c, 16, 1, 24),
++ MUX_GATE(CLK_TOP_AUD_K3_SRC_SEL, "aud_k3_src_sel", aud_src_parents, 0x012c, 17, 1, 25),
++ MUX_GATE(CLK_TOP_AUD_K4_SRC_SEL, "aud_k4_src_sel", aud_src_parents, 0x012c, 18, 1, 26),
++ MUX_GATE(CLK_TOP_AUD_K5_SRC_SEL, "aud_k5_src_sel", aud_src_parents, 0x012c, 19, 1, 27),
++ MUX_GATE(CLK_TOP_AUD_K6_SRC_SEL, "aud_k6_src_sel", aud_src_parents, 0x012c, 20, 1, 28),
++};
++
++static const struct mtk_clk_divider top_adj_divs[] __initconst = {
++ DIV_ADJ(CLK_TOP_AUD_EXTCK1_DIV, "audio_ext1_ck", "aud_ext_ck1", 0x0120, 0, 8),
++ DIV_ADJ(CLK_TOP_AUD_EXTCK2_DIV, "audio_ext2_ck", "aud_ext_ck2", 0x0120, 8, 8),
++ DIV_ADJ(CLK_TOP_AUD_MUX1_DIV, "aud_mux1_div", "aud_mux1_sel", 0x0120, 16, 8),
++ DIV_ADJ(CLK_TOP_AUD_MUX2_DIV, "aud_mux2_div", "aud_mux2_sel", 0x0120, 24, 8),
++ DIV_ADJ(CLK_TOP_AUD_K1_SRC_DIV, "aud_k1_src_div", "aud_k1_src_sel", 0x0124, 0, 8),
++ DIV_ADJ(CLK_TOP_AUD_K2_SRC_DIV, "aud_k2_src_div", "aud_k2_src_sel", 0x0124, 8, 8),
++ DIV_ADJ(CLK_TOP_AUD_K3_SRC_DIV, "aud_k3_src_div", "aud_k3_src_sel", 0x0124, 16, 8),
++ DIV_ADJ(CLK_TOP_AUD_K4_SRC_DIV, "aud_k4_src_div", "aud_k4_src_sel", 0x0124, 24, 8),
++ DIV_ADJ(CLK_TOP_AUD_K5_SRC_DIV, "aud_k5_src_div", "aud_k5_src_sel", 0x0128, 0, 8),
++ DIV_ADJ(CLK_TOP_AUD_K6_SRC_DIV, "aud_k6_src_div", "aud_k6_src_sel", 0x0128, 8, 8),
++};
++
++static const struct mtk_gate_regs top_aud_cg_regs __initconst = {
++ .sta_ofs = 0x012C,
++};
++
++#define GATE_TOP_AUD(_id, _name, _parent, _shift) { \
++ .id = _id, \
++ .name = _name, \
++ .parent_name = _parent, \
++ .regs = &top_aud_cg_regs, \
++ .shift = _shift, \
++ .ops = &mtk_clk_gate_ops_no_setclr, \
++ }
++
++static const struct mtk_gate top_clks[] __initconst = {
++ GATE_TOP_AUD(CLK_TOP_AUD_48K_TIMING, "a1sys_hp_ck", "aud_mux1_div", 21),
++ GATE_TOP_AUD(CLK_TOP_AUD_44K_TIMING, "a2sys_hp_ck", "aud_mux2_div", 22),
++ GATE_TOP_AUD(CLK_TOP_AUD_I2S1_MCLK, "aud_i2s1_mclk", "aud_k1_src_div", 23),
++ GATE_TOP_AUD(CLK_TOP_AUD_I2S2_MCLK, "aud_i2s2_mclk", "aud_k2_src_div", 24),
++ GATE_TOP_AUD(CLK_TOP_AUD_I2S3_MCLK, "aud_i2s3_mclk", "aud_k3_src_div", 25),
++ GATE_TOP_AUD(CLK_TOP_AUD_I2S4_MCLK, "aud_i2s4_mclk", "aud_k4_src_div", 26),
++ GATE_TOP_AUD(CLK_TOP_AUD_I2S5_MCLK, "aud_i2s5_mclk", "aud_k5_src_div", 27),
++ GATE_TOP_AUD(CLK_TOP_AUD_I2S6_MCLK, "aud_i2s6_mclk", "aud_k6_src_div", 28),
++};
++
++static void __init mtk_topckgen_init(struct device_node *node)
++{
++ struct clk_onecell_data *clk_data;
++ void __iomem *base;
++ int r;
++
++ base = of_iomap(node, 0);
++ if (!base) {
++ pr_err("%s(): ioremap failed\n", __func__);
++ return;
++ }
++
++ clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
++
++ mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
++ clk_data);
++
++ mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs),
++ clk_data);
++
++ mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes),
++ base, &lock, clk_data);
++
++ mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
++ base, &lock, clk_data);
++
++ mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_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_topckgen, "mediatek,mt2701-topckgen", mtk_topckgen_init);
++
++static const struct mtk_gate_regs infra_cg_regs __initconst = {
++ .set_ofs = 0x0040,
++ .clr_ofs = 0x0044,
++ .sta_ofs = 0x0048,
++};
++
++#define GATE_ICG(_id, _name, _parent, _shift) { \
++ .id = _id, \
++ .name = _name, \
++ .parent_name = _parent, \
++ .regs = &infra_cg_regs, \
++ .shift = _shift, \
++ .ops = &mtk_clk_gate_ops_setclr, \
++ }
++
++static const struct mtk_gate infra_clks[] __initconst = {
++ GATE_ICG(CLK_INFRA_DBG, "dbgclk", "axi_sel", 0),
++ GATE_ICG(CLK_INFRA_SMI, "smi_ck", "mm_sel", 1),
++ GATE_ICG(CLK_INFRA_QAXI_CM4, "cm4_ck", "axi_sel", 2),
++ GATE_ICG(CLK_INFRA_AUD_SPLIN_B, "audio_splin_bck", "hadds2_294m_ck", 4),
++ GATE_ICG(CLK_INFRA_AUDIO, "audio_ck", "clk_null", 5),
++ GATE_ICG(CLK_INFRA_EFUSE, "efuse_ck", "clk26m", 6),
++ GATE_ICG(CLK_INFRA_L2C_SRAM, "l2c_sram_ck", "mm_sel", 7),
++ GATE_ICG(CLK_INFRA_M4U, "m4u_ck", "mem_sel", 8),
++ GATE_ICG(CLK_INFRA_CONNMCU, "connsys_bus", "wbg_dig_ck_416m", 12),
++ GATE_ICG(CLK_INFRA_TRNG, "trng_ck", "axi_sel", 13),
++ GATE_ICG(CLK_INFRA_RAMBUFIF, "rambufif_ck", "mem_sel", 14),
++ GATE_ICG(CLK_INFRA_CPUM, "cpum_ck", "mem_sel", 15),
++ GATE_ICG(CLK_INFRA_KP, "kp_ck", "axi_sel", 16),
++ GATE_ICG(CLK_INFRA_CEC, "cec_ck", "rtc_sel", 18),
++ GATE_ICG(CLK_INFRA_IRRX, "irrx_ck", "axi_sel", 19),
++ GATE_ICG(CLK_INFRA_PMICSPI, "pmicspi_ck", "pmicspi_sel", 22),
++ GATE_ICG(CLK_INFRA_PMICWRAP, "pmicwrap_ck", "axi_sel", 23),
++ GATE_ICG(CLK_INFRA_DDCCI, "ddcci_ck", "axi_sel", 24),
++};
++
++static const struct mtk_fixed_factor infra_fixed_divs[] __initconst = {
++ FACTOR(CLK_INFRA_CLK_13M, "clk13m", "clk26m", 1, 2),
++};
++
++static void __init mtk_infrasys_init(struct device_node *node)
++{
++ struct clk_onecell_data *clk_data;
++ int r;
++
++ clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
++
++ mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
++ clk_data);
++ mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
++ 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_infrasys, "mediatek,mt2701-infracfg", mtk_infrasys_init);
++
++static const struct mtk_gate_regs peri0_cg_regs __initconst = {
++ .set_ofs = 0x0008,
++ .clr_ofs = 0x0010,
++ .sta_ofs = 0x0018,
++};
++
++static const struct mtk_gate_regs peri1_cg_regs __initconst = {
++ .set_ofs = 0x000c,
++ .clr_ofs = 0x0014,
++ .sta_ofs = 0x001c,
++};
++
++#define GATE_PERI0(_id, _name, _parent, _shift) { \
++ .id = _id, \
++ .name = _name, \
++ .parent_name = _parent, \
++ .regs = &peri0_cg_regs, \
++ .shift = _shift, \
++ .ops = &mtk_clk_gate_ops_setclr, \
++ }
++
++#define GATE_PERI1(_id, _name, _parent, _shift) { \
++ .id = _id, \
++ .name = _name, \
++ .parent_name = _parent, \
++ .regs = &peri1_cg_regs, \
++ .shift = _shift, \
++ .ops = &mtk_clk_gate_ops_setclr, \
++ }
++
++static const struct mtk_gate peri_clks[] __initconst = {
++ GATE_PERI1(CLK_PERI_USB0_MCU, "usb0_mcu_ck", "axi_sel", 31),
++ GATE_PERI1(CLK_PERI_ETH, "eth_ck", "clk26m", 30),
++ GATE_PERI1(CLK_PERI_SPI0, "spi0_ck", "spi0_sel", 29),
++ GATE_PERI1(CLK_PERI_AUXADC, "auxadc_ck", "clk26m", 28),
++ GATE_PERI0(CLK_PERI_I2C3, "i2c3_ck", "clk26m", 27),
++ GATE_PERI0(CLK_PERI_I2C2, "i2c2_ck", "axi_sel", 26),
++ GATE_PERI0(CLK_PERI_I2C1, "i2c1_ck", "axi_sel", 25),
++ GATE_PERI0(CLK_PERI_I2C0, "i2c0_ck", "axi_sel", 24),
++ GATE_PERI0(CLK_PERI_BTIF, "bitif_ck", "axi_sel", 23),
++ GATE_PERI0(CLK_PERI_UART3, "uart3_ck", "axi_sel", 22),
++ GATE_PERI0(CLK_PERI_UART2, "uart2_ck", "axi_sel", 21),
++ GATE_PERI0(CLK_PERI_UART1, "uart1_ck", "axi_sel", 20),
++ GATE_PERI0(CLK_PERI_UART0, "uart0_ck", "axi_sel", 19),
++ GATE_PERI0(CLK_PERI_NLI, "nli_ck", "axi_sel", 18),
++ GATE_PERI0(CLK_PERI_MSDC50_3, "msdc50_3_ck", "emmc_hclk_sel", 17),
++ GATE_PERI0(CLK_PERI_MSDC30_3, "msdc30_3_ck", "msdc30_3_sel", 16),
++ GATE_PERI0(CLK_PERI_MSDC30_2, "msdc30_2_ck", "msdc30_2_sel", 15),
++ GATE_PERI0(CLK_PERI_MSDC30_1, "msdc30_1_ck", "msdc30_1_sel", 14),
++ GATE_PERI0(CLK_PERI_MSDC30_0, "msdc30_0_ck", "msdc30_0_sel", 13),
++ GATE_PERI0(CLK_PERI_AP_DMA, "ap_dma_ck", "axi_sel", 12),
++ GATE_PERI0(CLK_PERI_USB1, "usb1_ck", "usb20_sel", 11),
++ GATE_PERI0(CLK_PERI_USB0, "usb0_ck", "usb20_sel", 10),
++ GATE_PERI0(CLK_PERI_PWM, "pwm_ck", "axi_sel", 9),
++ GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axi_sel", 8),
++ GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axi_sel", 7),
++ GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axi_sel", 6),
++ GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axi_sel", 5),
++ GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axi_sel", 4),
++ GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axi_sel", 3),
++ GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axi_sel", 2),
++ GATE_PERI0(CLK_PERI_THERM, "therm_ck", "axi_sel", 1),
++ GATE_PERI0(CLK_PERI_NFI, "nfi_ck", "nfi2x_sel", 0),
++
++ GATE_PERI1(CLK_PERI_FCI, "fci_ck", "ms_card", 11),
++ GATE_PERI1(CLK_PERI_SPI2, "spi2_ck", "spi2_sel", 10),
++ GATE_PERI1(CLK_PERI_SPI1, "spi1_ck", "spi1_sel", 9),
++ GATE_PERI1(CLK_PERI_HOST89_DVD, "host89_dvd_ck", "aud2dvd_sel", 8),
++ GATE_PERI1(CLK_PERI_HOST89_SPI, "host89_spi_ck", "spi0_sel", 7),
++ GATE_PERI1(CLK_PERI_HOST89_INT, "host89_int_ck", "axi_sel", 6),
++ GATE_PERI1(CLK_PERI_FLASH, "flash_ck", "nfi2x_sel", 5),
++ GATE_PERI1(CLK_PERI_NFI_PAD, "nfi_pad_ck", "nfi_sel", 4),
++ GATE_PERI1(CLK_PERI_NFI_ECC, "nfi_ecc_ck", "nfi_sel", 3),
++ GATE_PERI1(CLK_PERI_GCPU, "gcpu_ck", "axi_sel", 2),
++ GATE_PERI1(CLK_PERI_USB_SLV, "usbslv_ck", "axi_sel", 1),
++ GATE_PERI1(CLK_PERI_USB1_MCU, "usb1_mcu_ck", "axi_sel", 0),
++};
++
++static const char * const uart_ck_sel_parents[] __initconst = {
++ "clk26m",
++ "uart_sel",
++};
++
++static const struct mtk_composite peri_muxs[] __initconst = {
++ MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents, 0x40c, 0, 1),
++ MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents, 0x40c, 1, 1),
++ MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents, 0x40c, 2, 1),
++ MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1),
++};
++
++static void __init mtk_pericfg_init(struct device_node *node)
++{
++ struct clk_onecell_data *clk_data;
++ void __iomem *base;
++ int r;
++
++ base = of_iomap(node, 0);
++ if (!base) {
++ pr_err("%s(): ioremap failed\n", __func__);
++ return;
++ }
++
++ clk_data = mtk_alloc_clk_data(CLK_PERI_NR);
++
++ mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
++ clk_data);
++
++ mtk_clk_register_composites(peri_muxs, ARRAY_SIZE(peri_muxs), base,
++ &lock, 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_pericfg, "mediatek,mt2701-pericfg", mtk_pericfg_init);
++
++static const struct mtk_gate_regs disp0_cg_regs __initconst = {
++ .set_ofs = 0x0104,
++ .clr_ofs = 0x0108,
++ .sta_ofs = 0x0100,
++};
++
++static const struct mtk_gate_regs disp1_cg_regs __initconst = {
++ .set_ofs = 0x0114,
++ .clr_ofs = 0x0118,
++ .sta_ofs = 0x0110,
++};
++
++#define GATE_DISP0(_id, _name, _parent, _shift) { \
++ .id = _id, \
++ .name = _name, \
++ .parent_name = _parent, \
++ .regs = &disp0_cg_regs, \
++ .shift = _shift, \
++ .ops = &mtk_clk_gate_ops_setclr, \
++ }
++
++#define GATE_DISP1(_id, _name, _parent, _shift) { \
++ .id = _id, \
++ .name = _name, \
++ .parent_name = _parent, \
++ .regs = &disp1_cg_regs, \
++ .shift = _shift, \
++ .ops = &mtk_clk_gate_ops_setclr, \
++ }
++
++static const struct mtk_gate mm_clks[] __initconst = {
++ GATE_DISP0(CLK_MM_SMI_COMMON, "mm_smi_comm", "mm_sel", 0),
++ GATE_DISP0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
++ GATE_DISP0(CLK_MM_CMDQ, "mm_cmdq", "mm_sel", 2),
++ GATE_DISP0(CLK_MM_MUTEX, "mm_mutex", "mm_sel", 3),
++ GATE_DISP0(CLK_MM_DISP_COLOR, "mm_disp_color", "mm_sel", 4),
++ GATE_DISP0(CLK_MM_DISP_BLS, "mm_disp_bls", "mm_sel", 5),
++ GATE_DISP0(CLK_MM_DISP_WDMA, "mm_disp_wdma", "mm_sel", 6),
++ GATE_DISP0(CLK_MM_DISP_RDMA, "mm_disp_rdma", "mm_sel", 7),
++ GATE_DISP0(CLK_MM_DISP_OVL, "mm_disp_ovl", "mm_sel", 8),
++ GATE_DISP0(CLK_MM_MDP_TDSHP, "mm_mdp_tdshp", "mm_sel", 9),
++ GATE_DISP0(CLK_MM_MDP_WROT, "mm_mdp_wrot", "mm_sel", 10),
++ GATE_DISP0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11),
++ GATE_DISP0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 12),
++ GATE_DISP0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 13),
++ GATE_DISP0(CLK_MM_MDP_RDMA, "mm_mdp_rdma", "mm_sel", 14),
++ GATE_DISP0(CLK_MM_MDP_BLS_26M, "mm_mdp_bls_26m", "clk26m", 15),
++ GATE_DISP0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 16),
++ GATE_DISP0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 17),
++ GATE_DISP0(CLK_MM_MUTEX_32K, "mm_mutex_32k", "rtc_sel", 18),
++ GATE_DISP0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 19),
++ GATE_DISP0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 20),
++ GATE_DISP1(CLK_MM_DSI_ENGINE, "mm_dsi_eng", "mm_sel", 0),
++ GATE_DISP1(CLK_MM_DSI_DIG, "mm_dsi_dig", "dsio_lntc_dsiclk", 1),
++ GATE_DISP1(CLK_MM_DPI_DIGL, "mm_dpi_digl", "dpi0_sel", 2),
++ GATE_DISP1(CLK_MM_DPI_ENGINE, "mm_dpi_eng", "mm_sel", 3),
++ GATE_DISP1(CLK_MM_DPI1_DIGL, "mm_dpi1_digl", "dpi1_sel", 4),
++ GATE_DISP1(CLK_MM_DPI1_ENGINE, "mm_dpi1_eng", "mm_sel", 5),
++ GATE_DISP1(CLK_MM_TVE_OUTPUT, "mm_tve_output", "tve_sel", 6),
++ GATE_DISP1(CLK_MM_TVE_INPUT, "mm_tve_input", "dpi0_sel", 7),
++ GATE_DISP1(CLK_MM_HDMI_PIXEL, "mm_hdmi_pixel", "dpi1_sel", 8),
++ GATE_DISP1(CLK_MM_HDMI_PLL, "mm_hdmi_pll", "hdmi_sel", 9),
++ GATE_DISP1(CLK_MM_HDMI_AUDIO, "mm_hdmi_audio", "apll_sel", 10),
++ GATE_DISP1(CLK_MM_HDMI_SPDIF, "mm_hdmi_spdif", "apll_sel", 11),
++ GATE_DISP1(CLK_MM_TVE_FMM, "mm_tve_fmm", "mm_sel", 14),
++};
++
++static void __init mtk_mmsys_init(struct device_node *node)
++{
++ struct clk_onecell_data *clk_data;
++ int r;
++
++ clk_data = mtk_alloc_clk_data(CLK_MM_NR);
++
++ mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_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_mmsys, "mediatek,mt2701-mmsys", mtk_mmsys_init);
++
++static const struct mtk_gate_regs img_cg_regs __initconst = {
++ .set_ofs = 0x0004,
++ .clr_ofs = 0x0008,
++ .sta_ofs = 0x0000,
++};
++
++#define GATE_IMG(_id, _name, _parent, _shift) { \
++ .id = _id, \
++ .name = _name, \
++ .parent_name = _parent, \
++ .regs = &img_cg_regs, \
++ .shift = _shift, \
++ .ops = &mtk_clk_gate_ops_setclr, \
++ }
++
++static const struct mtk_gate img_clks[] __initconst = {
++ GATE_IMG(CLK_IMG_SMI_COMM, "img_smi_comm", "mm_sel", 0),
++ GATE_IMG(CLK_IMG_RESZ, "img_resz", "mm_sel", 1),
++ GATE_IMG(CLK_IMG_JPGDEC, "img_jpgdec", "mm_sel", 5),
++ GATE_IMG(CLK_IMG_VENC_LT, "img_venc_lt", "mm_sel", 8),
++ GATE_IMG(CLK_IMG_VENC, "img_venc", "mm_sel", 9),
++};
++
++static void __init mtk_imgsys_init(struct device_node *node)
++{
++ struct clk_onecell_data *clk_data;
++ int r;
++
++ clk_data = mtk_alloc_clk_data(CLK_IMG_NR);
++
++ mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_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_imgsys, "mediatek,mt2701-imgsys", mtk_imgsys_init);
++
++static const struct mtk_gate_regs vdec0_cg_regs __initconst = {
++ .set_ofs = 0x0000,
++ .clr_ofs = 0x0004,
++ .sta_ofs = 0x0000,
++};
++
++static const struct mtk_gate_regs vdec1_cg_regs __initconst = {
++ .set_ofs = 0x0008,
++ .clr_ofs = 0x000c,
++ .sta_ofs = 0x0008,
++};
++
++#define GATE_VDEC0(_id, _name, _parent, _shift) { \
++ .id = _id, \
++ .name = _name, \
++ .parent_name = _parent, \
++ .regs = &vdec0_cg_regs, \
++ .shift = _shift, \
++ .ops = &mtk_clk_gate_ops_setclr_inv, \
++ }
++
++#define GATE_VDEC1(_id, _name, _parent, _shift) { \
++ .id = _id, \
++ .name = _name, \
++ .parent_name = _parent, \
++ .regs = &vdec1_cg_regs, \
++ .shift = _shift, \
++ .ops = &mtk_clk_gate_ops_setclr_inv, \
++ }
++
++static const struct mtk_gate vdec_clks[] __initconst = {
++ GATE_VDEC0(CLK_VDEC_CKGEN, "vdec_cken", "vdec_sel", 0),
++ GATE_VDEC1(CLK_VDEC_LARB, "vdec_larb_cken", "mm_sel", 0),
++};
++
++static void __init mtk_vdecsys_init(struct device_node *node)
++{
++ struct clk_onecell_data *clk_data;
++ int r;
++
++ clk_data = mtk_alloc_clk_data(CLK_VDEC_NR);
++
++ mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_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_vdecsys, "mediatek,mt2701-vdecsys", mtk_vdecsys_init);
++
++static const struct mtk_gate_regs hif_cg_regs __initconst = {
++ .sta_ofs = 0x0008,
++};
++
++#define GATE_HIF(_id, _name, _parent, _shift) { \
++ .id = _id, \
++ .name = _name, \
++ .parent_name = _parent, \
++ .regs = &hif_cg_regs, \
++ .shift = _shift, \
++ .ops = &mtk_clk_gate_ops_no_setclr_inv, \
++ }
++
++static const struct mtk_gate hif_clks[] __initconst = {
++ GATE_HIF(CLK_HIFSYS_USB0PHY, "usb0_phy_clk", "ethpll_500m_ck", 21),
++ GATE_HIF(CLK_HIFSYS_USB1PHY, "usb1_phy_clk", "ethpll_500m_ck", 22),
++ GATE_HIF(CLK_HIFSYS_PCIE0, "pcie0_clk", "ethpll_500m_ck", 24),
++ GATE_HIF(CLK_HIFSYS_PCIE1, "pcie1_clk", "ethpll_500m_ck", 25),
++ GATE_HIF(CLK_HIFSYS_PCIE2, "pcie2_clk", "ethpll_500m_ck", 26),
++};
++
++static void __init mtk_hifsys_init(struct device_node *node)
++{
++ struct clk_onecell_data *clk_data;
++ int r;
++
++ clk_data = mtk_alloc_clk_data(CLK_HIFSYS_NR);
++
++ mtk_clk_register_gates(node, hif_clks, ARRAY_SIZE(hif_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_hifsys, "mediatek,mt2701-hifsys", mtk_hifsys_init);
++
++static const struct mtk_gate_regs eth_cg_regs __initconst = {
++ .sta_ofs = 0x0030,
++};
++
++#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_HIF(CLK_ETHSYS_HSDMA, "hsdma_clk", "ethif_sel", 5),
++ GATE_HIF(CLK_ETHSYS_ESW, "esw_clk", "ethpll_500m_ck", 6),
++ GATE_HIF(CLK_ETHSYS_GP2, "gp2_clk", "trgpll", 7),
++ GATE_HIF(CLK_ETHSYS_GP1, "gp1_clk", "ethpll_500m_ck", 8),
++ GATE_HIF(CLK_ETHSYS_PCM, "pcm_clk", "ethif_sel", 11),
++ GATE_HIF(CLK_ETHSYS_GDMA, "gdma_clk", "ethif_sel", 14),
++ GATE_HIF(CLK_ETHSYS_I2S, "i2s_clk", "ethif_sel", 17),
++ GATE_HIF(CLK_ETHSYS_CRYPTO, "crypto_clk", "ethif_sel", 29),
++};
++
++static void __init mtk_ethsys_init(struct device_node *node)
++{
++ struct clk_onecell_data *clk_data;
++ int r;
++
++ clk_data = mtk_alloc_clk_data(CLK_ETHSYS_NR);
++
++ 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,mt2701-ethsys", mtk_ethsys_init);
++
++static const struct mtk_gate_regs bdp0_cg_regs __initconst = {
++ .set_ofs = 0x0104,
++ .clr_ofs = 0x0108,
++ .sta_ofs = 0x0100,
++};
++
++static const struct mtk_gate_regs bdp1_cg_regs __initconst = {
++ .set_ofs = 0x0114,
++ .clr_ofs = 0x0118,
++ .sta_ofs = 0x0110,
++};
++
++#define GATE_BDP0(_id, _name, _parent, _shift) { \
++ .id = _id, \
++ .name = _name, \
++ .parent_name = _parent, \
++ .regs = &bdp0_cg_regs, \
++ .shift = _shift, \
++ .ops = &mtk_clk_gate_ops_setclr_inv, \
++ }
++
++#define GATE_BDP1(_id, _name, _parent, _shift) { \
++ .id = _id, \
++ .name = _name, \
++ .parent_name = _parent, \
++ .regs = &bdp1_cg_regs, \
++ .shift = _shift, \
++ .ops = &mtk_clk_gate_ops_setclr_inv, \
++ }
++
++static const struct mtk_gate bdp_clks[] __initconst = {
++ GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0),
++ GATE_BDP0(CLK_BDP_BRG_DRAM, "brg_dram", "mm_sel", 1),
++ GATE_BDP0(CLK_BDP_LARB_DRAM, "larb_dram", "mm_sel", 2),
++ GATE_BDP0(CLK_BDP_WR_VDI_PXL, "wr_vdi_pxl", "hdmi_0_deep340m", 3),
++ GATE_BDP0(CLK_BDP_WR_VDI_DRAM, "wr_vdi_dram", "mm_sel", 4),
++ GATE_BDP0(CLK_BDP_WR_B, "wr_bclk", "mm_sel", 5),
++ GATE_BDP0(CLK_BDP_DGI_IN, "dgi_in", "dpi1_sel", 6),
++ GATE_BDP0(CLK_BDP_DGI_OUT, "dgi_out", "dpi_sel", 7),
++ GATE_BDP0(CLK_BDP_FMT_MAST_27, "fmt_mast_27", "dpi1_sel", 8),
++ GATE_BDP0(CLK_BDP_FMT_B, "fmt_bclk", "mm_sel", 9),
++ GATE_BDP0(CLK_BDP_OSD_B, "osd_bclk", "mm_sel", 10),
++ GATE_BDP0(CLK_BDP_OSD_DRAM, "osd_dram", "mm_sel", 11),
++ GATE_BDP0(CLK_BDP_OSD_AGENT, "osd_agent", "osd_sel", 12),
++ GATE_BDP0(CLK_BDP_OSD_PXL, "osd_pxl", "dpi1_sel", 13),
++ GATE_BDP0(CLK_BDP_RLE_B, "rle_bclk", "mm_sel", 14),
++ GATE_BDP0(CLK_BDP_RLE_AGENT, "rle_agent", "mm_sel", 15),
++ GATE_BDP0(CLK_BDP_RLE_DRAM, "rle_dram", "mm_sel", 16),
++ GATE_BDP0(CLK_BDP_F27M, "f27m", "di_sel", 17),
++ GATE_BDP0(CLK_BDP_F27M_VDOUT, "f27m_vdout", "di_sel", 18),
++ GATE_BDP0(CLK_BDP_F27_74_74, "f27_74_74", "di_sel", 19),
++ GATE_BDP0(CLK_BDP_F2FS, "f2fs", "di_sel", 20),
++ GATE_BDP0(CLK_BDP_F2FS74_148, "f2fs74_148", "di_sel", 21),
++ GATE_BDP0(CLK_BDP_FB, "fbclk", "mm_sel", 22),
++ GATE_BDP0(CLK_BDP_VDO_DRAM, "vdo_dram", "mm_sel", 23),
++ GATE_BDP0(CLK_BDP_VDO_2FS, "vdo_2fs", "di_sel", 24),
++ GATE_BDP0(CLK_BDP_VDO_B, "vdo_bclk", "mm_sel", 25),
++ GATE_BDP0(CLK_BDP_WR_DI_PXL, "wr_di_pxl", "di_sel", 26),
++ GATE_BDP0(CLK_BDP_WR_DI_DRAM, "wr_di_dram", "mm_sel", 27),
++ GATE_BDP0(CLK_BDP_WR_DI_B, "wr_di_bclk", "mm_sel", 28),
++ GATE_BDP0(CLK_BDP_NR_PXL, "nr_pxl", "nr_sel", 29),
++ GATE_BDP0(CLK_BDP_NR_DRAM, "nr_dram", "mm_sel", 30),
++ GATE_BDP0(CLK_BDP_NR_B, "nr_bclk", "mm_sel", 31),
++ GATE_BDP1(CLK_BDP_RX_F, "rx_fclk", "hadds2_fbclk", 0),
++ GATE_BDP1(CLK_BDP_RX_X, "rx_xclk", "clk26m", 1),
++ GATE_BDP1(CLK_BDP_RXPDT, "rxpdtclk", "hdmi_0_pix340m", 2),
++ GATE_BDP1(CLK_BDP_RX_CSCL_N, "rx_cscl_n", "clk26m", 3),
++ GATE_BDP1(CLK_BDP_RX_CSCL, "rx_cscl", "clk26m", 4),
++ GATE_BDP1(CLK_BDP_RX_DDCSCL_N, "rx_ddcscl_n", "hdmi_scl_rx", 5),
++ GATE_BDP1(CLK_BDP_RX_DDCSCL, "rx_ddcscl", "hdmi_scl_rx", 6),
++ GATE_BDP1(CLK_BDP_RX_VCO, "rx_vcoclk", "hadds2pll_294m", 7),
++ GATE_BDP1(CLK_BDP_RX_DP, "rx_dpclk", "hdmi_0_pll340m", 8),
++ GATE_BDP1(CLK_BDP_RX_P, "rx_pclk", "hdmi_0_pll340m", 9),
++ GATE_BDP1(CLK_BDP_RX_M, "rx_mclk", "hadds2pll_294m", 10),
++ GATE_BDP1(CLK_BDP_RX_PLL, "rx_pllclk", "hdmi_0_pix340m", 11),
++ GATE_BDP1(CLK_BDP_BRG_RT_B, "brg_rt_bclk", "mm_sel", 12),
++ GATE_BDP1(CLK_BDP_BRG_RT_DRAM, "brg_rt_dram", "mm_sel", 13),
++ GATE_BDP1(CLK_BDP_LARBRT_DRAM, "larbrt_dram", "mm_sel", 14),
++ GATE_BDP1(CLK_BDP_TMDS_SYN, "tmds_syn", "hdmi_0_pll340m", 15),
++ GATE_BDP1(CLK_BDP_HDMI_MON, "hdmi_mon", "hdmi_0_mon", 16),
++};
++
++static void __init mtk_bdpsys_init(struct device_node *node)
++{
++ struct clk_onecell_data *clk_data;
++ int r;
++
++ clk_data = mtk_alloc_clk_data(CLK_BDP_NR);
++
++ mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_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_bdpsys, "mediatek,mt2701-bdpsys", mtk_bdpsys_init);
++
++#define MT8590_PLL_FMAX (2000 * MHZ)
++#define CON0_MT8590_RST_BAR BIT(27)
++
++#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \
++ _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \
++ .id = _id, \
++ .name = _name, \
++ .reg = _reg, \
++ .pwr_reg = _pwr_reg, \
++ .en_mask = _en_mask, \
++ .flags = _flags, \
++ .rst_bar_mask = CON0_MT8590_RST_BAR, \
++ .fmax = MT8590_PLL_FMAX, \
++ .pcwbits = _pcwbits, \
++ .pd_reg = _pd_reg, \
++ .pd_shift = _pd_shift, \
++ .tuner_reg = _tuner_reg, \
++ .pcw_reg = _pcw_reg, \
++ .pcw_shift = _pcw_shift, \
++ }
++
++static const struct mtk_pll_data apmixed_plls[] = {
++ PLL(CLK_APMIXED_ARMPLL, "armpll", 0x200, 0x20c, 0x80000001, 0,
++ 21, 0x204, 24, 0x0, 0x204, 0),
++ PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x210, 0x21c, 0xf0000001,
++ HAVE_RST_BAR, 21, 0x210, 4, 0x0, 0x214, 0),
++ PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x220, 0x22c, 0xf3000001,
++ HAVE_RST_BAR, 7, 0x220, 4, 0x0, 0x224, 14),
++ PLL(CLK_APMIXED_MMPLL, "mmpll", 0x230, 0x23c, 0x00000001, 0,
++ 21, 0x230, 4, 0x0, 0x234, 0),
++ PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x240, 0x24c, 0x00000001, 0,
++ 21, 0x240, 4, 0x0, 0x244, 0),
++ PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x250, 0x25c, 0x00000001, 0,
++ 21, 0x250, 4, 0x0, 0x254, 0),
++ PLL(CLK_APMIXED_AUD1PLL, "aud1pll", 0x270, 0x27c, 0x00000001, 0,
++ 31, 0x270, 4, 0x0, 0x274, 0),
++ PLL(CLK_APMIXED_TRGPLL, "trgpll", 0x280, 0x28c, 0x00000001, 0,
++ 31, 0x280, 4, 0x0, 0x284, 0),
++ PLL(CLK_APMIXED_ETHPLL, "ethpll", 0x290, 0x29c, 0x00000001, 0,
++ 31, 0x290, 4, 0x0, 0x294, 0),
++ PLL(CLK_APMIXED_VDECPLL, "vdecpll", 0x2a0, 0x2ac, 0x00000001, 0,
++ 31, 0x2a0, 4, 0x0, 0x2a4, 0),
++ PLL(CLK_APMIXED_HADDS2PLL, "hadds2pll", 0x2b0, 0x2bc, 0x00000001, 0,
++ 31, 0x2b0, 4, 0x0, 0x2b4, 0),
++ PLL(CLK_APMIXED_AUD2PLL, "aud2pll", 0x2c0, 0x2cc, 0x00000001, 0,
++ 31, 0x2c0, 4, 0x0, 0x2c4, 0),
++ PLL(CLK_APMIXED_TVD2PLL, "tvd2pll", 0x2d0, 0x2dc, 0x00000001, 0,
++ 21, 0x2d0, 4, 0x0, 0x2d4, 0),
++};
++
++static void __init mtk_apmixedsys_init(struct device_node *node)
++{
++ struct clk_onecell_data *clk_data;
++ int r;
++
++ clk_data = mtk_alloc_clk_data(ARRAY_SIZE(apmixed_plls));
++ if (!clk_data)
++ return;
++
++ mtk_clk_register_plls(node, apmixed_plls, ARRAY_SIZE(apmixed_plls),
++ 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_apmixedsys, "mediatek,mt2701-apmixedsys",
++ mtk_apmixedsys_init);
+diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
+index cf08db6..be19a41 100644
+--- a/drivers/clk/mediatek/clk-mtk.c
++++ b/drivers/clk/mediatek/clk-mtk.c
+@@ -242,3 +242,28 @@ void __init mtk_clk_register_composites(const struct mtk_composite *mcs,
+ clk_data->clks[mc->id] = clk;
+ }
+ }
++
++void __init mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
++ int num, void __iomem *base, spinlock_t *lock,
++ struct clk_onecell_data *clk_data)
++{
++ struct clk *clk;
++ int i;
++
++ for (i = 0; i < num; i++) {
++ const struct mtk_clk_divider *mcd = &mcds[i];
++
++ clk = clk_register_divider(NULL, mcd->name, mcd->parent_name,
++ mcd->flags, base + mcd->div_reg, mcd->div_shift,
++ mcd->div_width, mcd->clk_divider_flags, lock);
++
++ if (IS_ERR(clk)) {
++ pr_err("Failed to register clk %s: %ld\n",
++ mcd->name, PTR_ERR(clk));
++ continue;
++ }
++
++ if (clk_data)
++ clk_data->clks[mcd->id] = clk;
++ }
++}
+diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
+index 32d2e45..60701e8 100644
+--- a/drivers/clk/mediatek/clk-mtk.h
++++ b/drivers/clk/mediatek/clk-mtk.h
+@@ -110,7 +110,8 @@ struct mtk_composite {
+ .flags = CLK_SET_RATE_PARENT, \
+ }
+
+-#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, _div_width, _div_shift) { \
++#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, \
++ _div_width, _div_shift) { \
+ .id = _id, \
+ .parent = _parent, \
+ .name = _name, \
+@@ -145,8 +146,36 @@ struct mtk_gate {
+ const struct clk_ops *ops;
+ };
+
+-int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks,
+- int num, struct clk_onecell_data *clk_data);
++int mtk_clk_register_gates(struct device_node *node,
++ const struct mtk_gate *clks, int num,
++ struct clk_onecell_data *clk_data);
++
++struct mtk_clk_divider {
++ int id;
++ const char *name;
++ const char *parent_name;
++ unsigned long flags;
++
++ uint32_t div_reg;
++ unsigned char div_shift;
++ unsigned char div_width;
++ unsigned char clk_divider_flags;
++ const struct clk_div_table *clk_div_table;
++};
++
++#define DIV_ADJ(_id, _name, _parent, _reg, _shift, _width) { \
++ .id = _id, \
++ .name = _name, \
++ .parent_name = _parent, \
++ .flags = CLK_SET_RATE_PARENT, \
++ .div_reg = _reg, \
++ .div_shift = _shift, \
++ .div_width = _width, \
++}
++
++void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
++ int num, void __iomem *base, spinlock_t *lock,
++ struct clk_onecell_data *clk_data);
+
+ struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num);
+
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0010-reset-mediatek-mt2701-reset-controller-dt-binding-fi.patch b/target/linux/mediatek/patches-4.4/0010-reset-mediatek-mt2701-reset-controller-dt-binding-fi.patch
new file mode 100644
index 0000000000..c78d7f8aad
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0010-reset-mediatek-mt2701-reset-controller-dt-binding-fi.patch
@@ -0,0 +1,99 @@
+From 8d134cbe750b59d15c591622d81e2e9daa09f0c4 Mon Sep 17 00:00:00 2001
+From: Shunli Wang <shunli.wang@mediatek.com>
+Date: Tue, 5 Jan 2016 14:30:21 +0800
+Subject: [PATCH 10/53] reset: mediatek: mt2701 reset controller dt-binding
+ file
+
+Dt-binding file about reset controller is used to provide
+kinds of definition, which is referenced by dts file and
+IC-specified reset controller driver code.
+
+Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
+---
+ .../dt-bindings/reset-controller/mt2701-resets.h | 74 ++++++++++++++++++++
+ 1 file changed, 74 insertions(+)
+ create mode 100644 include/dt-bindings/reset-controller/mt2701-resets.h
+
+diff --git a/include/dt-bindings/reset-controller/mt2701-resets.h b/include/dt-bindings/reset-controller/mt2701-resets.h
+new file mode 100644
+index 0000000..00efeb0
+--- /dev/null
++++ b/include/dt-bindings/reset-controller/mt2701-resets.h
+@@ -0,0 +1,74 @@
++/*
++ * Copyright (c) 2015 MediaTek, Shunli Wang <shunli.wang@mediatek.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT2701
++#define _DT_BINDINGS_RESET_CONTROLLER_MT2701
++
++/* INFRACFG resets */
++#define MT2701_INFRA_EMI_REG_RST 0
++#define MT2701_INFRA_DRAMC0_A0_RST 1
++#define MT2701_INFRA_FHCTL_RST 2
++#define MT2701_INFRA_APCIRQ_EINT_RST 3
++#define MT2701_INFRA_APXGPT_RST 4
++#define MT2701_INFRA_SCPSYS_RST 5
++#define MT2701_INFRA_KP_RST 6
++#define MT2701_INFRA_PMIC_WRAP_RST 7
++#define MT2701_INFRA_MIPI_RST 8
++#define MT2701_INFRA_IRRX_RST 9
++#define MT2701_INFRA_CEC_RST 10
++#define MT2701_INFRA_EMI_RST 32
++#define MT2701_INFRA_DRAMC0_RST 34
++#define MT2701_INFRA_TRNG_RST 37
++#define MT2701_INFRA_SYSIRQ_RST 38
++
++/* PERICFG resets */
++#define MT2701_PERI_UART0_SW_RST 0
++#define MT2701_PERI_UART1_SW_RST 1
++#define MT2701_PERI_UART2_SW_RST 2
++#define MT2701_PERI_UART3_SW_RST 3
++#define MT2701_PERI_GCPU_SW_RST 5
++#define MT2701_PERI_BTIF_SW_RST 6
++#define MT2701_PERI_PWM_SW_RST 8
++#define MT2701_PERI_AUXADC_SW_RST 10
++#define MT2701_PERI_DMA_SW_RST 11
++#define MT2701_PERI_NFI_SW_RST 14
++#define MT2701_PERI_NLI_SW_RST 15
++#define MT2701_PERI_THERM_SW_RST 16
++#define MT2701_PERI_MSDC2_SW_RST 17
++#define MT2701_PERI_MSDC0_SW_RST 19
++#define MT2701_PERI_MSDC1_SW_RST 20
++#define MT2701_PERI_I2C0_SW_RST 22
++#define MT2701_PERI_I2C1_SW_RST 23
++#define MT2701_PERI_I2C2_SW_RST 24
++#define MT2701_PERI_I2C3_SW_RST 25
++#define MT2701_PERI_USB_SW_RST 28
++#define MT2701_PERI_ETH_SW_RST 29
++#define MT2701_PERI_SPI0_SW_RST 33
++
++/* TOPRGU resets */
++#define MT2701_TOPRGU_INFRA_RST 0
++#define MT2701_TOPRGU_MM_RST 1
++#define MT2701_TOPRGU_MFG_RST 2
++#define MT2701_TOPRGU_ETHDMA_RST 3
++#define MT2701_TOPRGU_VDEC_RST 4
++#define MT2701_TOPRGU_VENC_IMG_RST 5
++#define MT2701_TOPRGU_DDRPHY_RST 6
++#define MT2701_TOPRGU_MD_RST 7
++#define MT2701_TOPRGU_INFRA_AO_RST 8
++#define MT2701_TOPRGU_CONN_RST 9
++#define MT2701_TOPRGU_APMIXED_RST 10
++#define MT2701_TOPRGU_HIFSYS_RST 11
++#define MT2701_TOPRGU_CONN_MCU_RST 12
++#define MT2701_TOPRGU_BDP_DISP_RST 13
++
++#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT2701 */
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0011-reset-mediatek-mt2701-reset-driver.patch b/target/linux/mediatek/patches-4.4/0011-reset-mediatek-mt2701-reset-driver.patch
new file mode 100644
index 0000000000..64d31334d6
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0011-reset-mediatek-mt2701-reset-driver.patch
@@ -0,0 +1,41 @@
+From b86d3303db25a8296e4c3de46ee1470f60f71b0c Mon Sep 17 00:00:00 2001
+From: Shunli Wang <shunli.wang@mediatek.com>
+Date: Tue, 5 Jan 2016 14:30:22 +0800
+Subject: [PATCH 11/53] reset: mediatek: mt2701 reset driver
+
+In infrasys and perifsys, there are many reset
+control bits for kinds of modules. These bits are
+used as actual reset controllers to be registered
+into kernel's generic reset controller framework.
+
+Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
+Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
+---
+ drivers/clk/mediatek/clk-mt2701.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c
+index 2f521f4..39472e4 100644
+--- a/drivers/clk/mediatek/clk-mt2701.c
++++ b/drivers/clk/mediatek/clk-mt2701.c
+@@ -665,6 +665,8 @@ static void __init mtk_infrasys_init(struct device_node *node)
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
++
++ mtk_register_reset_controller(node, 2, 0x30);
+ }
+ CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt2701-infracfg", mtk_infrasys_init);
+
+@@ -782,6 +784,8 @@ static void __init mtk_pericfg_init(struct device_node *node)
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
++
++ mtk_register_reset_controller(node, 2, 0x0);
+ }
+ CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt2701-pericfg", mtk_pericfg_init);
+
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch b/target/linux/mediatek/patches-4.4/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch
new file mode 100644
index 0000000000..81e67ca4ca
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch
@@ -0,0 +1,34 @@
+From 3b5df542d52b13a1b20d25311fa4c4029a3b83af Mon Sep 17 00:00:00 2001
+From: Erin Lo <erin.lo@mediatek.com>
+Date: Mon, 28 Dec 2015 15:09:02 +0800
+Subject: [PATCH 12/53] ARM: mediatek: Add MT2701 config options for mediatek
+ SoCs.
+
+The upcoming MTK pinctrl driver have a big pin table for each SoC
+and we don't want to bloat the kernel binary if we don't need it.
+Add config options so we can build for one SoC only. Add MT2701.
+
+Signed-off-by: Erin Lo <erin.lo@mediatek.com>
+Acked-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ arch/arm/mach-mediatek/Kconfig | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
+index aeece17..37dd438 100644
+--- a/arch/arm/mach-mediatek/Kconfig
++++ b/arch/arm/mach-mediatek/Kconfig
+@@ -9,6 +9,10 @@ menuconfig ARCH_MEDIATEK
+
+ if ARCH_MEDIATEK
+
++config MACH_MT2701
++ bool "MediaTek MT2701 SoCs support"
++ default ARCH_MEDIATEK
++
+ config MACH_MT6589
+ bool "MediaTek MT6589 SoCs support"
+ default ARCH_MEDIATEK
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0013-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt2.patch b/target/linux/mediatek/patches-4.4/0013-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt2.patch
new file mode 100644
index 0000000000..35b613710f
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0013-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt2.patch
@@ -0,0 +1,36 @@
+From 1a254735cad9db5c8605c972b0f16b3929dc0d6e Mon Sep 17 00:00:00 2001
+From: Biao Huang <biao.huang@mediatek.com>
+Date: Mon, 28 Dec 2015 15:09:03 +0800
+Subject: [PATCH 13/53] dt-bindings: mediatek: Modify pinctrl bindings for
+ mt2701
+
+Signed-off-by: Biao Huang <biao.huang@mediatek.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Mathias Brugger <matthias.bgg@gmail.com>
+---
+ Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
+index 0480bc3..9ffb0b2 100644
+--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
++++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
+@@ -4,10 +4,11 @@ The Mediatek's Pin controller is used to control SoC pins.
+
+ Required properties:
+ - compatible: value should be one of the following.
+- (a) "mediatek,mt8135-pinctrl", compatible with mt8135 pinctrl.
+- (b) "mediatek,mt8173-pinctrl", compatible with mt8173 pinctrl.
+- (c) "mediatek,mt6397-pinctrl", compatible with mt6397 pinctrl.
+- (d) "mediatek,mt8127-pinctrl", compatible with mt8127 pinctrl.
++ "mediatek,mt2701-pinctrl", compatible with mt2701 pinctrl.
++ "mediatek,mt6397-pinctrl", compatible with mt6397 pinctrl.
++ "mediatek,mt8127-pinctrl", compatible with mt8127 pinctrl.
++ "mediatek,mt8135-pinctrl", compatible with mt8135 pinctrl.
++ "mediatek,mt8173-pinctrl", compatible with mt8173 pinctrl.
+ - pins-are-numbered: Specify the subnodes are using numbered pinmux to
+ specify pins.
+ - gpio-controller : Marks the device node as a gpio controller.
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0014-pinctrl-dt-bindings-Add-pinfunc-header-file-for-mt27.patch b/target/linux/mediatek/patches-4.4/0014-pinctrl-dt-bindings-Add-pinfunc-header-file-for-mt27.patch
new file mode 100644
index 0000000000..77696b37d7
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0014-pinctrl-dt-bindings-Add-pinfunc-header-file-for-mt27.patch
@@ -0,0 +1,3812 @@
+From 416720ba33d4fd7d3166c17be7c13651cc08d408 Mon Sep 17 00:00:00 2001
+From: Biao Huang <biao.huang@mediatek.com>
+Date: Mon, 28 Dec 2015 15:09:04 +0800
+Subject: [PATCH 14/53] pinctrl: dt bindings: Add pinfunc header file for
+ mt2701
+
+Add pinfunc header file, mt2701 related dts will include it
+
+Signed-off-by: Biao Huang <biao.huang@mediatek.com>
+Acked-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ arch/arm/boot/dts/mt2701-pinfunc.h | 735 ++++++++
+ drivers/pinctrl/mediatek/Kconfig | 6 +
+ drivers/pinctrl/mediatek/Makefile | 1 +
+ drivers/pinctrl/mediatek/pinctrl-mt2701.c | 586 +++++++
+ drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 16 +
+ drivers/pinctrl/mediatek/pinctrl-mtk-common.h | 12 +-
+ drivers/pinctrl/mediatek/pinctrl-mtk-mt2701.h | 2323 +++++++++++++++++++++++++
+ 7 files changed, 3678 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm/boot/dts/mt2701-pinfunc.h
+ create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt2701.c
+ create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt2701.h
+
+diff --git a/arch/arm/boot/dts/mt2701-pinfunc.h b/arch/arm/boot/dts/mt2701-pinfunc.h
+new file mode 100644
+index 0000000..e24ebc8
+--- /dev/null
++++ b/arch/arm/boot/dts/mt2701-pinfunc.h
+@@ -0,0 +1,735 @@
++/*
++ * Copyright (c) 2015 MediaTek Inc.
++ * Author: Biao Huang <biao.huang@mediatek.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef __DTS_MT2701_PINFUNC_H
++#define __DTS_MT2701_PINFUNC_H
++
++#include <dt-bindings/pinctrl/mt65xx.h>
++
++#define MT2701_PIN_0_PWRAP_SPI0_MI__FUNC_GPIO0 (MTK_PIN_NO(0) | 0)
++#define MT2701_PIN_0_PWRAP_SPI0_MI__FUNC_PWRAP_SPIDO (MTK_PIN_NO(0) | 1)
++#define MT2701_PIN_0_PWRAP_SPI0_MI__FUNC_PWRAP_SPIDI (MTK_PIN_NO(0) | 2)
++
++#define MT2701_PIN_1_PWRAP_SPI0_MO__FUNC_GPIO1 (MTK_PIN_NO(1) | 0)
++#define MT2701_PIN_1_PWRAP_SPI0_MO__FUNC_PWRAP_SPIDI (MTK_PIN_NO(1) | 1)
++#define MT2701_PIN_1_PWRAP_SPI0_MO__FUNC_PWRAP_SPIDO (MTK_PIN_NO(1) | 2)
++
++#define MT2701_PIN_2_PWRAP_INT__FUNC_GPIO2 (MTK_PIN_NO(2) | 0)
++#define MT2701_PIN_2_PWRAP_INT__FUNC_PWRAP_INT (MTK_PIN_NO(2) | 1)
++
++#define MT2701_PIN_3_PWRAP_SPI0_CK__FUNC_GPIO3 (MTK_PIN_NO(3) | 0)
++#define MT2701_PIN_3_PWRAP_SPI0_CK__FUNC_PWRAP_SPICK_I (MTK_PIN_NO(3) | 1)
++
++#define MT2701_PIN_4_PWRAP_SPI0_CSN__FUNC_GPIO4 (MTK_PIN_NO(4) | 0)
++#define MT2701_PIN_4_PWRAP_SPI0_CSN__FUNC_PWRAP_SPICS_B_I (MTK_PIN_NO(4) | 1)
++
++#define MT2701_PIN_5_PWRAP_SPI0_CK2__FUNC_GPIO5 (MTK_PIN_NO(5) | 0)
++#define MT2701_PIN_5_PWRAP_SPI0_CK2__FUNC_PWRAP_SPICK2_I (MTK_PIN_NO(5) | 1)
++#define MT2701_PIN_5_PWRAP_SPI0_CK2__FUNC_ANT_SEL1 (MTK_PIN_NO(5) | 5)
++
++#define MT2701_PIN_6_PWRAP_SPI0_CSN2__FUNC_GPIO6 (MTK_PIN_NO(6) | 0)
++#define MT2701_PIN_6_PWRAP_SPI0_CSN2__FUNC_PWRAP_SPICS2_B_I (MTK_PIN_NO(6) | 1)
++#define MT2701_PIN_6_PWRAP_SPI0_CSN2__FUNC_ANT_SEL0 (MTK_PIN_NO(6) | 5)
++#define MT2701_PIN_6_PWRAP_SPI0_CSN2__FUNC_DBG_MON_A_0 (MTK_PIN_NO(6) | 7)
++
++#define MT2701_PIN_7_SPI1_CSN__FUNC_GPIO7 (MTK_PIN_NO(7) | 0)
++#define MT2701_PIN_7_SPI1_CSN__FUNC_SPI1_CS (MTK_PIN_NO(7) | 1)
++#define MT2701_PIN_7_SPI1_CSN__FUNC_KCOL0 (MTK_PIN_NO(7) | 4)
++#define MT2701_PIN_7_SPI1_CSN__FUNC_DBG_MON_B_12 (MTK_PIN_NO(7) | 7)
++
++#define MT2701_PIN_8_SPI1_MI__FUNC_GPIO8 (MTK_PIN_NO(8) | 0)
++#define MT2701_PIN_8_SPI1_MI__FUNC_SPI1_MI (MTK_PIN_NO(8) | 1)
++#define MT2701_PIN_8_SPI1_MI__FUNC_SPI1_MO (MTK_PIN_NO(8) | 2)
++#define MT2701_PIN_8_SPI1_MI__FUNC_KCOL1 (MTK_PIN_NO(8) | 4)
++#define MT2701_PIN_8_SPI1_MI__FUNC_DBG_MON_B_13 (MTK_PIN_NO(8) | 7)
++
++#define MT2701_PIN_9_SPI1_MO__FUNC_GPIO9 (MTK_PIN_NO(9) | 0)
++#define MT2701_PIN_9_SPI1_MO__FUNC_SPI1_MO (MTK_PIN_NO(9) | 1)
++#define MT2701_PIN_9_SPI1_MO__FUNC_SPI1_MI (MTK_PIN_NO(9) | 2)
++#define MT2701_PIN_9_SPI1_MO__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(9) | 3)
++#define MT2701_PIN_9_SPI1_MO__FUNC_KCOL2 (MTK_PIN_NO(9) | 4)
++#define MT2701_PIN_9_SPI1_MO__FUNC_DBG_MON_B_14 (MTK_PIN_NO(9) | 7)
++
++#define MT2701_PIN_10_RTC32K_CK__FUNC_GPIO10 (MTK_PIN_NO(10) | 0)
++#define MT2701_PIN_10_RTC32K_CK__FUNC_RTC32K_CK (MTK_PIN_NO(10) | 1)
++
++#define MT2701_PIN_11_WATCHDOG__FUNC_GPIO11 (MTK_PIN_NO(11) | 0)
++#define MT2701_PIN_11_WATCHDOG__FUNC_WATCHDOG (MTK_PIN_NO(11) | 1)
++
++#define MT2701_PIN_12_SRCLKENA__FUNC_GPIO12 (MTK_PIN_NO(12) | 0)
++#define MT2701_PIN_12_SRCLKENA__FUNC_SRCLKENA (MTK_PIN_NO(12) | 1)
++
++#define MT2701_PIN_13_SRCLKENAI__FUNC_GPIO13 (MTK_PIN_NO(13) | 0)
++#define MT2701_PIN_13_SRCLKENAI__FUNC_SRCLKENAI (MTK_PIN_NO(13) | 1)
++
++#define MT2701_PIN_14_URXD2__FUNC_GPIO14 (MTK_PIN_NO(14) | 0)
++#define MT2701_PIN_14_URXD2__FUNC_URXD2 (MTK_PIN_NO(14) | 1)
++#define MT2701_PIN_14_URXD2__FUNC_UTXD2 (MTK_PIN_NO(14) | 2)
++#define MT2701_PIN_14_URXD2__FUNC_SRCCLKENAI2 (MTK_PIN_NO(14) | 5)
++#define MT2701_PIN_14_URXD2__FUNC_DBG_MON_B_30 (MTK_PIN_NO(14) | 7)
++
++#define MT2701_PIN_15_UTXD2__FUNC_GPIO15 (MTK_PIN_NO(15) | 0)
++#define MT2701_PIN_15_UTXD2__FUNC_UTXD2 (MTK_PIN_NO(15) | 1)
++#define MT2701_PIN_15_UTXD2__FUNC_URXD2 (MTK_PIN_NO(15) | 2)
++#define MT2701_PIN_15_UTXD2__FUNC_DBG_MON_B_31 (MTK_PIN_NO(15) | 7)
++
++#define MT2701_PIN_18_PCM_CLK__FUNC_GPIO18 (MTK_PIN_NO(18) | 0)
++#define MT2701_PIN_18_PCM_CLK__FUNC_PCM_CLK0 (MTK_PIN_NO(18) | 1)
++#define MT2701_PIN_18_PCM_CLK__FUNC_MRG_CLK (MTK_PIN_NO(18) | 2)
++#define MT2701_PIN_18_PCM_CLK__FUNC_MM_TEST_CK (MTK_PIN_NO(18) | 4)
++#define MT2701_PIN_18_PCM_CLK__FUNC_CONN_DSP_JCK (MTK_PIN_NO(18) | 5)
++#define MT2701_PIN_18_PCM_CLK__FUNC_WCN_PCM_CLKO (MTK_PIN_NO(18) | 6)
++#define MT2701_PIN_18_PCM_CLK__FUNC_DBG_MON_A_3 (MTK_PIN_NO(18) | 7)
++
++#define MT2701_PIN_19_PCM_SYNC__FUNC_GPIO19 (MTK_PIN_NO(19) | 0)
++#define MT2701_PIN_19_PCM_SYNC__FUNC_PCM_SYNC (MTK_PIN_NO(19) | 1)
++#define MT2701_PIN_19_PCM_SYNC__FUNC_MRG_SYNC (MTK_PIN_NO(19) | 2)
++#define MT2701_PIN_19_PCM_SYNC__FUNC_CONN_DSP_JINTP (MTK_PIN_NO(19) | 5)
++#define MT2701_PIN_19_PCM_SYNC__FUNC_WCN_PCM_SYNC (MTK_PIN_NO(19) | 6)
++#define MT2701_PIN_19_PCM_SYNC__FUNC_DBG_MON_A_5 (MTK_PIN_NO(19) | 7)
++
++#define MT2701_PIN_20_PCM_RX__FUNC_GPIO20 (MTK_PIN_NO(20) | 0)
++#define MT2701_PIN_20_PCM_RX__FUNC_PCM_RX (MTK_PIN_NO(20) | 1)
++#define MT2701_PIN_20_PCM_RX__FUNC_MRG_RX (MTK_PIN_NO(20) | 2)
++#define MT2701_PIN_20_PCM_RX__FUNC_MRG_TX (MTK_PIN_NO(20) | 3)
++#define MT2701_PIN_20_PCM_RX__FUNC_PCM_TX (MTK_PIN_NO(20) | 4)
++#define MT2701_PIN_20_PCM_RX__FUNC_CONN_DSP_JDI (MTK_PIN_NO(20) | 5)
++#define MT2701_PIN_20_PCM_RX__FUNC_WCN_PCM_RX (MTK_PIN_NO(20) | 6)
++#define MT2701_PIN_20_PCM_RX__FUNC_DBG_MON_A_4 (MTK_PIN_NO(20) | 7)
++
++#define MT2701_PIN_21_PCM_TX__FUNC_GPIO21 (MTK_PIN_NO(21) | 0)
++#define MT2701_PIN_21_PCM_TX__FUNC_PCM_TX (MTK_PIN_NO(21) | 1)
++#define MT2701_PIN_21_PCM_TX__FUNC_MRG_TX (MTK_PIN_NO(21) | 2)
++#define MT2701_PIN_21_PCM_TX__FUNC_MRG_RX (MTK_PIN_NO(21) | 3)
++#define MT2701_PIN_21_PCM_TX__FUNC_PCM_RX (MTK_PIN_NO(21) | 4)
++#define MT2701_PIN_21_PCM_TX__FUNC_CONN_DSP_JMS (MTK_PIN_NO(21) | 5)
++#define MT2701_PIN_21_PCM_TX__FUNC_WCN_PCM_TX (MTK_PIN_NO(21) | 6)
++#define MT2701_PIN_21_PCM_TX__FUNC_DBG_MON_A_2 (MTK_PIN_NO(21) | 7)
++
++#define MT2701_PIN_22_EINT0__FUNC_GPIO22 (MTK_PIN_NO(22) | 0)
++#define MT2701_PIN_22_EINT0__FUNC_UCTS0 (MTK_PIN_NO(22) | 1)
++#define MT2701_PIN_22_EINT0__FUNC_KCOL3 (MTK_PIN_NO(22) | 3)
++#define MT2701_PIN_22_EINT0__FUNC_CONN_DSP_JDO (MTK_PIN_NO(22) | 4)
++#define MT2701_PIN_22_EINT0__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(22) | 5)
++#define MT2701_PIN_22_EINT0__FUNC_DBG_MON_A_30 (MTK_PIN_NO(22) | 7)
++#define MT2701_PIN_22_EINT0__FUNC_PCIE0_PERST_N (MTK_PIN_NO(22) | 10)
++
++#define MT2701_PIN_23_EINT1__FUNC_GPIO23 (MTK_PIN_NO(23) | 0)
++#define MT2701_PIN_23_EINT1__FUNC_URTS0 (MTK_PIN_NO(23) | 1)
++#define MT2701_PIN_23_EINT1__FUNC_KCOL2 (MTK_PIN_NO(23) | 3)
++#define MT2701_PIN_23_EINT1__FUNC_CONN_MCU_TDO (MTK_PIN_NO(23) | 4)
++#define MT2701_PIN_23_EINT1__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(23) | 5)
++#define MT2701_PIN_23_EINT1__FUNC_DBG_MON_A_29 (MTK_PIN_NO(23) | 7)
++#define MT2701_PIN_23_EINT1__FUNC_PCIE1_PERST_N (MTK_PIN_NO(23) | 10)
++
++#define MT2701_PIN_24_EINT2__FUNC_GPIO24 (MTK_PIN_NO(24) | 0)
++#define MT2701_PIN_24_EINT2__FUNC_UCTS1 (MTK_PIN_NO(24) | 1)
++#define MT2701_PIN_24_EINT2__FUNC_KCOL1 (MTK_PIN_NO(24) | 3)
++#define MT2701_PIN_24_EINT2__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(24) | 4)
++#define MT2701_PIN_24_EINT2__FUNC_DBG_MON_A_28 (MTK_PIN_NO(24) | 7)
++#define MT2701_PIN_24_EINT2__FUNC_PCIE2_PERST_N (MTK_PIN_NO(24) | 10)
++
++#define MT2701_PIN_25_EINT3__FUNC_GPIO25 (MTK_PIN_NO(25) | 0)
++#define MT2701_PIN_25_EINT3__FUNC_URTS1 (MTK_PIN_NO(25) | 1)
++#define MT2701_PIN_25_EINT3__FUNC_KCOL0 (MTK_PIN_NO(25) | 3)
++#define MT2701_PIN_25_EINT3__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(25) | 4)
++#define MT2701_PIN_25_EINT3__FUNC_DBG_MON_A_27 (MTK_PIN_NO(25) | 7)
++
++#define MT2701_PIN_26_EINT4__FUNC_GPIO26 (MTK_PIN_NO(26) | 0)
++#define MT2701_PIN_26_EINT4__FUNC_UCTS3 (MTK_PIN_NO(26) | 1)
++#define MT2701_PIN_26_EINT4__FUNC_DRV_VBUS_P1 (MTK_PIN_NO(26) | 2)
++#define MT2701_PIN_26_EINT4__FUNC_KROW3 (MTK_PIN_NO(26) | 3)
++#define MT2701_PIN_26_EINT4__FUNC_CONN_MCU_TCK0 (MTK_PIN_NO(26) | 4)
++#define MT2701_PIN_26_EINT4__FUNC_CONN_MCU_AICE_JCKC (MTK_PIN_NO(26) | 5)
++#define MT2701_PIN_26_EINT4__FUNC_PCIE2_WAKE_N (MTK_PIN_NO(26) | 6)
++#define MT2701_PIN_26_EINT4__FUNC_DBG_MON_A_26 (MTK_PIN_NO(26) | 7)
++
++#define MT2701_PIN_27_EINT5__FUNC_GPIO27 (MTK_PIN_NO(27) | 0)
++#define MT2701_PIN_27_EINT5__FUNC_URTS3 (MTK_PIN_NO(27) | 1)
++#define MT2701_PIN_27_EINT5__FUNC_IDDIG_P1 (MTK_PIN_NO(27) | 2)
++#define MT2701_PIN_27_EINT5__FUNC_KROW2 (MTK_PIN_NO(27) | 3)
++#define MT2701_PIN_27_EINT5__FUNC_CONN_MCU_TDI (MTK_PIN_NO(27) | 4)
++#define MT2701_PIN_27_EINT5__FUNC_PCIE1_WAKE_N (MTK_PIN_NO(27) | 6)
++#define MT2701_PIN_27_EINT5__FUNC_DBG_MON_A_25 (MTK_PIN_NO(27) | 7)
++
++#define MT2701_PIN_28_EINT6__FUNC_GPIO28 (MTK_PIN_NO(28) | 0)
++#define MT2701_PIN_28_EINT6__FUNC_DRV_VBUS (MTK_PIN_NO(28) | 1)
++#define MT2701_PIN_28_EINT6__FUNC_KROW1 (MTK_PIN_NO(28) | 3)
++#define MT2701_PIN_28_EINT6__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(28) | 4)
++#define MT2701_PIN_28_EINT6__FUNC_PCIE0_WAKE_N (MTK_PIN_NO(28) | 6)
++#define MT2701_PIN_28_EINT6__FUNC_DBG_MON_A_24 (MTK_PIN_NO(28) | 7)
++
++#define MT2701_PIN_29_EINT7__FUNC_GPIO29 (MTK_PIN_NO(29) | 0)
++#define MT2701_PIN_29_EINT7__FUNC_IDDIG (MTK_PIN_NO(29) | 1)
++#define MT2701_PIN_29_EINT7__FUNC_MSDC1_WP (MTK_PIN_NO(29) | 2)
++#define MT2701_PIN_29_EINT7__FUNC_KROW0 (MTK_PIN_NO(29) | 3)
++#define MT2701_PIN_29_EINT7__FUNC_CONN_MCU_TMS (MTK_PIN_NO(29) | 4)
++#define MT2701_PIN_29_EINT7__FUNC_CONN_MCU_AICE_JMSC (MTK_PIN_NO(29) | 5)
++#define MT2701_PIN_29_EINT7__FUNC_DBG_MON_A_23 (MTK_PIN_NO(29) | 7)
++#define MT2701_PIN_29_EINT7__FUNC_PCIE2_PERST_N (MTK_PIN_NO(29) | 14)
++
++#define MT2701_PIN_33_I2S1_DATA__FUNC_GPIO33 (MTK_PIN_NO(33) | 0)
++#define MT2701_PIN_33_I2S1_DATA__FUNC_I2S1_DATA (MTK_PIN_NO(33) | 1)
++#define MT2701_PIN_33_I2S1_DATA__FUNC_I2S1_DATA_BYPS (MTK_PIN_NO(33) | 2)
++#define MT2701_PIN_33_I2S1_DATA__FUNC_PCM_TX (MTK_PIN_NO(33) | 3)
++#define MT2701_PIN_33_I2S1_DATA__FUNC_IMG_TEST_CK (MTK_PIN_NO(33) | 4)
++#define MT2701_PIN_33_I2S1_DATA__FUNC_G1_RXD0 (MTK_PIN_NO(33) | 5)
++#define MT2701_PIN_33_I2S1_DATA__FUNC_WCN_PCM_TX (MTK_PIN_NO(33) | 6)
++#define MT2701_PIN_33_I2S1_DATA__FUNC_DBG_MON_B_8 (MTK_PIN_NO(33) | 7)
++
++#define MT2701_PIN_34_I2S1_DATA_IN__FUNC_GPIO34 (MTK_PIN_NO(34) | 0)
++#define MT2701_PIN_34_I2S1_DATA_IN__FUNC_I2S1_DATA_IN (MTK_PIN_NO(34) | 1)
++#define MT2701_PIN_34_I2S1_DATA_IN__FUNC_PCM_RX (MTK_PIN_NO(34) | 3)
++#define MT2701_PIN_34_I2S1_DATA_IN__FUNC_VDEC_TEST_CK (MTK_PIN_NO(34) | 4)
++#define MT2701_PIN_34_I2S1_DATA_IN__FUNC_G1_RXD1 (MTK_PIN_NO(34) | 5)
++#define MT2701_PIN_34_I2S1_DATA_IN__FUNC_WCN_PCM_RX (MTK_PIN_NO(34) | 6)
++#define MT2701_PIN_34_I2S1_DATA_IN__FUNC_DBG_MON_B_7 (MTK_PIN_NO(34) | 7)
++
++#define MT2701_PIN_35_I2S1_BCK__FUNC_GPIO35 (MTK_PIN_NO(35) | 0)
++#define MT2701_PIN_35_I2S1_BCK__FUNC_I2S1_BCK (MTK_PIN_NO(35) | 1)
++#define MT2701_PIN_35_I2S1_BCK__FUNC_PCM_CLK0 (MTK_PIN_NO(35) | 3)
++#define MT2701_PIN_35_I2S1_BCK__FUNC_G1_RXD2 (MTK_PIN_NO(35) | 5)
++#define MT2701_PIN_35_I2S1_BCK__FUNC_WCN_PCM_CLKO (MTK_PIN_NO(35) | 6)
++#define MT2701_PIN_35_I2S1_BCK__FUNC_DBG_MON_B_9 (MTK_PIN_NO(35) | 7)
++
++#define MT2701_PIN_36_I2S1_LRCK__FUNC_GPIO36 (MTK_PIN_NO(36) | 0)
++#define MT2701_PIN_36_I2S1_LRCK__FUNC_I2S1_LRCK (MTK_PIN_NO(36) | 1)
++#define MT2701_PIN_36_I2S1_LRCK__FUNC_PCM_SYNC (MTK_PIN_NO(36) | 3)
++#define MT2701_PIN_36_I2S1_LRCK__FUNC_G1_RXD3 (MTK_PIN_NO(36) | 5)
++#define MT2701_PIN_36_I2S1_LRCK__FUNC_WCN_PCM_SYNC (MTK_PIN_NO(36) | 6)
++#define MT2701_PIN_36_I2S1_LRCK__FUNC_DBG_MON_B_10 (MTK_PIN_NO(36) | 7)
++
++#define MT2701_PIN_37_I2S1_MCLK__FUNC_GPIO37 (MTK_PIN_NO(37) | 0)
++#define MT2701_PIN_37_I2S1_MCLK__FUNC_I2S1_MCLK (MTK_PIN_NO(37) | 1)
++#define MT2701_PIN_37_I2S1_MCLK__FUNC_G1_RXDV (MTK_PIN_NO(37) | 5)
++#define MT2701_PIN_37_I2S1_MCLK__FUNC_DBG_MON_B_11 (MTK_PIN_NO(37) | 7)
++
++#define MT2701_PIN_39_JTMS__FUNC_GPIO39 (MTK_PIN_NO(39) | 0)
++#define MT2701_PIN_39_JTMS__FUNC_JTMS (MTK_PIN_NO(39) | 1)
++#define MT2701_PIN_39_JTMS__FUNC_CONN_MCU_TMS (MTK_PIN_NO(39) | 2)
++#define MT2701_PIN_39_JTMS__FUNC_CONN_MCU_AICE_JMSC (MTK_PIN_NO(39) | 3)
++#define MT2701_PIN_39_JTMS__FUNC_DFD_TMS_XI (MTK_PIN_NO(39) | 4)
++
++#define MT2701_PIN_40_JTCK__FUNC_GPIO40 (MTK_PIN_NO(40) | 0)
++#define MT2701_PIN_40_JTCK__FUNC_JTCK (MTK_PIN_NO(40) | 1)
++#define MT2701_PIN_40_JTCK__FUNC_CONN_MCU_TCK1 (MTK_PIN_NO(40) | 2)
++#define MT2701_PIN_40_JTCK__FUNC_CONN_MCU_AICE_JCKC (MTK_PIN_NO(40) | 3)
++#define MT2701_PIN_40_JTCK__FUNC_DFD_TCK_XI (MTK_PIN_NO(40) | 4)
++
++#define MT2701_PIN_41_JTDI__FUNC_GPIO41 (MTK_PIN_NO(41) | 0)
++#define MT2701_PIN_41_JTDI__FUNC_JTDI (MTK_PIN_NO(41) | 1)
++#define MT2701_PIN_41_JTDI__FUNC_CONN_MCU_TDI (MTK_PIN_NO(41) | 2)
++#define MT2701_PIN_41_JTDI__FUNC_DFD_TDI_XI (MTK_PIN_NO(41) | 4)
++
++#define MT2701_PIN_42_JTDO__FUNC_GPIO42 (MTK_PIN_NO(42) | 0)
++#define MT2701_PIN_42_JTDO__FUNC_JTDO (MTK_PIN_NO(42) | 1)
++#define MT2701_PIN_42_JTDO__FUNC_CONN_MCU_TDO (MTK_PIN_NO(42) | 2)
++#define MT2701_PIN_42_JTDO__FUNC_DFD_TDO (MTK_PIN_NO(42) | 4)
++
++#define MT2701_PIN_43_NCLE__FUNC_GPIO43 (MTK_PIN_NO(43) | 0)
++#define MT2701_PIN_43_NCLE__FUNC_NCLE (MTK_PIN_NO(43) | 1)
++#define MT2701_PIN_43_NCLE__FUNC_EXT_XCS2 (MTK_PIN_NO(43) | 2)
++
++#define MT2701_PIN_44_NCEB1__FUNC_GPIO44 (MTK_PIN_NO(44) | 0)
++#define MT2701_PIN_44_NCEB1__FUNC_NCEB1 (MTK_PIN_NO(44) | 1)
++#define MT2701_PIN_44_NCEB1__FUNC_IDDIG (MTK_PIN_NO(44) | 2)
++
++#define MT2701_PIN_45_NCEB0__FUNC_GPIO45 (MTK_PIN_NO(45) | 0)
++#define MT2701_PIN_45_NCEB0__FUNC_NCEB0 (MTK_PIN_NO(45) | 1)
++#define MT2701_PIN_45_NCEB0__FUNC_DRV_VBUS (MTK_PIN_NO(45) | 2)
++
++#define MT2701_PIN_46_IR__FUNC_GPIO46 (MTK_PIN_NO(46) | 0)
++#define MT2701_PIN_46_IR__FUNC_IR (MTK_PIN_NO(46) | 1)
++
++#define MT2701_PIN_47_NREB__FUNC_GPIO47 (MTK_PIN_NO(47) | 0)
++#define MT2701_PIN_47_NREB__FUNC_NREB (MTK_PIN_NO(47) | 1)
++#define MT2701_PIN_47_NREB__FUNC_IDDIG_P1 (MTK_PIN_NO(47) | 2)
++
++#define MT2701_PIN_48_NRNB__FUNC_GPIO48 (MTK_PIN_NO(48) | 0)
++#define MT2701_PIN_48_NRNB__FUNC_NRNB (MTK_PIN_NO(48) | 1)
++#define MT2701_PIN_48_NRNB__FUNC_DRV_VBUS_P1 (MTK_PIN_NO(48) | 2)
++
++#define MT2701_PIN_49_I2S0_DATA__FUNC_GPIO49 (MTK_PIN_NO(49) | 0)
++#define MT2701_PIN_49_I2S0_DATA__FUNC_I2S0_DATA (MTK_PIN_NO(49) | 1)
++#define MT2701_PIN_49_I2S0_DATA__FUNC_I2S0_DATA_BYPS (MTK_PIN_NO(49) | 2)
++#define MT2701_PIN_49_I2S0_DATA__FUNC_PCM_TX (MTK_PIN_NO(49) | 3)
++#define MT2701_PIN_49_I2S0_DATA__FUNC_WCN_I2S_DO (MTK_PIN_NO(49) | 6)
++#define MT2701_PIN_49_I2S0_DATA__FUNC_DBG_MON_B_3 (MTK_PIN_NO(49) | 7)
++
++#define MT2701_PIN_53_SPI0_CSN__FUNC_GPIO53 (MTK_PIN_NO(53) | 0)
++#define MT2701_PIN_53_SPI0_CSN__FUNC_SPI0_CS (MTK_PIN_NO(53) | 1)
++#define MT2701_PIN_53_SPI0_CSN__FUNC_SPDIF (MTK_PIN_NO(53) | 3)
++#define MT2701_PIN_53_SPI0_CSN__FUNC_ADC_CK (MTK_PIN_NO(53) | 4)
++#define MT2701_PIN_53_SPI0_CSN__FUNC_PWM1 (MTK_PIN_NO(53) | 5)
++#define MT2701_PIN_53_SPI0_CSN__FUNC_DBG_MON_A_7 (MTK_PIN_NO(53) | 7)
++
++#define MT2701_PIN_54_SPI0_CK__FUNC_GPIO54 (MTK_PIN_NO(54) | 0)
++#define MT2701_PIN_54_SPI0_CK__FUNC_SPI0_CK (MTK_PIN_NO(54) | 1)
++#define MT2701_PIN_54_SPI0_CK__FUNC_SPDIF_IN1 (MTK_PIN_NO(54) | 3)
++#define MT2701_PIN_54_SPI0_CK__FUNC_ADC_DAT_IN (MTK_PIN_NO(54) | 4)
++#define MT2701_PIN_54_SPI0_CK__FUNC_DBG_MON_A_10 (MTK_PIN_NO(54) | 7)
++
++#define MT2701_PIN_55_SPI0_MI__FUNC_GPIO55 (MTK_PIN_NO(55) | 0)
++#define MT2701_PIN_55_SPI0_MI__FUNC_SPI0_MI (MTK_PIN_NO(55) | 1)
++#define MT2701_PIN_55_SPI0_MI__FUNC_SPI0_MO (MTK_PIN_NO(55) | 2)
++#define MT2701_PIN_55_SPI0_MI__FUNC_MSDC1_WP (MTK_PIN_NO(55) | 3)
++#define MT2701_PIN_55_SPI0_MI__FUNC_ADC_WS (MTK_PIN_NO(55) | 4)
++#define MT2701_PIN_55_SPI0_MI__FUNC_PWM2 (MTK_PIN_NO(55) | 5)
++#define MT2701_PIN_55_SPI0_MI__FUNC_DBG_MON_A_8 (MTK_PIN_NO(55) | 7)
++
++#define MT2701_PIN_56_SPI0_MO__FUNC_GPIO56 (MTK_PIN_NO(56) | 0)
++#define MT2701_PIN_56_SPI0_MO__FUNC_SPI0_MO (MTK_PIN_NO(56) | 1)
++#define MT2701_PIN_56_SPI0_MO__FUNC_SPI0_MI (MTK_PIN_NO(56) | 2)
++#define MT2701_PIN_56_SPI0_MO__FUNC_SPDIF_IN0 (MTK_PIN_NO(56) | 3)
++#define MT2701_PIN_56_SPI0_MO__FUNC_DBG_MON_A_9 (MTK_PIN_NO(56) | 7)
++
++#define MT2701_PIN_57_SDA1__FUNC_GPIO57 (MTK_PIN_NO(57) | 0)
++#define MT2701_PIN_57_SDA1__FUNC_SDA1 (MTK_PIN_NO(57) | 1)
++
++#define MT2701_PIN_58_SCL1__FUNC_GPIO58 (MTK_PIN_NO(58) | 0)
++#define MT2701_PIN_58_SCL1__FUNC_SCL1 (MTK_PIN_NO(58) | 1)
++
++#define MT2701_PIN_72_I2S0_DATA_IN__FUNC_GPIO72 (MTK_PIN_NO(72) | 0)
++#define MT2701_PIN_72_I2S0_DATA_IN__FUNC_I2S0_DATA_IN (MTK_PIN_NO(72) | 1)
++#define MT2701_PIN_72_I2S0_DATA_IN__FUNC_PCM_RX (MTK_PIN_NO(72) | 3)
++#define MT2701_PIN_72_I2S0_DATA_IN__FUNC_PWM0 (MTK_PIN_NO(72) | 4)
++#define MT2701_PIN_72_I2S0_DATA_IN__FUNC_DISP_PWM (MTK_PIN_NO(72) | 5)
++#define MT2701_PIN_72_I2S0_DATA_IN__FUNC_WCN_I2S_DI (MTK_PIN_NO(72) | 6)
++#define MT2701_PIN_72_I2S0_DATA_IN__FUNC_DBG_MON_B_2 (MTK_PIN_NO(72) | 7)
++
++#define MT2701_PIN_73_I2S0_LRCK__FUNC_GPIO73 (MTK_PIN_NO(73) | 0)
++#define MT2701_PIN_73_I2S0_LRCK__FUNC_I2S0_LRCK (MTK_PIN_NO(73) | 1)
++#define MT2701_PIN_73_I2S0_LRCK__FUNC_PCM_SYNC (MTK_PIN_NO(73) | 3)
++#define MT2701_PIN_73_I2S0_LRCK__FUNC_WCN_I2S_LRCK (MTK_PIN_NO(73) | 6)
++#define MT2701_PIN_73_I2S0_LRCK__FUNC_DBG_MON_B_5 (MTK_PIN_NO(73) | 7)
++
++#define MT2701_PIN_74_I2S0_BCK__FUNC_GPIO74 (MTK_PIN_NO(74) | 0)
++#define MT2701_PIN_74_I2S0_BCK__FUNC_I2S0_BCK (MTK_PIN_NO(74) | 1)
++#define MT2701_PIN_74_I2S0_BCK__FUNC_PCM_CLK0 (MTK_PIN_NO(74) | 3)
++#define MT2701_PIN_74_I2S0_BCK__FUNC_WCN_I2S_BCK (MTK_PIN_NO(74) | 6)
++#define MT2701_PIN_74_I2S0_BCK__FUNC_DBG_MON_B_4 (MTK_PIN_NO(74) | 7)
++
++#define MT2701_PIN_75_SDA0__FUNC_GPIO75 (MTK_PIN_NO(75) | 0)
++#define MT2701_PIN_75_SDA0__FUNC_SDA0 (MTK_PIN_NO(75) | 1)
++
++#define MT2701_PIN_76_SCL0__FUNC_GPIO76 (MTK_PIN_NO(76) | 0)
++#define MT2701_PIN_76_SCL0__FUNC_SCL0 (MTK_PIN_NO(76) | 1)
++
++#define MT2701_PIN_77_SDA2__FUNC_GPIO77 (MTK_PIN_NO(77) | 0)
++#define MT2701_PIN_77_SDA2__FUNC_SDA2 (MTK_PIN_NO(77) | 1)
++
++#define MT2701_PIN_78_SCL2__FUNC_GPIO78 (MTK_PIN_NO(78) | 0)
++#define MT2701_PIN_78_SCL2__FUNC_SCL2 (MTK_PIN_NO(78) | 1)
++
++#define MT2701_PIN_79_URXD0__FUNC_GPIO79 (MTK_PIN_NO(79) | 0)
++#define MT2701_PIN_79_URXD0__FUNC_URXD0 (MTK_PIN_NO(79) | 1)
++#define MT2701_PIN_79_URXD0__FUNC_UTXD0 (MTK_PIN_NO(79) | 2)
++#define MT2701_PIN_79_URXD0__FUNC_ (MTK_PIN_NO(79) | 5)
++
++#define MT2701_PIN_80_UTXD0__FUNC_GPIO80 (MTK_PIN_NO(80) | 0)
++#define MT2701_PIN_80_UTXD0__FUNC_UTXD0 (MTK_PIN_NO(80) | 1)
++#define MT2701_PIN_80_UTXD0__FUNC_URXD0 (MTK_PIN_NO(80) | 2)
++
++#define MT2701_PIN_81_URXD1__FUNC_GPIO81 (MTK_PIN_NO(81) | 0)
++#define MT2701_PIN_81_URXD1__FUNC_URXD1 (MTK_PIN_NO(81) | 1)
++#define MT2701_PIN_81_URXD1__FUNC_UTXD1 (MTK_PIN_NO(81) | 2)
++
++#define MT2701_PIN_82_UTXD1__FUNC_GPIO82 (MTK_PIN_NO(82) | 0)
++#define MT2701_PIN_82_UTXD1__FUNC_UTXD1 (MTK_PIN_NO(82) | 1)
++#define MT2701_PIN_82_UTXD1__FUNC_URXD1 (MTK_PIN_NO(82) | 2)
++
++#define MT2701_PIN_83_LCM_RST__FUNC_GPIO83 (MTK_PIN_NO(83) | 0)
++#define MT2701_PIN_83_LCM_RST__FUNC_LCM_RST (MTK_PIN_NO(83) | 1)
++#define MT2701_PIN_83_LCM_RST__FUNC_VDAC_CK_XI (MTK_PIN_NO(83) | 2)
++#define MT2701_PIN_83_LCM_RST__FUNC_DBG_MON_B_1 (MTK_PIN_NO(83) | 7)
++
++#define MT2701_PIN_84_DSI_TE__FUNC_GPIO84 (MTK_PIN_NO(84) | 0)
++#define MT2701_PIN_84_DSI_TE__FUNC_DSI_TE (MTK_PIN_NO(84) | 1)
++#define MT2701_PIN_84_DSI_TE__FUNC_DBG_MON_B_0 (MTK_PIN_NO(84) | 7)
++
++#define MT2701_PIN_91_TDN3__FUNC_GPI91 (MTK_PIN_NO(91) | 0)
++#define MT2701_PIN_91_TDN3__FUNC_TDN3 (MTK_PIN_NO(91) | 1)
++
++#define MT2701_PIN_92_TDP3__FUNC_GPI92 (MTK_PIN_NO(92) | 0)
++#define MT2701_PIN_92_TDP3__FUNC_TDP3 (MTK_PIN_NO(92) | 1)
++
++#define MT2701_PIN_93_TDN2__FUNC_GPI93 (MTK_PIN_NO(93) | 0)
++#define MT2701_PIN_93_TDN2__FUNC_TDN2 (MTK_PIN_NO(93) | 1)
++
++#define MT2701_PIN_94_TDP2__FUNC_GPI94 (MTK_PIN_NO(94) | 0)
++#define MT2701_PIN_94_TDP2__FUNC_TDP2 (MTK_PIN_NO(94) | 1)
++
++#define MT2701_PIN_95_TCN__FUNC_GPI95 (MTK_PIN_NO(95) | 0)
++#define MT2701_PIN_95_TCN__FUNC_TCN (MTK_PIN_NO(95) | 1)
++
++#define MT2701_PIN_96_TCP__FUNC_GPI96 (MTK_PIN_NO(96) | 0)
++#define MT2701_PIN_96_TCP__FUNC_TCP (MTK_PIN_NO(96) | 1)
++
++#define MT2701_PIN_97_TDN1__FUNC_GPI97 (MTK_PIN_NO(97) | 0)
++#define MT2701_PIN_97_TDN1__FUNC_TDN1 (MTK_PIN_NO(97) | 1)
++
++#define MT2701_PIN_98_TDP1__FUNC_GPI98 (MTK_PIN_NO(98) | 0)
++#define MT2701_PIN_98_TDP1__FUNC_TDP1 (MTK_PIN_NO(98) | 1)
++
++#define MT2701_PIN_99_TDN0__FUNC_GPI99 (MTK_PIN_NO(99) | 0)
++#define MT2701_PIN_99_TDN0__FUNC_TDN0 (MTK_PIN_NO(99) | 1)
++
++#define MT2701_PIN_100_TDP0__FUNC_GPI100 (MTK_PIN_NO(100) | 0)
++#define MT2701_PIN_100_TDP0__FUNC_TDP0 (MTK_PIN_NO(100) | 1)
++
++#define MT2701_PIN_101_SPI2_CSN__FUNC_GPIO101 (MTK_PIN_NO(101) | 0)
++#define MT2701_PIN_101_SPI2_CSN__FUNC_SPI2_CS (MTK_PIN_NO(101) | 1)
++#define MT2701_PIN_101_SPI2_CSN__FUNC_SCL3 (MTK_PIN_NO(101) | 3)
++#define MT2701_PIN_101_SPI2_CSN__FUNC_KROW0 (MTK_PIN_NO(101) | 4)
++
++#define MT2701_PIN_102_SPI2_MI__FUNC_GPIO102 (MTK_PIN_NO(102) | 0)
++#define MT2701_PIN_102_SPI2_MI__FUNC_SPI2_MI (MTK_PIN_NO(102) | 1)
++#define MT2701_PIN_102_SPI2_MI__FUNC_SPI2_MO (MTK_PIN_NO(102) | 2)
++#define MT2701_PIN_102_SPI2_MI__FUNC_SDA3 (MTK_PIN_NO(102) | 3)
++#define MT2701_PIN_102_SPI2_MI__FUNC_KROW1 (MTK_PIN_NO(102) | 4)
++
++#define MT2701_PIN_103_SPI2_MO__FUNC_GPIO103 (MTK_PIN_NO(103) | 0)
++#define MT2701_PIN_103_SPI2_MO__FUNC_SPI2_MO (MTK_PIN_NO(103) | 1)
++#define MT2701_PIN_103_SPI2_MO__FUNC_SPI2_MI (MTK_PIN_NO(103) | 2)
++#define MT2701_PIN_103_SPI2_MO__FUNC_SCL3 (MTK_PIN_NO(103) | 3)
++#define MT2701_PIN_103_SPI2_MO__FUNC_KROW2 (MTK_PIN_NO(103) | 4)
++
++#define MT2701_PIN_104_SPI2_CLK__FUNC_GPIO104 (MTK_PIN_NO(104) | 0)
++#define MT2701_PIN_104_SPI2_CLK__FUNC_SPI2_CK (MTK_PIN_NO(104) | 1)
++#define MT2701_PIN_104_SPI2_CLK__FUNC_SDA3 (MTK_PIN_NO(104) | 3)
++#define MT2701_PIN_104_SPI2_CLK__FUNC_KROW3 (MTK_PIN_NO(104) | 4)
++
++#define MT2701_PIN_105_MSDC1_CMD__FUNC_GPIO105 (MTK_PIN_NO(105) | 0)
++#define MT2701_PIN_105_MSDC1_CMD__FUNC_MSDC1_CMD (MTK_PIN_NO(105) | 1)
++#define MT2701_PIN_105_MSDC1_CMD__FUNC_ANT_SEL0 (MTK_PIN_NO(105) | 2)
++#define MT2701_PIN_105_MSDC1_CMD__FUNC_SDA1 (MTK_PIN_NO(105) | 3)
++#define MT2701_PIN_105_MSDC1_CMD__FUNC_I2SOUT_BCK (MTK_PIN_NO(105) | 6)
++#define MT2701_PIN_105_MSDC1_CMD__FUNC_DBG_MON_B_27 (MTK_PIN_NO(105) | 7)
++
++#define MT2701_PIN_106_MSDC1_CLK__FUNC_GPIO106 (MTK_PIN_NO(106) | 0)
++#define MT2701_PIN_106_MSDC1_CLK__FUNC_MSDC1_CLK (MTK_PIN_NO(106) | 1)
++#define MT2701_PIN_106_MSDC1_CLK__FUNC_ANT_SEL1 (MTK_PIN_NO(106) | 2)
++#define MT2701_PIN_106_MSDC1_CLK__FUNC_SCL1 (MTK_PIN_NO(106) | 3)
++#define MT2701_PIN_106_MSDC1_CLK__FUNC_I2SOUT_LRCK (MTK_PIN_NO(106) | 6)
++#define MT2701_PIN_106_MSDC1_CLK__FUNC_DBG_MON_B_28 (MTK_PIN_NO(106) | 7)
++
++#define MT2701_PIN_107_MSDC1_DAT0__FUNC_GPIO107 (MTK_PIN_NO(107) | 0)
++#define MT2701_PIN_107_MSDC1_DAT0__FUNC_MSDC1_DAT0 (MTK_PIN_NO(107) | 1)
++#define MT2701_PIN_107_MSDC1_DAT0__FUNC_ANT_SEL2 (MTK_PIN_NO(107) | 2)
++#define MT2701_PIN_107_MSDC1_DAT0__FUNC_UTXD0 (MTK_PIN_NO(107) | 5)
++#define MT2701_PIN_107_MSDC1_DAT0__FUNC_I2SOUT_DATA_OUT (MTK_PIN_NO(107) | 6)
++#define MT2701_PIN_107_MSDC1_DAT0__FUNC_DBG_MON_B_26 (MTK_PIN_NO(107) | 7)
++
++#define MT2701_PIN_108_MSDC1_DAT1__FUNC_GPIO108 (MTK_PIN_NO(108) | 0)
++#define MT2701_PIN_108_MSDC1_DAT1__FUNC_MSDC1_DAT1 (MTK_PIN_NO(108) | 1)
++#define MT2701_PIN_108_MSDC1_DAT1__FUNC_ANT_SEL3 (MTK_PIN_NO(108) | 2)
++#define MT2701_PIN_108_MSDC1_DAT1__FUNC_PWM0 (MTK_PIN_NO(108) | 3)
++#define MT2701_PIN_108_MSDC1_DAT1__FUNC_URXD0 (MTK_PIN_NO(108) | 5)
++#define MT2701_PIN_108_MSDC1_DAT1__FUNC_PWM1 (MTK_PIN_NO(108) | 6)
++#define MT2701_PIN_108_MSDC1_DAT1__FUNC_DBG_MON_B_25 (MTK_PIN_NO(108) | 7)
++
++#define MT2701_PIN_109_MSDC1_DAT2__FUNC_GPIO109 (MTK_PIN_NO(109) | 0)
++#define MT2701_PIN_109_MSDC1_DAT2__FUNC_MSDC1_DAT2 (MTK_PIN_NO(109) | 1)
++#define MT2701_PIN_109_MSDC1_DAT2__FUNC_ANT_SEL4 (MTK_PIN_NO(109) | 2)
++#define MT2701_PIN_109_MSDC1_DAT2__FUNC_SDA2 (MTK_PIN_NO(109) | 3)
++#define MT2701_PIN_109_MSDC1_DAT2__FUNC_UTXD1 (MTK_PIN_NO(109) | 5)
++#define MT2701_PIN_109_MSDC1_DAT2__FUNC_PWM2 (MTK_PIN_NO(109) | 6)
++#define MT2701_PIN_109_MSDC1_DAT2__FUNC_DBG_MON_B_24 (MTK_PIN_NO(109) | 7)
++
++#define MT2701_PIN_110_MSDC1_DAT3__FUNC_GPIO110 (MTK_PIN_NO(110) | 0)
++#define MT2701_PIN_110_MSDC1_DAT3__FUNC_MSDC1_DAT3 (MTK_PIN_NO(110) | 1)
++#define MT2701_PIN_110_MSDC1_DAT3__FUNC_ANT_SEL5 (MTK_PIN_NO(110) | 2)
++#define MT2701_PIN_110_MSDC1_DAT3__FUNC_SCL2 (MTK_PIN_NO(110) | 3)
++#define MT2701_PIN_110_MSDC1_DAT3__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(110) | 4)
++#define MT2701_PIN_110_MSDC1_DAT3__FUNC_URXD1 (MTK_PIN_NO(110) | 5)
++#define MT2701_PIN_110_MSDC1_DAT3__FUNC_PWM3 (MTK_PIN_NO(110) | 6)
++#define MT2701_PIN_110_MSDC1_DAT3__FUNC_DBG_MON_B_23 (MTK_PIN_NO(110) | 7)
++
++#define MT2701_PIN_111_MSDC0_DAT7__FUNC_GPIO111 (MTK_PIN_NO(111) | 0)
++#define MT2701_PIN_111_MSDC0_DAT7__FUNC_MSDC0_DAT7 (MTK_PIN_NO(111) | 1)
++#define MT2701_PIN_111_MSDC0_DAT7__FUNC_NLD7 (MTK_PIN_NO(111) | 4)
++
++#define MT2701_PIN_112_MSDC0_DAT6__FUNC_GPIO112 (MTK_PIN_NO(112) | 0)
++#define MT2701_PIN_112_MSDC0_DAT6__FUNC_MSDC0_DAT6 (MTK_PIN_NO(112) | 1)
++#define MT2701_PIN_112_MSDC0_DAT6__FUNC_NLD6 (MTK_PIN_NO(112) | 4)
++
++#define MT2701_PIN_113_MSDC0_DAT5__FUNC_GPIO113 (MTK_PIN_NO(113) | 0)
++#define MT2701_PIN_113_MSDC0_DAT5__FUNC_MSDC0_DAT5 (MTK_PIN_NO(113) | 1)
++#define MT2701_PIN_113_MSDC0_DAT5__FUNC_NLD5 (MTK_PIN_NO(113) | 4)
++
++#define MT2701_PIN_114_MSDC0_DAT4__FUNC_GPIO114 (MTK_PIN_NO(114) | 0)
++#define MT2701_PIN_114_MSDC0_DAT4__FUNC_MSDC0_DAT4 (MTK_PIN_NO(114) | 1)
++#define MT2701_PIN_114_MSDC0_DAT4__FUNC_NLD4 (MTK_PIN_NO(114) | 4)
++
++#define MT2701_PIN_115_MSDC0_RSTB__FUNC_GPIO115 (MTK_PIN_NO(115) | 0)
++#define MT2701_PIN_115_MSDC0_RSTB__FUNC_MSDC0_RSTB (MTK_PIN_NO(115) | 1)
++#define MT2701_PIN_115_MSDC0_RSTB__FUNC_NLD8 (MTK_PIN_NO(115) | 4)
++
++#define MT2701_PIN_116_MSDC0_CMD__FUNC_GPIO116 (MTK_PIN_NO(116) | 0)
++#define MT2701_PIN_116_MSDC0_CMD__FUNC_MSDC0_CMD (MTK_PIN_NO(116) | 1)
++#define MT2701_PIN_116_MSDC0_CMD__FUNC_NALE (MTK_PIN_NO(116) | 4)
++
++#define MT2701_PIN_117_MSDC0_CLK__FUNC_GPIO117 (MTK_PIN_NO(117) | 0)
++#define MT2701_PIN_117_MSDC0_CLK__FUNC_MSDC0_CLK (MTK_PIN_NO(117) | 1)
++#define MT2701_PIN_117_MSDC0_CLK__FUNC_NWEB (MTK_PIN_NO(117) | 4)
++
++#define MT2701_PIN_118_MSDC0_DAT3__FUNC_GPIO118 (MTK_PIN_NO(118) | 0)
++#define MT2701_PIN_118_MSDC0_DAT3__FUNC_MSDC0_DAT3 (MTK_PIN_NO(118) | 1)
++#define MT2701_PIN_118_MSDC0_DAT3__FUNC_NLD3 (MTK_PIN_NO(118) | 4)
++
++#define MT2701_PIN_119_MSDC0_DAT2__FUNC_GPIO119 (MTK_PIN_NO(119) | 0)
++#define MT2701_PIN_119_MSDC0_DAT2__FUNC_MSDC0_DAT2 (MTK_PIN_NO(119) | 1)
++#define MT2701_PIN_119_MSDC0_DAT2__FUNC_NLD2 (MTK_PIN_NO(119) | 4)
++
++#define MT2701_PIN_120_MSDC0_DAT1__FUNC_GPIO120 (MTK_PIN_NO(120) | 0)
++#define MT2701_PIN_120_MSDC0_DAT1__FUNC_MSDC0_DAT1 (MTK_PIN_NO(120) | 1)
++#define MT2701_PIN_120_MSDC0_DAT1__FUNC_NLD1 (MTK_PIN_NO(120) | 4)
++
++#define MT2701_PIN_121_MSDC0_DAT0__FUNC_GPIO121 (MTK_PIN_NO(121) | 0)
++#define MT2701_PIN_121_MSDC0_DAT0__FUNC_MSDC0_DAT0 (MTK_PIN_NO(121) | 1)
++#define MT2701_PIN_121_MSDC0_DAT0__FUNC_NLD0 (MTK_PIN_NO(121) | 4)
++#define MT2701_PIN_121_MSDC0_DAT0__FUNC_WATCHDOG (MTK_PIN_NO(121) | 5)
++
++#define MT2701_PIN_122_CEC__FUNC_GPIO122 (MTK_PIN_NO(122) | 0)
++#define MT2701_PIN_122_CEC__FUNC_CEC (MTK_PIN_NO(122) | 1)
++#define MT2701_PIN_122_CEC__FUNC_SDA2 (MTK_PIN_NO(122) | 4)
++#define MT2701_PIN_122_CEC__FUNC_URXD0 (MTK_PIN_NO(122) | 5)
++
++#define MT2701_PIN_123_HTPLG__FUNC_GPIO123 (MTK_PIN_NO(123) | 0)
++#define MT2701_PIN_123_HTPLG__FUNC_HTPLG (MTK_PIN_NO(123) | 1)
++#define MT2701_PIN_123_HTPLG__FUNC_SCL2 (MTK_PIN_NO(123) | 4)
++#define MT2701_PIN_123_HTPLG__FUNC_UTXD0 (MTK_PIN_NO(123) | 5)
++
++#define MT2701_PIN_124_HDMISCK__FUNC_GPIO124 (MTK_PIN_NO(124) | 0)
++#define MT2701_PIN_124_HDMISCK__FUNC_HDMISCK (MTK_PIN_NO(124) | 1)
++#define MT2701_PIN_124_HDMISCK__FUNC_SDA1 (MTK_PIN_NO(124) | 4)
++#define MT2701_PIN_124_HDMISCK__FUNC_PWM3 (MTK_PIN_NO(124) | 5)
++
++#define MT2701_PIN_125_HDMISD__FUNC_GPIO125 (MTK_PIN_NO(125) | 0)
++#define MT2701_PIN_125_HDMISD__FUNC_HDMISD (MTK_PIN_NO(125) | 1)
++#define MT2701_PIN_125_HDMISD__FUNC_SCL1 (MTK_PIN_NO(125) | 4)
++#define MT2701_PIN_125_HDMISD__FUNC_PWM4 (MTK_PIN_NO(125) | 5)
++
++#define MT2701_PIN_126_I2S0_MCLK__FUNC_GPIO126 (MTK_PIN_NO(126) | 0)
++#define MT2701_PIN_126_I2S0_MCLK__FUNC_I2S0_MCLK (MTK_PIN_NO(126) | 1)
++#define MT2701_PIN_126_I2S0_MCLK__FUNC_WCN_I2S_MCLK (MTK_PIN_NO(126) | 6)
++#define MT2701_PIN_126_I2S0_MCLK__FUNC_DBG_MON_B_6 (MTK_PIN_NO(126) | 7)
++
++#define MT2701_PIN_199_SPI1_CLK__FUNC_GPIO199 (MTK_PIN_NO(199) | 0)
++#define MT2701_PIN_199_SPI1_CLK__FUNC_SPI1_CK (MTK_PIN_NO(199) | 1)
++#define MT2701_PIN_199_SPI1_CLK__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(199) | 3)
++#define MT2701_PIN_199_SPI1_CLK__FUNC_KCOL3 (MTK_PIN_NO(199) | 4)
++#define MT2701_PIN_199_SPI1_CLK__FUNC_DBG_MON_B_15 (MTK_PIN_NO(199) | 7)
++
++#define MT2701_PIN_200_SPDIF_OUT__FUNC_GPIO200 (MTK_PIN_NO(200) | 0)
++#define MT2701_PIN_200_SPDIF_OUT__FUNC_SPDIF_OUT (MTK_PIN_NO(200) | 1)
++#define MT2701_PIN_200_SPDIF_OUT__FUNC_G1_TXD3 (MTK_PIN_NO(200) | 5)
++#define MT2701_PIN_200_SPDIF_OUT__FUNC_URXD2 (MTK_PIN_NO(200) | 6)
++#define MT2701_PIN_200_SPDIF_OUT__FUNC_DBG_MON_B_16 (MTK_PIN_NO(200) | 7)
++
++#define MT2701_PIN_201_SPDIF_IN0__FUNC_GPIO201 (MTK_PIN_NO(201) | 0)
++#define MT2701_PIN_201_SPDIF_IN0__FUNC_SPDIF_IN0 (MTK_PIN_NO(201) | 1)
++#define MT2701_PIN_201_SPDIF_IN0__FUNC_G1_TXEN (MTK_PIN_NO(201) | 5)
++#define MT2701_PIN_201_SPDIF_IN0__FUNC_UTXD2 (MTK_PIN_NO(201) | 6)
++#define MT2701_PIN_201_SPDIF_IN0__FUNC_DBG_MON_B_17 (MTK_PIN_NO(201) | 7)
++
++#define MT2701_PIN_202_SPDIF_IN1__FUNC_GPIO202 (MTK_PIN_NO(202) | 0)
++#define MT2701_PIN_202_SPDIF_IN1__FUNC_SPDIF_IN1 (MTK_PIN_NO(202) | 1)
++
++#define MT2701_PIN_203_PWM0__FUNC_GPIO203 (MTK_PIN_NO(203) | 0)
++#define MT2701_PIN_203_PWM0__FUNC_PWM0 (MTK_PIN_NO(203) | 1)
++#define MT2701_PIN_203_PWM0__FUNC_DISP_PWM (MTK_PIN_NO(203) | 2)
++#define MT2701_PIN_203_PWM0__FUNC_G1_TXD2 (MTK_PIN_NO(203) | 5)
++#define MT2701_PIN_203_PWM0__FUNC_DBG_MON_B_18 (MTK_PIN_NO(203) | 7)
++#define MT2701_PIN_203_PWM0__FUNC_I2S2_DATA (MTK_PIN_NO(203) | 9)
++
++#define MT2701_PIN_204_PWM1__FUNC_GPIO204 (MTK_PIN_NO(204) | 0)
++#define MT2701_PIN_204_PWM1__FUNC_PWM1 (MTK_PIN_NO(204) | 1)
++#define MT2701_PIN_204_PWM1__FUNC_CLKM3 (MTK_PIN_NO(204) | 2)
++#define MT2701_PIN_204_PWM1__FUNC_G1_TXD1 (MTK_PIN_NO(204) | 5)
++#define MT2701_PIN_204_PWM1__FUNC_DBG_MON_B_19 (MTK_PIN_NO(204) | 7)
++#define MT2701_PIN_204_PWM1__FUNC_I2S3_DATA (MTK_PIN_NO(204) | 9)
++
++#define MT2701_PIN_205_PWM2__FUNC_GPIO205 (MTK_PIN_NO(205) | 0)
++#define MT2701_PIN_205_PWM2__FUNC_PWM2 (MTK_PIN_NO(205) | 1)
++#define MT2701_PIN_205_PWM2__FUNC_CLKM2 (MTK_PIN_NO(205) | 2)
++#define MT2701_PIN_205_PWM2__FUNC_G1_TXD0 (MTK_PIN_NO(205) | 5)
++#define MT2701_PIN_205_PWM2__FUNC_DBG_MON_B_20 (MTK_PIN_NO(205) | 7)
++
++#define MT2701_PIN_206_PWM3__FUNC_GPIO206 (MTK_PIN_NO(206) | 0)
++#define MT2701_PIN_206_PWM3__FUNC_PWM3 (MTK_PIN_NO(206) | 1)
++#define MT2701_PIN_206_PWM3__FUNC_CLKM1 (MTK_PIN_NO(206) | 2)
++#define MT2701_PIN_206_PWM3__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(206) | 3)
++#define MT2701_PIN_206_PWM3__FUNC_G1_TXC (MTK_PIN_NO(206) | 5)
++#define MT2701_PIN_206_PWM3__FUNC_DBG_MON_B_21 (MTK_PIN_NO(206) | 7)
++
++#define MT2701_PIN_207_PWM4__FUNC_GPIO207 (MTK_PIN_NO(207) | 0)
++#define MT2701_PIN_207_PWM4__FUNC_PWM4 (MTK_PIN_NO(207) | 1)
++#define MT2701_PIN_207_PWM4__FUNC_CLKM0 (MTK_PIN_NO(207) | 2)
++#define MT2701_PIN_207_PWM4__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(207) | 3)
++#define MT2701_PIN_207_PWM4__FUNC_G1_RXC (MTK_PIN_NO(207) | 5)
++#define MT2701_PIN_207_PWM4__FUNC_DBG_MON_B_22 (MTK_PIN_NO(207) | 7)
++
++#define MT2701_PIN_208_AUD_EXT_CK1__FUNC_GPIO208 (MTK_PIN_NO(208) | 0)
++#define MT2701_PIN_208_AUD_EXT_CK1__FUNC_AUD_EXT_CK1 (MTK_PIN_NO(208) | 1)
++#define MT2701_PIN_208_AUD_EXT_CK1__FUNC_PWM0 (MTK_PIN_NO(208) | 2)
++#define MT2701_PIN_208_AUD_EXT_CK1__FUNC_ANT_SEL5 (MTK_PIN_NO(208) | 4)
++#define MT2701_PIN_208_AUD_EXT_CK1__FUNC_DISP_PWM (MTK_PIN_NO(208) | 5)
++#define MT2701_PIN_208_AUD_EXT_CK1__FUNC_DBG_MON_A_31 (MTK_PIN_NO(208) | 7)
++#define MT2701_PIN_208_AUD_EXT_CK1__FUNC_PCIE0_PERST_N (MTK_PIN_NO(208) | 11)
++
++#define MT2701_PIN_209_AUD_EXT_CK2__FUNC_GPIO209 (MTK_PIN_NO(209) | 0)
++#define MT2701_PIN_209_AUD_EXT_CK2__FUNC_AUD_EXT_CK2 (MTK_PIN_NO(209) | 1)
++#define MT2701_PIN_209_AUD_EXT_CK2__FUNC_MSDC1_WP (MTK_PIN_NO(209) | 2)
++#define MT2701_PIN_209_AUD_EXT_CK2__FUNC_PWM1 (MTK_PIN_NO(209) | 5)
++#define MT2701_PIN_209_AUD_EXT_CK2__FUNC_DBG_MON_A_32 (MTK_PIN_NO(209) | 7)
++#define MT2701_PIN_209_AUD_EXT_CK2__FUNC_PCIE1_PERST_N (MTK_PIN_NO(209) | 11)
++
++#define MT2701_PIN_236_EXT_SDIO3__FUNC_GPIO236 (MTK_PIN_NO(236) | 0)
++#define MT2701_PIN_236_EXT_SDIO3__FUNC_EXT_SDIO3 (MTK_PIN_NO(236) | 1)
++#define MT2701_PIN_236_EXT_SDIO3__FUNC_IDDIG (MTK_PIN_NO(236) | 2)
++#define MT2701_PIN_236_EXT_SDIO3__FUNC_DBG_MON_A_1 (MTK_PIN_NO(236) | 7)
++
++#define MT2701_PIN_237_EXT_SDIO2__FUNC_GPIO237 (MTK_PIN_NO(237) | 0)
++#define MT2701_PIN_237_EXT_SDIO2__FUNC_EXT_SDIO2 (MTK_PIN_NO(237) | 1)
++#define MT2701_PIN_237_EXT_SDIO2__FUNC_DRV_VBUS (MTK_PIN_NO(237) | 2)
++
++#define MT2701_PIN_238_EXT_SDIO1__FUNC_GPIO238 (MTK_PIN_NO(238) | 0)
++#define MT2701_PIN_238_EXT_SDIO1__FUNC_EXT_SDIO1 (MTK_PIN_NO(238) | 1)
++#define MT2701_PIN_238_EXT_SDIO1__FUNC_IDDIG_P1 (MTK_PIN_NO(238) | 2)
++
++#define MT2701_PIN_239_EXT_SDIO0__FUNC_GPIO239 (MTK_PIN_NO(239) | 0)
++#define MT2701_PIN_239_EXT_SDIO0__FUNC_EXT_SDIO0 (MTK_PIN_NO(239) | 1)
++#define MT2701_PIN_239_EXT_SDIO0__FUNC_DRV_VBUS_P1 (MTK_PIN_NO(239) | 2)
++
++#define MT2701_PIN_240_EXT_XCS__FUNC_GPIO240 (MTK_PIN_NO(240) | 0)
++#define MT2701_PIN_240_EXT_XCS__FUNC_EXT_XCS (MTK_PIN_NO(240) | 1)
++
++#define MT2701_PIN_241_EXT_SCK__FUNC_GPIO241 (MTK_PIN_NO(241) | 0)
++#define MT2701_PIN_241_EXT_SCK__FUNC_EXT_SCK (MTK_PIN_NO(241) | 1)
++
++#define MT2701_PIN_242_URTS2__FUNC_GPIO242 (MTK_PIN_NO(242) | 0)
++#define MT2701_PIN_242_URTS2__FUNC_URTS2 (MTK_PIN_NO(242) | 1)
++#define MT2701_PIN_242_URTS2__FUNC_UTXD3 (MTK_PIN_NO(242) | 2)
++#define MT2701_PIN_242_URTS2__FUNC_URXD3 (MTK_PIN_NO(242) | 3)
++#define MT2701_PIN_242_URTS2__FUNC_SCL1 (MTK_PIN_NO(242) | 4)
++#define MT2701_PIN_242_URTS2__FUNC_DBG_MON_B_32 (MTK_PIN_NO(242) | 7)
++
++#define MT2701_PIN_243_UCTS2__FUNC_GPIO243 (MTK_PIN_NO(243) | 0)
++#define MT2701_PIN_243_UCTS2__FUNC_UCTS2 (MTK_PIN_NO(243) | 1)
++#define MT2701_PIN_243_UCTS2__FUNC_URXD3 (MTK_PIN_NO(243) | 2)
++#define MT2701_PIN_243_UCTS2__FUNC_UTXD3 (MTK_PIN_NO(243) | 3)
++#define MT2701_PIN_243_UCTS2__FUNC_SDA1 (MTK_PIN_NO(243) | 4)
++#define MT2701_PIN_243_UCTS2__FUNC_DBG_MON_A_6 (MTK_PIN_NO(243) | 7)
++
++#define MT2701_PIN_244_HDMI_SDA_RX__FUNC_GPIO244 (MTK_PIN_NO(244) | 0)
++#define MT2701_PIN_244_HDMI_SDA_RX__FUNC_HDMI_SDA_RX (MTK_PIN_NO(244) | 1)
++
++#define MT2701_PIN_245_HDMI_SCL_RX__FUNC_GPIO245 (MTK_PIN_NO(245) | 0)
++#define MT2701_PIN_245_HDMI_SCL_RX__FUNC_HDMI_SCL_RX (MTK_PIN_NO(245) | 1)
++
++#define MT2701_PIN_246_MHL_SENCE__FUNC_GPIO246 (MTK_PIN_NO(246) | 0)
++
++#define MT2701_PIN_247_HDMI_HPD_CBUS_RX__FUNC_GPIO247 (MTK_PIN_NO(247) | 0)
++#define MT2701_PIN_247_HDMI_HPD_CBUS_RX__FUNC_HDMI_HPD_RX (MTK_PIN_NO(247) | 1)
++
++#define MT2701_PIN_248_HDMI_TESTOUTP_RX__FUNC_GPIO248 (MTK_PIN_NO(248) | 0)
++#define MT2701_PIN_248_HDMI_TESTOUTP_RX__FUNC_HDMI_TESTOUTP_RX (MTK_PIN_NO(248) | 1)
++
++#define MT2701_PIN_249_MSDC0E_RSTB__FUNC_MSDC0E_RSTB (MTK_PIN_NO(249) | 9)
++
++#define MT2701_PIN_250_MSDC0E_DAT7__FUNC_MSDC3_DAT7 (MTK_PIN_NO(250) | 9)
++#define MT2701_PIN_250_MSDC0E_DAT7__FUNC_PCIE0_CLKREQ_N (MTK_PIN_NO(250) | 14)
++
++#define MT2701_PIN_251_MSDC0E_DAT6__FUNC_MSDC3_DAT6 (MTK_PIN_NO(251) | 9)
++#define MT2701_PIN_251_MSDC0E_DAT6__FUNC_PCIE0_WAKE_N (MTK_PIN_NO(251) | 14)
++
++#define MT2701_PIN_252_MSDC0E_DAT5__FUNC_MSDC3_DAT5 (MTK_PIN_NO(252) | 9)
++#define MT2701_PIN_252_MSDC0E_DAT5__FUNC_PCIE1_CLKREQ_N (MTK_PIN_NO(252) | 14)
++
++#define MT2701_PIN_253_MSDC0E_DAT4__FUNC_MSDC3_DAT4 (MTK_PIN_NO(253) | 9)
++#define MT2701_PIN_253_MSDC0E_DAT4__FUNC_PCIE1_WAKE_N (MTK_PIN_NO(253) | 14)
++
++#define MT2701_PIN_254_MSDC0E_DAT3__FUNC_MSDC3_DAT3 (MTK_PIN_NO(254) | 9)
++#define MT2701_PIN_254_MSDC0E_DAT3__FUNC_PCIE2_CLKREQ_N (MTK_PIN_NO(254) | 14)
++
++#define MT2701_PIN_255_MSDC0E_DAT2__FUNC_MSDC3_DAT2 (MTK_PIN_NO(255) | 9)
++#define MT2701_PIN_255_MSDC0E_DAT2__FUNC_PCIE2_WAKE_N (MTK_PIN_NO(255) | 14)
++
++#define MT2701_PIN_256_MSDC0E_DAT1__FUNC_MSDC3_DAT1 (MTK_PIN_NO(256) | 9)
++
++#define MT2701_PIN_257_MSDC0E_DAT0__FUNC_MSDC3_DAT0 (MTK_PIN_NO(257) | 9)
++
++#define MT2701_PIN_258_MSDC0E_CMD__FUNC_MSDC3_CMD (MTK_PIN_NO(258) | 9)
++
++#define MT2701_PIN_259_MSDC0E_CLK__FUNC_MSDC3_CLK (MTK_PIN_NO(259) | 9)
++
++#define MT2701_PIN_260_MSDC0E_DSL__FUNC_MSDC3_DSL (MTK_PIN_NO(260) | 9)
++
++#define MT2701_PIN_261_MSDC1_INS__FUNC_GPIO261 (MTK_PIN_NO(261) | 0)
++#define MT2701_PIN_261_MSDC1_INS__FUNC_MSDC1_INS (MTK_PIN_NO(261) | 1)
++#define MT2701_PIN_261_MSDC1_INS__FUNC_DBG_MON_B_29 (MTK_PIN_NO(261) | 7)
++
++#define MT2701_PIN_262_G2_TXEN__FUNC_GPIO262 (MTK_PIN_NO(262) | 0)
++#define MT2701_PIN_262_G2_TXEN__FUNC_G2_TXEN (MTK_PIN_NO(262) | 1)
++
++#define MT2701_PIN_263_G2_TXD3__FUNC_GPIO263 (MTK_PIN_NO(263) | 0)
++#define MT2701_PIN_263_G2_TXD3__FUNC_G2_TXD3 (MTK_PIN_NO(263) | 1)
++#define MT2701_PIN_263_G2_TXD3__FUNC_ANT_SEL5 (MTK_PIN_NO(263) | 6)
++
++#define MT2701_PIN_264_G2_TXD2__FUNC_GPIO264 (MTK_PIN_NO(264) | 0)
++#define MT2701_PIN_264_G2_TXD2__FUNC_G2_TXD2 (MTK_PIN_NO(264) | 1)
++#define MT2701_PIN_264_G2_TXD2__FUNC_ANT_SEL4 (MTK_PIN_NO(264) | 6)
++
++#define MT2701_PIN_265_G2_TXD1__FUNC_GPIO265 (MTK_PIN_NO(265) | 0)
++#define MT2701_PIN_265_G2_TXD1__FUNC_G2_TXD1 (MTK_PIN_NO(265) | 1)
++#define MT2701_PIN_265_G2_TXD1__FUNC_ANT_SEL3 (MTK_PIN_NO(265) | 6)
++
++#define MT2701_PIN_266_G2_TXD0__FUNC_GPIO266 (MTK_PIN_NO(266) | 0)
++#define MT2701_PIN_266_G2_TXD0__FUNC_G2_TXD0 (MTK_PIN_NO(266) | 1)
++#define MT2701_PIN_266_G2_TXD0__FUNC_ANT_SEL2 (MTK_PIN_NO(266) | 6)
++
++#define MT2701_PIN_267_G2_TXC__FUNC_GPIO267 (MTK_PIN_NO(267) | 0)
++#define MT2701_PIN_267_G2_TXC__FUNC_G2_TXC (MTK_PIN_NO(267) | 1)
++
++#define MT2701_PIN_268_G2_RXC__FUNC_GPIO268 (MTK_PIN_NO(268) | 0)
++#define MT2701_PIN_268_G2_RXC__FUNC_G2_RXC (MTK_PIN_NO(268) | 1)
++
++#define MT2701_PIN_269_G2_RXD0__FUNC_GPIO269 (MTK_PIN_NO(269) | 0)
++#define MT2701_PIN_269_G2_RXD0__FUNC_G2_RXD0 (MTK_PIN_NO(269) | 1)
++
++#define MT2701_PIN_270_G2_RXD1__FUNC_GPIO270 (MTK_PIN_NO(270) | 0)
++#define MT2701_PIN_270_G2_RXD1__FUNC_G2_RXD1 (MTK_PIN_NO(270) | 1)
++
++#define MT2701_PIN_271_G2_RXD2__FUNC_GPIO271 (MTK_PIN_NO(271) | 0)
++#define MT2701_PIN_271_G2_RXD2__FUNC_G2_RXD2 (MTK_PIN_NO(271) | 1)
++
++#define MT2701_PIN_272_G2_RXD3__FUNC_GPIO272 (MTK_PIN_NO(272) | 0)
++#define MT2701_PIN_272_G2_RXD3__FUNC_G2_RXD3 (MTK_PIN_NO(272) | 1)
++
++#define MT2701_PIN_274_G2_RXDV__FUNC_GPIO274 (MTK_PIN_NO(274) | 0)
++#define MT2701_PIN_274_G2_RXDV__FUNC_G2_RXDV (MTK_PIN_NO(274) | 1)
++
++#define MT2701_PIN_275_MDC__FUNC_GPIO275 (MTK_PIN_NO(275) | 0)
++#define MT2701_PIN_275_MDC__FUNC_MDC (MTK_PIN_NO(275) | 1)
++#define MT2701_PIN_275_MDC__FUNC_ANT_SEL0 (MTK_PIN_NO(275) | 6)
++
++#define MT2701_PIN_276_MDIO__FUNC_GPIO276 (MTK_PIN_NO(276) | 0)
++#define MT2701_PIN_276_MDIO__FUNC_MDIO (MTK_PIN_NO(276) | 1)
++#define MT2701_PIN_276_MDIO__FUNC_ANT_SEL1 (MTK_PIN_NO(276) | 6)
++
++#define MT2701_PIN_278_JTAG_RESET__FUNC_GPIO278 (MTK_PIN_NO(278) | 0)
++#define MT2701_PIN_278_JTAG_RESET__FUNC_JTAG_RESET (MTK_PIN_NO(278) | 1)
++
++#endif /* __DTS_MT2701_PINFUNC_H */
+diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
+index 02f6f92..13e9939 100644
+--- a/drivers/pinctrl/mediatek/Kconfig
++++ b/drivers/pinctrl/mediatek/Kconfig
+@@ -9,6 +9,12 @@ config PINCTRL_MTK_COMMON
+ select OF_GPIO
+
+ # For ARMv7 SoCs
++config PINCTRL_MT2701
++ bool "Mediatek MT2701 pin control" if COMPILE_TEST && !MACH_MT2701
++ depends on OF
++ default MACH_MT2701
++ select PINCTRL_MTK_COMMON
++
+ config PINCTRL_MT8135
+ bool "Mediatek MT8135 pin control" if COMPILE_TEST && !MACH_MT8135
+ depends on OF
+diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
+index eb923d6..da30314 100644
+--- a/drivers/pinctrl/mediatek/Makefile
++++ b/drivers/pinctrl/mediatek/Makefile
+@@ -2,6 +2,7 @@
+ obj-$(CONFIG_PINCTRL_MTK_COMMON) += pinctrl-mtk-common.o
+
+ # SoC Drivers
++obj-$(CONFIG_PINCTRL_MT2701) += pinctrl-mt2701.o
+ obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o
+ obj-$(CONFIG_PINCTRL_MT8127) += pinctrl-mt8127.o
+ obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt2701.c b/drivers/pinctrl/mediatek/pinctrl-mt2701.c
+new file mode 100644
+index 0000000..4861b5d
+--- /dev/null
++++ b/drivers/pinctrl/mediatek/pinctrl-mt2701.c
+@@ -0,0 +1,586 @@
++/*
++ * Copyright (c) 2015 MediaTek Inc.
++ * Author: Biao Huang <biao.huang@mediatek.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <dt-bindings/pinctrl/mt65xx.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/pinctrl/pinctrl.h>
++#include <linux/regmap.h>
++
++#include "pinctrl-mtk-common.h"
++#include "pinctrl-mtk-mt2701.h"
++
++/**
++ * struct mtk_spec_pinmux_set
++ * - For special pins' mode setting
++ * @pin: The pin number.
++ * @offset: The offset of extra setting register.
++ * @bit: The bit of extra setting register.
++ */
++struct mtk_spec_pinmux_set {
++ unsigned short pin;
++ unsigned short offset;
++ unsigned char bit;
++};
++
++#define MTK_PINMUX_SPEC(_pin, _offset, _bit) \
++ { \
++ .pin = _pin, \
++ .offset = _offset, \
++ .bit = _bit, \
++ }
++
++static const struct mtk_drv_group_desc mt2701_drv_grp[] = {
++ /* 0E4E8SR 4/8/12/16 */
++ MTK_DRV_GRP(4, 16, 1, 2, 4),
++ /* 0E2E4SR 2/4/6/8 */
++ MTK_DRV_GRP(2, 8, 1, 2, 2),
++ /* E8E4E2 2/4/6/8/10/12/14/16 */
++ MTK_DRV_GRP(2, 16, 0, 2, 2)
++};
++
++static const struct mtk_pin_drv_grp mt2701_pin_drv[] = {
++ MTK_PIN_DRV_GRP(0, 0xf50, 0, 1),
++ MTK_PIN_DRV_GRP(1, 0xf50, 0, 1),
++ MTK_PIN_DRV_GRP(2, 0xf50, 0, 1),
++ MTK_PIN_DRV_GRP(3, 0xf50, 0, 1),
++ MTK_PIN_DRV_GRP(4, 0xf50, 0, 1),
++ MTK_PIN_DRV_GRP(5, 0xf50, 0, 1),
++ MTK_PIN_DRV_GRP(6, 0xf50, 0, 1),
++ MTK_PIN_DRV_GRP(7, 0xf50, 4, 1),
++ MTK_PIN_DRV_GRP(8, 0xf50, 4, 1),
++ MTK_PIN_DRV_GRP(9, 0xf50, 4, 1),
++ MTK_PIN_DRV_GRP(10, 0xf50, 8, 1),
++ MTK_PIN_DRV_GRP(11, 0xf50, 8, 1),
++ MTK_PIN_DRV_GRP(12, 0xf50, 8, 1),
++ MTK_PIN_DRV_GRP(13, 0xf50, 8, 1),
++ MTK_PIN_DRV_GRP(14, 0xf50, 12, 0),
++ MTK_PIN_DRV_GRP(15, 0xf50, 12, 0),
++ MTK_PIN_DRV_GRP(16, 0xf60, 0, 0),
++ MTK_PIN_DRV_GRP(17, 0xf60, 0, 0),
++ MTK_PIN_DRV_GRP(18, 0xf60, 4, 0),
++ MTK_PIN_DRV_GRP(19, 0xf60, 4, 0),
++ MTK_PIN_DRV_GRP(20, 0xf60, 4, 0),
++ MTK_PIN_DRV_GRP(21, 0xf60, 4, 0),
++ MTK_PIN_DRV_GRP(22, 0xf60, 8, 0),
++ MTK_PIN_DRV_GRP(23, 0xf60, 8, 0),
++ MTK_PIN_DRV_GRP(24, 0xf60, 8, 0),
++ MTK_PIN_DRV_GRP(25, 0xf60, 8, 0),
++ MTK_PIN_DRV_GRP(26, 0xf60, 8, 0),
++ MTK_PIN_DRV_GRP(27, 0xf60, 12, 0),
++ MTK_PIN_DRV_GRP(28, 0xf60, 12, 0),
++ MTK_PIN_DRV_GRP(29, 0xf60, 12, 0),
++ MTK_PIN_DRV_GRP(30, 0xf60, 0, 0),
++ MTK_PIN_DRV_GRP(31, 0xf60, 0, 0),
++ MTK_PIN_DRV_GRP(32, 0xf60, 0, 0),
++ MTK_PIN_DRV_GRP(33, 0xf70, 0, 0),
++ MTK_PIN_DRV_GRP(34, 0xf70, 0, 0),
++ MTK_PIN_DRV_GRP(35, 0xf70, 0, 0),
++ MTK_PIN_DRV_GRP(36, 0xf70, 0, 0),
++ MTK_PIN_DRV_GRP(37, 0xf70, 0, 0),
++ MTK_PIN_DRV_GRP(38, 0xf70, 4, 0),
++ MTK_PIN_DRV_GRP(39, 0xf70, 8, 1),
++ MTK_PIN_DRV_GRP(40, 0xf70, 8, 1),
++ MTK_PIN_DRV_GRP(41, 0xf70, 8, 1),
++ MTK_PIN_DRV_GRP(42, 0xf70, 8, 1),
++ MTK_PIN_DRV_GRP(43, 0xf70, 12, 0),
++ MTK_PIN_DRV_GRP(44, 0xf70, 12, 0),
++ MTK_PIN_DRV_GRP(45, 0xf70, 12, 0),
++ MTK_PIN_DRV_GRP(47, 0xf80, 0, 0),
++ MTK_PIN_DRV_GRP(48, 0xf80, 0, 0),
++ MTK_PIN_DRV_GRP(49, 0xf80, 4, 0),
++ MTK_PIN_DRV_GRP(50, 0xf70, 4, 0),
++ MTK_PIN_DRV_GRP(51, 0xf70, 4, 0),
++ MTK_PIN_DRV_GRP(52, 0xf70, 4, 0),
++ MTK_PIN_DRV_GRP(53, 0xf80, 12, 0),
++ MTK_PIN_DRV_GRP(54, 0xf80, 12, 0),
++ MTK_PIN_DRV_GRP(55, 0xf80, 12, 0),
++ MTK_PIN_DRV_GRP(56, 0xf80, 12, 0),
++ MTK_PIN_DRV_GRP(60, 0xf90, 8, 1),
++ MTK_PIN_DRV_GRP(61, 0xf90, 8, 1),
++ MTK_PIN_DRV_GRP(62, 0xf90, 8, 1),
++ MTK_PIN_DRV_GRP(63, 0xf90, 12, 1),
++ MTK_PIN_DRV_GRP(64, 0xf90, 12, 1),
++ MTK_PIN_DRV_GRP(65, 0xf90, 12, 1),
++ MTK_PIN_DRV_GRP(66, 0xfa0, 0, 1),
++ MTK_PIN_DRV_GRP(67, 0xfa0, 0, 1),
++ MTK_PIN_DRV_GRP(68, 0xfa0, 0, 1),
++ MTK_PIN_DRV_GRP(69, 0xfa0, 0, 1),
++ MTK_PIN_DRV_GRP(70, 0xfa0, 0, 1),
++ MTK_PIN_DRV_GRP(71, 0xfa0, 0, 1),
++ MTK_PIN_DRV_GRP(72, 0xf80, 4, 0),
++ MTK_PIN_DRV_GRP(73, 0xf80, 4, 0),
++ MTK_PIN_DRV_GRP(74, 0xf80, 4, 0),
++ MTK_PIN_DRV_GRP(85, 0xda0, 0, 2),
++ MTK_PIN_DRV_GRP(86, 0xd90, 0, 2),
++ MTK_PIN_DRV_GRP(87, 0xdb0, 0, 2),
++ MTK_PIN_DRV_GRP(88, 0xdb0, 0, 2),
++ MTK_PIN_DRV_GRP(89, 0xdb0, 0, 2),
++ MTK_PIN_DRV_GRP(90, 0xdb0, 0, 2),
++ MTK_PIN_DRV_GRP(105, 0xd40, 0, 2),
++ MTK_PIN_DRV_GRP(106, 0xd30, 0, 2),
++ MTK_PIN_DRV_GRP(107, 0xd50, 0, 2),
++ MTK_PIN_DRV_GRP(108, 0xd50, 0, 2),
++ MTK_PIN_DRV_GRP(109, 0xd50, 0, 2),
++ MTK_PIN_DRV_GRP(110, 0xd50, 0, 2),
++ MTK_PIN_DRV_GRP(111, 0xce0, 0, 2),
++ MTK_PIN_DRV_GRP(112, 0xce0, 0, 2),
++ MTK_PIN_DRV_GRP(113, 0xce0, 0, 2),
++ MTK_PIN_DRV_GRP(114, 0xce0, 0, 2),
++ MTK_PIN_DRV_GRP(115, 0xce0, 0, 2),
++ MTK_PIN_DRV_GRP(116, 0xcd0, 0, 2),
++ MTK_PIN_DRV_GRP(117, 0xcc0, 0, 2),
++ MTK_PIN_DRV_GRP(118, 0xce0, 0, 2),
++ MTK_PIN_DRV_GRP(119, 0xce0, 0, 2),
++ MTK_PIN_DRV_GRP(120, 0xce0, 0, 2),
++ MTK_PIN_DRV_GRP(121, 0xce0, 0, 2),
++ MTK_PIN_DRV_GRP(126, 0xf80, 4, 0),
++ MTK_PIN_DRV_GRP(188, 0xf70, 4, 0),
++ MTK_PIN_DRV_GRP(189, 0xfe0, 8, 0),
++ MTK_PIN_DRV_GRP(190, 0xfe0, 8, 0),
++ MTK_PIN_DRV_GRP(191, 0xfe0, 8, 0),
++ MTK_PIN_DRV_GRP(192, 0xfe0, 8, 0),
++ MTK_PIN_DRV_GRP(193, 0xfe0, 8, 0),
++ MTK_PIN_DRV_GRP(194, 0xfe0, 12, 0),
++ MTK_PIN_DRV_GRP(195, 0xfe0, 12, 0),
++ MTK_PIN_DRV_GRP(196, 0xfe0, 12, 0),
++ MTK_PIN_DRV_GRP(197, 0xfe0, 12, 0),
++ MTK_PIN_DRV_GRP(198, 0xfe0, 12, 0),
++ MTK_PIN_DRV_GRP(199, 0xf50, 4, 1),
++ MTK_PIN_DRV_GRP(200, 0xfd0, 0, 0),
++ MTK_PIN_DRV_GRP(201, 0xfd0, 0, 0),
++ MTK_PIN_DRV_GRP(202, 0xfd0, 0, 0),
++ MTK_PIN_DRV_GRP(203, 0xfd0, 4, 0),
++ MTK_PIN_DRV_GRP(204, 0xfd0, 4, 0),
++ MTK_PIN_DRV_GRP(205, 0xfd0, 4, 0),
++ MTK_PIN_DRV_GRP(206, 0xfd0, 4, 0),
++ MTK_PIN_DRV_GRP(207, 0xfd0, 4, 0),
++ MTK_PIN_DRV_GRP(208, 0xfd0, 8, 0),
++ MTK_PIN_DRV_GRP(209, 0xfd0, 8, 0),
++ MTK_PIN_DRV_GRP(210, 0xfd0, 12, 1),
++ MTK_PIN_DRV_GRP(211, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(212, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(213, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(214, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(215, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(216, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(217, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(218, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(219, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(220, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(221, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(222, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(223, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(224, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(225, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(226, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(227, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(228, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(229, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(230, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(231, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(232, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(233, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(234, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(235, 0xff0, 0, 1),
++ MTK_PIN_DRV_GRP(236, 0xff0, 4, 0),
++ MTK_PIN_DRV_GRP(237, 0xff0, 4, 0),
++ MTK_PIN_DRV_GRP(238, 0xff0, 4, 0),
++ MTK_PIN_DRV_GRP(239, 0xff0, 4, 0),
++ MTK_PIN_DRV_GRP(240, 0xff0, 4, 0),
++ MTK_PIN_DRV_GRP(241, 0xff0, 4, 0),
++ MTK_PIN_DRV_GRP(242, 0xff0, 8, 0),
++ MTK_PIN_DRV_GRP(243, 0xff0, 8, 0),
++ MTK_PIN_DRV_GRP(248, 0xf00, 0, 0),
++ MTK_PIN_DRV_GRP(249, 0xfc0, 0, 2),
++ MTK_PIN_DRV_GRP(250, 0xfc0, 0, 2),
++ MTK_PIN_DRV_GRP(251, 0xfc0, 0, 2),
++ MTK_PIN_DRV_GRP(252, 0xfc0, 0, 2),
++ MTK_PIN_DRV_GRP(253, 0xfc0, 0, 2),
++ MTK_PIN_DRV_GRP(254, 0xfc0, 0, 2),
++ MTK_PIN_DRV_GRP(255, 0xfc0, 0, 2),
++ MTK_PIN_DRV_GRP(256, 0xfc0, 0, 2),
++ MTK_PIN_DRV_GRP(257, 0xce0, 0, 2),
++ MTK_PIN_DRV_GRP(258, 0xcb0, 0, 2),
++ MTK_PIN_DRV_GRP(259, 0xc90, 0, 2),
++ MTK_PIN_DRV_GRP(260, 0x3a0, 0, 2),
++ MTK_PIN_DRV_GRP(261, 0xd50, 0, 2),
++ MTK_PIN_DRV_GRP(262, 0xf00, 8, 0),
++ MTK_PIN_DRV_GRP(263, 0xf00, 8, 0),
++ MTK_PIN_DRV_GRP(264, 0xf00, 8, 0),
++ MTK_PIN_DRV_GRP(265, 0xf00, 8, 0),
++ MTK_PIN_DRV_GRP(266, 0xf00, 8, 0),
++ MTK_PIN_DRV_GRP(267, 0xf00, 8, 0),
++ MTK_PIN_DRV_GRP(268, 0xf00, 8, 0),
++ MTK_PIN_DRV_GRP(269, 0xf00, 8, 0),
++ MTK_PIN_DRV_GRP(270, 0xf00, 8, 0),
++ MTK_PIN_DRV_GRP(271, 0xf00, 8, 0),
++ MTK_PIN_DRV_GRP(272, 0xf00, 8, 0),
++ MTK_PIN_DRV_GRP(273, 0xf00, 8, 0),
++ MTK_PIN_DRV_GRP(274, 0xf00, 8, 0),
++ MTK_PIN_DRV_GRP(275, 0xf00, 8, 0),
++ MTK_PIN_DRV_GRP(276, 0xf00, 8, 0),
++ MTK_PIN_DRV_GRP(277, 0xf00, 8, 0),
++ MTK_PIN_DRV_GRP(278, 0xf70, 8, 1),
++};
++
++static const struct mtk_pin_spec_pupd_set_samereg mt2701_spec_pupd[] = {
++ MTK_PIN_PUPD_SPEC_SR(111, 0xd00, 12, 13, 14), /* ms0 data7 */
++ MTK_PIN_PUPD_SPEC_SR(112, 0xd00, 8, 9, 10), /* ms0 data6 */
++ MTK_PIN_PUPD_SPEC_SR(113, 0xd00, 4, 5, 6), /* ms0 data5 */
++ MTK_PIN_PUPD_SPEC_SR(114, 0xd00, 0, 1, 2), /* ms0 data4 */
++ MTK_PIN_PUPD_SPEC_SR(115, 0xd10, 0, 1, 2), /* ms0 rstb */
++ MTK_PIN_PUPD_SPEC_SR(116, 0xcd0, 8, 9, 10), /* ms0 cmd */
++ MTK_PIN_PUPD_SPEC_SR(117, 0xcc0, 8, 9, 10), /* ms0 clk */
++ MTK_PIN_PUPD_SPEC_SR(118, 0xcf0, 12, 13, 14), /* ms0 data3 */
++ MTK_PIN_PUPD_SPEC_SR(119, 0xcf0, 8, 9, 10), /* ms0 data2 */
++ MTK_PIN_PUPD_SPEC_SR(120, 0xcf0, 4, 5, 6), /* ms0 data1 */
++ MTK_PIN_PUPD_SPEC_SR(121, 0xcf0, 0, 1, 2), /* ms0 data0 */
++
++ MTK_PIN_PUPD_SPEC_SR(105, 0xd40, 8, 9, 10), /* ms1 cmd */
++ MTK_PIN_PUPD_SPEC_SR(106, 0xd30, 8, 9, 10), /* ms1 clk */
++ MTK_PIN_PUPD_SPEC_SR(107, 0xd60, 0, 1, 2), /* ms1 dat0 */
++ MTK_PIN_PUPD_SPEC_SR(108, 0xd60, 10, 9, 8), /* ms1 dat1 */
++ MTK_PIN_PUPD_SPEC_SR(109, 0xd60, 4, 5, 6), /* ms1 dat2 */
++ MTK_PIN_PUPD_SPEC_SR(110, 0xc60, 12, 13, 14), /* ms1 dat3 */
++
++ MTK_PIN_PUPD_SPEC_SR(85, 0xda0, 8, 9, 10), /* ms2 cmd */
++ MTK_PIN_PUPD_SPEC_SR(86, 0xd90, 8, 9, 10), /* ms2 clk */
++ MTK_PIN_PUPD_SPEC_SR(87, 0xdc0, 0, 1, 2), /* ms2 dat0 */
++ MTK_PIN_PUPD_SPEC_SR(88, 0xdc0, 10, 9, 8), /* ms2 dat1 */
++ MTK_PIN_PUPD_SPEC_SR(89, 0xdc0, 4, 5, 6), /* ms2 dat2 */
++ MTK_PIN_PUPD_SPEC_SR(90, 0xdc0, 12, 13, 14), /* ms2 dat3 */
++
++ MTK_PIN_PUPD_SPEC_SR(249, 0x140, 0, 1, 2), /* ms0e rstb */
++ MTK_PIN_PUPD_SPEC_SR(250, 0x130, 12, 13, 14), /* ms0e dat7 */
++ MTK_PIN_PUPD_SPEC_SR(251, 0x130, 8, 9, 10), /* ms0e dat6 */
++ MTK_PIN_PUPD_SPEC_SR(252, 0x130, 4, 5, 6), /* ms0e dat5 */
++ MTK_PIN_PUPD_SPEC_SR(253, 0x130, 0, 1, 2), /* ms0e dat4 */
++ MTK_PIN_PUPD_SPEC_SR(254, 0xf40, 12, 13, 14), /* ms0e dat3 */
++ MTK_PIN_PUPD_SPEC_SR(255, 0xf40, 8, 9, 10), /* ms0e dat2 */
++ MTK_PIN_PUPD_SPEC_SR(256, 0xf40, 4, 5, 6), /* ms0e dat1 */
++ MTK_PIN_PUPD_SPEC_SR(257, 0xf40, 0, 1, 2), /* ms0e dat0 */
++ MTK_PIN_PUPD_SPEC_SR(258, 0xcb0, 8, 9, 10), /* ms0e cmd */
++ MTK_PIN_PUPD_SPEC_SR(259, 0xc90, 8, 9, 10), /* ms0e clk */
++ MTK_PIN_PUPD_SPEC_SR(261, 0x140, 8, 9, 10), /* ms1 ins */
++};
++
++static int mt2701_spec_pull_set(struct regmap *regmap, unsigned int pin,
++ unsigned char align, bool isup, unsigned int r1r0)
++{
++ return mtk_pctrl_spec_pull_set_samereg(regmap, mt2701_spec_pupd,
++ ARRAY_SIZE(mt2701_spec_pupd), pin, align, isup, r1r0);
++}
++
++static const struct mtk_pin_ies_smt_set mt2701_ies_set[] = {
++ MTK_PIN_IES_SMT_SPEC(0, 6, 0xb20, 0),
++ MTK_PIN_IES_SMT_SPEC(7, 9, 0xb20, 1),
++ MTK_PIN_IES_SMT_SPEC(10, 13, 0xb30, 3),
++ MTK_PIN_IES_SMT_SPEC(14, 15, 0xb30, 13),
++ MTK_PIN_IES_SMT_SPEC(16, 17, 0xb40, 7),
++ MTK_PIN_IES_SMT_SPEC(18, 21, 0xb40, 13),
++ MTK_PIN_IES_SMT_SPEC(22, 26, 0xb40, 13),
++ MTK_PIN_IES_SMT_SPEC(27, 29, 0xb40, 13),
++ MTK_PIN_IES_SMT_SPEC(30, 32, 0xb40, 7),
++ MTK_PIN_IES_SMT_SPEC(33, 37, 0xb40, 13),
++ MTK_PIN_IES_SMT_SPEC(38, 38, 0xb20, 13),
++ MTK_PIN_IES_SMT_SPEC(39, 42, 0xb40, 13),
++ MTK_PIN_IES_SMT_SPEC(43, 45, 0xb20, 10),
++ MTK_PIN_IES_SMT_SPEC(47, 48, 0xb20, 11),
++ MTK_PIN_IES_SMT_SPEC(49, 49, 0xb20, 12),
++ MTK_PIN_IES_SMT_SPEC(50, 52, 0xb20, 13),
++ MTK_PIN_IES_SMT_SPEC(53, 56, 0xb20, 14),
++ MTK_PIN_IES_SMT_SPEC(57, 58, 0xb20, 15),
++ MTK_PIN_IES_SMT_SPEC(59, 59, 0xb30, 10),
++ MTK_PIN_IES_SMT_SPEC(60, 62, 0xb30, 0),
++ MTK_PIN_IES_SMT_SPEC(63, 65, 0xb30, 1),
++ MTK_PIN_IES_SMT_SPEC(66, 71, 0xb30, 2),
++ MTK_PIN_IES_SMT_SPEC(72, 74, 0xb20, 12),
++ MTK_PIN_IES_SMT_SPEC(75, 76, 0xb30, 3),
++ MTK_PIN_IES_SMT_SPEC(77, 78, 0xb30, 4),
++ MTK_PIN_IES_SMT_SPEC(79, 82, 0xb30, 5),
++ MTK_PIN_IES_SMT_SPEC(83, 84, 0xb30, 2),
++ MTK_PIN_IES_SMT_SPEC(85, 85, 0xda0, 4),
++ MTK_PIN_IES_SMT_SPEC(86, 86, 0xd90, 4),
++ MTK_PIN_IES_SMT_SPEC(87, 90, 0xdb0, 4),
++ MTK_PIN_IES_SMT_SPEC(101, 104, 0xb30, 6),
++ MTK_PIN_IES_SMT_SPEC(105, 105, 0xd40, 4),
++ MTK_PIN_IES_SMT_SPEC(106, 106, 0xd30, 4),
++ MTK_PIN_IES_SMT_SPEC(107, 110, 0xd50, 4),
++ MTK_PIN_IES_SMT_SPEC(111, 115, 0xce0, 4),
++ MTK_PIN_IES_SMT_SPEC(116, 116, 0xcd0, 4),
++ MTK_PIN_IES_SMT_SPEC(117, 117, 0xcc0, 4),
++ MTK_PIN_IES_SMT_SPEC(118, 121, 0xce0, 4),
++ MTK_PIN_IES_SMT_SPEC(122, 125, 0xb30, 7),
++ MTK_PIN_IES_SMT_SPEC(126, 126, 0xb20, 12),
++ MTK_PIN_IES_SMT_SPEC(127, 142, 0xb30, 9),
++ MTK_PIN_IES_SMT_SPEC(143, 160, 0xb30, 10),
++ MTK_PIN_IES_SMT_SPEC(161, 168, 0xb30, 12),
++ MTK_PIN_IES_SMT_SPEC(169, 183, 0xb30, 10),
++ MTK_PIN_IES_SMT_SPEC(184, 186, 0xb30, 9),
++ MTK_PIN_IES_SMT_SPEC(187, 187, 0xb30, 14),
++ MTK_PIN_IES_SMT_SPEC(188, 188, 0xb20, 13),
++ MTK_PIN_IES_SMT_SPEC(189, 193, 0xb30, 15),
++ MTK_PIN_IES_SMT_SPEC(194, 198, 0xb40, 0),
++ MTK_PIN_IES_SMT_SPEC(199, 199, 0xb20, 1),
++ MTK_PIN_IES_SMT_SPEC(200, 202, 0xb40, 1),
++ MTK_PIN_IES_SMT_SPEC(203, 207, 0xb40, 2),
++ MTK_PIN_IES_SMT_SPEC(208, 209, 0xb40, 3),
++ MTK_PIN_IES_SMT_SPEC(210, 210, 0xb40, 4),
++ MTK_PIN_IES_SMT_SPEC(211, 235, 0xb40, 5),
++ MTK_PIN_IES_SMT_SPEC(236, 241, 0xb40, 6),
++ MTK_PIN_IES_SMT_SPEC(242, 243, 0xb40, 7),
++ MTK_PIN_IES_SMT_SPEC(244, 247, 0xb40, 8),
++ MTK_PIN_IES_SMT_SPEC(248, 248, 0xb40, 9),
++ MTK_PIN_IES_SMT_SPEC(249, 257, 0xfc0, 4),
++ MTK_PIN_IES_SMT_SPEC(258, 258, 0xcb0, 4),
++ MTK_PIN_IES_SMT_SPEC(259, 259, 0xc90, 4),
++ MTK_PIN_IES_SMT_SPEC(260, 260, 0x3a0, 4),
++ MTK_PIN_IES_SMT_SPEC(261, 261, 0xd50, 4),
++ MTK_PIN_IES_SMT_SPEC(262, 277, 0xb40, 12),
++ MTK_PIN_IES_SMT_SPEC(278, 278, 0xb40, 13),
++};
++
++static const struct mtk_pin_ies_smt_set mt2701_smt_set[] = {
++ MTK_PIN_IES_SMT_SPEC(0, 6, 0xb50, 0),
++ MTK_PIN_IES_SMT_SPEC(7, 9, 0xb50, 1),
++ MTK_PIN_IES_SMT_SPEC(10, 13, 0xb60, 3),
++ MTK_PIN_IES_SMT_SPEC(14, 15, 0xb60, 13),
++ MTK_PIN_IES_SMT_SPEC(16, 17, 0xb70, 7),
++ MTK_PIN_IES_SMT_SPEC(18, 21, 0xb70, 13),
++ MTK_PIN_IES_SMT_SPEC(22, 26, 0xb70, 13),
++ MTK_PIN_IES_SMT_SPEC(27, 29, 0xb70, 13),
++ MTK_PIN_IES_SMT_SPEC(30, 32, 0xb70, 7),
++ MTK_PIN_IES_SMT_SPEC(33, 37, 0xb70, 13),
++ MTK_PIN_IES_SMT_SPEC(38, 38, 0xb50, 13),
++ MTK_PIN_IES_SMT_SPEC(39, 42, 0xb70, 13),
++ MTK_PIN_IES_SMT_SPEC(43, 45, 0xb50, 10),
++ MTK_PIN_IES_SMT_SPEC(47, 48, 0xb50, 11),
++ MTK_PIN_IES_SMT_SPEC(49, 49, 0xb50, 12),
++ MTK_PIN_IES_SMT_SPEC(50, 52, 0xb50, 13),
++ MTK_PIN_IES_SMT_SPEC(53, 56, 0xb50, 14),
++ MTK_PIN_IES_SMT_SPEC(57, 58, 0xb50, 15),
++ MTK_PIN_IES_SMT_SPEC(59, 59, 0xb60, 10),
++ MTK_PIN_IES_SMT_SPEC(60, 62, 0xb60, 0),
++ MTK_PIN_IES_SMT_SPEC(63, 65, 0xb60, 1),
++ MTK_PIN_IES_SMT_SPEC(66, 71, 0xb60, 2),
++ MTK_PIN_IES_SMT_SPEC(72, 74, 0xb50, 12),
++ MTK_PIN_IES_SMT_SPEC(75, 76, 0xb60, 3),
++ MTK_PIN_IES_SMT_SPEC(77, 78, 0xb60, 4),
++ MTK_PIN_IES_SMT_SPEC(79, 82, 0xb60, 5),
++ MTK_PIN_IES_SMT_SPEC(83, 84, 0xb60, 2),
++ MTK_PIN_IES_SMT_SPEC(85, 85, 0xda0, 11),
++ MTK_PIN_IES_SMT_SPEC(86, 86, 0xd90, 11),
++ MTK_PIN_IES_SMT_SPEC(87, 87, 0xdc0, 3),
++ MTK_PIN_IES_SMT_SPEC(88, 88, 0xdc0, 7),
++ MTK_PIN_IES_SMT_SPEC(89, 89, 0xdc0, 11),
++ MTK_PIN_IES_SMT_SPEC(90, 90, 0xdc0, 15),
++ MTK_PIN_IES_SMT_SPEC(101, 104, 0xb60, 6),
++ MTK_PIN_IES_SMT_SPEC(105, 105, 0xd40, 11),
++ MTK_PIN_IES_SMT_SPEC(106, 106, 0xd30, 11),
++ MTK_PIN_IES_SMT_SPEC(107, 107, 0xd60, 3),
++ MTK_PIN_IES_SMT_SPEC(108, 108, 0xd60, 7),
++ MTK_PIN_IES_SMT_SPEC(109, 109, 0xd60, 11),
++ MTK_PIN_IES_SMT_SPEC(110, 110, 0xd60, 15),
++ MTK_PIN_IES_SMT_SPEC(111, 111, 0xd00, 15),
++ MTK_PIN_IES_SMT_SPEC(112, 112, 0xd00, 11),
++ MTK_PIN_IES_SMT_SPEC(113, 113, 0xd00, 7),
++ MTK_PIN_IES_SMT_SPEC(114, 114, 0xd00, 3),
++ MTK_PIN_IES_SMT_SPEC(115, 115, 0xd10, 3),
++ MTK_PIN_IES_SMT_SPEC(116, 116, 0xcd0, 11),
++ MTK_PIN_IES_SMT_SPEC(117, 117, 0xcc0, 11),
++ MTK_PIN_IES_SMT_SPEC(118, 118, 0xcf0, 15),
++ MTK_PIN_IES_SMT_SPEC(119, 119, 0xcf0, 11),
++ MTK_PIN_IES_SMT_SPEC(120, 120, 0xcf0, 7),
++ MTK_PIN_IES_SMT_SPEC(121, 121, 0xcf0, 3),
++ MTK_PIN_IES_SMT_SPEC(122, 125, 0xb60, 7),
++ MTK_PIN_IES_SMT_SPEC(126, 126, 0xb50, 12),
++ MTK_PIN_IES_SMT_SPEC(127, 142, 0xb60, 9),
++ MTK_PIN_IES_SMT_SPEC(143, 160, 0xb60, 10),
++ MTK_PIN_IES_SMT_SPEC(161, 168, 0xb60, 12),
++ MTK_PIN_IES_SMT_SPEC(169, 183, 0xb60, 10),
++ MTK_PIN_IES_SMT_SPEC(184, 186, 0xb60, 9),
++ MTK_PIN_IES_SMT_SPEC(187, 187, 0xb60, 14),
++ MTK_PIN_IES_SMT_SPEC(188, 188, 0xb50, 13),
++ MTK_PIN_IES_SMT_SPEC(189, 193, 0xb60, 15),
++ MTK_PIN_IES_SMT_SPEC(194, 198, 0xb70, 0),
++ MTK_PIN_IES_SMT_SPEC(199, 199, 0xb50, 1),
++ MTK_PIN_IES_SMT_SPEC(200, 202, 0xb70, 1),
++ MTK_PIN_IES_SMT_SPEC(203, 207, 0xb70, 2),
++ MTK_PIN_IES_SMT_SPEC(208, 209, 0xb70, 3),
++ MTK_PIN_IES_SMT_SPEC(210, 210, 0xb70, 4),
++ MTK_PIN_IES_SMT_SPEC(211, 235, 0xb70, 5),
++ MTK_PIN_IES_SMT_SPEC(236, 241, 0xb70, 6),
++ MTK_PIN_IES_SMT_SPEC(242, 243, 0xb70, 7),
++ MTK_PIN_IES_SMT_SPEC(244, 247, 0xb70, 8),
++ MTK_PIN_IES_SMT_SPEC(248, 248, 0xb70, 9),
++ MTK_PIN_IES_SMT_SPEC(249, 249, 0x140, 3),
++ MTK_PIN_IES_SMT_SPEC(250, 250, 0x130, 15),
++ MTK_PIN_IES_SMT_SPEC(251, 251, 0x130, 11),
++ MTK_PIN_IES_SMT_SPEC(252, 252, 0x130, 7),
++ MTK_PIN_IES_SMT_SPEC(253, 253, 0x130, 3),
++ MTK_PIN_IES_SMT_SPEC(254, 254, 0xf40, 15),
++ MTK_PIN_IES_SMT_SPEC(255, 255, 0xf40, 11),
++ MTK_PIN_IES_SMT_SPEC(256, 256, 0xf40, 7),
++ MTK_PIN_IES_SMT_SPEC(257, 257, 0xf40, 3),
++ MTK_PIN_IES_SMT_SPEC(258, 258, 0xcb0, 11),
++ MTK_PIN_IES_SMT_SPEC(259, 259, 0xc90, 11),
++ MTK_PIN_IES_SMT_SPEC(260, 260, 0x3a0, 11),
++ MTK_PIN_IES_SMT_SPEC(261, 261, 0x0b0, 3),
++ MTK_PIN_IES_SMT_SPEC(262, 277, 0xb70, 12),
++ MTK_PIN_IES_SMT_SPEC(278, 278, 0xb70, 13),
++};
++
++static int mt2701_ies_smt_set(struct regmap *regmap, unsigned int pin,
++ unsigned char align, int value, enum pin_config_param arg)
++{
++ if (arg == PIN_CONFIG_INPUT_ENABLE)
++ return mtk_pconf_spec_set_ies_smt_range(regmap, mt2701_ies_set,
++ ARRAY_SIZE(mt2701_ies_set), pin, align, value);
++ else if (arg == PIN_CONFIG_INPUT_SCHMITT_ENABLE)
++ return mtk_pconf_spec_set_ies_smt_range(regmap, mt2701_smt_set,
++ ARRAY_SIZE(mt2701_smt_set), pin, align, value);
++ return -EINVAL;
++}
++
++static const struct mtk_spec_pinmux_set mt2701_spec_pinmux[] = {
++ MTK_PINMUX_SPEC(22, 0xb10, 3),
++ MTK_PINMUX_SPEC(23, 0xb10, 4),
++ MTK_PINMUX_SPEC(24, 0xb10, 5),
++ MTK_PINMUX_SPEC(29, 0xb10, 9),
++ MTK_PINMUX_SPEC(208, 0xb10, 7),
++ MTK_PINMUX_SPEC(209, 0xb10, 8),
++ MTK_PINMUX_SPEC(203, 0xf20, 0),
++ MTK_PINMUX_SPEC(204, 0xf20, 1),
++ MTK_PINMUX_SPEC(249, 0xef0, 0),
++ MTK_PINMUX_SPEC(250, 0xef0, 0),
++ MTK_PINMUX_SPEC(251, 0xef0, 0),
++ MTK_PINMUX_SPEC(252, 0xef0, 0),
++ MTK_PINMUX_SPEC(253, 0xef0, 0),
++ MTK_PINMUX_SPEC(254, 0xef0, 0),
++ MTK_PINMUX_SPEC(255, 0xef0, 0),
++ MTK_PINMUX_SPEC(256, 0xef0, 0),
++ MTK_PINMUX_SPEC(257, 0xef0, 0),
++ MTK_PINMUX_SPEC(258, 0xef0, 0),
++ MTK_PINMUX_SPEC(259, 0xef0, 0),
++ MTK_PINMUX_SPEC(260, 0xef0, 0),
++};
++
++static void mt2701_spec_pinmux_set(struct regmap *reg, unsigned int pin,
++ unsigned int mode)
++{
++ unsigned int i, value, mask;
++ unsigned int info_num = ARRAY_SIZE(mt2701_spec_pinmux);
++ unsigned int spec_flag;
++
++ for (i = 0; i < info_num; i++) {
++ if (pin == mt2701_spec_pinmux[i].pin)
++ break;
++ }
++
++ if (i == info_num)
++ return;
++
++ spec_flag = (mode >> 3);
++ mask = BIT(mt2701_spec_pinmux[i].bit);
++ if (!spec_flag)
++ value = mask;
++ else
++ value = 0;
++ regmap_update_bits(reg, mt2701_spec_pinmux[i].offset, mask, value);
++}
++
++static void mt2701_spec_dir_set(unsigned int *reg_addr, unsigned int pin)
++{
++ if (pin > 175)
++ *reg_addr += 0x10;
++}
++
++static const struct mtk_pinctrl_devdata mt2701_pinctrl_data = {
++ .pins = mtk_pins_mt2701,
++ .npins = ARRAY_SIZE(mtk_pins_mt2701),
++ .grp_desc = mt2701_drv_grp,
++ .n_grp_cls = ARRAY_SIZE(mt2701_drv_grp),
++ .pin_drv_grp = mt2701_pin_drv,
++ .n_pin_drv_grps = ARRAY_SIZE(mt2701_pin_drv),
++ .spec_pull_set = mt2701_spec_pull_set,
++ .spec_ies_smt_set = mt2701_ies_smt_set,
++ .spec_pinmux_set = mt2701_spec_pinmux_set,
++ .spec_dir_set = mt2701_spec_dir_set,
++ .dir_offset = 0x0000,
++ .pullen_offset = 0x0150,
++ .pullsel_offset = 0x0280,
++ .dout_offset = 0x0500,
++ .din_offset = 0x0630,
++ .pinmux_offset = 0x0760,
++ .type1_start = 280,
++ .type1_end = 280,
++ .port_shf = 4,
++ .port_mask = 0x1f,
++ .port_align = 4,
++ .eint_offsets = {
++ .name = "mt2701_eint",
++ .stat = 0x000,
++ .ack = 0x040,
++ .mask = 0x080,
++ .mask_set = 0x0c0,
++ .mask_clr = 0x100,
++ .sens = 0x140,
++ .sens_set = 0x180,
++ .sens_clr = 0x1c0,
++ .soft = 0x200,
++ .soft_set = 0x240,
++ .soft_clr = 0x280,
++ .pol = 0x300,
++ .pol_set = 0x340,
++ .pol_clr = 0x380,
++ .dom_en = 0x400,
++ .dbnc_ctrl = 0x500,
++ .dbnc_set = 0x600,
++ .dbnc_clr = 0x700,
++ .port_mask = 6,
++ .ports = 6,
++ },
++ .ap_num = 169,
++ .db_cnt = 16,
++};
++
++static int mt2701_pinctrl_probe(struct platform_device *pdev)
++{
++ return mtk_pctrl_init(pdev, &mt2701_pinctrl_data, NULL);
++}
++
++static const struct of_device_id mt2701_pctrl_match[] = {
++ { .compatible = "mediatek,mt2701-pinctrl", },
++ {}
++};
++MODULE_DEVICE_TABLE(of, mt2701_pctrl_match);
++
++static struct platform_driver mtk_pinctrl_driver = {
++ .probe = mt2701_pinctrl_probe,
++ .driver = {
++ .name = "mediatek-mt2701-pinctrl",
++ .owner = THIS_MODULE,
++ .of_match_table = mt2701_pctrl_match,
++ },
++};
++
++static int __init mtk_pinctrl_init(void)
++{
++ return platform_driver_register(&mtk_pinctrl_driver);
++}
++
++arch_initcall(mtk_pinctrl_init);
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+index 5c71727..05ba7a8 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+@@ -47,6 +47,8 @@
+ static const char * const mtk_gpio_functions[] = {
+ "func0", "func1", "func2", "func3",
+ "func4", "func5", "func6", "func7",
++ "func8", "func9", "func10", "func11",
++ "func12", "func13", "func14", "func15",
+ };
+
+ /*
+@@ -81,6 +83,9 @@ static int mtk_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
+ reg_addr = mtk_get_port(pctl, offset) + pctl->devdata->dir_offset;
+ bit = BIT(offset & 0xf);
+
++ if (pctl->devdata->spec_dir_set)
++ pctl->devdata->spec_dir_set(&reg_addr, offset);
++
+ if (input)
+ /* Different SoC has different alignment offset. */
+ reg_addr = CLR_ADDR(reg_addr, pctl);
+@@ -347,6 +352,7 @@ static int mtk_pconf_parse_conf(struct pinctrl_dev *pctldev,
+ ret = mtk_pconf_set_pull_select(pctl, pin, true, false, arg);
+ break;
+ case PIN_CONFIG_INPUT_ENABLE:
++ mtk_pmx_gpio_set_direction(pctldev, NULL, pin, true);
+ ret = mtk_pconf_set_ies_smt(pctl, pin, arg, param);
+ break;
+ case PIN_CONFIG_OUTPUT:
+@@ -354,6 +360,7 @@ static int mtk_pconf_parse_conf(struct pinctrl_dev *pctldev,
+ ret = mtk_pmx_gpio_set_direction(pctldev, NULL, pin, false);
+ break;
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
++ mtk_pmx_gpio_set_direction(pctldev, NULL, pin, true);
+ ret = mtk_pconf_set_ies_smt(pctl, pin, arg, param);
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+@@ -667,9 +674,14 @@ static int mtk_pmx_set_mode(struct pinctrl_dev *pctldev,
+ unsigned int mask = (1L << GPIO_MODE_BITS) - 1;
+ struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+
++ if (pctl->devdata->spec_pinmux_set)
++ pctl->devdata->spec_pinmux_set(mtk_get_regmap(pctl, pin),
++ pin, mode);
++
+ reg_addr = ((pin / MAX_GPIO_MODE_PER_REG) << pctl->devdata->port_shf)
+ + pctl->devdata->pinmux_offset;
+
++ mode &= mask;
+ bit = pin % MAX_GPIO_MODE_PER_REG;
+ mask <<= (GPIO_MODE_BITS * bit);
+ val = (mode << (GPIO_MODE_BITS * bit));
+@@ -746,6 +758,10 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
+
+ reg_addr = mtk_get_port(pctl, offset) + pctl->devdata->dir_offset;
+ bit = BIT(offset & 0xf);
++
++ if (pctl->devdata->spec_dir_set)
++ pctl->devdata->spec_dir_set(&reg_addr, offset);
++
+ regmap_read(pctl->regmap1, reg_addr, &read_val);
+ return !(read_val & bit);
+ }
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
+index 55a5343..8543bc4 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
+@@ -209,7 +209,14 @@ struct mtk_eint_offsets {
+ * means when user set smt, input enable is set at the same time. So they
+ * also need special control. If special control is success, this should
+ * return 0, otherwise return non-zero value.
+- *
++ * @spec_pinmux_set: In some cases, there are two pinmux functions share
++ * the same value in the same segment of pinmux control register. If user
++ * want to use one of the two functions, they need an extra bit setting to
++ * select the right one.
++ * @spec_dir_set: In very few SoCs, direction control registers are not
++ * arranged continuously, they may be cut to parts. So they need special
++ * dir setting.
++
+ * @dir_offset: The direction register offset.
+ * @pullen_offset: The pull-up/pull-down enable register offset.
+ * @pinmux_offset: The pinmux register offset.
+@@ -234,6 +241,9 @@ struct mtk_pinctrl_devdata {
+ unsigned char align, bool isup, unsigned int arg);
+ int (*spec_ies_smt_set)(struct regmap *reg, unsigned int pin,
+ unsigned char align, int value, enum pin_config_param arg);
++ void (*spec_pinmux_set)(struct regmap *reg, unsigned int pin,
++ unsigned int mode);
++ void (*spec_dir_set)(unsigned int *reg_addr, unsigned int pin);
+ unsigned int dir_offset;
+ unsigned int ies_offset;
+ unsigned int smt_offset;
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-mt2701.h b/drivers/pinctrl/mediatek/pinctrl-mtk-mt2701.h
+new file mode 100644
+index 0000000..f906420
+--- /dev/null
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-mt2701.h
+@@ -0,0 +1,2323 @@
++/*
++ * Copyright (c) 2015 MediaTek Inc.
++ * Author: Biao Huang <biao.huang@mediatek.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef __PINCTRL_MTK_MT2701_H
++#define __PINCTRL_MTK_MT2701_H
++
++#include <linux/pinctrl/pinctrl.h>
++#include "pinctrl-mtk-common.h"
++
++static const struct mtk_desc_pin mtk_pins_mt2701[] = {
++ MTK_PIN(
++ PINCTRL_PIN(0, "PWRAP_SPI0_MI"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 148),
++ MTK_FUNCTION(0, "GPIO0"),
++ MTK_FUNCTION(1, "PWRAP_SPIDO"),
++ MTK_FUNCTION(2, "PWRAP_SPIDI")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(1, "PWRAP_SPI0_MO"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 149),
++ MTK_FUNCTION(0, "GPIO1"),
++ MTK_FUNCTION(1, "PWRAP_SPIDI"),
++ MTK_FUNCTION(2, "PWRAP_SPIDO")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(2, "PWRAP_INT"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 150),
++ MTK_FUNCTION(0, "GPIO2"),
++ MTK_FUNCTION(1, "PWRAP_INT")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(3, "PWRAP_SPI0_CK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 151),
++ MTK_FUNCTION(0, "GPIO3"),
++ MTK_FUNCTION(1, "PWRAP_SPICK_I")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(4, "PWRAP_SPI0_CSN"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 152),
++ MTK_FUNCTION(0, "GPIO4"),
++ MTK_FUNCTION(1, "PWRAP_SPICS_B_I")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(5, "PWRAP_SPI0_CK2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 153),
++ MTK_FUNCTION(0, "GPIO5"),
++ MTK_FUNCTION(1, "PWRAP_SPICK2_I"),
++ MTK_FUNCTION(5, "ANT_SEL1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(6, "PWRAP_SPI0_CSN2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 154),
++ MTK_FUNCTION(0, "GPIO6"),
++ MTK_FUNCTION(1, "PWRAP_SPICS2_B_I"),
++ MTK_FUNCTION(5, "ANT_SEL0"),
++ MTK_FUNCTION(7, "DBG_MON_A[0]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(7, "SPI1_CSN"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 155),
++ MTK_FUNCTION(0, "GPIO7"),
++ MTK_FUNCTION(1, "SPI1_CS"),
++ MTK_FUNCTION(4, "KCOL0"),
++ MTK_FUNCTION(7, "DBG_MON_B[12]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(8, "SPI1_MI"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 156),
++ MTK_FUNCTION(0, "GPIO8"),
++ MTK_FUNCTION(1, "SPI1_MI"),
++ MTK_FUNCTION(2, "SPI1_MO"),
++ MTK_FUNCTION(4, "KCOL1"),
++ MTK_FUNCTION(7, "DBG_MON_B[13]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(9, "SPI1_MO"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 157),
++ MTK_FUNCTION(0, "GPIO9"),
++ MTK_FUNCTION(1, "SPI1_MO"),
++ MTK_FUNCTION(2, "SPI1_MI"),
++ MTK_FUNCTION(3, "EXT_FRAME_SYNC"),
++ MTK_FUNCTION(4, "KCOL2"),
++ MTK_FUNCTION(7, "DBG_MON_B[14]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(10, "RTC32K_CK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 158),
++ MTK_FUNCTION(0, "GPIO10"),
++ MTK_FUNCTION(1, "RTC32K_CK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(11, "WATCHDOG"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 159),
++ MTK_FUNCTION(0, "GPIO11"),
++ MTK_FUNCTION(1, "WATCHDOG")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(12, "SRCLKENA"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 160),
++ MTK_FUNCTION(0, "GPIO12"),
++ MTK_FUNCTION(1, "SRCLKENA")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(13, "SRCLKENAI"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 161),
++ MTK_FUNCTION(0, "GPIO13"),
++ MTK_FUNCTION(1, "SRCLKENAI")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(14, "URXD2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 162),
++ MTK_FUNCTION(0, "GPIO14"),
++ MTK_FUNCTION(1, "URXD2"),
++ MTK_FUNCTION(2, "UTXD2"),
++ MTK_FUNCTION(5, "SRCCLKENAI2"),
++ MTK_FUNCTION(7, "DBG_MON_B[30]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(15, "UTXD2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 163),
++ MTK_FUNCTION(0, "GPIO15"),
++ MTK_FUNCTION(1, "UTXD2"),
++ MTK_FUNCTION(2, "URXD2"),
++ MTK_FUNCTION(7, "DBG_MON_B[31]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(16, "I2S5_DATA_IN"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 164),
++ MTK_FUNCTION(0, "GPIO16"),
++ MTK_FUNCTION(1, "I2S5_DATA_IN"),
++ MTK_FUNCTION(3, "PCM_RX"),
++ MTK_FUNCTION(4, "ANT_SEL4")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(17, "I2S5_BCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 165),
++ MTK_FUNCTION(0, "GPIO17"),
++ MTK_FUNCTION(1, "I2S5_BCK"),
++ MTK_FUNCTION(3, "PCM_CLK0"),
++ MTK_FUNCTION(4, "ANT_SEL2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(18, "PCM_CLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 166),
++ MTK_FUNCTION(0, "GPIO18"),
++ MTK_FUNCTION(1, "PCM_CLK0"),
++ MTK_FUNCTION(2, "MRG_CLK"),
++ MTK_FUNCTION(4, "MM_TEST_CK"),
++ MTK_FUNCTION(5, "CONN_DSP_JCK"),
++ MTK_FUNCTION(6, "WCN_PCM_CLKO"),
++ MTK_FUNCTION(7, "DBG_MON_A[3]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(19, "PCM_SYNC"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 167),
++ MTK_FUNCTION(0, "GPIO19"),
++ MTK_FUNCTION(1, "PCM_SYNC"),
++ MTK_FUNCTION(2, "MRG_SYNC"),
++ MTK_FUNCTION(5, "CONN_DSP_JINTP"),
++ MTK_FUNCTION(6, "WCN_PCM_SYNC"),
++ MTK_FUNCTION(7, "DBG_MON_A[5]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(20, "PCM_RX"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO20"),
++ MTK_FUNCTION(1, "PCM_RX"),
++ MTK_FUNCTION(2, "MRG_RX"),
++ MTK_FUNCTION(3, "MRG_TX"),
++ MTK_FUNCTION(4, "PCM_TX"),
++ MTK_FUNCTION(5, "CONN_DSP_JDI"),
++ MTK_FUNCTION(6, "WCN_PCM_RX"),
++ MTK_FUNCTION(7, "DBG_MON_A[4]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(21, "PCM_TX"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO21"),
++ MTK_FUNCTION(1, "PCM_TX"),
++ MTK_FUNCTION(2, "MRG_TX"),
++ MTK_FUNCTION(3, "MRG_RX"),
++ MTK_FUNCTION(4, "PCM_RX"),
++ MTK_FUNCTION(5, "CONN_DSP_JMS"),
++ MTK_FUNCTION(6, "WCN_PCM_TX"),
++ MTK_FUNCTION(7, "DBG_MON_A[2]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(22, "EINT0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 0),
++ MTK_FUNCTION(0, "GPIO22"),
++ MTK_FUNCTION(1, "UCTS0"),
++ MTK_FUNCTION(3, "KCOL3"),
++ MTK_FUNCTION(4, "CONN_DSP_JDO"),
++ MTK_FUNCTION(5, "EXT_FRAME_SYNC"),
++ MTK_FUNCTION(7, "DBG_MON_A[30]"),
++ MTK_FUNCTION(10, "PCIE0_PERST_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(23, "EINT1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 1),
++ MTK_FUNCTION(0, "GPIO23"),
++ MTK_FUNCTION(1, "URTS0"),
++ MTK_FUNCTION(3, "KCOL2"),
++ MTK_FUNCTION(4, "CONN_MCU_TDO"),
++ MTK_FUNCTION(5, "EXT_FRAME_SYNC"),
++ MTK_FUNCTION(7, "DBG_MON_A[29]"),
++ MTK_FUNCTION(10, "PCIE1_PERST_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(24, "EINT2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 2),
++ MTK_FUNCTION(0, "GPIO24"),
++ MTK_FUNCTION(1, "UCTS1"),
++ MTK_FUNCTION(3, "KCOL1"),
++ MTK_FUNCTION(4, "CONN_MCU_DBGACK_N"),
++ MTK_FUNCTION(7, "DBG_MON_A[28]"),
++ MTK_FUNCTION(10, "PCIE2_PERST_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(25, "EINT3"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 3),
++ MTK_FUNCTION(0, "GPIO25"),
++ MTK_FUNCTION(1, "URTS1"),
++ MTK_FUNCTION(3, "KCOL0"),
++ MTK_FUNCTION(4, "CONN_MCU_DBGI_N"),
++ MTK_FUNCTION(7, "DBG_MON_A[27]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(26, "EINT4"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 4),
++ MTK_FUNCTION(0, "GPIO26"),
++ MTK_FUNCTION(1, "UCTS3"),
++ MTK_FUNCTION(2, "DRV_VBUS_P1"),
++ MTK_FUNCTION(3, "KROW3"),
++ MTK_FUNCTION(4, "CONN_MCU_TCK0"),
++ MTK_FUNCTION(5, "CONN_MCU_AICE_JCKC"),
++ MTK_FUNCTION(6, "PCIE2_WAKE_N"),
++ MTK_FUNCTION(7, "DBG_MON_A[26]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(27, "EINT5"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 5),
++ MTK_FUNCTION(0, "GPIO27"),
++ MTK_FUNCTION(1, "URTS3"),
++ MTK_FUNCTION(2, "IDDIG_P1"),
++ MTK_FUNCTION(3, "KROW2"),
++ MTK_FUNCTION(4, "CONN_MCU_TDI"),
++ MTK_FUNCTION(6, "PCIE1_WAKE_N"),
++ MTK_FUNCTION(7, "DBG_MON_A[25]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(28, "EINT6"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 6),
++ MTK_FUNCTION(0, "GPIO28"),
++ MTK_FUNCTION(1, "DRV_VBUS"),
++ MTK_FUNCTION(3, "KROW1"),
++ MTK_FUNCTION(4, "CONN_MCU_TRST_B"),
++ MTK_FUNCTION(6, "PCIE0_WAKE_N"),
++ MTK_FUNCTION(7, "DBG_MON_A[24]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(29, "EINT7"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 7),
++ MTK_FUNCTION(0, "GPIO29"),
++ MTK_FUNCTION(1, "IDDIG"),
++ MTK_FUNCTION(2, "MSDC1_WP"),
++ MTK_FUNCTION(3, "KROW0"),
++ MTK_FUNCTION(4, "CONN_MCU_TMS"),
++ MTK_FUNCTION(5, "CONN_MCU_AICE_JMSC"),
++ MTK_FUNCTION(7, "DBG_MON_A[23]"),
++ MTK_FUNCTION(14, "PCIE2_PERST_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(30, "I2S5_LRCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 12),
++ MTK_FUNCTION(0, "GPIO30"),
++ MTK_FUNCTION(1, "I2S5_LRCK"),
++ MTK_FUNCTION(3, "PCM_SYNC"),
++ MTK_FUNCTION(4, "ANT_SEL1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(31, "I2S5_MCLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 13),
++ MTK_FUNCTION(0, "GPIO31"),
++ MTK_FUNCTION(1, "I2S5_MCLK"),
++ MTK_FUNCTION(4, "ANT_SEL0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(32, "I2S5_DATA"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 14),
++ MTK_FUNCTION(0, "GPIO32"),
++ MTK_FUNCTION(1, "I2S5_DATA"),
++ MTK_FUNCTION(2, "I2S5_DATA_BYPS"),
++ MTK_FUNCTION(3, "PCM_TX"),
++ MTK_FUNCTION(4, "ANT_SEL3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(33, "I2S1_DATA"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 15),
++ MTK_FUNCTION(0, "GPIO33"),
++ MTK_FUNCTION(1, "I2S1_DATA"),
++ MTK_FUNCTION(2, "I2S1_DATA_BYPS"),
++ MTK_FUNCTION(3, "PCM_TX"),
++ MTK_FUNCTION(4, "IMG_TEST_CK"),
++ MTK_FUNCTION(5, "G1_RXD0"),
++ MTK_FUNCTION(6, "WCN_PCM_TX"),
++ MTK_FUNCTION(7, "DBG_MON_B[8]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(34, "I2S1_DATA_IN"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 16),
++ MTK_FUNCTION(0, "GPIO34"),
++ MTK_FUNCTION(1, "I2S1_DATA_IN"),
++ MTK_FUNCTION(3, "PCM_RX"),
++ MTK_FUNCTION(4, "VDEC_TEST_CK"),
++ MTK_FUNCTION(5, "G1_RXD1"),
++ MTK_FUNCTION(6, "WCN_PCM_RX"),
++ MTK_FUNCTION(7, "DBG_MON_B[7]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(35, "I2S1_BCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 17),
++ MTK_FUNCTION(0, "GPIO35"),
++ MTK_FUNCTION(1, "I2S1_BCK"),
++ MTK_FUNCTION(3, "PCM_CLK0"),
++ MTK_FUNCTION(5, "G1_RXD2"),
++ MTK_FUNCTION(6, "WCN_PCM_CLKO"),
++ MTK_FUNCTION(7, "DBG_MON_B[9]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(36, "I2S1_LRCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 18),
++ MTK_FUNCTION(0, "GPIO36"),
++ MTK_FUNCTION(1, "I2S1_LRCK"),
++ MTK_FUNCTION(3, "PCM_SYNC"),
++ MTK_FUNCTION(5, "G1_RXD3"),
++ MTK_FUNCTION(6, "WCN_PCM_SYNC"),
++ MTK_FUNCTION(7, "DBG_MON_B[10]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(37, "I2S1_MCLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 19),
++ MTK_FUNCTION(0, "GPIO37"),
++ MTK_FUNCTION(1, "I2S1_MCLK"),
++ MTK_FUNCTION(5, "G1_RXDV"),
++ MTK_FUNCTION(7, "DBG_MON_B[11]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(38, "I2S2_DATA"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 20),
++ MTK_FUNCTION(0, "GPIO38"),
++ MTK_FUNCTION(2, "I2S2_DATA_BYPS"),
++ MTK_FUNCTION(3, "PCM_TX"),
++ MTK_FUNCTION(4, "DMIC_DAT0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(39, "JTMS"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 21),
++ MTK_FUNCTION(0, "GPIO39"),
++ MTK_FUNCTION(1, "JTMS"),
++ MTK_FUNCTION(2, "CONN_MCU_TMS"),
++ MTK_FUNCTION(3, "CONN_MCU_AICE_JMSC"),
++ MTK_FUNCTION(4, "DFD_TMS_XI")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(40, "JTCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 22),
++ MTK_FUNCTION(0, "GPIO40"),
++ MTK_FUNCTION(1, "JTCK"),
++ MTK_FUNCTION(2, "CONN_MCU_TCK1"),
++ MTK_FUNCTION(3, "CONN_MCU_AICE_JCKC"),
++ MTK_FUNCTION(4, "DFD_TCK_XI")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(41, "JTDI"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 23),
++ MTK_FUNCTION(0, "GPIO41"),
++ MTK_FUNCTION(1, "JTDI"),
++ MTK_FUNCTION(2, "CONN_MCU_TDI"),
++ MTK_FUNCTION(4, "DFD_TDI_XI")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(42, "JTDO"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 24),
++ MTK_FUNCTION(0, "GPIO42"),
++ MTK_FUNCTION(1, "JTDO"),
++ MTK_FUNCTION(2, "CONN_MCU_TDO"),
++ MTK_FUNCTION(4, "DFD_TDO")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(43, "NCLE"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 25),
++ MTK_FUNCTION(0, "GPIO43"),
++ MTK_FUNCTION(1, "NCLE"),
++ MTK_FUNCTION(2, "EXT_XCS2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(44, "NCEB1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 26),
++ MTK_FUNCTION(0, "GPIO44"),
++ MTK_FUNCTION(1, "NCEB1"),
++ MTK_FUNCTION(2, "IDDIG")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(45, "NCEB0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 27),
++ MTK_FUNCTION(0, "GPIO45"),
++ MTK_FUNCTION(1, "NCEB0"),
++ MTK_FUNCTION(2, "DRV_VBUS")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(46, "IR"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 28),
++ MTK_FUNCTION(0, "GPIO46"),
++ MTK_FUNCTION(1, "IR")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(47, "NREB"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 29),
++ MTK_FUNCTION(0, "GPIO47"),
++ MTK_FUNCTION(1, "NREB"),
++ MTK_FUNCTION(2, "IDDIG_P1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(48, "NRNB"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 30),
++ MTK_FUNCTION(0, "GPIO48"),
++ MTK_FUNCTION(1, "NRNB"),
++ MTK_FUNCTION(2, "DRV_VBUS_P1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(49, "I2S0_DATA"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 31),
++ MTK_FUNCTION(0, "GPIO49"),
++ MTK_FUNCTION(1, "I2S0_DATA"),
++ MTK_FUNCTION(2, "I2S0_DATA_BYPS"),
++ MTK_FUNCTION(3, "PCM_TX"),
++ MTK_FUNCTION(6, "WCN_I2S_DO"),
++ MTK_FUNCTION(7, "DBG_MON_B[3]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(50, "I2S2_BCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 32),
++ MTK_FUNCTION(0, "GPIO50"),
++ MTK_FUNCTION(1, "I2S2_BCK"),
++ MTK_FUNCTION(3, "PCM_CLK0"),
++ MTK_FUNCTION(4, "DMIC_SCK1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(51, "I2S2_DATA_IN"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 33),
++ MTK_FUNCTION(0, "GPIO51"),
++ MTK_FUNCTION(1, "I2S2_DATA_IN"),
++ MTK_FUNCTION(3, "PCM_RX"),
++ MTK_FUNCTION(4, "DMIC_SCK0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(52, "I2S2_LRCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 34),
++ MTK_FUNCTION(0, "GPIO52"),
++ MTK_FUNCTION(1, "I2S2_LRCK"),
++ MTK_FUNCTION(3, "PCM_SYNC"),
++ MTK_FUNCTION(4, "DMIC_DAT1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(53, "SPI0_CSN"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 35),
++ MTK_FUNCTION(0, "GPIO53"),
++ MTK_FUNCTION(1, "SPI0_CS"),
++ MTK_FUNCTION(3, "SPDIF"),
++ MTK_FUNCTION(4, "ADC_CK"),
++ MTK_FUNCTION(5, "PWM1"),
++ MTK_FUNCTION(7, "DBG_MON_A[7]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(54, "SPI0_CK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 36),
++ MTK_FUNCTION(0, "GPIO54"),
++ MTK_FUNCTION(1, "SPI0_CK"),
++ MTK_FUNCTION(3, "SPDIF_IN1"),
++ MTK_FUNCTION(4, "ADC_DAT_IN"),
++ MTK_FUNCTION(7, "DBG_MON_A[10]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(55, "SPI0_MI"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 37),
++ MTK_FUNCTION(0, "GPIO55"),
++ MTK_FUNCTION(1, "SPI0_MI"),
++ MTK_FUNCTION(2, "SPI0_MO"),
++ MTK_FUNCTION(3, "MSDC1_WP"),
++ MTK_FUNCTION(4, "ADC_WS"),
++ MTK_FUNCTION(5, "PWM2"),
++ MTK_FUNCTION(7, "DBG_MON_A[8]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(56, "SPI0_MO"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 38),
++ MTK_FUNCTION(0, "GPIO56"),
++ MTK_FUNCTION(1, "SPI0_MO"),
++ MTK_FUNCTION(2, "SPI0_MI"),
++ MTK_FUNCTION(3, "SPDIF_IN0"),
++ MTK_FUNCTION(7, "DBG_MON_A[9]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(57, "SDA1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 39),
++ MTK_FUNCTION(0, "GPIO57"),
++ MTK_FUNCTION(1, "SDA1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(58, "SCL1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 40),
++ MTK_FUNCTION(0, "GPIO58"),
++ MTK_FUNCTION(1, "SCL1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(59, "RAMBUF_I_CLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO59"),
++ MTK_FUNCTION(1, "RAMBUF_I_CLK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(60, "WB_RSTB"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 41),
++ MTK_FUNCTION(0, "GPIO60"),
++ MTK_FUNCTION(1, "WB_RSTB"),
++ MTK_FUNCTION(7, "DBG_MON_A[11]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(61, "F2W_DATA"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 42),
++ MTK_FUNCTION(0, "GPIO61"),
++ MTK_FUNCTION(1, "F2W_DATA"),
++ MTK_FUNCTION(7, "DBG_MON_A[16]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(62, "F2W_CLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 43),
++ MTK_FUNCTION(0, "GPIO62"),
++ MTK_FUNCTION(1, "F2W_CK"),
++ MTK_FUNCTION(7, "DBG_MON_A[15]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(63, "WB_SCLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 44),
++ MTK_FUNCTION(0, "GPIO63"),
++ MTK_FUNCTION(1, "WB_SCLK"),
++ MTK_FUNCTION(7, "DBG_MON_A[13]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(64, "WB_SDATA"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 45),
++ MTK_FUNCTION(0, "GPIO64"),
++ MTK_FUNCTION(1, "WB_SDATA"),
++ MTK_FUNCTION(7, "DBG_MON_A[12]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(65, "WB_SEN"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 46),
++ MTK_FUNCTION(0, "GPIO65"),
++ MTK_FUNCTION(1, "WB_SEN"),
++ MTK_FUNCTION(7, "DBG_MON_A[14]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(66, "WB_CRTL0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 47),
++ MTK_FUNCTION(0, "GPIO66"),
++ MTK_FUNCTION(1, "WB_CRTL0"),
++ MTK_FUNCTION(5, "DFD_NTRST_XI"),
++ MTK_FUNCTION(7, "DBG_MON_A[17]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(67, "WB_CRTL1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 48),
++ MTK_FUNCTION(0, "GPIO67"),
++ MTK_FUNCTION(1, "WB_CRTL1"),
++ MTK_FUNCTION(5, "DFD_TMS_XI"),
++ MTK_FUNCTION(7, "DBG_MON_A[18]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(68, "WB_CRTL2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 49),
++ MTK_FUNCTION(0, "GPIO68"),
++ MTK_FUNCTION(1, "WB_CRTL2"),
++ MTK_FUNCTION(5, "DFD_TCK_XI"),
++ MTK_FUNCTION(7, "DBG_MON_A[19]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(69, "WB_CRTL3"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 50),
++ MTK_FUNCTION(0, "GPIO69"),
++ MTK_FUNCTION(1, "WB_CRTL3"),
++ MTK_FUNCTION(5, "DFD_TDI_XI"),
++ MTK_FUNCTION(7, "DBG_MON_A[20]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(70, "WB_CRTL4"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 51),
++ MTK_FUNCTION(0, "GPIO70"),
++ MTK_FUNCTION(1, "WB_CRTL4"),
++ MTK_FUNCTION(5, "DFD_TDO"),
++ MTK_FUNCTION(7, "DBG_MON_A[21]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(71, "WB_CRTL5"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 52),
++ MTK_FUNCTION(0, "GPIO71"),
++ MTK_FUNCTION(1, "WB_CRTL5"),
++ MTK_FUNCTION(7, "DBG_MON_A[22]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(72, "I2S0_DATA_IN"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 53),
++ MTK_FUNCTION(0, "GPIO72"),
++ MTK_FUNCTION(1, "I2S0_DATA_IN"),
++ MTK_FUNCTION(3, "PCM_RX"),
++ MTK_FUNCTION(4, "PWM0"),
++ MTK_FUNCTION(5, "DISP_PWM"),
++ MTK_FUNCTION(6, "WCN_I2S_DI"),
++ MTK_FUNCTION(7, "DBG_MON_B[2]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(73, "I2S0_LRCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 54),
++ MTK_FUNCTION(0, "GPIO73"),
++ MTK_FUNCTION(1, "I2S0_LRCK"),
++ MTK_FUNCTION(3, "PCM_SYNC"),
++ MTK_FUNCTION(6, "WCN_I2S_LRCK"),
++ MTK_FUNCTION(7, "DBG_MON_B[5]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(74, "I2S0_BCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 55),
++ MTK_FUNCTION(0, "GPIO74"),
++ MTK_FUNCTION(1, "I2S0_BCK"),
++ MTK_FUNCTION(3, "PCM_CLK0"),
++ MTK_FUNCTION(6, "WCN_I2S_BCK"),
++ MTK_FUNCTION(7, "DBG_MON_B[4]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(75, "SDA0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 56),
++ MTK_FUNCTION(0, "GPIO75"),
++ MTK_FUNCTION(1, "SDA0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(76, "SCL0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 57),
++ MTK_FUNCTION(0, "GPIO76"),
++ MTK_FUNCTION(1, "SCL0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(77, "SDA2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 58),
++ MTK_FUNCTION(0, "GPIO77"),
++ MTK_FUNCTION(1, "SDA2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(78, "SCL2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 59),
++ MTK_FUNCTION(0, "GPIO78"),
++ MTK_FUNCTION(1, "SCL2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(79, "URXD0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 60),
++ MTK_FUNCTION(0, "GPIO79"),
++ MTK_FUNCTION(1, "URXD0"),
++ MTK_FUNCTION(2, "UTXD0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(80, "UTXD0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 61),
++ MTK_FUNCTION(0, "GPIO80"),
++ MTK_FUNCTION(1, "UTXD0"),
++ MTK_FUNCTION(2, "URXD0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(81, "URXD1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 62),
++ MTK_FUNCTION(0, "GPIO81"),
++ MTK_FUNCTION(1, "URXD1"),
++ MTK_FUNCTION(2, "UTXD1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(82, "UTXD1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 63),
++ MTK_FUNCTION(0, "GPIO82"),
++ MTK_FUNCTION(1, "UTXD1"),
++ MTK_FUNCTION(2, "URXD1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(83, "LCM_RST"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 64),
++ MTK_FUNCTION(0, "GPIO83"),
++ MTK_FUNCTION(1, "LCM_RST"),
++ MTK_FUNCTION(2, "VDAC_CK_XI"),
++ MTK_FUNCTION(7, "DBG_MON_B[1]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(84, "DSI_TE"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 65),
++ MTK_FUNCTION(0, "GPIO84"),
++ MTK_FUNCTION(1, "DSI_TE"),
++ MTK_FUNCTION(7, "DBG_MON_B[0]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(85, "MSDC2_CMD"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 66),
++ MTK_FUNCTION(0, "GPIO85"),
++ MTK_FUNCTION(1, "MSDC2_CMD"),
++ MTK_FUNCTION(2, "ANT_SEL0"),
++ MTK_FUNCTION(3, "SDA1"),
++ MTK_FUNCTION(6, "I2SOUT_BCK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(86, "MSDC2_CLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 67),
++ MTK_FUNCTION(0, "GPIO86"),
++ MTK_FUNCTION(1, "MSDC2_CLK"),
++ MTK_FUNCTION(2, "ANT_SEL1"),
++ MTK_FUNCTION(3, "SCL1"),
++ MTK_FUNCTION(6, "I2SOUT_LRCK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(87, "MSDC2_DAT0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 68),
++ MTK_FUNCTION(0, "GPIO87"),
++ MTK_FUNCTION(1, "MSDC2_DAT0"),
++ MTK_FUNCTION(2, "ANT_SEL2"),
++ MTK_FUNCTION(5, "UTXD0"),
++ MTK_FUNCTION(6, "I2SOUT_DATA_OUT")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(88, "MSDC2_DAT1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 71),
++ MTK_FUNCTION(0, "GPIO88"),
++ MTK_FUNCTION(1, "MSDC2_DAT1"),
++ MTK_FUNCTION(2, "ANT_SEL3"),
++ MTK_FUNCTION(3, "PWM0"),
++ MTK_FUNCTION(5, "URXD0"),
++ MTK_FUNCTION(6, "PWM1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(89, "MSDC2_DAT2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 72),
++ MTK_FUNCTION(0, "GPIO89"),
++ MTK_FUNCTION(1, "MSDC2_DAT2"),
++ MTK_FUNCTION(2, "ANT_SEL4"),
++ MTK_FUNCTION(3, "SDA2"),
++ MTK_FUNCTION(5, "UTXD1"),
++ MTK_FUNCTION(6, "PWM2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(90, "MSDC2_DAT3"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 73),
++ MTK_FUNCTION(0, "GPIO90"),
++ MTK_FUNCTION(1, "MSDC2_DAT3"),
++ MTK_FUNCTION(2, "ANT_SEL5"),
++ MTK_FUNCTION(3, "SCL2"),
++ MTK_FUNCTION(4, "EXT_FRAME_SYNC"),
++ MTK_FUNCTION(5, "URXD1"),
++ MTK_FUNCTION(6, "PWM3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(91, "TDN3"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPI91"),
++ MTK_FUNCTION(1, "TDN3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(92, "TDP3"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPI92"),
++ MTK_FUNCTION(1, "TDP3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(93, "TDN2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPI93"),
++ MTK_FUNCTION(1, "TDN2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(94, "TDP2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPI94"),
++ MTK_FUNCTION(1, "TDP2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(95, "TCN"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPI95"),
++ MTK_FUNCTION(1, "TCN")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(96, "TCP"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPI96"),
++ MTK_FUNCTION(1, "TCP")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(97, "TDN1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPI97"),
++ MTK_FUNCTION(1, "TDN1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(98, "TDP1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPI98"),
++ MTK_FUNCTION(1, "TDP1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(99, "TDN0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPI99"),
++ MTK_FUNCTION(1, "TDN0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(100, "TDP0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPI100"),
++ MTK_FUNCTION(1, "TDP0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(101, "SPI2_CSN"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 74),
++ MTK_FUNCTION(0, "GPIO101"),
++ MTK_FUNCTION(1, "SPI2_CS"),
++ MTK_FUNCTION(3, "SCL3"),
++ MTK_FUNCTION(4, "KROW0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(102, "SPI2_MI"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 75),
++ MTK_FUNCTION(0, "GPIO102"),
++ MTK_FUNCTION(1, "SPI2_MI"),
++ MTK_FUNCTION(2, "SPI2_MO"),
++ MTK_FUNCTION(3, "SDA3"),
++ MTK_FUNCTION(4, "KROW1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(103, "SPI2_MO"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 76),
++ MTK_FUNCTION(0, "GPIO103"),
++ MTK_FUNCTION(1, "SPI2_MO"),
++ MTK_FUNCTION(2, "SPI2_MI"),
++ MTK_FUNCTION(3, "SCL3"),
++ MTK_FUNCTION(4, "KROW2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(104, "SPI2_CLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 77),
++ MTK_FUNCTION(0, "GPIO104"),
++ MTK_FUNCTION(1, "SPI2_CK"),
++ MTK_FUNCTION(3, "SDA3"),
++ MTK_FUNCTION(4, "KROW3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(105, "MSDC1_CMD"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 78),
++ MTK_FUNCTION(0, "GPIO105"),
++ MTK_FUNCTION(1, "MSDC1_CMD"),
++ MTK_FUNCTION(2, "ANT_SEL0"),
++ MTK_FUNCTION(3, "SDA1"),
++ MTK_FUNCTION(6, "I2SOUT_BCK"),
++ MTK_FUNCTION(7, "DBG_MON_B[27]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(106, "MSDC1_CLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 79),
++ MTK_FUNCTION(0, "GPIO106"),
++ MTK_FUNCTION(1, "MSDC1_CLK"),
++ MTK_FUNCTION(2, "ANT_SEL1"),
++ MTK_FUNCTION(3, "SCL1"),
++ MTK_FUNCTION(6, "I2SOUT_LRCK"),
++ MTK_FUNCTION(7, "DBG_MON_B[28]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(107, "MSDC1_DAT0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 80),
++ MTK_FUNCTION(0, "GPIO107"),
++ MTK_FUNCTION(1, "MSDC1_DAT0"),
++ MTK_FUNCTION(2, "ANT_SEL2"),
++ MTK_FUNCTION(5, "UTXD0"),
++ MTK_FUNCTION(6, "I2SOUT_DATA_OUT"),
++ MTK_FUNCTION(7, "DBG_MON_B[26]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(108, "MSDC1_DAT1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 81),
++ MTK_FUNCTION(0, "GPIO108"),
++ MTK_FUNCTION(1, "MSDC1_DAT1"),
++ MTK_FUNCTION(2, "ANT_SEL3"),
++ MTK_FUNCTION(3, "PWM0"),
++ MTK_FUNCTION(5, "URXD0"),
++ MTK_FUNCTION(6, "PWM1"),
++ MTK_FUNCTION(7, "DBG_MON_B[25]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(109, "MSDC1_DAT2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 82),
++ MTK_FUNCTION(0, "GPIO109"),
++ MTK_FUNCTION(1, "MSDC1_DAT2"),
++ MTK_FUNCTION(2, "ANT_SEL4"),
++ MTK_FUNCTION(3, "SDA2"),
++ MTK_FUNCTION(5, "UTXD1"),
++ MTK_FUNCTION(6, "PWM2"),
++ MTK_FUNCTION(7, "DBG_MON_B[24]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(110, "MSDC1_DAT3"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 83),
++ MTK_FUNCTION(0, "GPIO110"),
++ MTK_FUNCTION(1, "MSDC1_DAT3"),
++ MTK_FUNCTION(2, "ANT_SEL5"),
++ MTK_FUNCTION(3, "SCL2"),
++ MTK_FUNCTION(4, "EXT_FRAME_SYNC"),
++ MTK_FUNCTION(5, "URXD1"),
++ MTK_FUNCTION(6, "PWM3"),
++ MTK_FUNCTION(7, "DBG_MON_B[23]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(111, "MSDC0_DAT7"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 84),
++ MTK_FUNCTION(0, "GPIO111"),
++ MTK_FUNCTION(1, "MSDC0_DAT7"),
++ MTK_FUNCTION(4, "NLD7")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(112, "MSDC0_DAT6"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 85),
++ MTK_FUNCTION(0, "GPIO112"),
++ MTK_FUNCTION(1, "MSDC0_DAT6"),
++ MTK_FUNCTION(4, "NLD6")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(113, "MSDC0_DAT5"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 86),
++ MTK_FUNCTION(0, "GPIO113"),
++ MTK_FUNCTION(1, "MSDC0_DAT5"),
++ MTK_FUNCTION(4, "NLD5")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(114, "MSDC0_DAT4"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 87),
++ MTK_FUNCTION(0, "GPIO114"),
++ MTK_FUNCTION(1, "MSDC0_DAT4"),
++ MTK_FUNCTION(4, "NLD4")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(115, "MSDC0_RSTB"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 88),
++ MTK_FUNCTION(0, "GPIO115"),
++ MTK_FUNCTION(1, "MSDC0_RSTB"),
++ MTK_FUNCTION(4, "NLD8")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(116, "MSDC0_CMD"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 89),
++ MTK_FUNCTION(0, "GPIO116"),
++ MTK_FUNCTION(1, "MSDC0_CMD"),
++ MTK_FUNCTION(4, "NALE")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(117, "MSDC0_CLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 90),
++ MTK_FUNCTION(0, "GPIO117"),
++ MTK_FUNCTION(1, "MSDC0_CLK"),
++ MTK_FUNCTION(4, "NWEB")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(118, "MSDC0_DAT3"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 91),
++ MTK_FUNCTION(0, "GPIO118"),
++ MTK_FUNCTION(1, "MSDC0_DAT3"),
++ MTK_FUNCTION(4, "NLD3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(119, "MSDC0_DAT2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 92),
++ MTK_FUNCTION(0, "GPIO119"),
++ MTK_FUNCTION(1, "MSDC0_DAT2"),
++ MTK_FUNCTION(4, "NLD2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(120, "MSDC0_DAT1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 93),
++ MTK_FUNCTION(0, "GPIO120"),
++ MTK_FUNCTION(1, "MSDC0_DAT1"),
++ MTK_FUNCTION(4, "NLD1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(121, "MSDC0_DAT0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 94),
++ MTK_FUNCTION(0, "GPIO121"),
++ MTK_FUNCTION(1, "MSDC0_DAT0"),
++ MTK_FUNCTION(4, "NLD0"),
++ MTK_FUNCTION(5, "WATCHDOG")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(122, "CEC"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 95),
++ MTK_FUNCTION(0, "GPIO122"),
++ MTK_FUNCTION(1, "CEC"),
++ MTK_FUNCTION(4, "SDA2"),
++ MTK_FUNCTION(5, "URXD0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(123, "HTPLG"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 96),
++ MTK_FUNCTION(0, "GPIO123"),
++ MTK_FUNCTION(1, "HTPLG"),
++ MTK_FUNCTION(4, "SCL2"),
++ MTK_FUNCTION(5, "UTXD0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(124, "HDMISCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 97),
++ MTK_FUNCTION(0, "GPIO124"),
++ MTK_FUNCTION(1, "HDMISCK"),
++ MTK_FUNCTION(4, "SDA1"),
++ MTK_FUNCTION(5, "PWM3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(125, "HDMISD"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 98),
++ MTK_FUNCTION(0, "GPIO125"),
++ MTK_FUNCTION(1, "HDMISD"),
++ MTK_FUNCTION(4, "SCL1"),
++ MTK_FUNCTION(5, "PWM4")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(126, "I2S0_MCLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 99),
++ MTK_FUNCTION(0, "GPIO126"),
++ MTK_FUNCTION(1, "I2S0_MCLK"),
++ MTK_FUNCTION(6, "WCN_I2S_MCLK"),
++ MTK_FUNCTION(7, "DBG_MON_B[6]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(127, "RAMBUF_IDATA0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO127"),
++ MTK_FUNCTION(1, "RAMBUF_IDATA0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(128, "RAMBUF_IDATA1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO128"),
++ MTK_FUNCTION(1, "RAMBUF_IDATA1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(129, "RAMBUF_IDATA2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO129"),
++ MTK_FUNCTION(1, "RAMBUF_IDATA2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(130, "RAMBUF_IDATA3"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO130"),
++ MTK_FUNCTION(1, "RAMBUF_IDATA3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(131, "RAMBUF_IDATA4"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO131"),
++ MTK_FUNCTION(1, "RAMBUF_IDATA4")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(132, "RAMBUF_IDATA5"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO132"),
++ MTK_FUNCTION(1, "RAMBUF_IDATA5")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(133, "RAMBUF_IDATA6"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO133"),
++ MTK_FUNCTION(1, "RAMBUF_IDATA6")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(134, "RAMBUF_IDATA7"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO134"),
++ MTK_FUNCTION(1, "RAMBUF_IDATA7")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(135, "RAMBUF_IDATA8"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO135"),
++ MTK_FUNCTION(1, "RAMBUF_IDATA8")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(136, "RAMBUF_IDATA9"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO136"),
++ MTK_FUNCTION(1, "RAMBUF_IDATA9")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(137, "RAMBUF_IDATA10"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO137"),
++ MTK_FUNCTION(1, "RAMBUF_IDATA10")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(138, "RAMBUF_IDATA11"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO138"),
++ MTK_FUNCTION(1, "RAMBUF_IDATA11")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(139, "RAMBUF_IDATA12"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO139"),
++ MTK_FUNCTION(1, "RAMBUF_IDATA12")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(140, "RAMBUF_IDATA13"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO140"),
++ MTK_FUNCTION(1, "RAMBUF_IDATA13")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(141, "RAMBUF_IDATA14"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO141"),
++ MTK_FUNCTION(1, "RAMBUF_IDATA14")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(142, "RAMBUF_IDATA15"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO142"),
++ MTK_FUNCTION(1, "RAMBUF_IDATA15")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(143, "RAMBUF_ODATA0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO143"),
++ MTK_FUNCTION(1, "RAMBUF_ODATA0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(144, "RAMBUF_ODATA1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO144"),
++ MTK_FUNCTION(1, "RAMBUF_ODATA1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(145, "RAMBUF_ODATA2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO145"),
++ MTK_FUNCTION(1, "RAMBUF_ODATA2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(146, "RAMBUF_ODATA3"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO146"),
++ MTK_FUNCTION(1, "RAMBUF_ODATA3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(147, "RAMBUF_ODATA4"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO147"),
++ MTK_FUNCTION(1, "RAMBUF_ODATA4")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(148, "RAMBUF_ODATA5"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO148"),
++ MTK_FUNCTION(1, "RAMBUF_ODATA5")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(149, "RAMBUF_ODATA6"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO149"),
++ MTK_FUNCTION(1, "RAMBUF_ODATA6")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(150, "RAMBUF_ODATA7"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO150"),
++ MTK_FUNCTION(1, "RAMBUF_ODATA7")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(151, "RAMBUF_ODATA8"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO151"),
++ MTK_FUNCTION(1, "RAMBUF_ODATA8")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(152, "RAMBUF_ODATA9"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO152"),
++ MTK_FUNCTION(1, "RAMBUF_ODATA9")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(153, "RAMBUF_ODATA10"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO153"),
++ MTK_FUNCTION(1, "RAMBUF_ODATA10")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(154, "RAMBUF_ODATA11"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO154"),
++ MTK_FUNCTION(1, "RAMBUF_ODATA11")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(155, "RAMBUF_ODATA12"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO155"),
++ MTK_FUNCTION(1, "RAMBUF_ODATA12")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(156, "RAMBUF_ODATA13"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO156"),
++ MTK_FUNCTION(1, "RAMBUF_ODATA13")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(157, "RAMBUF_ODATA14"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO157"),
++ MTK_FUNCTION(1, "RAMBUF_ODATA14")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(158, "RAMBUF_ODATA15"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO158"),
++ MTK_FUNCTION(1, "RAMBUF_ODATA15")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(159, "RAMBUF_BE0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO159"),
++ MTK_FUNCTION(1, "RAMBUF_BE0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(160, "RAMBUF_BE1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO160"),
++ MTK_FUNCTION(1, "RAMBUF_BE1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(161, "AP2PT_INT"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO161"),
++ MTK_FUNCTION(1, "AP2PT_INT")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(162, "AP2PT_INT_CLR"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO162"),
++ MTK_FUNCTION(1, "AP2PT_INT_CLR")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(163, "PT2AP_INT"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO163"),
++ MTK_FUNCTION(1, "PT2AP_INT")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(164, "PT2AP_INT_CLR"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO164"),
++ MTK_FUNCTION(1, "PT2AP_INT_CLR")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(165, "AP2UP_INT"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO165"),
++ MTK_FUNCTION(1, "AP2UP_INT")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(166, "AP2UP_INT_CLR"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO166"),
++ MTK_FUNCTION(1, "AP2UP_INT_CLR")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(167, "UP2AP_INT"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO167"),
++ MTK_FUNCTION(1, "UP2AP_INT")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(168, "UP2AP_INT_CLR"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO168"),
++ MTK_FUNCTION(1, "UP2AP_INT_CLR")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(169, "RAMBUF_ADDR0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO169"),
++ MTK_FUNCTION(1, "RAMBUF_ADDR0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(170, "RAMBUF_ADDR1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO170"),
++ MTK_FUNCTION(1, "RAMBUF_ADDR1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(171, "RAMBUF_ADDR2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO171"),
++ MTK_FUNCTION(1, "RAMBUF_ADDR2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(172, "RAMBUF_ADDR3"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO172"),
++ MTK_FUNCTION(1, "RAMBUF_ADDR3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(173, "RAMBUF_ADDR4"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO173"),
++ MTK_FUNCTION(1, "RAMBUF_ADDR4")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(174, "RAMBUF_ADDR5"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO174"),
++ MTK_FUNCTION(1, "RAMBUF_ADDR5")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(175, "RAMBUF_ADDR6"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO175"),
++ MTK_FUNCTION(1, "RAMBUF_ADDR6")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(176, "RAMBUF_ADDR7"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO176"),
++ MTK_FUNCTION(1, "RAMBUF_ADDR7")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(177, "RAMBUF_ADDR8"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO177"),
++ MTK_FUNCTION(1, "RAMBUF_ADDR8")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(178, "RAMBUF_ADDR9"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO178"),
++ MTK_FUNCTION(1, "RAMBUF_ADDR9")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(179, "RAMBUF_ADDR10"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO179"),
++ MTK_FUNCTION(1, "RAMBUF_ADDR10")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(180, "RAMBUF_RW"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO180"),
++ MTK_FUNCTION(1, "RAMBUF_RW")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(181, "RAMBUF_LAST"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO181"),
++ MTK_FUNCTION(1, "RAMBUF_LAST")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(182, "RAMBUF_HP"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO182"),
++ MTK_FUNCTION(1, "RAMBUF_HP")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(183, "RAMBUF_REQ"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO183"),
++ MTK_FUNCTION(1, "RAMBUF_REQ")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(184, "RAMBUF_ALE"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO184"),
++ MTK_FUNCTION(1, "RAMBUF_ALE")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(185, "RAMBUF_DLE"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO185"),
++ MTK_FUNCTION(1, "RAMBUF_DLE")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(186, "RAMBUF_WDLE"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO186"),
++ MTK_FUNCTION(1, "RAMBUF_WDLE")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(187, "RAMBUF_O_CLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO187"),
++ MTK_FUNCTION(1, "RAMBUF_O_CLK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(188, "I2S2_MCLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 100),
++ MTK_FUNCTION(0, "GPIO188"),
++ MTK_FUNCTION(1, "I2S2_MCLK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(189, "I2S3_DATA"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 101),
++ MTK_FUNCTION(0, "GPIO189"),
++ MTK_FUNCTION(2, "I2S3_DATA_BYPS"),
++ MTK_FUNCTION(3, "PCM_TX")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(190, "I2S3_DATA_IN"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 102),
++ MTK_FUNCTION(0, "GPIO190"),
++ MTK_FUNCTION(1, "I2S3_DATA_IN"),
++ MTK_FUNCTION(3, "PCM_RX")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(191, "I2S3_BCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 103),
++ MTK_FUNCTION(0, "GPIO191"),
++ MTK_FUNCTION(1, "I2S3_BCK"),
++ MTK_FUNCTION(3, "PCM_CLK0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(192, "I2S3_LRCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 104),
++ MTK_FUNCTION(0, "GPIO192"),
++ MTK_FUNCTION(1, "I2S3_LRCK"),
++ MTK_FUNCTION(3, "PCM_SYNC")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(193, "I2S3_MCLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 105),
++ MTK_FUNCTION(0, "GPIO193"),
++ MTK_FUNCTION(1, "I2S3_MCLK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(194, "I2S4_DATA"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 106),
++ MTK_FUNCTION(0, "GPIO194"),
++ MTK_FUNCTION(1, "I2S4_DATA"),
++ MTK_FUNCTION(2, "I2S4_DATA_BYPS"),
++ MTK_FUNCTION(3, "PCM_TX")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(195, "I2S4_DATA_IN"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 107),
++ MTK_FUNCTION(0, "GPIO195"),
++ MTK_FUNCTION(1, "I2S4_DATA_IN"),
++ MTK_FUNCTION(3, "PCM_RX")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(196, "I2S4_BCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 108),
++ MTK_FUNCTION(0, "GPIO196"),
++ MTK_FUNCTION(1, "I2S4_BCK"),
++ MTK_FUNCTION(3, "PCM_CLK0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(197, "I2S4_LRCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 109),
++ MTK_FUNCTION(0, "GPIO197"),
++ MTK_FUNCTION(1, "I2S4_LRCK"),
++ MTK_FUNCTION(3, "PCM_SYNC")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(198, "I2S4_MCLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 110),
++ MTK_FUNCTION(0, "GPIO198"),
++ MTK_FUNCTION(1, "I2S4_MCLK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(199, "SPI1_CLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 111),
++ MTK_FUNCTION(0, "GPIO199"),
++ MTK_FUNCTION(1, "SPI1_CK"),
++ MTK_FUNCTION(3, "EXT_FRAME_SYNC"),
++ MTK_FUNCTION(4, "KCOL3"),
++ MTK_FUNCTION(7, "DBG_MON_B[15]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(200, "SPDIF_OUT"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 112),
++ MTK_FUNCTION(0, "GPIO200"),
++ MTK_FUNCTION(1, "SPDIF_OUT"),
++ MTK_FUNCTION(5, "G1_TXD3"),
++ MTK_FUNCTION(6, "URXD2"),
++ MTK_FUNCTION(7, "DBG_MON_B[16]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(201, "SPDIF_IN0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 113),
++ MTK_FUNCTION(0, "GPIO201"),
++ MTK_FUNCTION(1, "SPDIF_IN0"),
++ MTK_FUNCTION(5, "G1_TXEN"),
++ MTK_FUNCTION(6, "UTXD2"),
++ MTK_FUNCTION(7, "DBG_MON_B[17]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(202, "SPDIF_IN1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 114),
++ MTK_FUNCTION(0, "GPIO202"),
++ MTK_FUNCTION(1, "SPDIF_IN1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(203, "PWM0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 115),
++ MTK_FUNCTION(0, "GPIO203"),
++ MTK_FUNCTION(1, "PWM0"),
++ MTK_FUNCTION(2, "DISP_PWM"),
++ MTK_FUNCTION(5, "G1_TXD2"),
++ MTK_FUNCTION(7, "DBG_MON_B[18]"),
++ MTK_FUNCTION(9, "I2S2_DATA")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(204, "PWM1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 116),
++ MTK_FUNCTION(0, "GPIO204"),
++ MTK_FUNCTION(1, "PWM1"),
++ MTK_FUNCTION(2, "CLKM3"),
++ MTK_FUNCTION(5, "G1_TXD1"),
++ MTK_FUNCTION(7, "DBG_MON_B[19]"),
++ MTK_FUNCTION(9, "I2S3_DATA")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(205, "PWM2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 117),
++ MTK_FUNCTION(0, "GPIO205"),
++ MTK_FUNCTION(1, "PWM2"),
++ MTK_FUNCTION(2, "CLKM2"),
++ MTK_FUNCTION(5, "G1_TXD0"),
++ MTK_FUNCTION(7, "DBG_MON_B[20]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(206, "PWM3"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 118),
++ MTK_FUNCTION(0, "GPIO206"),
++ MTK_FUNCTION(1, "PWM3"),
++ MTK_FUNCTION(2, "CLKM1"),
++ MTK_FUNCTION(3, "EXT_FRAME_SYNC"),
++ MTK_FUNCTION(5, "G1_TXC"),
++ MTK_FUNCTION(7, "DBG_MON_B[21]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(207, "PWM4"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 119),
++ MTK_FUNCTION(0, "GPIO207"),
++ MTK_FUNCTION(1, "PWM4"),
++ MTK_FUNCTION(2, "CLKM0"),
++ MTK_FUNCTION(3, "EXT_FRAME_SYNC"),
++ MTK_FUNCTION(5, "G1_RXC"),
++ MTK_FUNCTION(7, "DBG_MON_B[22]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(208, "AUD_EXT_CK1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 120),
++ MTK_FUNCTION(0, "GPIO208"),
++ MTK_FUNCTION(1, "AUD_EXT_CK1"),
++ MTK_FUNCTION(2, "PWM0"),
++ MTK_FUNCTION(4, "ANT_SEL5"),
++ MTK_FUNCTION(5, "DISP_PWM"),
++ MTK_FUNCTION(7, "DBG_MON_A[31]"),
++ MTK_FUNCTION(11, "PCIE0_PERST_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(209, "AUD_EXT_CK2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 121),
++ MTK_FUNCTION(0, "GPIO209"),
++ MTK_FUNCTION(1, "AUD_EXT_CK2"),
++ MTK_FUNCTION(2, "MSDC1_WP"),
++ MTK_FUNCTION(5, "PWM1"),
++ MTK_FUNCTION(7, "DBG_MON_A[32]"),
++ MTK_FUNCTION(11, "PCIE1_PERST_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(210, "AUD_CLOCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO210"),
++ MTK_FUNCTION(1, "AUD_CLOCK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(211, "DVP_RESET"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO211"),
++ MTK_FUNCTION(1, "DVP_RESET")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(212, "DVP_CLOCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO212"),
++ MTK_FUNCTION(1, "DVP_CLOCK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(213, "DVP_CS"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO213"),
++ MTK_FUNCTION(1, "DVP_CS")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(214, "DVP_CK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO214"),
++ MTK_FUNCTION(1, "DVP_CK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(215, "DVP_DI"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO215"),
++ MTK_FUNCTION(1, "DVP_DI")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(216, "DVP_DO"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO216"),
++ MTK_FUNCTION(1, "DVP_DO")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(217, "AP_CS"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO217"),
++ MTK_FUNCTION(1, "AP_CS")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(218, "AP_CK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO218"),
++ MTK_FUNCTION(1, "AP_CK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(219, "AP_DI"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO219"),
++ MTK_FUNCTION(1, "AP_DI")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(220, "AP_DO"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO220"),
++ MTK_FUNCTION(1, "AP_DO")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(221, "DVD_BCLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO221"),
++ MTK_FUNCTION(1, "DVD_BCLK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(222, "T8032_CLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO222"),
++ MTK_FUNCTION(1, "T8032_CLK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(223, "AP_BCLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO223"),
++ MTK_FUNCTION(1, "AP_BCLK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(224, "HOST_CS"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO224"),
++ MTK_FUNCTION(1, "HOST_CS")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(225, "HOST_CK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO225"),
++ MTK_FUNCTION(1, "HOST_CK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(226, "HOST_DO0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO226"),
++ MTK_FUNCTION(1, "HOST_DO0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(227, "HOST_DO1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO227"),
++ MTK_FUNCTION(1, "HOST_DO1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(228, "SLV_CS"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO228"),
++ MTK_FUNCTION(1, "SLV_CS")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(229, "SLV_CK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO229"),
++ MTK_FUNCTION(1, "SLV_CK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(230, "SLV_DI0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO230"),
++ MTK_FUNCTION(1, "SLV_DI0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(231, "SLV_DI1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO231"),
++ MTK_FUNCTION(1, "SLV_DI1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(232, "AP2DSP_INT"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO232"),
++ MTK_FUNCTION(1, "AP2DSP_INT")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(233, "AP2DSP_INT_CLR"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO233"),
++ MTK_FUNCTION(1, "AP2DSP_INT_CLR")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(234, "DSP2AP_INT"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO234"),
++ MTK_FUNCTION(1, "DSP2AP_INT")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(235, "DSP2AP_INT_CLR"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO235"),
++ MTK_FUNCTION(1, "DSP2AP_INT_CLR")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(236, "EXT_SDIO3"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 122),
++ MTK_FUNCTION(0, "GPIO236"),
++ MTK_FUNCTION(1, "EXT_SDIO3"),
++ MTK_FUNCTION(2, "IDDIG"),
++ MTK_FUNCTION(7, "DBG_MON_A[1]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(237, "EXT_SDIO2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 123),
++ MTK_FUNCTION(0, "GPIO237"),
++ MTK_FUNCTION(1, "EXT_SDIO2"),
++ MTK_FUNCTION(2, "DRV_VBUS")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(238, "EXT_SDIO1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 124),
++ MTK_FUNCTION(0, "GPIO238"),
++ MTK_FUNCTION(1, "EXT_SDIO1"),
++ MTK_FUNCTION(2, "IDDIG_P1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(239, "EXT_SDIO0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 125),
++ MTK_FUNCTION(0, "GPIO239"),
++ MTK_FUNCTION(1, "EXT_SDIO0"),
++ MTK_FUNCTION(2, "DRV_VBUS_P1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(240, "EXT_XCS"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 126),
++ MTK_FUNCTION(0, "GPIO240"),
++ MTK_FUNCTION(1, "EXT_XCS")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(241, "EXT_SCK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 127),
++ MTK_FUNCTION(0, "GPIO241"),
++ MTK_FUNCTION(1, "EXT_SCK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(242, "URTS2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 128),
++ MTK_FUNCTION(0, "GPIO242"),
++ MTK_FUNCTION(1, "URTS2"),
++ MTK_FUNCTION(2, "UTXD3"),
++ MTK_FUNCTION(3, "URXD3"),
++ MTK_FUNCTION(4, "SCL1"),
++ MTK_FUNCTION(7, "DBG_MON_B[32]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(243, "UCTS2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 129),
++ MTK_FUNCTION(0, "GPIO243"),
++ MTK_FUNCTION(1, "UCTS2"),
++ MTK_FUNCTION(2, "URXD3"),
++ MTK_FUNCTION(3, "UTXD3"),
++ MTK_FUNCTION(4, "SDA1"),
++ MTK_FUNCTION(7, "DBG_MON_A[6]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(244, "HDMI_SDA_RX"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 130),
++ MTK_FUNCTION(0, "GPIO244"),
++ MTK_FUNCTION(1, "HDMI_SDA_RX")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(245, "HDMI_SCL_RX"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 131),
++ MTK_FUNCTION(0, "GPIO245"),
++ MTK_FUNCTION(1, "HDMI_SCL_RX")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(246, "MHL_SENCE"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 132),
++ MTK_FUNCTION(0, "GPIO246")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(247, "HDMI_HPD_CBUS_RX"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 69),
++ MTK_FUNCTION(0, "GPIO247"),
++ MTK_FUNCTION(1, "HDMI_HPD_RX")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(248, "HDMI_TESTOUTP_RX"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 133),
++ MTK_FUNCTION(0, "GPIO248"),
++ MTK_FUNCTION(1, "HDMI_TESTOUTP_RX")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(249, "MSDC0E_RSTB"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 134),
++ MTK_FUNCTION(0, "GPIO249"),
++ MTK_FUNCTION(1, "MSDC0E_RSTB")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(250, "MSDC0E_DAT7"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 135),
++ MTK_FUNCTION(0, "GPIO250"),
++ MTK_FUNCTION(1, "MSDC3_DAT7"),
++ MTK_FUNCTION(6, "PCIE0_CLKREQ_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(251, "MSDC0E_DAT6"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 136),
++ MTK_FUNCTION(0, "GPIO251"),
++ MTK_FUNCTION(1, "MSDC3_DAT6"),
++ MTK_FUNCTION(6, "PCIE0_WAKE_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(252, "MSDC0E_DAT5"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 137),
++ MTK_FUNCTION(0, "GPIO252"),
++ MTK_FUNCTION(1, "MSDC3_DAT5"),
++ MTK_FUNCTION(6, "PCIE1_CLKREQ_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(253, "MSDC0E_DAT4"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 138),
++ MTK_FUNCTION(0, "GPIO253"),
++ MTK_FUNCTION(1, "MSDC3_DAT4"),
++ MTK_FUNCTION(6, "PCIE1_WAKE_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(254, "MSDC0E_DAT3"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 139),
++ MTK_FUNCTION(0, "GPIO254"),
++ MTK_FUNCTION(1, "MSDC3_DAT3"),
++ MTK_FUNCTION(6, "PCIE2_CLKREQ_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(255, "MSDC0E_DAT2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 140),
++ MTK_FUNCTION(0, "GPIO255"),
++ MTK_FUNCTION(1, "MSDC3_DAT2"),
++ MTK_FUNCTION(6, "PCIE2_WAKE_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(256, "MSDC0E_DAT1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 141),
++ MTK_FUNCTION(0, "GPIO256"),
++ MTK_FUNCTION(1, "MSDC3_DAT1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(257, "MSDC0E_DAT0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 142),
++ MTK_FUNCTION(0, "GPIO257"),
++ MTK_FUNCTION(1, "MSDC3_DAT0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(258, "MSDC0E_CMD"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 143),
++ MTK_FUNCTION(0, "GPIO258"),
++ MTK_FUNCTION(1, "MSDC3_CMD")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(259, "MSDC0E_CLK"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 144),
++ MTK_FUNCTION(0, "GPIO259"),
++ MTK_FUNCTION(1, "MSDC3_CLK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(260, "MSDC0E_DSL"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 145),
++ MTK_FUNCTION(0, "GPIO260"),
++ MTK_FUNCTION(1, "MSDC3_DSL")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(261, "MSDC1_INS"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 146),
++ MTK_FUNCTION(0, "GPIO261"),
++ MTK_FUNCTION(1, "MSDC1_INS"),
++ MTK_FUNCTION(7, "DBG_MON_B[29]")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(262, "G2_TXEN"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 8),
++ MTK_FUNCTION(0, "GPIO262"),
++ MTK_FUNCTION(1, "G2_TXEN")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(263, "G2_TXD3"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 9),
++ MTK_FUNCTION(0, "GPIO263"),
++ MTK_FUNCTION(1, "G2_TXD3"),
++ MTK_FUNCTION(6, "ANT_SEL5")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(264, "G2_TXD2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 10),
++ MTK_FUNCTION(0, "GPIO264"),
++ MTK_FUNCTION(1, "G2_TXD2"),
++ MTK_FUNCTION(6, "ANT_SEL4")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(265, "G2_TXD1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 11),
++ MTK_FUNCTION(0, "GPIO265"),
++ MTK_FUNCTION(1, "G2_TXD1"),
++ MTK_FUNCTION(6, "ANT_SEL3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(266, "G2_TXD0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO266"),
++ MTK_FUNCTION(1, "G2_TXD0"),
++ MTK_FUNCTION(6, "ANT_SEL2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(267, "G2_TXC"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO267"),
++ MTK_FUNCTION(1, "G2_TXC")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(268, "G2_RXC"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO268"),
++ MTK_FUNCTION(1, "G2_RXC")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(269, "G2_RXD0"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO269"),
++ MTK_FUNCTION(1, "G2_RXD0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(270, "G2_RXD1"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO270"),
++ MTK_FUNCTION(1, "G2_RXD1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(271, "G2_RXD2"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO271"),
++ MTK_FUNCTION(1, "G2_RXD2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(272, "G2_RXD3"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO272"),
++ MTK_FUNCTION(1, "G2_RXD3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(273, "ESW_INT"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 168),
++ MTK_FUNCTION(0, "GPIO273"),
++ MTK_FUNCTION(1, "ESW_INT")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(274, "G2_RXDV"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO274"),
++ MTK_FUNCTION(1, "G2_RXDV")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(275, "MDC"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO275"),
++ MTK_FUNCTION(1, "MDC"),
++ MTK_FUNCTION(6, "ANT_SEL0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(276, "MDIO"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO276"),
++ MTK_FUNCTION(1, "MDIO"),
++ MTK_FUNCTION(6, "ANT_SEL1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(277, "ESW_RST"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO277"),
++ MTK_FUNCTION(1, "ESW_RST")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(278, "JTAG_RESET"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(0, 147),
++ MTK_FUNCTION(0, "GPIO278"),
++ MTK_FUNCTION(1, "JTAG_RESET")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(279, "USB3_RES_BOND"),
++ NULL, "mt2701",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO279"),
++ MTK_FUNCTION(1, "USB3_RES_BOND")
++ ),
++};
++
++#endif /* __PINCTRL_MTK_MT2701_H */
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0015-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt7.patch b/target/linux/mediatek/patches-4.4/0015-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt7.patch
new file mode 100644
index 0000000000..3f91087385
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0015-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt7.patch
@@ -0,0 +1,555 @@
+From ddc72b659b3642d0496dee4e1ee39416ca008053 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 7 Jan 2016 23:42:06 +0100
+Subject: [PATCH 15/53] dt-bindings: mediatek: Modify pinctrl bindings for
+ mt7623
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ .../devicetree/bindings/pinctrl/pinctrl-mt65xx.txt | 1 +
+ include/dt-bindings/pinctrl/mt7623-pinfunc.h | 521 ++++++++++++++++++++
+ 2 files changed, 522 insertions(+)
+ create mode 100644 include/dt-bindings/pinctrl/mt7623-pinfunc.h
+
+diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
+index 9ffb0b2..17631d0 100644
+--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
++++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
+@@ -6,6 +6,7 @@ Required properties:
+ - compatible: value should be one of the following.
+ "mediatek,mt2701-pinctrl", compatible with mt2701 pinctrl.
+ "mediatek,mt6397-pinctrl", compatible with mt6397 pinctrl.
++ "mediatek,mt7623-pinctrl", compatible with mt7623 pinctrl.
+ "mediatek,mt8127-pinctrl", compatible with mt8127 pinctrl.
+ "mediatek,mt8135-pinctrl", compatible with mt8135 pinctrl.
+ "mediatek,mt8173-pinctrl", compatible with mt8173 pinctrl.
+diff --git a/include/dt-bindings/pinctrl/mt7623-pinfunc.h b/include/dt-bindings/pinctrl/mt7623-pinfunc.h
+new file mode 100644
+index 0000000..891b173
+--- /dev/null
++++ b/include/dt-bindings/pinctrl/mt7623-pinfunc.h
+@@ -0,0 +1,521 @@
++#ifndef __DTS_MT7623_PINFUNC_H
++#define __DTS_MT7623_PINFUNC_H
++
++#include <dt-bindings/pinctrl/mt65xx.h>
++
++#define MT7623_PIN_0_PWRAP_SPI0_MI_FUNC_GPIO0 (MTK_PIN_NO(0) | 0)
++#define MT7623_PIN_0_PWRAP_SPI0_MI_FUNC_PWRAP_SPIDO (MTK_PIN_NO(0) | 1)
++#define MT7623_PIN_0_PWRAP_SPI0_MI_FUNC_PWRAP_SPIDI (MTK_PIN_NO(0) | 2)
++
++#define MT7623_PIN_1_PWRAP_SPI0_MO_FUNC_GPIO1 (MTK_PIN_NO(1) | 0)
++#define MT7623_PIN_1_PWRAP_SPI0_MO_FUNC_PWRAP_SPIDI (MTK_PIN_NO(1) | 1)
++#define MT7623_PIN_1_PWRAP_SPI0_MO_FUNC_PWRAP_SPIDO (MTK_PIN_NO(1) | 2)
++
++#define MT7623_PIN_2_PWRAP_INT_FUNC_GPIO2 (MTK_PIN_NO(2) | 0)
++#define MT7623_PIN_2_PWRAP_INT_FUNC_PWRAP_INT (MTK_PIN_NO(2) | 1)
++
++#define MT7623_PIN_3_PWRAP_SPI0_CK_FUNC_GPIO3 (MTK_PIN_NO(3) | 0)
++#define MT7623_PIN_3_PWRAP_SPI0_CK_FUNC_PWRAP_SPICK_I (MTK_PIN_NO(3) | 1)
++
++#define MT7623_PIN_4_PWRAP_SPI0_CSN_FUNC_GPIO4 (MTK_PIN_NO(4) | 0)
++#define MT7623_PIN_4_PWRAP_SPI0_CSN_FUNC_PWRAP_SPICS_B_I (MTK_PIN_NO(4) | 1)
++
++#define MT7623_PIN_5_PWRAP_SPI0_CK2_FUNC_GPIO5 (MTK_PIN_NO(5) | 0)
++#define MT7623_PIN_5_PWRAP_SPI0_CK2_FUNC_PWRAP_SPICK2_I (MTK_PIN_NO(5) | 1)
++
++#define MT7623_PIN_6_PWRAP_SPI0_CSN2_FUNC_GPIO6 (MTK_PIN_NO(6) | 0)
++#define MT7623_PIN_6_PWRAP_SPI0_CSN2_FUNC_PWRAP_SPICS2_B_I (MTK_PIN_NO(6) | 1)
++
++#define MT7623_PIN_7_SPI1_CSN_FUNC_GPIO7 (MTK_PIN_NO(7) | 0)
++#define MT7623_PIN_7_SPI1_CSN_FUNC_SPI1_CS (MTK_PIN_NO(7) | 1)
++
++#define MT7623_PIN_8_SPI1_MI_FUNC_GPIO8 (MTK_PIN_NO(8) | 0)
++#define MT7623_PIN_8_SPI1_MI_FUNC_SPI1_MI (MTK_PIN_NO(8) | 1)
++#define MT7623_PIN_8_SPI1_MI_FUNC_SPI1_MO (MTK_PIN_NO(8) | 2)
++
++#define MT7623_PIN_9_SPI1_MO_FUNC_GPIO9 (MTK_PIN_NO(9) | 0)
++#define MT7623_PIN_9_SPI1_MO_FUNC_SPI1_MO (MTK_PIN_NO(9) | 1)
++#define MT7623_PIN_9_SPI1_MO_FUNC_SPI1_MI (MTK_PIN_NO(9) | 2)
++
++#define MT7623_PIN_10_RTC32K_CK_FUNC_GPIO10 (MTK_PIN_NO(10) | 0)
++#define MT7623_PIN_10_RTC32K_CK_FUNC_RTC32K_CK (MTK_PIN_NO(10) | 1)
++
++#define MT7623_PIN_11_WATCHDOG_FUNC_GPIO11 (MTK_PIN_NO(11) | 0)
++#define MT7623_PIN_11_WATCHDOG_FUNC_WATCHDOG (MTK_PIN_NO(11) | 1)
++
++#define MT7623_PIN_12_SRCLKENA_FUNC_GPIO12 (MTK_PIN_NO(12) | 0)
++#define MT7623_PIN_12_SRCLKENA_FUNC_SRCLKENA (MTK_PIN_NO(12) | 1)
++
++#define MT7623_PIN_13_SRCLKENAI_FUNC_GPIO13 (MTK_PIN_NO(13) | 0)
++#define MT7623_PIN_13_SRCLKENAI_FUNC_SRCLKENAI (MTK_PIN_NO(13) | 1)
++
++#define MT7623_PIN_14_GPIO14_FUNC_GPIO14 (MTK_PIN_NO(14) | 0)
++#define MT7623_PIN_14_GPIO14_FUNC_URXD2 (MTK_PIN_NO(14) | 1)
++#define MT7623_PIN_14_GPIO14_FUNC_UTXD2 (MTK_PIN_NO(14) | 2)
++
++#define MT7623_PIN_15_GPIO15_FUNC_GPIO15 (MTK_PIN_NO(15) | 0)
++#define MT7623_PIN_15_GPIO15_FUNC_UTXD2 (MTK_PIN_NO(15) | 1)
++#define MT7623_PIN_15_GPIO15_FUNC_URXD2 (MTK_PIN_NO(15) | 2)
++
++#define MT7623_PIN_18_PCM_CLK_FUNC_GPIO18 (MTK_PIN_NO(18) | 0)
++#define MT7623_PIN_18_PCM_CLK_FUNC_PCM_CLK0 (MTK_PIN_NO(18) | 1)
++#define MT7623_PIN_18_PCM_CLK_FUNC_AP_PCM_CLKO (MTK_PIN_NO(18) | 6)
++
++#define MT7623_PIN_19_PCM_SYNC_FUNC_GPIO19 (MTK_PIN_NO(19) | 0)
++#define MT7623_PIN_19_PCM_SYNC_FUNC_PCM_SYNC (MTK_PIN_NO(19) | 1)
++#define MT7623_PIN_19_PCM_SYNC_FUNC_AP_PCM_SYNC (MTK_PIN_NO(19) | 6)
++
++#define MT7623_PIN_20_PCM_RX_FUNC_GPIO20 (MTK_PIN_NO(20) | 0)
++#define MT7623_PIN_20_PCM_RX_FUNC_PCM_RX (MTK_PIN_NO(20) | 1)
++#define MT7623_PIN_20_PCM_RX_FUNC_PCM_TX (MTK_PIN_NO(20) | 4)
++#define MT7623_PIN_20_PCM_RX_FUNC_AP_PCM_RX (MTK_PIN_NO(20) | 6)
++
++#define MT7623_PIN_21_PCM_TX_FUNC_GPIO21 (MTK_PIN_NO(21) | 0)
++#define MT7623_PIN_21_PCM_TX_FUNC_PCM_TX (MTK_PIN_NO(21) | 1)
++#define MT7623_PIN_21_PCM_TX_FUNC_PCM_RX (MTK_PIN_NO(21) | 4)
++#define MT7623_PIN_21_PCM_TX_FUNC_AP_PCM_TX (MTK_PIN_NO(21) | 6)
++
++#define MT7623_PIN_22_EINT0_FUNC_GPIO22 (MTK_PIN_NO(22) | 0)
++#define MT7623_PIN_22_EINT0_FUNC_UCTS0 (MTK_PIN_NO(22) | 1)
++#define MT7623_PIN_22_EINT0_FUNC_PCIE0_PERST_N (MTK_PIN_NO(22) | 2)
++
++#define MT7623_PIN_23_EINT1_FUNC_GPIO23 (MTK_PIN_NO(23) | 0)
++#define MT7623_PIN_23_EINT1_FUNC_URTS0 (MTK_PIN_NO(23) | 1)
++#define MT7623_PIN_23_EINT1_FUNC_PCIE1_PERST_N (MTK_PIN_NO(23) | 2)
++
++#define MT7623_PIN_24_EINT2_FUNC_GPIO24 (MTK_PIN_NO(24) | 0)
++#define MT7623_PIN_24_EINT2_FUNC_UCTS1 (MTK_PIN_NO(24) | 1)
++#define MT7623_PIN_24_EINT2_FUNC_PCIE2_PERST_N (MTK_PIN_NO(24) | 2)
++
++#define MT7623_PIN_25_EINT3_FUNC_GPIO25 (MTK_PIN_NO(25) | 0)
++#define MT7623_PIN_25_EINT3_FUNC_URTS1 (MTK_PIN_NO(25) | 1)
++
++#define MT7623_PIN_26_EINT4_FUNC_GPIO26 (MTK_PIN_NO(26) | 0)
++#define MT7623_PIN_26_EINT4_FUNC_UCTS3 (MTK_PIN_NO(26) | 1)
++#define MT7623_PIN_26_EINT4_FUNC_PCIE2_WAKE_N (MTK_PIN_NO(26) | 6)
++
++#define MT7623_PIN_27_EINT5_FUNC_GPIO27 (MTK_PIN_NO(27) | 0)
++#define MT7623_PIN_27_EINT5_FUNC_URTS3 (MTK_PIN_NO(27) | 1)
++#define MT7623_PIN_27_EINT5_FUNC_PCIE1_WAKE_N (MTK_PIN_NO(27) | 6)
++
++#define MT7623_PIN_28_EINT6_FUNC_GPIO28 (MTK_PIN_NO(28) | 0)
++#define MT7623_PIN_28_EINT6_FUNC_DRV_VBUS (MTK_PIN_NO(28) | 1)
++#define MT7623_PIN_28_EINT6_FUNC_PCIE0_WAKE_N (MTK_PIN_NO(28) | 6)
++
++#define MT7623_PIN_29_EINT7_FUNC_GPIO29 (MTK_PIN_NO(29) | 0)
++#define MT7623_PIN_29_EINT7_FUNC_IDDIG (MTK_PIN_NO(29) | 1)
++#define MT7623_PIN_29_EINT7_FUNC_MSDC1_WP (MTK_PIN_NO(29) | 2)
++#define MT7623_PIN_29_EINT7_FUNC_PCIE2_PERST_N (MTK_PIN_NO(29) | 6)
++
++#define MT7623_PIN_33_I2S1_DATA_FUNC_GPIO33 (MTK_PIN_NO(33) | 0)
++#define MT7623_PIN_33_I2S1_DATA_FUNC_I2S1_DATA (MTK_PIN_NO(33) | 1)
++#define MT7623_PIN_33_I2S1_DATA_FUNC_PCM_TX (MTK_PIN_NO(33) | 3)
++#define MT7623_PIN_33_I2S1_DATA_FUNC_AP_PCM_TX (MTK_PIN_NO(33) | 6)
++
++#define MT7623_PIN_34_I2S1_DATA_IN_FUNC_GPIO34 (MTK_PIN_NO(34) | 0)
++#define MT7623_PIN_34_I2S1_DATA_IN_FUNC_I2S1_DATA_IN (MTK_PIN_NO(34) | 1)
++#define MT7623_PIN_34_I2S1_DATA_IN_FUNC_PCM_RX (MTK_PIN_NO(34) | 3)
++#define MT7623_PIN_34_I2S1_DATA_IN_FUNC_AP_PCM_RX (MTK_PIN_NO(34) | 6)
++
++#define MT7623_PIN_35_I2S1_BCK_FUNC_GPIO35 (MTK_PIN_NO(35) | 0)
++#define MT7623_PIN_35_I2S1_BCK_FUNC_I2S1_BCK (MTK_PIN_NO(35) | 1)
++#define MT7623_PIN_35_I2S1_BCK_FUNC_PCM_CLK0 (MTK_PIN_NO(35) | 3)
++#define MT7623_PIN_35_I2S1_BCK_FUNC_AP_PCM_CLKO (MTK_PIN_NO(35) | 6)
++
++#define MT7623_PIN_36_I2S1_LRCK_FUNC_GPIO36 (MTK_PIN_NO(36) | 0)
++#define MT7623_PIN_36_I2S1_LRCK_FUNC_I2S1_LRCK (MTK_PIN_NO(36) | 1)
++#define MT7623_PIN_36_I2S1_LRCK_FUNC_PCM_SYNC (MTK_PIN_NO(36) | 3)
++#define MT7623_PIN_36_I2S1_LRCK_FUNC_AP_PCM_SYNC (MTK_PIN_NO(36) | 6)
++
++#define MT7623_PIN_37_I2S1_MCLK_FUNC_GPIO37 (MTK_PIN_NO(37) | 0)
++#define MT7623_PIN_37_I2S1_MCLK_FUNC_I2S1_MCLK (MTK_PIN_NO(37) | 1)
++
++#define MT7623_PIN_39_JTMS_FUNC_GPIO39 (MTK_PIN_NO(39) | 0)
++#define MT7623_PIN_39_JTMS_FUNC_JTMS (MTK_PIN_NO(39) | 1)
++
++#define MT7623_PIN_40_JTCK_FUNC_GPIO40 (MTK_PIN_NO(40) | 0)
++#define MT7623_PIN_40_JTCK_FUNC_JTCK (MTK_PIN_NO(40) | 1)
++
++#define MT7623_PIN_41_JTDI_FUNC_GPIO41 (MTK_PIN_NO(41) | 0)
++#define MT7623_PIN_41_JTDI_FUNC_JTDI (MTK_PIN_NO(41) | 1)
++
++#define MT7623_PIN_42_JTDO_FUNC_GPIO42 (MTK_PIN_NO(42) | 0)
++#define MT7623_PIN_42_JTDO_FUNC_JTDO (MTK_PIN_NO(42) | 1)
++
++#define MT7623_PIN_43_NCLE_FUNC_GPIO43 (MTK_PIN_NO(43) | 0)
++#define MT7623_PIN_43_NCLE_FUNC_NCLE (MTK_PIN_NO(43) | 1)
++#define MT7623_PIN_43_NCLE_FUNC_EXT_XCS2 (MTK_PIN_NO(43) | 2)
++
++#define MT7623_PIN_44_NCEB1_FUNC_GPIO44 (MTK_PIN_NO(44) | 0)
++#define MT7623_PIN_44_NCEB1_FUNC_NCEB1 (MTK_PIN_NO(44) | 1)
++#define MT7623_PIN_44_NCEB1_FUNC_IDDIG (MTK_PIN_NO(44) | 2)
++
++#define MT7623_PIN_45_NCEB0_FUNC_GPIO45 (MTK_PIN_NO(45) | 0)
++#define MT7623_PIN_45_NCEB0_FUNC_NCEB0 (MTK_PIN_NO(45) | 1)
++#define MT7623_PIN_45_NCEB0_FUNC_DRV_VBUS (MTK_PIN_NO(45) | 2)
++
++#define MT7623_PIN_46_IR_FUNC_GPIO46 (MTK_PIN_NO(46) | 0)
++#define MT7623_PIN_46_IR_FUNC_IR (MTK_PIN_NO(46) | 1)
++
++#define MT7623_PIN_47_NREB_FUNC_GPIO47 (MTK_PIN_NO(47) | 0)
++#define MT7623_PIN_47_NREB_FUNC_NREB (MTK_PIN_NO(47) | 1)
++
++#define MT7623_PIN_48_NRNB_FUNC_GPIO48 (MTK_PIN_NO(48) | 0)
++#define MT7623_PIN_48_NRNB_FUNC_NRNB (MTK_PIN_NO(48) | 1)
++
++#define MT7623_PIN_49_I2S0_DATA_FUNC_GPIO49 (MTK_PIN_NO(49) | 0)
++#define MT7623_PIN_49_I2S0_DATA_FUNC_I2S0_DATA (MTK_PIN_NO(49) | 1)
++#define MT7623_PIN_49_I2S0_DATA_FUNC_PCM_TX (MTK_PIN_NO(49) | 3)
++#define MT7623_PIN_49_I2S0_DATA_FUNC_AP_I2S_DO (MTK_PIN_NO(49) | 6)
++
++#define MT7623_PIN_53_SPI0_CSN_FUNC_GPIO53 (MTK_PIN_NO(53) | 0)
++#define MT7623_PIN_53_SPI0_CSN_FUNC_SPI0_CS (MTK_PIN_NO(53) | 1)
++#define MT7623_PIN_53_SPI0_CSN_FUNC_PWM1 (MTK_PIN_NO(53) | 5)
++
++#define MT7623_PIN_54_SPI0_CK_FUNC_GPIO54 (MTK_PIN_NO(54) | 0)
++#define MT7623_PIN_54_SPI0_CK_FUNC_SPI0_CK (MTK_PIN_NO(54) | 1)
++
++#define MT7623_PIN_55_SPI0_MI_FUNC_GPIO55 (MTK_PIN_NO(55) | 0)
++#define MT7623_PIN_55_SPI0_MI_FUNC_SPI0_MI (MTK_PIN_NO(55) | 1)
++#define MT7623_PIN_55_SPI0_MI_FUNC_SPI0_MO (MTK_PIN_NO(55) | 2)
++#define MT7623_PIN_55_SPI0_MI_FUNC_MSDC1_WP (MTK_PIN_NO(55) | 3)
++#define MT7623_PIN_55_SPI0_MI_FUNC_PWM2 (MTK_PIN_NO(55) | 5)
++
++#define MT7623_PIN_56_SPI0_MO_FUNC_GPIO56 (MTK_PIN_NO(56) | 0)
++#define MT7623_PIN_56_SPI0_MO_FUNC_SPI0_MO (MTK_PIN_NO(56) | 1)
++#define MT7623_PIN_56_SPI0_MO_FUNC_SPI0_MI (MTK_PIN_NO(56) | 2)
++
++#define MT7623_PIN_60_WB_RSTB_FUNC_GPIO60 (MTK_PIN_NO(60) | 0)
++#define MT7623_PIN_60_WB_RSTB_FUNC_WB_RSTB (MTK_PIN_NO(60) | 1)
++
++#define MT7623_PIN_61_GPIO61_FUNC_GPIO61 (MTK_PIN_NO(61) | 0)
++#define MT7623_PIN_61_GPIO61_FUNC_TEST_FD (MTK_PIN_NO(61) | 1)
++
++#define MT7623_PIN_62_GPIO62_FUNC_GPIO62 (MTK_PIN_NO(62) | 0)
++#define MT7623_PIN_62_GPIO62_FUNC_TEST_FC (MTK_PIN_NO(62) | 1)
++
++#define MT7623_PIN_63_WB_SCLK_FUNC_GPIO63 (MTK_PIN_NO(63) | 0)
++#define MT7623_PIN_63_WB_SCLK_FUNC_WB_SCLK (MTK_PIN_NO(63) | 1)
++
++#define MT7623_PIN_64_WB_SDATA_FUNC_GPIO64 (MTK_PIN_NO(64) | 0)
++#define MT7623_PIN_64_WB_SDATA_FUNC_WB_SDATA (MTK_PIN_NO(64) | 1)
++
++#define MT7623_PIN_65_WB_SEN_FUNC_GPIO65 (MTK_PIN_NO(65) | 0)
++#define MT7623_PIN_65_WB_SEN_FUNC_WB_SEN (MTK_PIN_NO(65) | 1)
++
++#define MT7623_PIN_66_WB_CRTL0_FUNC_GPIO66 (MTK_PIN_NO(66) | 0)
++#define MT7623_PIN_66_WB_CRTL0_FUNC_WB_CRTL0 (MTK_PIN_NO(66) | 1)
++
++#define MT7623_PIN_67_WB_CRTL1_FUNC_GPIO67 (MTK_PIN_NO(67) | 0)
++#define MT7623_PIN_67_WB_CRTL1_FUNC_WB_CRTL1 (MTK_PIN_NO(67) | 1)
++
++#define MT7623_PIN_68_WB_CRTL2_FUNC_GPIO68 (MTK_PIN_NO(68) | 0)
++#define MT7623_PIN_68_WB_CRTL2_FUNC_WB_CRTL2 (MTK_PIN_NO(68) | 1)
++
++#define MT7623_PIN_69_WB_CRTL3_FUNC_GPIO69 (MTK_PIN_NO(69) | 0)
++#define MT7623_PIN_69_WB_CRTL3_FUNC_WB_CRTL3 (MTK_PIN_NO(69) | 1)
++
++#define MT7623_PIN_70_WB_CRTL4_FUNC_GPIO70 (MTK_PIN_NO(70) | 0)
++#define MT7623_PIN_70_WB_CRTL4_FUNC_WB_CRTL4 (MTK_PIN_NO(70) | 1)
++
++#define MT7623_PIN_71_WB_CRTL5_FUNC_GPIO71 (MTK_PIN_NO(71) | 0)
++#define MT7623_PIN_71_WB_CRTL5_FUNC_WB_CRTL5 (MTK_PIN_NO(71) | 1)
++
++#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_GPIO72 (MTK_PIN_NO(72) | 0)
++#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_I2S0_DATA_IN (MTK_PIN_NO(72) | 1)
++#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_PCM_RX (MTK_PIN_NO(72) | 3)
++#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_PWM0 (MTK_PIN_NO(72) | 4)
++#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_DISP_PWM (MTK_PIN_NO(72) | 5)
++#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_AP_I2S_DI (MTK_PIN_NO(72) | 6)
++
++#define MT7623_PIN_73_I2S0_LRCK_FUNC_GPIO73 (MTK_PIN_NO(73) | 0)
++#define MT7623_PIN_73_I2S0_LRCK_FUNC_I2S0_LRCK (MTK_PIN_NO(73) | 1)
++#define MT7623_PIN_73_I2S0_LRCK_FUNC_PCM_SYNC (MTK_PIN_NO(73) | 3)
++#define MT7623_PIN_73_I2S0_LRCK_FUNC_AP_I2S_LRCK (MTK_PIN_NO(73) | 6)
++
++#define MT7623_PIN_74_I2S0_BCK_FUNC_GPIO74 (MTK_PIN_NO(74) | 0)
++#define MT7623_PIN_74_I2S0_BCK_FUNC_I2S0_BCK (MTK_PIN_NO(74) | 1)
++#define MT7623_PIN_74_I2S0_BCK_FUNC_PCM_CLK0 (MTK_PIN_NO(74) | 3)
++#define MT7623_PIN_74_I2S0_BCK_FUNC_AP_I2S_BCK (MTK_PIN_NO(74) | 6)
++
++#define MT7623_PIN_75_SDA0_FUNC_GPIO75 (MTK_PIN_NO(75) | 0)
++#define MT7623_PIN_75_SDA0_FUNC_SDA0 (MTK_PIN_NO(75) | 1)
++
++#define MT7623_PIN_76_SCL0_FUNC_GPIO76 (MTK_PIN_NO(76) | 0)
++#define MT7623_PIN_76_SCL0_FUNC_SCL0 (MTK_PIN_NO(76) | 1)
++
++#define MT7623_PIN_83_LCM_RST_FUNC_GPIO83 (MTK_PIN_NO(83) | 0)
++#define MT7623_PIN_83_LCM_RST_FUNC_LCM_RST (MTK_PIN_NO(83) | 1)
++
++#define MT7623_PIN_84_DSI_TE_FUNC_GPIO84 (MTK_PIN_NO(84) | 0)
++#define MT7623_PIN_84_DSI_TE_FUNC_DSI_TE (MTK_PIN_NO(84) | 1)
++
++#define MT7623_PIN_95_MIPI_TCN_FUNC_GPIO95 (MTK_PIN_NO(95) | 0)
++#define MT7623_PIN_95_MIPI_TCN_FUNC_TCN (MTK_PIN_NO(95) | 1)
++
++#define MT7623_PIN_96_MIPI_TCP_FUNC_GPIO96 (MTK_PIN_NO(96) | 0)
++#define MT7623_PIN_96_MIPI_TCP_FUNC_TCP (MTK_PIN_NO(96) | 1)
++
++#define MT7623_PIN_97_MIPI_TDN1_FUNC_GPIO97 (MTK_PIN_NO(97) | 0)
++#define MT7623_PIN_97_MIPI_TDN1_FUNC_TDN1 (MTK_PIN_NO(97) | 1)
++
++#define MT7623_PIN_98_MIPI_TDP1_FUNC_GPIO98 (MTK_PIN_NO(98) | 0)
++#define MT7623_PIN_98_MIPI_TDP1_FUNC_TDP1 (MTK_PIN_NO(98) | 1)
++
++#define MT7623_PIN_99_MIPI_TDN0_FUNC_GPIO99 (MTK_PIN_NO(99) | 0)
++#define MT7623_PIN_99_MIPI_TDN0_FUNC_TDN0 (MTK_PIN_NO(99) | 1)
++
++#define MT7623_PIN_100_MIPI_TDP0_FUNC_GPIO100 (MTK_PIN_NO(100) | 0)
++#define MT7623_PIN_100_MIPI_TDP0_FUNC_TDP0 (MTK_PIN_NO(100) | 1)
++
++#define MT7623_PIN_105_MSDC1_CMD_FUNC_GPIO105 (MTK_PIN_NO(105) | 0)
++#define MT7623_PIN_105_MSDC1_CMD_FUNC_MSDC1_CMD (MTK_PIN_NO(105) | 1)
++#define MT7623_PIN_105_MSDC1_CMD_FUNC_SDA1 (MTK_PIN_NO(105) | 3)
++#define MT7623_PIN_105_MSDC1_CMD_FUNC_I2SOUT_BCK (MTK_PIN_NO(105) | 6)
++
++#define MT7623_PIN_106_MSDC1_CLK_FUNC_GPIO106 (MTK_PIN_NO(106) | 0)
++#define MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK (MTK_PIN_NO(106) | 1)
++#define MT7623_PIN_106_MSDC1_CLK_FUNC_SCL1 (MTK_PIN_NO(106) | 3)
++#define MT7623_PIN_106_MSDC1_CLK_FUNC_I2SOUT_LRCK (MTK_PIN_NO(106) | 6)
++
++#define MT7623_PIN_107_MSDC1_DAT0_FUNC_GPIO107 (MTK_PIN_NO(107) | 0)
++#define MT7623_PIN_107_MSDC1_DAT0_FUNC_MSDC1_DAT0 (MTK_PIN_NO(107) | 1)
++#define MT7623_PIN_107_MSDC1_DAT0_FUNC_UTXD0 (MTK_PIN_NO(107) | 5)
++#define MT7623_PIN_107_MSDC1_DAT0_FUNC_I2SOUT_DATA_OUT (MTK_PIN_NO(107) | 6)
++
++#define MT7623_PIN_108_MSDC1_DAT1_FUNC_GPIO108 (MTK_PIN_NO(108) | 0)
++#define MT7623_PIN_108_MSDC1_DAT1_FUNC_MSDC1_DAT1 (MTK_PIN_NO(108) | 1)
++#define MT7623_PIN_108_MSDC1_DAT1_FUNC_PWM0 (MTK_PIN_NO(108) | 3)
++#define MT7623_PIN_108_MSDC1_DAT1_FUNC_URXD0 (MTK_PIN_NO(108) | 5)
++#define MT7623_PIN_108_MSDC1_DAT1_FUNC_PWM1 (MTK_PIN_NO(108) | 6)
++
++#define MT7623_PIN_109_MSDC1_DAT2_FUNC_GPIO109 (MTK_PIN_NO(109) | 0)
++#define MT7623_PIN_109_MSDC1_DAT2_FUNC_MSDC1_DAT2 (MTK_PIN_NO(109) | 1)
++#define MT7623_PIN_109_MSDC1_DAT2_FUNC_SDA2 (MTK_PIN_NO(109) | 3)
++#define MT7623_PIN_109_MSDC1_DAT2_FUNC_UTXD1 (MTK_PIN_NO(109) | 5)
++#define MT7623_PIN_109_MSDC1_DAT2_FUNC_PWM2 (MTK_PIN_NO(109) | 6)
++
++#define MT7623_PIN_110_MSDC1_DAT3_FUNC_GPIO110 (MTK_PIN_NO(110) | 0)
++#define MT7623_PIN_110_MSDC1_DAT3_FUNC_MSDC1_DAT3 (MTK_PIN_NO(110) | 1)
++#define MT7623_PIN_110_MSDC1_DAT3_FUNC_SCL2 (MTK_PIN_NO(110) | 3)
++#define MT7623_PIN_110_MSDC1_DAT3_FUNC_URXD1 (MTK_PIN_NO(110) | 5)
++#define MT7623_PIN_110_MSDC1_DAT3_FUNC_PWM3 (MTK_PIN_NO(110) | 6)
++
++#define MT7623_PIN_111_MSDC0_DAT7_FUNC_GPIO111 (MTK_PIN_NO(111) | 0)
++#define MT7623_PIN_111_MSDC0_DAT7_FUNC_MSDC0_DAT7 (MTK_PIN_NO(111) | 1)
++#define MT7623_PIN_111_MSDC0_DAT7_FUNC_NLD7 (MTK_PIN_NO(111) | 4)
++
++#define MT7623_PIN_112_MSDC0_DAT6_FUNC_GPIO112 (MTK_PIN_NO(112) | 0)
++#define MT7623_PIN_112_MSDC0_DAT6_FUNC_MSDC0_DAT6 (MTK_PIN_NO(112) | 1)
++#define MT7623_PIN_112_MSDC0_DAT6_FUNC_NLD6 (MTK_PIN_NO(112) | 4)
++
++#define MT7623_PIN_113_MSDC0_DAT5_FUNC_GPIO113 (MTK_PIN_NO(113) | 0)
++#define MT7623_PIN_113_MSDC0_DAT5_FUNC_MSDC0_DAT5 (MTK_PIN_NO(113) | 1)
++#define MT7623_PIN_113_MSDC0_DAT5_FUNC_NLD5 (MTK_PIN_NO(113) | 4)
++
++#define MT7623_PIN_114_MSDC0_DAT4_FUNC_GPIO114 (MTK_PIN_NO(114) | 0)
++#define MT7623_PIN_114_MSDC0_DAT4_FUNC_MSDC0_DAT4 (MTK_PIN_NO(114) | 1)
++#define MT7623_PIN_114_MSDC0_DAT4_FUNC_NLD4 (MTK_PIN_NO(114) | 4)
++
++#define MT7623_PIN_115_MSDC0_RSTB_FUNC_GPIO115 (MTK_PIN_NO(115) | 0)
++#define MT7623_PIN_115_MSDC0_RSTB_FUNC_MSDC0_RSTB (MTK_PIN_NO(115) | 1)
++#define MT7623_PIN_115_MSDC0_RSTB_FUNC_NLD8 (MTK_PIN_NO(115) | 4)
++
++#define MT7623_PIN_116_MSDC0_CMD_FUNC_GPIO116 (MTK_PIN_NO(116) | 0)
++#define MT7623_PIN_116_MSDC0_CMD_FUNC_MSDC0_CMD (MTK_PIN_NO(116) | 1)
++#define MT7623_PIN_116_MSDC0_CMD_FUNC_NALE (MTK_PIN_NO(116) | 4)
++
++#define MT7623_PIN_117_MSDC0_CLK_FUNC_GPIO117 (MTK_PIN_NO(117) | 0)
++#define MT7623_PIN_117_MSDC0_CLK_FUNC_MSDC0_CLK (MTK_PIN_NO(117) | 1)
++#define MT7623_PIN_117_MSDC0_CLK_FUNC_NWEB (MTK_PIN_NO(117) | 4)
++
++#define MT7623_PIN_118_MSDC0_DAT3_FUNC_GPIO118 (MTK_PIN_NO(118) | 0)
++#define MT7623_PIN_118_MSDC0_DAT3_FUNC_MSDC0_DAT3 (MTK_PIN_NO(118) | 1)
++#define MT7623_PIN_118_MSDC0_DAT3_FUNC_NLD3 (MTK_PIN_NO(118) | 4)
++
++#define MT7623_PIN_119_MSDC0_DAT2_FUNC_GPIO119 (MTK_PIN_NO(119) | 0)
++#define MT7623_PIN_119_MSDC0_DAT2_FUNC_MSDC0_DAT2 (MTK_PIN_NO(119) | 1)
++#define MT7623_PIN_119_MSDC0_DAT2_FUNC_NLD2 (MTK_PIN_NO(119) | 4)
++
++#define MT7623_PIN_120_MSDC0_DAT1_FUNC_GPIO120 (MTK_PIN_NO(120) | 0)
++#define MT7623_PIN_120_MSDC0_DAT1_FUNC_MSDC0_DAT1 (MTK_PIN_NO(120) | 1)
++#define MT7623_PIN_120_MSDC0_DAT1_FUNC_NLD1 (MTK_PIN_NO(120) | 4)
++
++#define MT7623_PIN_121_MSDC0_DAT0_FUNC_GPIO121 (MTK_PIN_NO(121) | 0)
++#define MT7623_PIN_121_MSDC0_DAT0_FUNC_MSDC0_DAT0 (MTK_PIN_NO(121) | 1)
++#define MT7623_PIN_121_MSDC0_DAT0_FUNC_NLD0 (MTK_PIN_NO(121) | 4)
++#define MT7623_PIN_121_MSDC0_DAT0_FUNC_WATCHDOG (MTK_PIN_NO(121) | 5)
++
++#define MT7623_PIN_122_GPIO122_FUNC_GPIO122 (MTK_PIN_NO(122) | 0)
++#define MT7623_PIN_122_GPIO122_FUNC_TEST (MTK_PIN_NO(122) | 1)
++#define MT7623_PIN_122_GPIO122_FUNC_SDA2 (MTK_PIN_NO(122) | 4)
++#define MT7623_PIN_122_GPIO122_FUNC_URXD0 (MTK_PIN_NO(122) | 5)
++
++#define MT7623_PIN_123_GPIO123_FUNC_GPIO123 (MTK_PIN_NO(123) | 0)
++#define MT7623_PIN_123_GPIO123_FUNC_TEST (MTK_PIN_NO(123) | 1)
++#define MT7623_PIN_123_GPIO123_FUNC_SCL2 (MTK_PIN_NO(123) | 4)
++#define MT7623_PIN_123_GPIO123_FUNC_UTXD0 (MTK_PIN_NO(123) | 5)
++
++#define MT7623_PIN_124_GPIO124_FUNC_GPIO124 (MTK_PIN_NO(124) | 0)
++#define MT7623_PIN_124_GPIO124_FUNC_TEST (MTK_PIN_NO(124) | 1)
++#define MT7623_PIN_124_GPIO124_FUNC_SDA1 (MTK_PIN_NO(124) | 4)
++#define MT7623_PIN_124_GPIO124_FUNC_PWM3 (MTK_PIN_NO(124) | 5)
++
++#define MT7623_PIN_125_GPIO125_FUNC_GPIO125 (MTK_PIN_NO(125) | 0)
++#define MT7623_PIN_125_GPIO125_FUNC_TEST (MTK_PIN_NO(125) | 1)
++#define MT7623_PIN_125_GPIO125_FUNC_SCL1 (MTK_PIN_NO(125) | 4)
++#define MT7623_PIN_125_GPIO125_FUNC_PWM4 (MTK_PIN_NO(125) | 5)
++
++#define MT7623_PIN_126_I2S0_MCLK_FUNC_GPIO126 (MTK_PIN_NO(126) | 0)
++#define MT7623_PIN_126_I2S0_MCLK_FUNC_I2S0_MCLK (MTK_PIN_NO(126) | 1)
++#define MT7623_PIN_126_I2S0_MCLK_FUNC_AP_I2S_MCLK (MTK_PIN_NO(126) | 6)
++
++#define MT7623_PIN_199_SPI1_CK_FUNC_GPIO199 (MTK_PIN_NO(199) | 0)
++#define MT7623_PIN_199_SPI1_CK_FUNC_SPI1_CK (MTK_PIN_NO(199) | 1)
++
++#define MT7623_PIN_200_URXD2_FUNC_GPIO200 (MTK_PIN_NO(200) | 0)
++#define MT7623_PIN_200_URXD2_FUNC_URXD2 (MTK_PIN_NO(200) | 6)
++
++#define MT7623_PIN_201_UTXD2_FUNC_GPIO201 (MTK_PIN_NO(201) | 0)
++#define MT7623_PIN_201_UTXD2_FUNC_UTXD2 (MTK_PIN_NO(201) | 6)
++
++#define MT7623_PIN_203_PWM0_FUNC_GPIO203 (MTK_PIN_NO(203) | 0)
++#define MT7623_PIN_203_PWM0_FUNC_PWM0 (MTK_PIN_NO(203) | 1)
++#define MT7623_PIN_203_PWM0_FUNC_DISP_PWM (MTK_PIN_NO(203) | 2)
++
++#define MT7623_PIN_204_PWM1_FUNC_GPIO204 (MTK_PIN_NO(204) | 0)
++#define MT7623_PIN_204_PWM1_FUNC_PWM1 (MTK_PIN_NO(204) | 1)
++
++#define MT7623_PIN_205_PWM2_FUNC_GPIO205 (MTK_PIN_NO(205) | 0)
++#define MT7623_PIN_205_PWM2_FUNC_PWM2 (MTK_PIN_NO(205) | 1)
++
++#define MT7623_PIN_206_PWM3_FUNC_GPIO206 (MTK_PIN_NO(206) | 0)
++#define MT7623_PIN_206_PWM3_FUNC_PWM3 (MTK_PIN_NO(206) | 1)
++
++#define MT7623_PIN_207_PWM4_FUNC_GPIO207 (MTK_PIN_NO(207) | 0)
++#define MT7623_PIN_207_PWM4_FUNC_PWM4 (MTK_PIN_NO(207) | 1)
++
++#define MT7623_PIN_208_AUD_EXT_CK1_FUNC_GPIO208 (MTK_PIN_NO(208) | 0)
++#define MT7623_PIN_208_AUD_EXT_CK1_FUNC_AUD_EXT_CK1 (MTK_PIN_NO(208) | 1)
++#define MT7623_PIN_208_AUD_EXT_CK1_FUNC_PWM0 (MTK_PIN_NO(208) | 2)
++#define MT7623_PIN_208_AUD_EXT_CK1_FUNC_PCIE0_PERST_N (MTK_PIN_NO(208) | 3)
++#define MT7623_PIN_208_AUD_EXT_CK1_FUNC_DISP_PWM (MTK_PIN_NO(208) | 5)
++
++#define MT7623_PIN_209_AUD_EXT_CK2_FUNC_GPIO209 (MTK_PIN_NO(209) | 0)
++#define MT7623_PIN_209_AUD_EXT_CK2_FUNC_AUD_EXT_CK2 (MTK_PIN_NO(209) | 1)
++#define MT7623_PIN_209_AUD_EXT_CK2_FUNC_MSDC1_WP (MTK_PIN_NO(209) | 2)
++#define MT7623_PIN_209_AUD_EXT_CK2_FUNC_PCIE1_PERST_N (MTK_PIN_NO(209) | 3)
++#define MT7623_PIN_209_AUD_EXT_CK2_FUNC_PWM1 (MTK_PIN_NO(209) | 5)
++
++#define MT7623_PIN_236_EXT_SDIO3_FUNC_GPIO236 (MTK_PIN_NO(236) | 0)
++#define MT7623_PIN_236_EXT_SDIO3_FUNC_EXT_SDIO3 (MTK_PIN_NO(236) | 1)
++#define MT7623_PIN_236_EXT_SDIO3_FUNC_IDDIG (MTK_PIN_NO(236) | 2)
++
++#define MT7623_PIN_237_EXT_SDIO2_FUNC_GPIO237 (MTK_PIN_NO(237) | 0)
++#define MT7623_PIN_237_EXT_SDIO2_FUNC_EXT_SDIO2 (MTK_PIN_NO(237) | 1)
++#define MT7623_PIN_237_EXT_SDIO2_FUNC_DRV_VBUS (MTK_PIN_NO(237) | 2)
++
++#define MT7623_PIN_238_EXT_SDIO1_FUNC_GPIO238 (MTK_PIN_NO(238) | 0)
++#define MT7623_PIN_238_EXT_SDIO1_FUNC_EXT_SDIO1 (MTK_PIN_NO(238) | 1)
++
++#define MT7623_PIN_239_EXT_SDIO0_FUNC_GPIO239 (MTK_PIN_NO(239) | 0)
++#define MT7623_PIN_239_EXT_SDIO0_FUNC_EXT_SDIO0 (MTK_PIN_NO(239) | 1)
++
++#define MT7623_PIN_240_EXT_XCS_FUNC_GPIO240 (MTK_PIN_NO(240) | 0)
++#define MT7623_PIN_240_EXT_XCS_FUNC_EXT_XCS (MTK_PIN_NO(240) | 1)
++
++#define MT7623_PIN_241_EXT_SCK_FUNC_GPIO241 (MTK_PIN_NO(241) | 0)
++#define MT7623_PIN_241_EXT_SCK_FUNC_EXT_SCK (MTK_PIN_NO(241) | 1)
++
++#define MT7623_PIN_242_URTS2_FUNC_GPIO242 (MTK_PIN_NO(242) | 0)
++#define MT7623_PIN_242_URTS2_FUNC_URTS2 (MTK_PIN_NO(242) | 1)
++#define MT7623_PIN_242_URTS2_FUNC_UTXD3 (MTK_PIN_NO(242) | 2)
++#define MT7623_PIN_242_URTS2_FUNC_URXD3 (MTK_PIN_NO(242) | 3)
++#define MT7623_PIN_242_URTS2_FUNC_SCL1 (MTK_PIN_NO(242) | 4)
++
++#define MT7623_PIN_243_UCTS2_FUNC_GPIO243 (MTK_PIN_NO(243) | 0)
++#define MT7623_PIN_243_UCTS2_FUNC_UCTS2 (MTK_PIN_NO(243) | 1)
++#define MT7623_PIN_243_UCTS2_FUNC_URXD3 (MTK_PIN_NO(243) | 2)
++#define MT7623_PIN_243_UCTS2_FUNC_UTXD3 (MTK_PIN_NO(243) | 3)
++#define MT7623_PIN_243_UCTS2_FUNC_SDA1 (MTK_PIN_NO(243) | 4)
++
++#define MT7623_PIN_250_GPIO250_FUNC_GPIO250 (MTK_PIN_NO(250) | 0)
++#define MT7623_PIN_250_GPIO250_FUNC_TEST_MD7 (MTK_PIN_NO(250) | 1)
++#define MT7623_PIN_250_GPIO250_FUNC_PCIE0_CLKREQ_N (MTK_PIN_NO(250) | 6)
++
++#define MT7623_PIN_251_GPIO251_FUNC_GPIO251 (MTK_PIN_NO(251) | 0)
++#define MT7623_PIN_251_GPIO251_FUNC_TEST_MD6 (MTK_PIN_NO(251) | 1)
++#define MT7623_PIN_251_GPIO251_FUNC_PCIE0_WAKE_N (MTK_PIN_NO(251) | 6)
++
++#define MT7623_PIN_252_GPIO252_FUNC_GPIO252 (MTK_PIN_NO(252) | 0)
++#define MT7623_PIN_252_GPIO252_FUNC_TEST_MD5 (MTK_PIN_NO(252) | 1)
++#define MT7623_PIN_252_GPIO252_FUNC_PCIE1_CLKREQ_N (MTK_PIN_NO(252) | 6)
++
++#define MT7623_PIN_253_GPIO253_FUNC_GPIO253 (MTK_PIN_NO(253) | 0)
++#define MT7623_PIN_253_GPIO253_FUNC_TEST_MD4 (MTK_PIN_NO(253) | 1)
++#define MT7623_PIN_253_GPIO253_FUNC_PCIE1_WAKE_N (MTK_PIN_NO(253) | 6)
++
++#define MT7623_PIN_254_GPIO254_FUNC_GPIO254 (MTK_PIN_NO(254) | 0)
++#define MT7623_PIN_254_GPIO254_FUNC_TEST_MD3 (MTK_PIN_NO(254) | 1)
++#define MT7623_PIN_254_GPIO254_FUNC_PCIE2_CLKREQ_N (MTK_PIN_NO(254) | 6)
++
++#define MT7623_PIN_255_GPIO255_FUNC_GPIO255 (MTK_PIN_NO(255) | 0)
++#define MT7623_PIN_255_GPIO255_FUNC_TEST_MD2 (MTK_PIN_NO(255) | 1)
++#define MT7623_PIN_255_GPIO255_FUNC_PCIE2_WAKE_N (MTK_PIN_NO(255) | 6)
++
++#define MT7623_PIN_256_GPIO256_FUNC_GPIO256 (MTK_PIN_NO(256) | 0)
++#define MT7623_PIN_256_GPIO256_FUNC_TEST_MD1 (MTK_PIN_NO(256) | 1)
++
++#define MT7623_PIN_257_GPIO257_FUNC_GPIO257 (MTK_PIN_NO(257) | 0)
++#define MT7623_PIN_257_GPIO257_FUNC_TEST_MD0 (MTK_PIN_NO(257) | 1)
++
++#define MT7623_PIN_261_MSDC1_INS_FUNC_GPIO261 (MTK_PIN_NO(261) | 0)
++#define MT7623_PIN_261_MSDC1_INS_FUNC_MSDC1_INS (MTK_PIN_NO(261) | 1)
++
++#define MT7623_PIN_262_G2_TXEN_FUNC_GPIO262 (MTK_PIN_NO(262) | 0)
++#define MT7623_PIN_262_G2_TXEN_FUNC_G2_TXEN (MTK_PIN_NO(262) | 1)
++
++#define MT7623_PIN_263_G2_TXD3_FUNC_GPIO263 (MTK_PIN_NO(263) | 0)
++#define MT7623_PIN_263_G2_TXD3_FUNC_G2_TXD3 (MTK_PIN_NO(263) | 1)
++
++#define MT7623_PIN_264_G2_TXD2_FUNC_GPIO264 (MTK_PIN_NO(264) | 0)
++#define MT7623_PIN_264_G2_TXD2_FUNC_G2_TXD2 (MTK_PIN_NO(264) | 1)
++
++#define MT7623_PIN_265_G2_TXD1_FUNC_GPIO265 (MTK_PIN_NO(265) | 0)
++#define MT7623_PIN_265_G2_TXD1_FUNC_G2_TXD1 (MTK_PIN_NO(265) | 1)
++
++#define MT7623_PIN_266_G2_TXD0_FUNC_GPIO266 (MTK_PIN_NO(266) | 0)
++#define MT7623_PIN_266_G2_TXD0_FUNC_G2_TXD0 (MTK_PIN_NO(266) | 1)
++
++#define MT7623_PIN_267_G2_TXCLK_FUNC_GPIO267 (MTK_PIN_NO(267) | 0)
++#define MT7623_PIN_267_G2_TXCLK_FUNC_G2_TXC (MTK_PIN_NO(267) | 1)
++
++#define MT7623_PIN_268_G2_RXCLK_FUNC_GPIO268 (MTK_PIN_NO(268) | 0)
++#define MT7623_PIN_268_G2_RXCLK_FUNC_G2_RXC (MTK_PIN_NO(268) | 1)
++
++#define MT7623_PIN_269_G2_RXD0_FUNC_GPIO269 (MTK_PIN_NO(269) | 0)
++#define MT7623_PIN_269_G2_RXD0_FUNC_G2_RXD0 (MTK_PIN_NO(269) | 1)
++
++#define MT7623_PIN_270_G2_RXD1_FUNC_GPIO270 (MTK_PIN_NO(270) | 0)
++#define MT7623_PIN_270_G2_RXD1_FUNC_G2_RXD1 (MTK_PIN_NO(270) | 1)
++
++#define MT7623_PIN_271_G2_RXD2_FUNC_GPIO271 (MTK_PIN_NO(271) | 0)
++#define MT7623_PIN_271_G2_RXD2_FUNC_G2_RXD2 (MTK_PIN_NO(271) | 1)
++
++#define MT7623_PIN_272_G2_RXD3_FUNC_GPIO272 (MTK_PIN_NO(272) | 0)
++#define MT7623_PIN_272_G2_RXD3_FUNC_G2_RXD3 (MTK_PIN_NO(272) | 1)
++
++#define MT7623_PIN_274_G2_RXDV_FUNC_GPIO274 (MTK_PIN_NO(274) | 0)
++#define MT7623_PIN_274_G2_RXDV_FUNC_G2_RXDV (MTK_PIN_NO(274) | 1)
++
++#define MT7623_PIN_275_G2_MDC_FUNC_GPIO275 (MTK_PIN_NO(275) | 0)
++#define MT7623_PIN_275_G2_MDC_FUNC_MDC (MTK_PIN_NO(275) | 1)
++
++#define MT7623_PIN_276_G2_MDIO_FUNC_GPIO276 (MTK_PIN_NO(276) | 0)
++#define MT7623_PIN_276_G2_MDIO_FUNC_MDIO (MTK_PIN_NO(276) | 1)
++
++#define MT7623_PIN_278_JTAG_RESET_FUNC_GPIO278 (MTK_PIN_NO(278) | 0)
++#define MT7623_PIN_278_JTAG_RESET_FUNC_JTAG_RESET (MTK_PIN_NO(278) | 1)
++
++#endif /* __DTS_MT7623_PINFUNC_H */
++
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0016-pinctrl-dt-bindings-Add-pinctrl-file-for-mt7623.patch b/target/linux/mediatek/patches-4.4/0016-pinctrl-dt-bindings-Add-pinctrl-file-for-mt7623.patch
new file mode 100644
index 0000000000..0ed28c3340
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0016-pinctrl-dt-bindings-Add-pinctrl-file-for-mt7623.patch
@@ -0,0 +1,2394 @@
+From 1255eaacd6cc9d1fa6bb33185380efed22008baf Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sat, 27 Jun 2015 13:13:05 +0200
+Subject: [PATCH 16/53] pinctrl: dt bindings: Add pinctrl file for mt7623
+
+Add the driver and header files required to make pinctrl work on MediaTek
+MT7623.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/pinctrl/mediatek/Kconfig | 6 +
+ drivers/pinctrl/mediatek/Makefile | 1 +
+ drivers/pinctrl/mediatek/pinctrl-mt7623.c | 380 +++++
+ drivers/pinctrl/mediatek/pinctrl-mtk-mt7623.h | 1937 +++++++++++++++++++++++++
+ include/dt-bindings/pinctrl/mt7623-pinfunc.h | 3 +
+ 5 files changed, 2327 insertions(+)
+ create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7623.c
+ create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt7623.h
+
+diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
+index 13e9939..78654a8 100644
+--- a/drivers/pinctrl/mediatek/Kconfig
++++ b/drivers/pinctrl/mediatek/Kconfig
+@@ -15,6 +15,12 @@ config PINCTRL_MT2701
+ default MACH_MT2701
+ select PINCTRL_MTK_COMMON
+
++config PINCTRL_MT7623
++ bool "Mediatek MT7623 pin control" if COMPILE_TEST && !MACH_MT7623
++ depends on OF
++ default MACH_MT7623
++ select PINCTRL_MTK_COMMON
++
+ config PINCTRL_MT8135
+ bool "Mediatek MT8135 pin control" if COMPILE_TEST && !MACH_MT8135
+ depends on OF
+diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
+index da30314..1be2f3f 100644
+--- a/drivers/pinctrl/mediatek/Makefile
++++ b/drivers/pinctrl/mediatek/Makefile
+@@ -3,6 +3,7 @@ obj-$(CONFIG_PINCTRL_MTK_COMMON) += pinctrl-mtk-common.o
+
+ # SoC Drivers
+ obj-$(CONFIG_PINCTRL_MT2701) += pinctrl-mt2701.o
++obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o
+ obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o
+ obj-$(CONFIG_PINCTRL_MT8127) += pinctrl-mt8127.o
+ obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7623.c b/drivers/pinctrl/mediatek/pinctrl-mt7623.c
+new file mode 100644
+index 0000000..bf0d05b
+--- /dev/null
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7623.c
+@@ -0,0 +1,380 @@
++/*
++ * Copyright (c) 2016 John Crispin <blogic@openwrt.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <dt-bindings/pinctrl/mt65xx.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/pinctrl/pinctrl.h>
++#include <linux/regmap.h>
++
++#include "pinctrl-mtk-common.h"
++#include "pinctrl-mtk-mt7623.h"
++
++static const struct mtk_drv_group_desc mt7623_drv_grp[] = {
++ /* 0E4E8SR 4/8/12/16 */
++ MTK_DRV_GRP(4, 16, 1, 2, 4),
++ /* 0E2E4SR 2/4/6/8 */
++ MTK_DRV_GRP(2, 8, 1, 2, 2),
++ /* E8E4E2 2/4/6/8/10/12/14/16 */
++ MTK_DRV_GRP(2, 16, 0, 2, 2)
++};
++
++#define DRV_SEL0 0xf50
++#define DRV_SEL1 0xf60
++#define DRV_SEL2 0xf70
++#define DRV_SEL3 0xf80
++#define DRV_SEL4 0xf90
++#define DRV_SEL5 0xfa0
++#define DRV_SEL6 0xfb0
++#define DRV_SEL7 0xfe0
++#define DRV_SEL8 0xfd0
++#define DRV_SEL9 0xff0
++#define DRV_SEL10 0xf00
++
++#define MSDC0_CTRL0 0xcc0
++#define MSDC0_CTRL1 0xcd0
++#define MSDC0_CTRL2 0xce0
++#define MSDC0_CTRL3 0xcf0
++#define MSDC0_CTRL4 0xd00
++#define MSDC0_CTRL5 0xd10
++#define MSDC0_CTRL6 0xd20
++#define MSDC1_CTRL0 0xd30
++#define MSDC1_CTRL1 0xd40
++#define MSDC1_CTRL2 0xd50
++#define MSDC1_CTRL3 0xd60
++#define MSDC1_CTRL4 0xd70
++#define MSDC1_CTRL5 0xd80
++#define MSDC1_CTRL6 0xd90
++
++#define IES_EN0 0xb20
++#define IES_EN1 0xb30
++#define IES_EN2 0xb40
++
++#define SMT_EN0 0xb50
++#define SMT_EN1 0xb60
++#define SMT_EN2 0xb70
++
++static const struct mtk_pin_drv_grp mt7623_pin_drv[] = {
++ MTK_PIN_DRV_GRP(0, DRV_SEL0, 0, 1),
++ MTK_PIN_DRV_GRP(1, DRV_SEL0, 0, 1),
++ MTK_PIN_DRV_GRP(2, DRV_SEL0, 0, 1),
++ MTK_PIN_DRV_GRP(3, DRV_SEL0, 0, 1),
++ MTK_PIN_DRV_GRP(4, DRV_SEL0, 0, 1),
++ MTK_PIN_DRV_GRP(5, DRV_SEL0, 0, 1),
++ MTK_PIN_DRV_GRP(6, DRV_SEL0, 0, 1),
++ MTK_PIN_DRV_GRP(7, DRV_SEL0, 4, 1),
++ MTK_PIN_DRV_GRP(8, DRV_SEL0, 4, 1),
++ MTK_PIN_DRV_GRP(9, DRV_SEL0, 4, 1),
++ MTK_PIN_DRV_GRP(10, DRV_SEL0, 8, 1),
++ MTK_PIN_DRV_GRP(11, DRV_SEL0, 8, 1),
++ MTK_PIN_DRV_GRP(12, DRV_SEL0, 8, 1),
++ MTK_PIN_DRV_GRP(13, DRV_SEL0, 8, 1),
++ MTK_PIN_DRV_GRP(14, DRV_SEL0, 12, 0),
++ MTK_PIN_DRV_GRP(15, DRV_SEL0, 12, 0),
++ MTK_PIN_DRV_GRP(18, DRV_SEL1, 4, 0),
++ MTK_PIN_DRV_GRP(19, DRV_SEL1, 4, 0),
++ MTK_PIN_DRV_GRP(20, DRV_SEL1, 4, 0),
++ MTK_PIN_DRV_GRP(21, DRV_SEL1, 4, 0),
++ MTK_PIN_DRV_GRP(22, DRV_SEL1, 8, 0),
++ MTK_PIN_DRV_GRP(23, DRV_SEL1, 8, 0),
++ MTK_PIN_DRV_GRP(24, DRV_SEL1, 8, 0),
++ MTK_PIN_DRV_GRP(25, DRV_SEL1, 8, 0),
++ MTK_PIN_DRV_GRP(26, DRV_SEL1, 8, 0),
++ MTK_PIN_DRV_GRP(27, DRV_SEL1, 12, 0),
++ MTK_PIN_DRV_GRP(28, DRV_SEL1, 12, 0),
++ MTK_PIN_DRV_GRP(29, DRV_SEL1, 12, 0),
++ MTK_PIN_DRV_GRP(33, DRV_SEL2, 0, 0),
++ MTK_PIN_DRV_GRP(34, DRV_SEL2, 0, 0),
++ MTK_PIN_DRV_GRP(35, DRV_SEL2, 0, 0),
++ MTK_PIN_DRV_GRP(36, DRV_SEL2, 0, 0),
++ MTK_PIN_DRV_GRP(37, DRV_SEL2, 0, 0),
++ MTK_PIN_DRV_GRP(39, DRV_SEL2, 8, 1),
++ MTK_PIN_DRV_GRP(40, DRV_SEL2, 8, 1),
++ MTK_PIN_DRV_GRP(41, DRV_SEL2, 8, 1),
++ MTK_PIN_DRV_GRP(42, DRV_SEL2, 8, 1),
++ MTK_PIN_DRV_GRP(43, DRV_SEL2, 12, 0),
++ MTK_PIN_DRV_GRP(44, DRV_SEL2, 12, 0),
++ MTK_PIN_DRV_GRP(45, DRV_SEL2, 12, 0),
++ MTK_PIN_DRV_GRP(47, DRV_SEL3, 0, 0),
++ MTK_PIN_DRV_GRP(48, DRV_SEL3, 0, 0),
++ MTK_PIN_DRV_GRP(49, DRV_SEL3, 4, 0),
++ MTK_PIN_DRV_GRP(53, DRV_SEL3, 12, 0),
++ MTK_PIN_DRV_GRP(54, DRV_SEL3, 12, 0),
++ MTK_PIN_DRV_GRP(55, DRV_SEL3, 12, 0),
++ MTK_PIN_DRV_GRP(56, DRV_SEL3, 12, 0),
++ MTK_PIN_DRV_GRP(60, DRV_SEL4, 8, 1),
++ MTK_PIN_DRV_GRP(61, DRV_SEL4, 8, 1),
++ MTK_PIN_DRV_GRP(62, DRV_SEL4, 8, 1),
++ MTK_PIN_DRV_GRP(63, DRV_SEL4, 12, 1),
++ MTK_PIN_DRV_GRP(64, DRV_SEL4, 12, 1),
++ MTK_PIN_DRV_GRP(65, DRV_SEL4, 12, 1),
++ MTK_PIN_DRV_GRP(66, DRV_SEL5, 0, 1),
++ MTK_PIN_DRV_GRP(67, DRV_SEL5, 0, 1),
++ MTK_PIN_DRV_GRP(68, DRV_SEL5, 0, 1),
++ MTK_PIN_DRV_GRP(69, DRV_SEL5, 0, 1),
++ MTK_PIN_DRV_GRP(70, DRV_SEL5, 0, 1),
++ MTK_PIN_DRV_GRP(71, DRV_SEL5, 0, 1),
++ MTK_PIN_DRV_GRP(72, DRV_SEL3, 4, 0),
++ MTK_PIN_DRV_GRP(73, DRV_SEL3, 4, 0),
++ MTK_PIN_DRV_GRP(74, DRV_SEL3, 4, 0),
++ MTK_PIN_DRV_GRP(83, DRV_SEL5, 0, 1),
++ MTK_PIN_DRV_GRP(84, DRV_SEL5, 0, 1),
++ MTK_PIN_DRV_GRP(105, MSDC1_CTRL1, 0, 1),
++ MTK_PIN_DRV_GRP(106, MSDC1_CTRL0, 0, 1),
++ MTK_PIN_DRV_GRP(107, MSDC1_CTRL2, 0, 1),
++ MTK_PIN_DRV_GRP(108, MSDC1_CTRL2, 0, 1),
++ MTK_PIN_DRV_GRP(109, MSDC1_CTRL2, 0, 1),
++ MTK_PIN_DRV_GRP(110, MSDC1_CTRL2, 0, 1),
++ MTK_PIN_DRV_GRP(111, MSDC0_CTRL2, 0, 1),
++ MTK_PIN_DRV_GRP(112, MSDC0_CTRL2, 0, 1),
++ MTK_PIN_DRV_GRP(113, MSDC0_CTRL2, 0, 1),
++ MTK_PIN_DRV_GRP(114, MSDC0_CTRL2, 0, 1),
++ MTK_PIN_DRV_GRP(115, MSDC0_CTRL2, 0, 1),
++ MTK_PIN_DRV_GRP(116, MSDC0_CTRL1, 0, 1),
++ MTK_PIN_DRV_GRP(117, MSDC0_CTRL0, 0, 1),
++ MTK_PIN_DRV_GRP(118, MSDC0_CTRL2, 0, 1),
++ MTK_PIN_DRV_GRP(119, MSDC0_CTRL2, 0, 1),
++ MTK_PIN_DRV_GRP(120, MSDC0_CTRL2, 0, 1),
++ MTK_PIN_DRV_GRP(121, MSDC0_CTRL2, 0, 1),
++ MTK_PIN_DRV_GRP(126, DRV_SEL3, 4, 0),
++ MTK_PIN_DRV_GRP(199, DRV_SEL0, 4, 1),
++ MTK_PIN_DRV_GRP(200, DRV_SEL8, 0, 0),
++ MTK_PIN_DRV_GRP(201, DRV_SEL8, 0, 0),
++ MTK_PIN_DRV_GRP(203, DRV_SEL8, 4, 0),
++ MTK_PIN_DRV_GRP(204, DRV_SEL8, 4, 0),
++ MTK_PIN_DRV_GRP(205, DRV_SEL8, 4, 0),
++ MTK_PIN_DRV_GRP(206, DRV_SEL8, 4, 0),
++ MTK_PIN_DRV_GRP(207, DRV_SEL8, 4, 0),
++ MTK_PIN_DRV_GRP(208, DRV_SEL8, 8, 0),
++ MTK_PIN_DRV_GRP(209, DRV_SEL8, 8, 0),
++ MTK_PIN_DRV_GRP(236, DRV_SEL9, 4, 0),
++ MTK_PIN_DRV_GRP(237, DRV_SEL9, 4, 0),
++ MTK_PIN_DRV_GRP(238, DRV_SEL9, 4, 0),
++ MTK_PIN_DRV_GRP(239, DRV_SEL9, 4, 0),
++ MTK_PIN_DRV_GRP(240, DRV_SEL9, 4, 0),
++ MTK_PIN_DRV_GRP(241, DRV_SEL9, 4, 0),
++ MTK_PIN_DRV_GRP(242, DRV_SEL9, 8, 0),
++ MTK_PIN_DRV_GRP(243, DRV_SEL9, 8, 0),
++ MTK_PIN_DRV_GRP(257, MSDC0_CTRL2, 0, 1),
++ MTK_PIN_DRV_GRP(261, MSDC1_CTRL2, 0, 1),
++ MTK_PIN_DRV_GRP(262, DRV_SEL10, 8, 0),
++ MTK_PIN_DRV_GRP(263, DRV_SEL10, 8, 0),
++ MTK_PIN_DRV_GRP(264, DRV_SEL10, 8, 0),
++ MTK_PIN_DRV_GRP(265, DRV_SEL10, 8, 0),
++ MTK_PIN_DRV_GRP(266, DRV_SEL10, 8, 0),
++ MTK_PIN_DRV_GRP(267, DRV_SEL10, 8, 0),
++ MTK_PIN_DRV_GRP(268, DRV_SEL10, 8, 0),
++ MTK_PIN_DRV_GRP(269, DRV_SEL10, 8, 0),
++ MTK_PIN_DRV_GRP(270, DRV_SEL10, 8, 0),
++ MTK_PIN_DRV_GRP(271, DRV_SEL10, 8, 0),
++ MTK_PIN_DRV_GRP(272, DRV_SEL10, 8, 0),
++ MTK_PIN_DRV_GRP(274, DRV_SEL10, 8, 0),
++ MTK_PIN_DRV_GRP(275, DRV_SEL10, 8, 0),
++ MTK_PIN_DRV_GRP(276, DRV_SEL10, 8, 0),
++ MTK_PIN_DRV_GRP(278, DRV_SEL2, 8, 1),
++};
++
++static const struct mtk_pin_spec_pupd_set_samereg mt7623_spec_pupd[] = {
++ MTK_PIN_PUPD_SPEC_SR(105, MSDC1_CTRL1, 8, 9, 10),
++ MTK_PIN_PUPD_SPEC_SR(106, MSDC1_CTRL0, 8, 9, 10),
++ MTK_PIN_PUPD_SPEC_SR(107, MSDC1_CTRL3, 0, 1, 2),
++ MTK_PIN_PUPD_SPEC_SR(108, MSDC1_CTRL3, 4, 5, 6),
++ MTK_PIN_PUPD_SPEC_SR(109, MSDC1_CTRL3, 8, 9, 10),
++ MTK_PIN_PUPD_SPEC_SR(110, MSDC1_CTRL3, 12, 13, 14),
++ MTK_PIN_PUPD_SPEC_SR(111, MSDC0_CTRL4, 12, 13, 14),
++ MTK_PIN_PUPD_SPEC_SR(112, MSDC0_CTRL4, 8, 9, 10),
++ MTK_PIN_PUPD_SPEC_SR(113, MSDC0_CTRL4, 4, 5, 6),
++ MTK_PIN_PUPD_SPEC_SR(114, MSDC0_CTRL4, 0, 1, 2),
++ MTK_PIN_PUPD_SPEC_SR(115, MSDC0_CTRL5, 0, 1, 2),
++ MTK_PIN_PUPD_SPEC_SR(116, MSDC0_CTRL1, 8, 9, 10),
++ MTK_PIN_PUPD_SPEC_SR(117, MSDC0_CTRL0, 8, 9, 10),
++ MTK_PIN_PUPD_SPEC_SR(118, MSDC0_CTRL3, 12, 13, 14),
++ MTK_PIN_PUPD_SPEC_SR(119, MSDC0_CTRL3, 8, 9, 10),
++ MTK_PIN_PUPD_SPEC_SR(120, MSDC0_CTRL3, 4, 5, 6),
++ MTK_PIN_PUPD_SPEC_SR(121, MSDC0_CTRL3, 0, 1, 2),
++};
++
++static int mt7623_spec_pull_set(struct regmap *regmap, unsigned int pin,
++ unsigned char align, bool isup, unsigned int r1r0)
++{
++ return mtk_pctrl_spec_pull_set_samereg(regmap, mt7623_spec_pupd,
++ ARRAY_SIZE(mt7623_spec_pupd), pin, align, isup, r1r0);
++}
++
++static const struct mtk_pin_ies_smt_set mt7623_ies_set[] = {
++ MTK_PIN_IES_SMT_SPEC(0, 6, IES_EN0, 0),
++ MTK_PIN_IES_SMT_SPEC(7, 9, IES_EN0, 1),
++ MTK_PIN_IES_SMT_SPEC(10, 13, IES_EN0, 2),
++ MTK_PIN_IES_SMT_SPEC(14, 15, IES_EN0, 3),
++ MTK_PIN_IES_SMT_SPEC(18, 21, IES_EN0, 5),
++ MTK_PIN_IES_SMT_SPEC(22, 26, IES_EN0, 6),
++ MTK_PIN_IES_SMT_SPEC(27, 29, IES_EN0, 7),
++ MTK_PIN_IES_SMT_SPEC(33, 37, IES_EN0, 8),
++ MTK_PIN_IES_SMT_SPEC(39, 42, IES_EN0, 9),
++ MTK_PIN_IES_SMT_SPEC(43, 45, IES_EN0, 10),
++ MTK_PIN_IES_SMT_SPEC(47, 48, IES_EN0, 11),
++ MTK_PIN_IES_SMT_SPEC(49, 49, IES_EN0, 12),
++ MTK_PIN_IES_SMT_SPEC(53, 56, IES_EN0, 14),
++ MTK_PIN_IES_SMT_SPEC(60, 62, IES_EN1, 0),
++ MTK_PIN_IES_SMT_SPEC(63, 65, IES_EN1, 1),
++ MTK_PIN_IES_SMT_SPEC(66, 71, IES_EN1, 2),
++ MTK_PIN_IES_SMT_SPEC(72, 74, IES_EN0, 12),
++ MTK_PIN_IES_SMT_SPEC(75, 76, IES_EN1, 3),
++ MTK_PIN_IES_SMT_SPEC(83, 84, IES_EN1, 2),
++ MTK_PIN_IES_SMT_SPEC(105, 121, MSDC1_CTRL1, 4),
++ MTK_PIN_IES_SMT_SPEC(122, 125, IES_EN1, 7),
++ MTK_PIN_IES_SMT_SPEC(126, 126, IES_EN0, 12),
++ MTK_PIN_IES_SMT_SPEC(199, 201, IES_EN0, 1),
++ MTK_PIN_IES_SMT_SPEC(203, 207, IES_EN2, 2),
++ MTK_PIN_IES_SMT_SPEC(208, 209, IES_EN2, 3),
++ MTK_PIN_IES_SMT_SPEC(236, 241, IES_EN2, 6),
++ MTK_PIN_IES_SMT_SPEC(242, 243, IES_EN2, 7),
++ MTK_PIN_IES_SMT_SPEC(261, 261, MSDC1_CTRL2, 4),
++ MTK_PIN_IES_SMT_SPEC(262, 272, IES_EN2, 12),
++ MTK_PIN_IES_SMT_SPEC(274, 276, IES_EN2, 12),
++ MTK_PIN_IES_SMT_SPEC(278, 278, IES_EN2, 13),
++};
++
++static const struct mtk_pin_ies_smt_set mt7623_smt_set[] = {
++ MTK_PIN_IES_SMT_SPEC(0, 6, SMT_EN0, 0),
++ MTK_PIN_IES_SMT_SPEC(7, 9, SMT_EN0, 1),
++ MTK_PIN_IES_SMT_SPEC(10, 13, SMT_EN0, 2),
++ MTK_PIN_IES_SMT_SPEC(14, 15, SMT_EN0, 3),
++ MTK_PIN_IES_SMT_SPEC(18, 21, SMT_EN0, 5),
++ MTK_PIN_IES_SMT_SPEC(22, 26, SMT_EN0, 6),
++ MTK_PIN_IES_SMT_SPEC(27, 29, SMT_EN0, 7),
++ MTK_PIN_IES_SMT_SPEC(33, 37, SMT_EN0, 8),
++ MTK_PIN_IES_SMT_SPEC(39, 42, SMT_EN0, 9),
++ MTK_PIN_IES_SMT_SPEC(43, 45, SMT_EN0, 10),
++ MTK_PIN_IES_SMT_SPEC(47, 48, SMT_EN0, 11),
++ MTK_PIN_IES_SMT_SPEC(49, 49, SMT_EN0, 12),
++ MTK_PIN_IES_SMT_SPEC(53, 56, SMT_EN0, 14),
++ MTK_PIN_IES_SMT_SPEC(60, 62, SMT_EN1, 0),
++ MTK_PIN_IES_SMT_SPEC(63, 65, SMT_EN1, 1),
++ MTK_PIN_IES_SMT_SPEC(66, 71, SMT_EN1, 2),
++ MTK_PIN_IES_SMT_SPEC(72, 74, SMT_EN0, 12),
++ MTK_PIN_IES_SMT_SPEC(75, 76, SMT_EN1, 3),
++ MTK_PIN_IES_SMT_SPEC(83, 84, SMT_EN1, 2),
++ MTK_PIN_IES_SMT_SPEC(105, 106, MSDC1_CTRL1, 11),
++ MTK_PIN_IES_SMT_SPEC(107, 107, MSDC1_CTRL3, 3),
++ MTK_PIN_IES_SMT_SPEC(108, 108, MSDC1_CTRL3, 7),
++ MTK_PIN_IES_SMT_SPEC(109, 109, MSDC1_CTRL3, 11),
++ MTK_PIN_IES_SMT_SPEC(110, 111, MSDC1_CTRL3, 15),
++ MTK_PIN_IES_SMT_SPEC(112, 112, MSDC0_CTRL4, 11),
++ MTK_PIN_IES_SMT_SPEC(113, 113, MSDC0_CTRL4, 7),
++ MTK_PIN_IES_SMT_SPEC(114, 115, MSDC0_CTRL4, 3),
++ MTK_PIN_IES_SMT_SPEC(116, 117, MSDC0_CTRL1, 11),
++ MTK_PIN_IES_SMT_SPEC(118, 118, MSDC0_CTRL3, 15),
++ MTK_PIN_IES_SMT_SPEC(119, 119, MSDC0_CTRL3, 11),
++ MTK_PIN_IES_SMT_SPEC(120, 120, MSDC0_CTRL3, 7),
++ MTK_PIN_IES_SMT_SPEC(121, 121, MSDC0_CTRL3, 3),
++ MTK_PIN_IES_SMT_SPEC(122, 125, SMT_EN1, 7),
++ MTK_PIN_IES_SMT_SPEC(126, 126, SMT_EN0, 12),
++ MTK_PIN_IES_SMT_SPEC(199, 201, SMT_EN0, 1),
++ MTK_PIN_IES_SMT_SPEC(203, 207, SMT_EN2, 2),
++ MTK_PIN_IES_SMT_SPEC(208, 209, SMT_EN2, 3),
++ MTK_PIN_IES_SMT_SPEC(236, 241, SMT_EN2, 6),
++ MTK_PIN_IES_SMT_SPEC(242, 243, SMT_EN2, 7),
++ MTK_PIN_IES_SMT_SPEC(261, 261, MSDC1_CTRL6, 3),
++ MTK_PIN_IES_SMT_SPEC(262, 272, SMT_EN2, 12),
++ MTK_PIN_IES_SMT_SPEC(274, 276, SMT_EN2, 12),
++ MTK_PIN_IES_SMT_SPEC(278, 278, SMT_EN2, 13),
++};
++
++static int mt7623_ies_smt_set(struct regmap *regmap, unsigned int pin,
++ unsigned char align, int value, enum pin_config_param arg)
++{
++ if (arg == PIN_CONFIG_INPUT_ENABLE)
++ return mtk_pconf_spec_set_ies_smt_range(regmap, mt7623_ies_set,
++ ARRAY_SIZE(mt7623_ies_set), pin, align, value);
++ else if (arg == PIN_CONFIG_INPUT_SCHMITT_ENABLE)
++ return mtk_pconf_spec_set_ies_smt_range(regmap, mt7623_smt_set,
++ ARRAY_SIZE(mt7623_smt_set), pin, align, value);
++ return -EINVAL;
++}
++
++static const struct mtk_pinctrl_devdata mt7623_pinctrl_data = {
++ .pins = mtk_pins_mt7623,
++ .npins = ARRAY_SIZE(mtk_pins_mt7623),
++ .grp_desc = mt7623_drv_grp,
++ .n_grp_cls = ARRAY_SIZE(mt7623_drv_grp),
++ .pin_drv_grp = mt7623_pin_drv,
++ .n_pin_drv_grps = ARRAY_SIZE(mt7623_pin_drv),
++ .spec_pull_set = mt7623_spec_pull_set,
++ .spec_ies_smt_set = mt7623_ies_smt_set,
++ .dir_offset = 0x0000,
++ .pullen_offset = 0x0150,
++ .pullsel_offset = 0x0280,
++ .dout_offset = 0x0500,
++ .din_offset = 0x0630,
++ .pinmux_offset = 0x0760,
++ .type1_start = 280,
++ .type1_end = 280,
++ .port_shf = 4,
++ .port_mask = 0x1f,
++ .port_align = 4,
++ .eint_offsets = {
++ .name = "mt7623_eint",
++ .stat = 0x000,
++ .ack = 0x040,
++ .mask = 0x080,
++ .mask_set = 0x0c0,
++ .mask_clr = 0x100,
++ .sens = 0x140,
++ .sens_set = 0x180,
++ .sens_clr = 0x1c0,
++ .soft = 0x200,
++ .soft_set = 0x240,
++ .soft_clr = 0x280,
++ .pol = 0x300,
++ .pol_set = 0x340,
++ .pol_clr = 0x380,
++ .dom_en = 0x400,
++ .dbnc_ctrl = 0x500,
++ .dbnc_set = 0x600,
++ .dbnc_clr = 0x700,
++ .port_mask = 6,
++ .ports = 6,
++ },
++ .ap_num = 169,
++ .db_cnt = 16,
++};
++
++static int mt7623_pinctrl_probe(struct platform_device *pdev)
++{
++ return mtk_pctrl_init(pdev, &mt7623_pinctrl_data, NULL);
++}
++
++static const struct of_device_id mt7623_pctrl_match[] = {
++ { .compatible = "mediatek,mt7623-pinctrl", },
++ {}
++};
++MODULE_DEVICE_TABLE(of, mt7623_pctrl_match);
++
++static struct platform_driver mtk_pinctrl_driver = {
++ .probe = mt7623_pinctrl_probe,
++ .driver = {
++ .name = "mediatek-mt7623-pinctrl",
++ .owner = THIS_MODULE,
++ .of_match_table = mt7623_pctrl_match,
++ },
++};
++
++static int __init mtk_pinctrl_init(void)
++{
++ return platform_driver_register(&mtk_pinctrl_driver);
++}
++
++arch_initcall(mtk_pinctrl_init);
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-mt7623.h b/drivers/pinctrl/mediatek/pinctrl-mtk-mt7623.h
+new file mode 100644
+index 0000000..fb63c01
+--- /dev/null
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-mt7623.h
+@@ -0,0 +1,1937 @@
++/*
++ * Copyright (c) 2016 John Crispin <blogic@openwrt.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef __PINCTRL_MTK_MT7623_H
++#define __PINCTRL_MTK_MT7623_H
++
++#include <linux/pinctrl/pinctrl.h>
++#include "pinctrl-mtk-common.h"
++
++static const struct mtk_desc_pin mtk_pins_mt7623[] = {
++ MTK_PIN(
++ PINCTRL_PIN(0, "PWRAP_SPI0_MI"),
++ "J20", "mt7623",
++ MTK_EINT_FUNCTION(0, 148),
++ MTK_FUNCTION(0, "GPIO0"),
++ MTK_FUNCTION(1, "PWRAP_SPIDO"),
++ MTK_FUNCTION(2, "PWRAP_SPIDI")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(1, "PWRAP_SPI0_MO"),
++ "D10", "mt7623",
++ MTK_EINT_FUNCTION(0, 149),
++ MTK_FUNCTION(0, "GPIO1"),
++ MTK_FUNCTION(1, "PWRAP_SPIDI"),
++ MTK_FUNCTION(2, "PWRAP_SPIDO")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(2, "PWRAP_INT"),
++ "E11", "mt7623",
++ MTK_EINT_FUNCTION(0, 150),
++ MTK_FUNCTION(0, "GPIO2"),
++ MTK_FUNCTION(1, "PWRAP_INT")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(3, "PWRAP_SPI0_CK"),
++ "H12", "mt7623",
++ MTK_EINT_FUNCTION(0, 151),
++ MTK_FUNCTION(0, "GPIO3"),
++ MTK_FUNCTION(1, "PWRAP_SPICK_I")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(4, "PWRAP_SPI0_CSN"),
++ "E12", "mt7623",
++ MTK_EINT_FUNCTION(0, 152),
++ MTK_FUNCTION(0, "GPIO4"),
++ MTK_FUNCTION(1, "PWRAP_SPICS_B_I")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(5, "PWRAP_SPI0_CK2"),
++ "H11", "mt7623",
++ MTK_EINT_FUNCTION(0, 155),
++ MTK_FUNCTION(0, "GPIO5"),
++ MTK_FUNCTION(1, "PWRAP_SPICK2_I")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(6, "PWRAP_SPI0_CSN2"),
++ "G11", "mt7623",
++ MTK_EINT_FUNCTION(0, 156),
++ MTK_FUNCTION(0, "GPIO6"),
++ MTK_FUNCTION(1, "PWRAP_SPICS2_B_I")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(7, "SPI1_CSN"),
++ "G19", "mt7623",
++ MTK_EINT_FUNCTION(0, 153),
++ MTK_FUNCTION(0, "GPIO7"),
++ MTK_FUNCTION(1, "SPI1_CS")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(8, "SPI1_MI"),
++ "F19", "mt7623",
++ MTK_EINT_FUNCTION(0, 154),
++ MTK_FUNCTION(0, "GPIO8"),
++ MTK_FUNCTION(1, "SPI1_MI"),
++ MTK_FUNCTION(2, "SPI1_MO")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(9, "SPI1_MO"),
++ "G20", "mt7623",
++ MTK_EINT_FUNCTION(0, 157),
++ MTK_FUNCTION(0, "GPIO9"),
++ MTK_FUNCTION(1, "SPI1_MO"),
++ MTK_FUNCTION(2, "SPI1_MI")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(10, "RTC32K_CK"),
++ "A13", "mt7623",
++ MTK_EINT_FUNCTION(0, 158),
++ MTK_FUNCTION(0, "GPIO10"),
++ MTK_FUNCTION(1, "RTC32K_CK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(11, "WATCHDOG"),
++ "D14", "mt7623",
++ MTK_EINT_FUNCTION(0, 159),
++ MTK_FUNCTION(0, "GPIO11"),
++ MTK_FUNCTION(1, "WATCHDOG")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(12, "SRCLKENA"),
++ "C13", "mt7623",
++ MTK_EINT_FUNCTION(0, 169),
++ MTK_FUNCTION(0, "GPIO12"),
++ MTK_FUNCTION(1, "SRCLKENA")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(13, "SRCLKENAI"),
++ "B13", "mt7623",
++ MTK_EINT_FUNCTION(0, 161),
++ MTK_FUNCTION(0, "GPIO13"),
++ MTK_FUNCTION(1, "SRCLKENAI")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(14, "GPIO14"),
++ "E18", "mt7623",
++ MTK_EINT_FUNCTION(0, 162),
++ MTK_FUNCTION(0, "GPIO14"),
++ MTK_FUNCTION(1, "URXD2"),
++ MTK_FUNCTION(2, "UTXD2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(15, "GPIO15"),
++ "E17", "mt7623",
++ MTK_EINT_FUNCTION(0, 163),
++ MTK_FUNCTION(0, "GPIO15"),
++ MTK_FUNCTION(1, "UTXD2"),
++ MTK_FUNCTION(2, "URXD2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(16, "GPIO16"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO16")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(17, "GPIO17"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO17")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(18, "PCM_CLK"),
++ "C19", "mt7623",
++ MTK_EINT_FUNCTION(0, 166),
++ MTK_FUNCTION(0, "GPIO18"),
++ MTK_FUNCTION(1, "PCM_CLK0"),
++ MTK_FUNCTION(6, "AP_PCM_CLKO")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(19, "PCM_SYNC"),
++ "D19", "mt7623",
++ MTK_EINT_FUNCTION(0, 167),
++ MTK_FUNCTION(0, "GPIO19"),
++ MTK_FUNCTION(1, "PCM_SYNC"),
++ MTK_FUNCTION(6, "AP_PCM_SYNC")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(20, "PCM_RX"),
++ "D18", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO20"),
++ MTK_FUNCTION(1, "PCM_RX"),
++ MTK_FUNCTION(4, "PCM_TX"),
++ MTK_FUNCTION(6, "AP_PCM_RX")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(21, "PCM_TX"),
++ "C18", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO21"),
++ MTK_FUNCTION(1, "PCM_TX"),
++ MTK_FUNCTION(4, "PCM_RX"),
++ MTK_FUNCTION(6, "AP_PCM_TX")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(22, "EINT0"),
++ "H15", "mt7623",
++ MTK_EINT_FUNCTION(0, 0),
++ MTK_FUNCTION(0, "GPIO22"),
++ MTK_FUNCTION(1, "UCTS0"),
++ MTK_FUNCTION(2, "PCIE0_PERST_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(23, "EINT1"),
++ "J16", "mt7623",
++ MTK_EINT_FUNCTION(0, 1),
++ MTK_FUNCTION(0, "GPIO23"),
++ MTK_FUNCTION(1, "URTS0"),
++ MTK_FUNCTION(2, "PCIE1_PERST_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(24, "EINT2"),
++ "H16", "mt7623",
++ MTK_EINT_FUNCTION(0, 2),
++ MTK_FUNCTION(0, "GPIO24"),
++ MTK_FUNCTION(1, "UCTS1"),
++ MTK_FUNCTION(2, "PCIE2_PERST_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(25, "EINT3"),
++ "K15", "mt7623",
++ MTK_EINT_FUNCTION(0, 3),
++ MTK_FUNCTION(0, "GPIO25"),
++ MTK_FUNCTION(1, "URTS1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(26, "EINT4"),
++ "G15", "mt7623",
++ MTK_EINT_FUNCTION(0, 4),
++ MTK_FUNCTION(0, "GPIO26"),
++ MTK_FUNCTION(1, "UCTS3"),
++ MTK_FUNCTION(6, "PCIE2_WAKE_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(27, "EINT5"),
++ "F15", "mt7623",
++ MTK_EINT_FUNCTION(0, 5),
++ MTK_FUNCTION(0, "GPIO27"),
++ MTK_FUNCTION(1, "URTS3"),
++ MTK_FUNCTION(6, "PCIE1_WAKE_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(28, "EINT6"),
++ "J15", "mt7623",
++ MTK_EINT_FUNCTION(0, 6),
++ MTK_FUNCTION(0, "GPIO28"),
++ MTK_FUNCTION(1, "DRV_VBUS"),
++ MTK_FUNCTION(6, "PCIE0_WAKE_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(29, "EINT7"),
++ "E15", "mt7623",
++ MTK_EINT_FUNCTION(0, 7),
++ MTK_FUNCTION(0, "GPIO29"),
++ MTK_FUNCTION(1, "IDDIG"),
++ MTK_FUNCTION(2, "MSDC1_WP"),
++ MTK_FUNCTION(6, "PCIE2_PERST_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(30, "GPIO30"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO30")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(31, "GPIO31"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO31")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(32, "GPIO32"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO32")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(33, "I2S1_DATA"),
++ "Y18", "mt7623",
++ MTK_EINT_FUNCTION(0, 15),
++ MTK_FUNCTION(0, "GPIO33"),
++ MTK_FUNCTION(1, "I2S1_DATA"),
++ MTK_FUNCTION(3, "PCM_TX"),
++ MTK_FUNCTION(6, "AP_PCM_TX")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(34, "I2S1_DATA_IN"),
++ "Y17", "mt7623",
++ MTK_EINT_FUNCTION(0, 16),
++ MTK_FUNCTION(0, "GPIO34"),
++ MTK_FUNCTION(1, "I2S1_DATA_IN"),
++ MTK_FUNCTION(3, "PCM_RX"),
++ MTK_FUNCTION(6, "AP_PCM_RX")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(35, "I2S1_BCK"),
++ "V17", "mt7623",
++ MTK_EINT_FUNCTION(0, 17),
++ MTK_FUNCTION(0, "GPIO35"),
++ MTK_FUNCTION(1, "I2S1_BCK"),
++ MTK_FUNCTION(3, "PCM_CLK0"),
++ MTK_FUNCTION(6, "AP_PCM_CLKO")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(36, "I2S1_LRCK"),
++ "W17", "mt7623",
++ MTK_EINT_FUNCTION(0, 18),
++ MTK_FUNCTION(0, "GPIO36"),
++ MTK_FUNCTION(1, "I2S1_LRCK"),
++ MTK_FUNCTION(3, "PCM_SYNC"),
++ MTK_FUNCTION(6, "AP_PCM_SYNC")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(37, "I2S1_MCLK"),
++ "AA18", "mt7623",
++ MTK_EINT_FUNCTION(0, 19),
++ MTK_FUNCTION(0, "GPIO37"),
++ MTK_FUNCTION(1, "I2S1_MCLK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(38, "GPIO38"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO38")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(39, "JTMS"),
++ "G21", "mt7623",
++ MTK_EINT_FUNCTION(0, 21),
++ MTK_FUNCTION(0, "GPIO39"),
++ MTK_FUNCTION(1, "JTMS")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(40, "GPIO40"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO40")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(41, "JTDI"),
++ "H22", "mt7623",
++ MTK_EINT_FUNCTION(0, 23),
++ MTK_FUNCTION(0, "GPIO41"),
++ MTK_FUNCTION(1, "JTDI")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(42, "JTDO"),
++ "H21", "mt7623",
++ MTK_EINT_FUNCTION(0, 24),
++ MTK_FUNCTION(0, "GPIO42"),
++ MTK_FUNCTION(1, "JTDO")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(43, "NCLE"),
++ "C7", "mt7623",
++ MTK_EINT_FUNCTION(0, 25),
++ MTK_FUNCTION(0, "GPIO43"),
++ MTK_FUNCTION(1, "NCLE"),
++ MTK_FUNCTION(2, "EXT_XCS2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(44, "NCEB1"),
++ "C6", "mt7623",
++ MTK_EINT_FUNCTION(0, 26),
++ MTK_FUNCTION(0, "GPIO44"),
++ MTK_FUNCTION(1, "NCEB1"),
++ MTK_FUNCTION(2, "IDDIG")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(45, "NCEB0"),
++ "D7", "mt7623",
++ MTK_EINT_FUNCTION(0, 27),
++ MTK_FUNCTION(0, "GPIO45"),
++ MTK_FUNCTION(1, "NCEB0"),
++ MTK_FUNCTION(2, "DRV_VBUS")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(46, "IR"),
++ "D15", "mt7623",
++ MTK_EINT_FUNCTION(0, 28),
++ MTK_FUNCTION(0, "GPIO46"),
++ MTK_FUNCTION(1, "IR")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(47, "NREB"),
++ "A6", "mt7623",
++ MTK_EINT_FUNCTION(0, 29),
++ MTK_FUNCTION(0, "GPIO47"),
++ MTK_FUNCTION(1, "NREB")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(48, "NRNB"),
++ "B6", "mt7623",
++ MTK_EINT_FUNCTION(0, 30),
++ MTK_FUNCTION(0, "GPIO48"),
++ MTK_FUNCTION(1, "NRNB")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(49, "I2S0_DATA"),
++ "AB18", "mt7623",
++ MTK_EINT_FUNCTION(0, 31),
++ MTK_FUNCTION(0, "GPIO49"),
++ MTK_FUNCTION(1, "I2S0_DATA"),
++ MTK_FUNCTION(3, "PCM_TX"),
++ MTK_FUNCTION(6, "AP_I2S_DO")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(50, "GPIO50"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO50")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(51, "GPIO51"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO51")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(52, "GPIO52"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO52")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(53, "SPI0_CSN"),
++ "E7", "mt7623",
++ MTK_EINT_FUNCTION(0, 35),
++ MTK_FUNCTION(0, "GPIO53"),
++ MTK_FUNCTION(1, "SPI0_CS"),
++ MTK_FUNCTION(5, "PWM1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(54, "SPI0_CK"),
++ "F7", "mt7623",
++ MTK_EINT_FUNCTION(0, 36),
++ MTK_FUNCTION(0, "GPIO54"),
++ MTK_FUNCTION(1, "SPI0_CK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(55, "SPI0_MI"),
++ "E6", "mt7623",
++ MTK_EINT_FUNCTION(0, 37),
++ MTK_FUNCTION(0, "GPIO55"),
++ MTK_FUNCTION(1, "SPI0_MI"),
++ MTK_FUNCTION(2, "SPI0_MO"),
++ MTK_FUNCTION(3, "MSDC1_WP"),
++ MTK_FUNCTION(5, "PWM2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(56, "SPI0_MO"),
++ "G7", "mt7623",
++ MTK_EINT_FUNCTION(0, 38),
++ MTK_FUNCTION(0, "GPIO56"),
++ MTK_FUNCTION(1, "SPI0_MO"),
++ MTK_FUNCTION(2, "SPI0_MI")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(57, "GPIO57"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO57")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(58, "GPIO58"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO58")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(59, "GPIO59"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO59")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(60, "WB_RSTB"),
++ "Y21", "mt7623",
++ MTK_EINT_FUNCTION(0, 41),
++ MTK_FUNCTION(0, "GPIO60"),
++ MTK_FUNCTION(1, "WB_RSTB")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(61, "GPIO61"),
++ "AA21", "mt7623",
++ MTK_EINT_FUNCTION(0, 42),
++ MTK_FUNCTION(0, "GPIO61"),
++ MTK_FUNCTION(1, "TEST_FD")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(62, "GPIO62"),
++ "AB22", "mt7623",
++ MTK_EINT_FUNCTION(0, 43),
++ MTK_FUNCTION(0, "GPIO62"),
++ MTK_FUNCTION(1, "TEST_FC")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(63, "WB_SCLK"),
++ "AC23", "mt7623",
++ MTK_EINT_FUNCTION(0, 44),
++ MTK_FUNCTION(0, "GPIO63"),
++ MTK_FUNCTION(1, "WB_SCLK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(64, "WB_SDATA"),
++ "AB21", "mt7623",
++ MTK_EINT_FUNCTION(0, 45),
++ MTK_FUNCTION(0, "GPIO64"),
++ MTK_FUNCTION(1, "WB_SDATA")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(65, "WB_SEN"),
++ "AB24", "mt7623",
++ MTK_EINT_FUNCTION(0, 46),
++ MTK_FUNCTION(0, "GPIO65"),
++ MTK_FUNCTION(1, "WB_SEN")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(66, "WB_CRTL0"),
++ "AB20", "mt7623",
++ MTK_EINT_FUNCTION(0, 47),
++ MTK_FUNCTION(0, "GPIO66"),
++ MTK_FUNCTION(1, "WB_CRTL0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(67, "WB_CRTL1"),
++ "AC20", "mt7623",
++ MTK_EINT_FUNCTION(0, 48),
++ MTK_FUNCTION(0, "GPIO67"),
++ MTK_FUNCTION(1, "WB_CRTL1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(68, "WB_CRTL2"),
++ "AB19", "mt7623",
++ MTK_EINT_FUNCTION(0, 49),
++ MTK_FUNCTION(0, "GPIO68"),
++ MTK_FUNCTION(1, "WB_CRTL2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(69, "WB_CRTL3"),
++ "AC19", "mt7623",
++ MTK_EINT_FUNCTION(0, 50),
++ MTK_FUNCTION(0, "GPIO69"),
++ MTK_FUNCTION(1, "WB_CRTL3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(70, "WB_CRTL4"),
++ "AD19", "mt7623",
++ MTK_EINT_FUNCTION(0, 51),
++ MTK_FUNCTION(0, "GPIO70"),
++ MTK_FUNCTION(1, "WB_CRTL4")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(71, "WB_CRTL5"),
++ "AE19", "mt7623",
++ MTK_EINT_FUNCTION(0, 52),
++ MTK_FUNCTION(0, "GPIO71"),
++ MTK_FUNCTION(1, "WB_CRTL5")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(72, "I2S0_DATA_IN"),
++ "AA20", "mt7623",
++ MTK_EINT_FUNCTION(0, 53),
++ MTK_FUNCTION(0, "GPIO72"),
++ MTK_FUNCTION(1, "I2S0_DATA_IN"),
++ MTK_FUNCTION(3, "PCM_RX"),
++ MTK_FUNCTION(4, "PWM0"),
++ MTK_FUNCTION(5, "DISP_PWM"),
++ MTK_FUNCTION(6, "AP_I2S_DI")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(73, "I2S0_LRCK"),
++ "Y20", "mt7623",
++ MTK_EINT_FUNCTION(0, 54),
++ MTK_FUNCTION(0, "GPIO73"),
++ MTK_FUNCTION(1, "I2S0_LRCK"),
++ MTK_FUNCTION(3, "PCM_SYNC"),
++ MTK_FUNCTION(6, "AP_I2S_LRCK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(74, "I2S0_BCK"),
++ "Y19", "mt7623",
++ MTK_EINT_FUNCTION(0, 55),
++ MTK_FUNCTION(0, "GPIO74"),
++ MTK_FUNCTION(1, "I2S0_BCK"),
++ MTK_FUNCTION(3, "PCM_CLK0"),
++ MTK_FUNCTION(6, "AP_I2S_BCK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(75, "SDA0"),
++ "K19", "mt7623",
++ MTK_EINT_FUNCTION(0, 56),
++ MTK_FUNCTION(0, "GPIO75"),
++ MTK_FUNCTION(1, "SDA0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(76, "SCL0"),
++ "K20", "mt7623",
++ MTK_EINT_FUNCTION(0, 57),
++ MTK_FUNCTION(0, "GPIO76"),
++ MTK_FUNCTION(1, "SCL0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(77, "GPIO77"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO77")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(78, "GPIO78"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO78")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(79, "GPIO79"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO79")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(80, "GPIO80"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO80")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(81, "GPIO81"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO81")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(82, "GPIO82"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO82")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(83, "LCM_RST"),
++ "V16", "mt7623",
++ MTK_EINT_FUNCTION(0, 64),
++ MTK_FUNCTION(0, "GPIO83"),
++ MTK_FUNCTION(1, "LCM_RST")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(84, "DSI_TE"),
++ "V14", "mt7623",
++ MTK_EINT_FUNCTION(0, 65),
++ MTK_FUNCTION(0, "GPIO84"),
++ MTK_FUNCTION(1, "DSI_TE")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(85, "GPIO85"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO85")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(86, "GPIO86"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO86")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(87, "GPIO87"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO87")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(88, "GPIO88"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO88")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(89, "GPIO89"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO89")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(90, "GPIO90"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO90")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(91, "GPIO91"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO91")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(92, "GPIO92"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO92")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(93, "GPIO93"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO93")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(94, "GPIO94"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO94")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(95, "MIPI_TCN"),
++ "AB14", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO95"),
++ MTK_FUNCTION(1, "TCN")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(96, "MIPI_TCP"),
++ "AC14", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO96"),
++ MTK_FUNCTION(1, "TCP")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(97, "MIPI_TDN1"),
++ "AE15", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO97"),
++ MTK_FUNCTION(1, "TDN1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(98, "MIPI_TDP1"),
++ "AD15", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO98"),
++ MTK_FUNCTION(1, "TDP1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(99, "MIPI_TDN0"),
++ "AB15", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO99"),
++ MTK_FUNCTION(1, "TDN0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(100, "MIPI_TDP0"),
++ "AC15", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO100"),
++ MTK_FUNCTION(1, "TDP0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(101, "GPIO101"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO101")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(102, "GPIO102"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO102")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(103, "GPIO103"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO103")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(104, "GPIO104"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO104")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(105, "MSDC1_CMD"),
++ "AD2", "mt7623",
++ MTK_EINT_FUNCTION(0, 78),
++ MTK_FUNCTION(0, "GPIO105"),
++ MTK_FUNCTION(1, "MSDC1_CMD"),
++ MTK_FUNCTION(3, "SDA1"),
++ MTK_FUNCTION(6, "I2SOUT_BCK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(106, "MSDC1_CLK"),
++ "AD3", "mt7623",
++ MTK_EINT_FUNCTION(0, 79),
++ MTK_FUNCTION(0, "GPIO106"),
++ MTK_FUNCTION(1, "MSDC1_CLK"),
++ MTK_FUNCTION(3, "SCL1"),
++ MTK_FUNCTION(6, "I2SOUT_LRCK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(107, "MSDC1_DAT0"),
++ "AE2", "mt7623",
++ MTK_EINT_FUNCTION(0, 80),
++ MTK_FUNCTION(0, "GPIO107"),
++ MTK_FUNCTION(1, "MSDC1_DAT0"),
++ MTK_FUNCTION(5, "UTXD0"),
++ MTK_FUNCTION(6, "I2SOUT_DATA_OUT")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(108, "MSDC1_DAT1"),
++ "AC1", "mt7623",
++ MTK_EINT_FUNCTION(0, 81),
++ MTK_FUNCTION(0, "GPIO108"),
++ MTK_FUNCTION(1, "MSDC1_DAT1"),
++ MTK_FUNCTION(3, "PWM0"),
++ MTK_FUNCTION(5, "URXD0"),
++ MTK_FUNCTION(6, "PWM1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(109, "MSDC1_DAT2"),
++ "AC3", "mt7623",
++ MTK_EINT_FUNCTION(0, 82),
++ MTK_FUNCTION(0, "GPIO109"),
++ MTK_FUNCTION(1, "MSDC1_DAT2"),
++ MTK_FUNCTION(3, "SDA2"),
++ MTK_FUNCTION(5, "UTXD1"),
++ MTK_FUNCTION(6, "PWM2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(110, "MSDC1_DAT3"),
++ "AC4", "mt7623",
++ MTK_EINT_FUNCTION(0, 83),
++ MTK_FUNCTION(0, "GPIO110"),
++ MTK_FUNCTION(1, "MSDC1_DAT3"),
++ MTK_FUNCTION(3, "SCL2"),
++ MTK_FUNCTION(5, "URXD1"),
++ MTK_FUNCTION(6, "PWM3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(111, "MSDC0_DAT7"),
++ "A2", "mt7623",
++ MTK_EINT_FUNCTION(0, 84),
++ MTK_FUNCTION(0, "GPIO111"),
++ MTK_FUNCTION(1, "MSDC0_DAT7"),
++ MTK_FUNCTION(4, "NLD7")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(112, "MSDC0_DAT6"),
++ "B3", "mt7623",
++ MTK_EINT_FUNCTION(0, 85),
++ MTK_FUNCTION(0, "GPIO112"),
++ MTK_FUNCTION(1, "MSDC0_DAT6"),
++ MTK_FUNCTION(4, "NLD6")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(113, "MSDC0_DAT5"),
++ "C4", "mt7623",
++ MTK_EINT_FUNCTION(0, 86),
++ MTK_FUNCTION(0, "GPIO113"),
++ MTK_FUNCTION(1, "MSDC0_DAT5"),
++ MTK_FUNCTION(4, "NLD5")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(114, "MSDC0_DAT4"),
++ "A4", "mt7623",
++ MTK_EINT_FUNCTION(0, 87),
++ MTK_FUNCTION(0, "GPIO114"),
++ MTK_FUNCTION(1, "MSDC0_DAT4"),
++ MTK_FUNCTION(4, "NLD4")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(115, "MSDC0_RSTB"),
++ "C5", "mt7623",
++ MTK_EINT_FUNCTION(0, 88),
++ MTK_FUNCTION(0, "GPIO115"),
++ MTK_FUNCTION(1, "MSDC0_RSTB"),
++ MTK_FUNCTION(4, "NLD8")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(116, "MSDC0_CMD"),
++ "D5", "mt7623",
++ MTK_EINT_FUNCTION(0, 89),
++ MTK_FUNCTION(0, "GPIO116"),
++ MTK_FUNCTION(1, "MSDC0_CMD"),
++ MTK_FUNCTION(4, "NALE")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(117, "MSDC0_CLK"),
++ "B1", "mt7623",
++ MTK_EINT_FUNCTION(0, 90),
++ MTK_FUNCTION(0, "GPIO117"),
++ MTK_FUNCTION(1, "MSDC0_CLK"),
++ MTK_FUNCTION(4, "NWEB")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(118, "MSDC0_DAT3"),
++ "D6", "mt7623",
++ MTK_EINT_FUNCTION(0, 91),
++ MTK_FUNCTION(0, "GPIO118"),
++ MTK_FUNCTION(1, "MSDC0_DAT3"),
++ MTK_FUNCTION(4, "NLD3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(119, "MSDC0_DAT2"),
++ "B2", "mt7623",
++ MTK_EINT_FUNCTION(0, 92),
++ MTK_FUNCTION(0, "GPIO119"),
++ MTK_FUNCTION(1, "MSDC0_DAT2"),
++ MTK_FUNCTION(4, "NLD2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(120, "MSDC0_DAT1"),
++ "A3", "mt7623",
++ MTK_EINT_FUNCTION(0, 93),
++ MTK_FUNCTION(0, "GPIO120"),
++ MTK_FUNCTION(1, "MSDC0_DAT1"),
++ MTK_FUNCTION(4, "NLD1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(121, "MSDC0_DAT0"),
++ "B4", "mt7623",
++ MTK_EINT_FUNCTION(0, 94),
++ MTK_FUNCTION(0, "GPIO121"),
++ MTK_FUNCTION(1, "MSDC0_DAT0"),
++ MTK_FUNCTION(4, "NLD0"),
++ MTK_FUNCTION(5, "WATCHDOG")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(122, "GPIO122"),
++ "H17", "mt7623",
++ MTK_EINT_FUNCTION(0, 95),
++ MTK_FUNCTION(0, "GPIO122"),
++ MTK_FUNCTION(1, "TEST"),
++ MTK_FUNCTION(4, "SDA2"),
++ MTK_FUNCTION(5, "URXD0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(123, "GPIO123"),
++ "F17", "mt7623",
++ MTK_EINT_FUNCTION(0, 96),
++ MTK_FUNCTION(0, "GPIO123"),
++ MTK_FUNCTION(1, "TEST"),
++ MTK_FUNCTION(4, "SCL2"),
++ MTK_FUNCTION(5, "UTXD0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(124, "GPIO124"),
++ "H18", "mt7623",
++ MTK_EINT_FUNCTION(0, 97),
++ MTK_FUNCTION(0, "GPIO124"),
++ MTK_FUNCTION(1, "TEST"),
++ MTK_FUNCTION(4, "SDA1"),
++ MTK_FUNCTION(5, "PWM3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(125, "GPIO125"),
++ "G17", "mt7623",
++ MTK_EINT_FUNCTION(0, 98),
++ MTK_FUNCTION(0, "GPIO125"),
++ MTK_FUNCTION(1, "TEST"),
++ MTK_FUNCTION(4, "SCL1"),
++ MTK_FUNCTION(5, "PWM4")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(126, "I2S0_MCLK"),
++ "AA19", "mt7623",
++ MTK_EINT_FUNCTION(0, 99),
++ MTK_FUNCTION(0, "GPIO126"),
++ MTK_FUNCTION(1, "I2S0_MCLK"),
++ MTK_FUNCTION(6, "AP_I2S_MCLK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(127, "GPIO127"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO127")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(128, "GPIO128"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO128")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(129, "GPIO129"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO129")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(130, "GPIO130"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO130")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(131, "GPIO131"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO131")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(132, "GPIO132"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO132")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(133, "GPIO133"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO133")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(134, "GPIO134"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO134")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(135, "GPIO135"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO135")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(136, "GPIO136"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO136")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(137, "GPIO137"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO137")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(138, "GPIO138"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO138")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(139, "GPIO139"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO139")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(140, "GPIO140"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO140")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(141, "GPIO141"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO141")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(142, "GPIO142"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO142")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(143, "GPIO143"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO143")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(144, "GPIO144"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO144")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(145, "GPIO145"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO145")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(146, "GPIO146"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO146")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(147, "GPIO147"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO147")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(148, "GPIO148"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO148")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(149, "GPIO149"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO149")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(150, "GPIO150"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO150")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(151, "GPIO151"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO151")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(152, "GPIO152"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO152")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(153, "GPIO153"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO153")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(154, "GPIO154"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO154")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(155, "GPIO155"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO155")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(156, "GPIO156"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO156")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(157, "GPIO157"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO157")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(158, "GPIO158"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO158")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(159, "GPIO159"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO159")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(160, "GPIO160"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO160")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(161, "GPIO161"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO161")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(162, "GPIO162"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO162")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(163, "GPIO163"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO163")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(164, "GPIO164"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO164")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(165, "GPIO165"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO165")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(166, "GPIO166"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO166")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(167, "GPIO167"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO167")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(168, "GPIO168"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO168")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(169, "GPIO169"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO169")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(170, "GPIO170"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO170")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(171, "GPIO171"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO171")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(172, "GPIO172"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO172")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(173, "GPIO173"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO173")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(174, "GPIO174"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO174")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(175, "GPIO175"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO175")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(176, "GPIO176"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO176")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(177, "GPIO177"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO177")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(178, "GPIO178"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO178")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(179, "GPIO179"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO179")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(180, "GPIO180"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO180")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(181, "GPIO181"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO181")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(182, "GPIO182"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO182")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(183, "GPIO183"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO183")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(184, "GPIO184"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO184")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(185, "GPIO185"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO185")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(186, "GPIO186"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO186")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(187, "GPIO187"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO187")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(188, "GPIO188"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO188")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(189, "GPIO189"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO189")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(190, "GPIO190"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO190")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(191, "GPIO191"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO191")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(192, "GPIO192"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO192")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(193, "GPIO193"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO193")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(194, "GPIO194"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO194")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(195, "GPIO195"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO195")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(196, "GPIO196"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO196")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(197, "GPIO197"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO197")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(198, "GPIO198"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO198")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(199, "SPI1_CK"),
++ "E19", "mt7623",
++ MTK_EINT_FUNCTION(0, 111),
++ MTK_FUNCTION(0, "GPIO199"),
++ MTK_FUNCTION(1, "SPI1_CK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(200, "URXD2"),
++ "K18", "mt7623",
++ MTK_EINT_FUNCTION(0, 112),
++ MTK_FUNCTION(0, "GPIO200"),
++ MTK_FUNCTION(6, "URXD2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(201, "UTXD2"),
++ "L18", "mt7623",
++ MTK_EINT_FUNCTION(0, 113),
++ MTK_FUNCTION(0, "GPIO201"),
++ MTK_FUNCTION(6, "UTXD2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(202, "GPIO202"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO202")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(203, "PWM0"),
++ "AA16", "mt7623",
++ MTK_EINT_FUNCTION(0, 115),
++ MTK_FUNCTION(0, "GPIO203"),
++ MTK_FUNCTION(1, "PWM0"),
++ MTK_FUNCTION(2, "DISP_PWM")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(204, "PWM1"),
++ "Y16", "mt7623",
++ MTK_EINT_FUNCTION(0, 116),
++ MTK_FUNCTION(0, "GPIO204"),
++ MTK_FUNCTION(1, "PWM1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(205, "PWM2"),
++ "AA15", "mt7623",
++ MTK_EINT_FUNCTION(0, 117),
++ MTK_FUNCTION(0, "GPIO205"),
++ MTK_FUNCTION(1, "PWM2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(206, "PWM3"),
++ "AA17", "mt7623",
++ MTK_EINT_FUNCTION(0, 118),
++ MTK_FUNCTION(0, "GPIO206"),
++ MTK_FUNCTION(1, "PWM3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(207, "PWM4"),
++ "Y15", "mt7623",
++ MTK_EINT_FUNCTION(0, 119),
++ MTK_FUNCTION(0, "GPIO207"),
++ MTK_FUNCTION(1, "PWM4")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(208, "AUD_EXT_CK1"),
++ "W14", "mt7623",
++ MTK_EINT_FUNCTION(0, 120),
++ MTK_FUNCTION(0, "GPIO208"),
++ MTK_FUNCTION(1, "AUD_EXT_CK1"),
++ MTK_FUNCTION(2, "PWM0"),
++ MTK_FUNCTION(3, "PCIE0_PERST_N"),
++ MTK_FUNCTION(5, "DISP_PWM")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(209, "AUD_EXT_CK2"),
++ "V15", "mt7623",
++ MTK_EINT_FUNCTION(0, 121),
++ MTK_FUNCTION(0, "GPIO209"),
++ MTK_FUNCTION(1, "AUD_EXT_CK2"),
++ MTK_FUNCTION(2, "MSDC1_WP"),
++ MTK_FUNCTION(3, "PCIE1_PERST_N"),
++ MTK_FUNCTION(5, "PWM1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(210, "GPIO210"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO210")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(211, "GPIO211"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO211")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(212, "GPIO212"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO212")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(213, "GPIO213"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO213")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(214, "GPIO214"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO214")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(215, "GPIO215"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO215")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(216, "GPIO216"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO216")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(217, "GPIO217"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO217")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(218, "GPIO218"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO218")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(219, "GPIO219"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO219")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(220, "GPIO220"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO220")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(221, "GPIO221"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO221")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(222, "GPIO222"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO222")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(223, "GPIO223"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO223")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(224, "GPIO224"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO224")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(225, "GPIO225"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO225")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(226, "GPIO226"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO226")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(227, "GPIO227"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO227")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(228, "GPIO228"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO228")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(229, "GPIO229"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO229")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(230, "GPIO230"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO230")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(231, "GPIO231"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO231")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(232, "GPIO232"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO232")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(233, "GPIO233"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO233")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(234, "GPIO234"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO234")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(235, "GPIO235"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO235")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(236, "EXT_SDIO3"),
++ "A8", "mt7623",
++ MTK_EINT_FUNCTION(0, 122),
++ MTK_FUNCTION(0, "GPIO236"),
++ MTK_FUNCTION(1, "EXT_SDIO3"),
++ MTK_FUNCTION(2, "IDDIG")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(237, "EXT_SDIO2"),
++ "D8", "mt7623",
++ MTK_EINT_FUNCTION(0, 123),
++ MTK_FUNCTION(0, "GPIO237"),
++ MTK_FUNCTION(1, "EXT_SDIO2"),
++ MTK_FUNCTION(2, "DRV_VBUS")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(238, "EXT_SDIO1"),
++ "D9", "mt7623",
++ MTK_EINT_FUNCTION(0, 124),
++ MTK_FUNCTION(0, "GPIO238"),
++ MTK_FUNCTION(1, "EXT_SDIO1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(239, "EXT_SDIO0"),
++ "B8", "mt7623",
++ MTK_EINT_FUNCTION(0, 125),
++ MTK_FUNCTION(0, "GPIO239"),
++ MTK_FUNCTION(1, "EXT_SDIO0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(240, "EXT_XCS"),
++ "C9", "mt7623",
++ MTK_EINT_FUNCTION(0, 126),
++ MTK_FUNCTION(0, "GPIO240"),
++ MTK_FUNCTION(1, "EXT_XCS")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(241, "EXT_SCK"),
++ "C8", "mt7623",
++ MTK_EINT_FUNCTION(0, 127),
++ MTK_FUNCTION(0, "GPIO241"),
++ MTK_FUNCTION(1, "EXT_SCK")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(242, "URTS2"),
++ "G18", "mt7623",
++ MTK_EINT_FUNCTION(0, 128),
++ MTK_FUNCTION(0, "GPIO242"),
++ MTK_FUNCTION(1, "URTS2"),
++ MTK_FUNCTION(2, "UTXD3"),
++ MTK_FUNCTION(3, "URXD3"),
++ MTK_FUNCTION(4, "SCL1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(243, "UCTS2"),
++ "H19", "mt7623",
++ MTK_EINT_FUNCTION(0, 129),
++ MTK_FUNCTION(0, "GPIO243"),
++ MTK_FUNCTION(1, "UCTS2"),
++ MTK_FUNCTION(2, "URXD3"),
++ MTK_FUNCTION(3, "UTXD3"),
++ MTK_FUNCTION(4, "SDA1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(244, "GPIO244"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO244")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(245, "GPIO245"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO245")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(246, "GPIO246"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO246")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(247, "GPIO247"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO247")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(248, "GPIO248"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO248")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(249, "GPIO249"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO249")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(250, "GPIO250"),
++ "A15", "mt7623",
++ MTK_EINT_FUNCTION(0, 135),
++ MTK_FUNCTION(0, "GPIO250"),
++ MTK_FUNCTION(1, "TEST_MD7"),
++ MTK_FUNCTION(6, "PCIE0_CLKREQ_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(251, "GPIO251"),
++ "B15", "mt7623",
++ MTK_EINT_FUNCTION(0, 136),
++ MTK_FUNCTION(0, "GPIO251"),
++ MTK_FUNCTION(1, "TEST_MD6"),
++ MTK_FUNCTION(6, "PCIE0_WAKE_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(252, "GPIO252"),
++ "C16", "mt7623",
++ MTK_EINT_FUNCTION(0, 137),
++ MTK_FUNCTION(0, "GPIO252"),
++ MTK_FUNCTION(1, "TEST_MD5"),
++ MTK_FUNCTION(6, "PCIE1_CLKREQ_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(253, "GPIO253"),
++ "D17", "mt7623",
++ MTK_EINT_FUNCTION(0, 138),
++ MTK_FUNCTION(0, "GPIO253"),
++ MTK_FUNCTION(1, "TEST_MD4"),
++ MTK_FUNCTION(6, "PCIE1_WAKE_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(254, "GPIO254"),
++ "D16", "mt7623",
++ MTK_EINT_FUNCTION(0, 139),
++ MTK_FUNCTION(0, "GPIO254"),
++ MTK_FUNCTION(1, "TEST_MD3"),
++ MTK_FUNCTION(6, "PCIE2_CLKREQ_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(255, "GPIO255"),
++ "C17", "mt7623",
++ MTK_EINT_FUNCTION(0, 140),
++ MTK_FUNCTION(0, "GPIO255"),
++ MTK_FUNCTION(1, "TEST_MD2"),
++ MTK_FUNCTION(6, "PCIE2_WAKE_N")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(256, "GPIO256"),
++ "B17", "mt7623",
++ MTK_EINT_FUNCTION(0, 141),
++ MTK_FUNCTION(0, "GPIO256"),
++ MTK_FUNCTION(1, "TEST_MD1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(257, "GPIO257"),
++ "C15", "mt7623",
++ MTK_EINT_FUNCTION(0, 142),
++ MTK_FUNCTION(0, "GPIO257"),
++ MTK_FUNCTION(1, "TEST_MD0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(258, "GPIO258"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO258")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(259, "GPIO259"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO259")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(260, "GPIO260"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO260")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(261, "MSDC1_INS"),
++ "AD1", "mt7623",
++ MTK_EINT_FUNCTION(0, 146),
++ MTK_FUNCTION(0, "GPIO261"),
++ MTK_FUNCTION(1, "MSDC1_INS")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(262, "G2_TXEN"),
++ "A23", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO262"),
++ MTK_FUNCTION(1, "G2_TXEN")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(263, "G2_TXD3"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO263"),
++ MTK_FUNCTION(1, "G2_TXD3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(264, "G2_TXD2"),
++ "C24", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO264"),
++ MTK_FUNCTION(1, "G2_TXD2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(265, "G2_TXD1"),
++ "B25", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO265"),
++ MTK_FUNCTION(1, "G2_TXD1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(266, "G2_TXD0"),
++ "A24", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO266"),
++ MTK_FUNCTION(1, "G2_TXD0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(267, "G2_TXCLK"),
++ "C23", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO267"),
++ MTK_FUNCTION(1, "G2_TXC")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(268, "G2_RXCLK"),
++ "B23", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO268"),
++ MTK_FUNCTION(1, "G2_RXC")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(269, "G2_RXD0"),
++ "D21", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO269"),
++ MTK_FUNCTION(1, "G2_RXD0")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(270, "G2_RXD1"),
++ "B22", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO270"),
++ MTK_FUNCTION(1, "G2_RXD1")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(271, "G2_RXD2"),
++ "A22", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO271"),
++ MTK_FUNCTION(1, "G2_RXD2")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(272, "G2_RXD3"),
++ "C22", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO272"),
++ MTK_FUNCTION(1, "G2_RXD3")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(273, "GPIO273"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(0, 168),
++ MTK_FUNCTION(0, "GPIO273"),
++ MTK_FUNCTION(1, "ESW_INT")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(274, "G2_RXDV"),
++ "C21", "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO274"),
++ MTK_FUNCTION(1, "G2_RXDV")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(275, "G2_MDC"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO275"),
++ MTK_FUNCTION(1, "MDC")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(276, "G2_MDIO"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO276"),
++ MTK_FUNCTION(1, "MDIO")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(277, "GPIO277"),
++ NULL, "mt7623",
++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
++ MTK_FUNCTION(0, "GPIO277")
++ ),
++ MTK_PIN(
++ PINCTRL_PIN(278, "JTAG_RESET"),
++ "H20", "mt7623",
++ MTK_EINT_FUNCTION(0, 147),
++ MTK_FUNCTION(0, "GPIO278"),
++ MTK_FUNCTION(1, "JTAG_RESET")
++ ),
++};
++
++#endif /* __PINCTRL_MTK_MT7623_H */
+diff --git a/include/dt-bindings/pinctrl/mt7623-pinfunc.h b/include/dt-bindings/pinctrl/mt7623-pinfunc.h
+index 891b173..eeb2380 100644
+--- a/include/dt-bindings/pinctrl/mt7623-pinfunc.h
++++ b/include/dt-bindings/pinctrl/mt7623-pinfunc.h
+@@ -505,6 +505,9 @@
+ #define MT7623_PIN_272_G2_RXD3_FUNC_GPIO272 (MTK_PIN_NO(272) | 0)
+ #define MT7623_PIN_272_G2_RXD3_FUNC_G2_RXD3 (MTK_PIN_NO(272) | 1)
+
++#define MT7623_PIN_273_ESW_INT_FUNC_GPIO273 (MTK_PIN_NO(273) | 0)
++#define MT7623_PIN_273_ESW_INT_FUNC_ESW_INT (MTK_PIN_NO(273) | 1)
++
+ #define MT7623_PIN_274_G2_RXDV_FUNC_GPIO274 (MTK_PIN_NO(274) | 0)
+ #define MT7623_PIN_274_G2_RXDV_FUNC_G2_RXDV (MTK_PIN_NO(274) | 1)
+
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0017-clk-add-hifsys-reset.patch b/target/linux/mediatek/patches-4.4/0017-clk-add-hifsys-reset.patch
new file mode 100644
index 0000000000..fb6e417a46
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0017-clk-add-hifsys-reset.patch
@@ -0,0 +1,54 @@
+From 294cf90337d70ad74edf147180bbeef837298bd0 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 6 Jan 2016 20:06:49 +0100
+Subject: [PATCH 17/53] clk: add hifsys reset
+
+Hi,
+
+small patch to add hifsys reset bits. Maybe you could add it to the next
+version of your patch series. i have teste scpsys and clk on mt7623 today
+and it works well.
+
+thanks,
+ John
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/clk/mediatek/clk-mt2701.c | 2 ++
+ include/dt-bindings/reset-controller/mt2701-resets.h | 9 +++++++++
+ 2 files changed, 11 insertions(+)
+
+diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c
+index 39472e4..0e40bb8 100644
+--- a/drivers/clk/mediatek/clk-mt2701.c
++++ b/drivers/clk/mediatek/clk-mt2701.c
+@@ -1000,6 +1000,8 @@ static void __init mtk_hifsys_init(struct device_node *node)
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
++
++ mtk_register_reset_controller(node, 1, 0x34);
+ }
+ CLK_OF_DECLARE(mtk_hifsys, "mediatek,mt2701-hifsys", mtk_hifsys_init);
+
+diff --git a/include/dt-bindings/reset-controller/mt2701-resets.h b/include/dt-bindings/reset-controller/mt2701-resets.h
+index 00efeb0..aaf0305 100644
+--- a/include/dt-bindings/reset-controller/mt2701-resets.h
++++ b/include/dt-bindings/reset-controller/mt2701-resets.h
+@@ -71,4 +71,13 @@
+ #define MT2701_TOPRGU_CONN_MCU_RST 12
+ #define MT2701_TOPRGU_BDP_DISP_RST 13
+
++/* HIFSYS resets */
++#define MT2701_HIFSYS_UHOST0_RST 3
++#define MT2701_HIFSYS_UHOST1_RST 4
++#define MT2701_HIFSYS_UPHY0_RST 21
++#define MT2701_HIFSYS_UPHY1_RST 22
++#define MT2701_HIFSYS_PCIE0_RST 24
++#define MT2701_HIFSYS_PCIE1_RST 25
++#define MT2701_HIFSYS_PCIE2_RST 26
++
+ #endif /* _DT_BINDINGS_RESET_CONTROLLER_MT2701 */
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0018-dt-bindings-Add-a-binding-for-Mediatek-xHCI-host-con.patch b/target/linux/mediatek/patches-4.4/0018-dt-bindings-Add-a-binding-for-Mediatek-xHCI-host-con.patch
new file mode 100644
index 0000000000..981d71f7ab
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0018-dt-bindings-Add-a-binding-for-Mediatek-xHCI-host-con.patch
@@ -0,0 +1,75 @@
+From 84d37aeef94deae3ce87e677f6016a5d980429e8 Mon Sep 17 00:00:00 2001
+From: "chunfeng.yun@mediatek.com" <chunfeng.yun@mediatek.com>
+Date: Tue, 17 Nov 2015 17:18:39 +0800
+Subject: [PATCH 18/53] dt-bindings: Add a binding for Mediatek xHCI host
+ controller
+
+add a DT binding documentation of xHCI host controller for the
+MT8173 SoC from Mediatek.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+---
+ .../devicetree/bindings/usb/mt8173-xhci.txt | 51 ++++++++++++++++++++
+ 1 file changed, 51 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/usb/mt8173-xhci.txt
+
+diff --git a/Documentation/devicetree/bindings/usb/mt8173-xhci.txt b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt
+new file mode 100644
+index 0000000..a78f20b
+--- /dev/null
++++ b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt
+@@ -0,0 +1,51 @@
++MT8173 xHCI
++
++The device node for Mediatek SOC USB3.0 host controller
++
++Required properties:
++ - compatible : should contain "mediatek,mt8173-xhci"
++ - reg : specifies physical base address and size of the registers,
++ the first one for MAC, the second for IPPC
++ - interrupts : interrupt used by the controller
++ - power-domains : a phandle to USB power domain node to control USB's
++ mtcmos
++ - vusb33-supply : regulator of USB avdd3.3v
++
++ - clocks : a list of phandle + clock-specifier pairs, one for each
++ entry in clock-names
++ - clock-names : must contain
++ "sys_ck": for clock of xHCI MAC
++ "wakeup_deb_p0": for USB wakeup debounce clock of port0
++ "wakeup_deb_p0": for USB wakeup debounce clock of port1
++
++ - phys : a list of phandle + phy specifier pairs
++
++Optional properties:
++ - mediatek,wakeup-src : 1: ip sleep wakeup mode; 2: line state wakeup
++ mode;
++ - mediatek,syscon-wakeup : phandle to syscon used to access USB wakeup
++ control register, it depends on "mediatek,wakeup-src".
++ - vbus-supply : reference to the VBUS regulator;
++ - usb3-lpm-capable : supports USB3.0 LPM
++
++Example:
++usb30: usb@11270000 {
++ compatible = "mediatek,mt8173-xhci";
++ reg = <0 0x11270000 0 0x1000>,
++ <0 0x11280700 0 0x0100>;
++ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_LOW>;
++ power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>;
++ clocks = <&topckgen CLK_TOP_USB30_SEL>,
++ <&pericfg CLK_PERI_USB0>,
++ <&pericfg CLK_PERI_USB1>;
++ clock-names = "sys_ck",
++ "wakeup_deb_p0",
++ "wakeup_deb_p1";
++ phys = <&phy_port0 PHY_TYPE_USB3>,
++ <&phy_port1 PHY_TYPE_USB2>;
++ vusb33-supply = <&mt6397_vusb_reg>;
++ vbus-supply = <&usb_p1_vbus>;
++ usb3-lpm-capable;
++ mediatek,syscon-wakeup = <&pericfg>;
++ mediatek,wakeup-src = <1>;
++};
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0019-xhci-mediatek-support-MTK-xHCI-host-controller.patch b/target/linux/mediatek/patches-4.4/0019-xhci-mediatek-support-MTK-xHCI-host-controller.patch
new file mode 100644
index 0000000000..05e000b5c5
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0019-xhci-mediatek-support-MTK-xHCI-host-controller.patch
@@ -0,0 +1,1547 @@
+From 651d8fff94718c7e48b8a40d7774878eb8ed62ee Mon Sep 17 00:00:00 2001
+From: "chunfeng.yun@mediatek.com" <chunfeng.yun@mediatek.com>
+Date: Tue, 17 Nov 2015 17:18:40 +0800
+Subject: [PATCH 19/53] xhci: mediatek: support MTK xHCI host controller
+
+There some vendor quirks for MTK xhci host controller:
+1. It defines some extra SW scheduling parameters for HW
+ to minimize the scheduling effort for synchronous and
+ interrupt endpoints. The parameters are put into reseved
+ DWs of slot context and endpoint context.
+2. Its IMODI unit for Interrupter Moderation register is
+ 8 times as much as that defined in xHCI spec.
+3. Its TDS in Normal TRB defines a number of packets that
+ remains to be transferred for a TD after processing all
+ Max packets in all previous TRBs.
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Tested-by: Daniel Thompson <daniel.thompson@linaro.org>
+Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
+---
+ drivers/usb/host/Kconfig | 9 +
+ drivers/usb/host/Makefile | 4 +
+ drivers/usb/host/xhci-mtk-sch.c | 415 +++++++++++++++++++++
+ drivers/usb/host/xhci-mtk.c | 763 +++++++++++++++++++++++++++++++++++++++
+ drivers/usb/host/xhci-mtk.h | 162 +++++++++
+ drivers/usb/host/xhci-ring.c | 16 +-
+ drivers/usb/host/xhci.c | 19 +-
+ drivers/usb/host/xhci.h | 1 +
+ 8 files changed, 1383 insertions(+), 6 deletions(-)
+ create mode 100644 drivers/usb/host/xhci-mtk-sch.c
+ create mode 100644 drivers/usb/host/xhci-mtk.c
+ create mode 100644 drivers/usb/host/xhci-mtk.h
+
+diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
+index 3bb0887..daa563f 100644
+--- a/drivers/usb/host/Kconfig
++++ b/drivers/usb/host/Kconfig
+@@ -41,6 +41,15 @@ config USB_XHCI_PLATFORM
+
+ If unsure, say N.
+
++config USB_XHCI_MTK
++ tristate "xHCI support for Mediatek MT65xx"
++ select MFD_SYSCON
++ depends on ARCH_MEDIATEK || COMPILE_TEST
++ ---help---
++ Say 'Y' to enable the support for the xHCI host controller
++ found in Mediatek MT65xx SoCs.
++ If unsure, say N.
++
+ config USB_XHCI_MVEBU
+ tristate "xHCI support for Marvell Armada 375/38x"
+ select USB_XHCI_PLATFORM
+diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
+index e7558ab..65a06b4 100644
+--- a/drivers/usb/host/Makefile
++++ b/drivers/usb/host/Makefile
+@@ -13,6 +13,9 @@ fhci-$(CONFIG_FHCI_DEBUG) += fhci-dbg.o
+ xhci-hcd-y := xhci.o xhci-mem.o
+ xhci-hcd-y += xhci-ring.o xhci-hub.o xhci-dbg.o
+ xhci-hcd-y += xhci-trace.o
++ifneq ($(CONFIG_USB_XHCI_MTK), )
++ xhci-hcd-y += xhci-mtk-sch.o
++endif
+
+ xhci-plat-hcd-y := xhci-plat.o
+ ifneq ($(CONFIG_USB_XHCI_MVEBU), )
+@@ -64,6 +67,7 @@ obj-$(CONFIG_USB_FHCI_HCD) += fhci.o
+ obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o
+ obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o
+ obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o
++obj-$(CONFIG_USB_XHCI_MTK) += xhci-mtk.o
+ obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o
+ obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o
+ obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o
+diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
+new file mode 100644
+index 0000000..c30de7c
+--- /dev/null
++++ b/drivers/usb/host/xhci-mtk-sch.c
+@@ -0,0 +1,415 @@
++/*
++ * Copyright (c) 2015 MediaTek Inc.
++ * Author:
++ * Zhigang.Wei <zhigang.wei@mediatek.com>
++ * Chunfeng.Yun <chunfeng.yun@mediatek.com>
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++
++#include "xhci.h"
++#include "xhci-mtk.h"
++
++#define SS_BW_BOUNDARY 51000
++/* table 5-5. High-speed Isoc Transaction Limits in usb_20 spec */
++#define HS_BW_BOUNDARY 6144
++/* usb2 spec section11.18.1: at most 188 FS bytes per microframe */
++#define FS_PAYLOAD_MAX 188
++
++/* mtk scheduler bitmasks */
++#define EP_BPKTS(p) ((p) & 0x3f)
++#define EP_BCSCOUNT(p) (((p) & 0x7) << 8)
++#define EP_BBM(p) ((p) << 11)
++#define EP_BOFFSET(p) ((p) & 0x3fff)
++#define EP_BREPEAT(p) (((p) & 0x7fff) << 16)
++
++static int is_fs_or_ls(enum usb_device_speed speed)
++{
++ return speed == USB_SPEED_FULL || speed == USB_SPEED_LOW;
++}
++
++/*
++* get the index of bandwidth domains array which @ep belongs to.
++*
++* the bandwidth domain array is saved to @sch_array of struct xhci_hcd_mtk,
++* each HS root port is treated as a single bandwidth domain,
++* but each SS root port is treated as two bandwidth domains, one for IN eps,
++* one for OUT eps.
++* @real_port value is defined as follow according to xHCI spec:
++* 1 for SSport0, ..., N+1 for SSportN, N+2 for HSport0, N+3 for HSport1, etc
++* so the bandwidth domain array is organized as follow for simplification:
++* SSport0-OUT, SSport0-IN, ..., SSportX-OUT, SSportX-IN, HSport0, ..., HSportY
++*/
++static int get_bw_index(struct xhci_hcd *xhci, struct usb_device *udev,
++ struct usb_host_endpoint *ep)
++{
++ struct xhci_virt_device *virt_dev;
++ int bw_index;
++
++ virt_dev = xhci->devs[udev->slot_id];
++
++ if (udev->speed == USB_SPEED_SUPER) {
++ if (usb_endpoint_dir_out(&ep->desc))
++ bw_index = (virt_dev->real_port - 1) * 2;
++ else
++ bw_index = (virt_dev->real_port - 1) * 2 + 1;
++ } else {
++ /* add one more for each SS port */
++ bw_index = virt_dev->real_port + xhci->num_usb3_ports - 1;
++ }
++
++ return bw_index;
++}
++
++static void setup_sch_info(struct usb_device *udev,
++ struct xhci_ep_ctx *ep_ctx, struct mu3h_sch_ep_info *sch_ep)
++{
++ u32 ep_type;
++ u32 ep_interval;
++ u32 max_packet_size;
++ u32 max_burst;
++ u32 mult;
++ u32 esit_pkts;
++
++ ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2));
++ ep_interval = CTX_TO_EP_INTERVAL(le32_to_cpu(ep_ctx->ep_info));
++ max_packet_size = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2));
++ max_burst = CTX_TO_MAX_BURST(le32_to_cpu(ep_ctx->ep_info2));
++ mult = CTX_TO_EP_MULT(le32_to_cpu(ep_ctx->ep_info));
++
++ sch_ep->esit = 1 << ep_interval;
++ sch_ep->offset = 0;
++ sch_ep->burst_mode = 0;
++
++ if (udev->speed == USB_SPEED_HIGH) {
++ sch_ep->cs_count = 0;
++
++ /*
++ * usb_20 spec section5.9
++ * a single microframe is enough for HS synchromous endpoints
++ * in a interval
++ */
++ sch_ep->num_budget_microframes = 1;
++ sch_ep->repeat = 0;
++
++ /*
++ * xHCI spec section6.2.3.4
++ * @max_burst is the number of additional transactions
++ * opportunities per microframe
++ */
++ sch_ep->pkts = max_burst + 1;
++ sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts;
++ } else if (udev->speed == USB_SPEED_SUPER) {
++ /* usb3_r1 spec section4.4.7 & 4.4.8 */
++ sch_ep->cs_count = 0;
++ esit_pkts = (mult + 1) * (max_burst + 1);
++ if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) {
++ sch_ep->pkts = esit_pkts;
++ sch_ep->num_budget_microframes = 1;
++ sch_ep->repeat = 0;
++ }
++
++ if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) {
++ if (esit_pkts <= sch_ep->esit)
++ sch_ep->pkts = 1;
++ else
++ sch_ep->pkts = roundup_pow_of_two(esit_pkts)
++ / sch_ep->esit;
++
++ sch_ep->num_budget_microframes =
++ DIV_ROUND_UP(esit_pkts, sch_ep->pkts);
++
++ if (sch_ep->num_budget_microframes > 1)
++ sch_ep->repeat = 1;
++ else
++ sch_ep->repeat = 0;
++ }
++ sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts;
++ } else if (is_fs_or_ls(udev->speed)) {
++
++ /*
++ * usb_20 spec section11.18.4
++ * assume worst cases
++ */
++ sch_ep->repeat = 0;
++ sch_ep->pkts = 1; /* at most one packet for each microframe */
++ if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) {
++ sch_ep->cs_count = 3; /* at most need 3 CS*/
++ /* one for SS and one for budgeted transaction */
++ sch_ep->num_budget_microframes = sch_ep->cs_count + 2;
++ sch_ep->bw_cost_per_microframe = max_packet_size;
++ }
++ if (ep_type == ISOC_OUT_EP) {
++
++ /*
++ * the best case FS budget assumes that 188 FS bytes
++ * occur in each microframe
++ */
++ sch_ep->num_budget_microframes = DIV_ROUND_UP(
++ max_packet_size, FS_PAYLOAD_MAX);
++ sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX;
++ sch_ep->cs_count = sch_ep->num_budget_microframes;
++ }
++ if (ep_type == ISOC_IN_EP) {
++ /* at most need additional two CS. */
++ sch_ep->cs_count = DIV_ROUND_UP(
++ max_packet_size, FS_PAYLOAD_MAX) + 2;
++ sch_ep->num_budget_microframes = sch_ep->cs_count + 2;
++ sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX;
++ }
++ }
++}
++
++/* Get maximum bandwidth when we schedule at offset slot. */
++static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
++ struct mu3h_sch_ep_info *sch_ep, u32 offset)
++{
++ u32 num_esit;
++ u32 max_bw = 0;
++ int i;
++ int j;
++
++ num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
++ for (i = 0; i < num_esit; i++) {
++ u32 base = offset + i * sch_ep->esit;
++
++ for (j = 0; j < sch_ep->num_budget_microframes; j++) {
++ if (sch_bw->bus_bw[base + j] > max_bw)
++ max_bw = sch_bw->bus_bw[base + j];
++ }
++ }
++ return max_bw;
++}
++
++static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
++ struct mu3h_sch_ep_info *sch_ep, int bw_cost)
++{
++ u32 num_esit;
++ u32 base;
++ int i;
++ int j;
++
++ num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
++ for (i = 0; i < num_esit; i++) {
++ base = sch_ep->offset + i * sch_ep->esit;
++ for (j = 0; j < sch_ep->num_budget_microframes; j++)
++ sch_bw->bus_bw[base + j] += bw_cost;
++ }
++}
++
++static int check_sch_bw(struct usb_device *udev,
++ struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep)
++{
++ u32 offset;
++ u32 esit;
++ u32 num_budget_microframes;
++ u32 min_bw;
++ u32 min_index;
++ u32 worst_bw;
++ u32 bw_boundary;
++
++ if (sch_ep->esit > XHCI_MTK_MAX_ESIT)
++ sch_ep->esit = XHCI_MTK_MAX_ESIT;
++
++ esit = sch_ep->esit;
++ num_budget_microframes = sch_ep->num_budget_microframes;
++
++ /*
++ * Search through all possible schedule microframes.
++ * and find a microframe where its worst bandwidth is minimum.
++ */
++ min_bw = ~0;
++ min_index = 0;
++ for (offset = 0; offset < esit; offset++) {
++ if ((offset + num_budget_microframes) > sch_ep->esit)
++ break;
++
++ /*
++ * usb_20 spec section11.18:
++ * must never schedule Start-Split in Y6
++ */
++ if (is_fs_or_ls(udev->speed) && (offset % 8 == 6))
++ continue;
++
++ worst_bw = get_max_bw(sch_bw, sch_ep, offset);
++ if (min_bw > worst_bw) {
++ min_bw = worst_bw;
++ min_index = offset;
++ }
++ if (min_bw == 0)
++ break;
++ }
++ sch_ep->offset = min_index;
++
++ bw_boundary = (udev->speed == USB_SPEED_SUPER)
++ ? SS_BW_BOUNDARY : HS_BW_BOUNDARY;
++
++ /* check bandwidth */
++ if (min_bw + sch_ep->bw_cost_per_microframe > bw_boundary)
++ return -ERANGE;
++
++ /* update bus bandwidth info */
++ update_bus_bw(sch_bw, sch_ep, sch_ep->bw_cost_per_microframe);
++
++ return 0;
++}
++
++static bool need_bw_sch(struct usb_host_endpoint *ep,
++ enum usb_device_speed speed, int has_tt)
++{
++ /* only for periodic endpoints */
++ if (usb_endpoint_xfer_control(&ep->desc)
++ || usb_endpoint_xfer_bulk(&ep->desc))
++ return false;
++
++ /*
++ * for LS & FS periodic endpoints which its device don't attach
++ * to TT are also ignored, root-hub will schedule them directly
++ */
++ if (is_fs_or_ls(speed) && !has_tt)
++ return false;
++
++ return true;
++}
++
++int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk)
++{
++ struct mu3h_sch_bw_info *sch_array;
++ int num_usb_bus;
++ int i;
++
++ /* ss IN and OUT are separated */
++ num_usb_bus = mtk->num_u3_ports * 2 + mtk->num_u2_ports;
++
++ sch_array = kcalloc(num_usb_bus, sizeof(*sch_array), GFP_KERNEL);
++ if (sch_array == NULL)
++ return -ENOMEM;
++
++ for (i = 0; i < num_usb_bus; i++)
++ INIT_LIST_HEAD(&sch_array[i].bw_ep_list);
++
++ mtk->sch_array = sch_array;
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(xhci_mtk_sch_init);
++
++void xhci_mtk_sch_exit(struct xhci_hcd_mtk *mtk)
++{
++ kfree(mtk->sch_array);
++}
++EXPORT_SYMBOL_GPL(xhci_mtk_sch_exit);
++
++int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
++ struct usb_host_endpoint *ep)
++{
++ struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
++ struct xhci_hcd *xhci;
++ struct xhci_ep_ctx *ep_ctx;
++ struct xhci_slot_ctx *slot_ctx;
++ struct xhci_virt_device *virt_dev;
++ struct mu3h_sch_bw_info *sch_bw;
++ struct mu3h_sch_ep_info *sch_ep;
++ struct mu3h_sch_bw_info *sch_array;
++ unsigned int ep_index;
++ int bw_index;
++ int ret = 0;
++
++ xhci = hcd_to_xhci(hcd);
++ virt_dev = xhci->devs[udev->slot_id];
++ ep_index = xhci_get_endpoint_index(&ep->desc);
++ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
++ ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
++ sch_array = mtk->sch_array;
++
++ xhci_dbg(xhci, "%s() type:%d, speed:%d, mpkt:%d, dir:%d, ep:%p\n",
++ __func__, usb_endpoint_type(&ep->desc), udev->speed,
++ GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)),
++ usb_endpoint_dir_in(&ep->desc), ep);
++
++ if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT))
++ return 0;
++
++ bw_index = get_bw_index(xhci, udev, ep);
++ sch_bw = &sch_array[bw_index];
++
++ sch_ep = kzalloc(sizeof(struct mu3h_sch_ep_info), GFP_NOIO);
++ if (!sch_ep)
++ return -ENOMEM;
++
++ setup_sch_info(udev, ep_ctx, sch_ep);
++
++ ret = check_sch_bw(udev, sch_bw, sch_ep);
++ if (ret) {
++ xhci_err(xhci, "Not enough bandwidth!\n");
++ kfree(sch_ep);
++ return -ENOSPC;
++ }
++
++ list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list);
++ sch_ep->ep = ep;
++
++ ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts)
++ | EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode));
++ ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset)
++ | EP_BREPEAT(sch_ep->repeat));
++
++ xhci_dbg(xhci, " PKTS:%x, CSCOUNT:%x, BM:%x, OFFSET:%x, REPEAT:%x\n",
++ sch_ep->pkts, sch_ep->cs_count, sch_ep->burst_mode,
++ sch_ep->offset, sch_ep->repeat);
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk);
++
++void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
++ struct usb_host_endpoint *ep)
++{
++ struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
++ struct xhci_hcd *xhci;
++ struct xhci_slot_ctx *slot_ctx;
++ struct xhci_virt_device *virt_dev;
++ struct mu3h_sch_bw_info *sch_array;
++ struct mu3h_sch_bw_info *sch_bw;
++ struct mu3h_sch_ep_info *sch_ep;
++ int bw_index;
++
++ xhci = hcd_to_xhci(hcd);
++ virt_dev = xhci->devs[udev->slot_id];
++ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
++ sch_array = mtk->sch_array;
++
++ xhci_dbg(xhci, "%s() type:%d, speed:%d, mpks:%d, dir:%d, ep:%p\n",
++ __func__, usb_endpoint_type(&ep->desc), udev->speed,
++ GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)),
++ usb_endpoint_dir_in(&ep->desc), ep);
++
++ if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT))
++ return;
++
++ bw_index = get_bw_index(xhci, udev, ep);
++ sch_bw = &sch_array[bw_index];
++
++ list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) {
++ if (sch_ep->ep == ep) {
++ update_bus_bw(sch_bw, sch_ep,
++ -sch_ep->bw_cost_per_microframe);
++ list_del(&sch_ep->endpoint);
++ kfree(sch_ep);
++ break;
++ }
++ }
++}
++EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk);
+diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
+new file mode 100644
+index 0000000..c9ab6a4
+--- /dev/null
++++ b/drivers/usb/host/xhci-mtk.c
+@@ -0,0 +1,763 @@
++/*
++ * MediaTek xHCI Host Controller Driver
++ *
++ * Copyright (c) 2015 MediaTek Inc.
++ * Author:
++ * Chunfeng Yun <chunfeng.yun@mediatek.com>
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/dma-mapping.h>
++#include <linux/iopoll.h>
++#include <linux/kernel.h>
++#include <linux/mfd/syscon.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/regmap.h>
++#include <linux/regulator/consumer.h>
++
++#include "xhci.h"
++#include "xhci-mtk.h"
++
++/* ip_pw_ctrl0 register */
++#define CTRL0_IP_SW_RST BIT(0)
++
++/* ip_pw_ctrl1 register */
++#define CTRL1_IP_HOST_PDN BIT(0)
++
++/* ip_pw_ctrl2 register */
++#define CTRL2_IP_DEV_PDN BIT(0)
++
++/* ip_pw_sts1 register */
++#define STS1_IP_SLEEP_STS BIT(30)
++#define STS1_XHCI_RST BIT(11)
++#define STS1_SYS125_RST BIT(10)
++#define STS1_REF_RST BIT(8)
++#define STS1_SYSPLL_STABLE BIT(0)
++
++/* ip_xhci_cap register */
++#define CAP_U3_PORT_NUM(p) ((p) & 0xff)
++#define CAP_U2_PORT_NUM(p) (((p) >> 8) & 0xff)
++
++/* u3_ctrl_p register */
++#define CTRL_U3_PORT_HOST_SEL BIT(2)
++#define CTRL_U3_PORT_PDN BIT(1)
++#define CTRL_U3_PORT_DIS BIT(0)
++
++/* u2_ctrl_p register */
++#define CTRL_U2_PORT_HOST_SEL BIT(2)
++#define CTRL_U2_PORT_PDN BIT(1)
++#define CTRL_U2_PORT_DIS BIT(0)
++
++/* u2_phy_pll register */
++#define CTRL_U2_FORCE_PLL_STB BIT(28)
++
++#define PERI_WK_CTRL0 0x400
++#define UWK_CTR0_0P_LS_PE BIT(8) /* posedge */
++#define UWK_CTR0_0P_LS_NE BIT(7) /* negedge for 0p linestate*/
++#define UWK_CTL1_1P_LS_C(x) (((x) & 0xf) << 1)
++#define UWK_CTL1_1P_LS_E BIT(0)
++
++#define PERI_WK_CTRL1 0x404
++#define UWK_CTL1_IS_C(x) (((x) & 0xf) << 26)
++#define UWK_CTL1_IS_E BIT(25)
++#define UWK_CTL1_0P_LS_C(x) (((x) & 0xf) << 21)
++#define UWK_CTL1_0P_LS_E BIT(20)
++#define UWK_CTL1_IDDIG_C(x) (((x) & 0xf) << 11) /* cycle debounce */
++#define UWK_CTL1_IDDIG_E BIT(10) /* enable debounce */
++#define UWK_CTL1_IDDIG_P BIT(9) /* polarity */
++#define UWK_CTL1_0P_LS_P BIT(7)
++#define UWK_CTL1_IS_P BIT(6) /* polarity for ip sleep */
++
++enum ssusb_wakeup_src {
++ SSUSB_WK_IP_SLEEP = 1,
++ SSUSB_WK_LINE_STATE = 2,
++};
++
++static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
++{
++ struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs;
++ u32 value, check_val;
++ int ret;
++ int i;
++
++ /* power on host ip */
++ value = readl(&ippc->ip_pw_ctr1);
++ value &= ~CTRL1_IP_HOST_PDN;
++ writel(value, &ippc->ip_pw_ctr1);
++
++ /* power on and enable all u3 ports */
++ for (i = 0; i < mtk->num_u3_ports; i++) {
++ value = readl(&ippc->u3_ctrl_p[i]);
++ value &= ~(CTRL_U3_PORT_PDN | CTRL_U3_PORT_DIS);
++ value |= CTRL_U3_PORT_HOST_SEL;
++ writel(value, &ippc->u3_ctrl_p[i]);
++ }
++
++ /* power on and enable all u2 ports */
++ for (i = 0; i < mtk->num_u2_ports; i++) {
++ value = readl(&ippc->u2_ctrl_p[i]);
++ value &= ~(CTRL_U2_PORT_PDN | CTRL_U2_PORT_DIS);
++ value |= CTRL_U2_PORT_HOST_SEL;
++ writel(value, &ippc->u2_ctrl_p[i]);
++ }
++
++ /*
++ * wait for clocks to be stable, and clock domains reset to
++ * be inactive after power on and enable ports
++ */
++ check_val = STS1_SYSPLL_STABLE | STS1_REF_RST |
++ STS1_SYS125_RST | STS1_XHCI_RST;
++
++ ret = readl_poll_timeout(&ippc->ip_pw_sts1, value,
++ (check_val == (value & check_val)), 100, 20000);
++ if (ret) {
++ dev_err(mtk->dev, "clocks are not stable (0x%x)\n", value);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int xhci_mtk_host_disable(struct xhci_hcd_mtk *mtk)
++{
++ struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs;
++ u32 value;
++ int ret;
++ int i;
++
++ /* power down all u3 ports */
++ for (i = 0; i < mtk->num_u3_ports; i++) {
++ value = readl(&ippc->u3_ctrl_p[i]);
++ value |= CTRL_U3_PORT_PDN;
++ writel(value, &ippc->u3_ctrl_p[i]);
++ }
++
++ /* power down all u2 ports */
++ for (i = 0; i < mtk->num_u2_ports; i++) {
++ value = readl(&ippc->u2_ctrl_p[i]);
++ value |= CTRL_U2_PORT_PDN;
++ writel(value, &ippc->u2_ctrl_p[i]);
++ }
++
++ /* power down host ip */
++ value = readl(&ippc->ip_pw_ctr1);
++ value |= CTRL1_IP_HOST_PDN;
++ writel(value, &ippc->ip_pw_ctr1);
++
++ /* wait for host ip to sleep */
++ ret = readl_poll_timeout(&ippc->ip_pw_sts1, value,
++ (value & STS1_IP_SLEEP_STS), 100, 100000);
++ if (ret) {
++ dev_err(mtk->dev, "ip sleep failed!!!\n");
++ return ret;
++ }
++ return 0;
++}
++
++static int xhci_mtk_ssusb_config(struct xhci_hcd_mtk *mtk)
++{
++ struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs;
++ u32 value;
++
++ /* reset whole ip */
++ value = readl(&ippc->ip_pw_ctr0);
++ value |= CTRL0_IP_SW_RST;
++ writel(value, &ippc->ip_pw_ctr0);
++ udelay(1);
++ value = readl(&ippc->ip_pw_ctr0);
++ value &= ~CTRL0_IP_SW_RST;
++ writel(value, &ippc->ip_pw_ctr0);
++
++ /*
++ * device ip is default power-on in fact
++ * power down device ip, otherwise ip-sleep will fail
++ */
++ value = readl(&ippc->ip_pw_ctr2);
++ value |= CTRL2_IP_DEV_PDN;
++ writel(value, &ippc->ip_pw_ctr2);
++
++ value = readl(&ippc->ip_xhci_cap);
++ mtk->num_u3_ports = CAP_U3_PORT_NUM(value);
++ mtk->num_u2_ports = CAP_U2_PORT_NUM(value);
++ dev_dbg(mtk->dev, "%s u2p:%d, u3p:%d\n", __func__,
++ mtk->num_u2_ports, mtk->num_u3_ports);
++
++ return xhci_mtk_host_enable(mtk);
++}
++
++static int xhci_mtk_clks_enable(struct xhci_hcd_mtk *mtk)
++{
++ int ret;
++
++ ret = clk_prepare_enable(mtk->sys_clk);
++ if (ret) {
++ dev_err(mtk->dev, "failed to enable sys_clk\n");
++ goto sys_clk_err;
++ }
++
++ if (mtk->wakeup_src) {
++ ret = clk_prepare_enable(mtk->wk_deb_p0);
++ if (ret) {
++ dev_err(mtk->dev, "failed to enable wk_deb_p0\n");
++ goto usb_p0_err;
++ }
++
++ ret = clk_prepare_enable(mtk->wk_deb_p1);
++ if (ret) {
++ dev_err(mtk->dev, "failed to enable wk_deb_p1\n");
++ goto usb_p1_err;
++ }
++ }
++ return 0;
++
++usb_p1_err:
++ clk_disable_unprepare(mtk->wk_deb_p0);
++usb_p0_err:
++ clk_disable_unprepare(mtk->sys_clk);
++sys_clk_err:
++ return -EINVAL;
++}
++
++static void xhci_mtk_clks_disable(struct xhci_hcd_mtk *mtk)
++{
++ if (mtk->wakeup_src) {
++ clk_disable_unprepare(mtk->wk_deb_p1);
++ clk_disable_unprepare(mtk->wk_deb_p0);
++ }
++ clk_disable_unprepare(mtk->sys_clk);
++}
++
++/* only clocks can be turn off for ip-sleep wakeup mode */
++static void usb_wakeup_ip_sleep_en(struct xhci_hcd_mtk *mtk)
++{
++ u32 tmp;
++ struct regmap *pericfg = mtk->pericfg;
++
++ regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
++ tmp &= ~UWK_CTL1_IS_P;
++ tmp &= ~(UWK_CTL1_IS_C(0xf));
++ tmp |= UWK_CTL1_IS_C(0x8);
++ regmap_write(pericfg, PERI_WK_CTRL1, tmp);
++ regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_IS_E);
++
++ regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
++ dev_dbg(mtk->dev, "%s(): WK_CTRL1[P6,E25,C26:29]=%#x\n",
++ __func__, tmp);
++}
++
++static void usb_wakeup_ip_sleep_dis(struct xhci_hcd_mtk *mtk)
++{
++ u32 tmp;
++
++ regmap_read(mtk->pericfg, PERI_WK_CTRL1, &tmp);
++ tmp &= ~UWK_CTL1_IS_E;
++ regmap_write(mtk->pericfg, PERI_WK_CTRL1, tmp);
++}
++
++/*
++* for line-state wakeup mode, phy's power should not power-down
++* and only support cable plug in/out
++*/
++static void usb_wakeup_line_state_en(struct xhci_hcd_mtk *mtk)
++{
++ u32 tmp;
++ struct regmap *pericfg = mtk->pericfg;
++
++ /* line-state of u2-port0 */
++ regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
++ tmp &= ~UWK_CTL1_0P_LS_P;
++ tmp &= ~(UWK_CTL1_0P_LS_C(0xf));
++ tmp |= UWK_CTL1_0P_LS_C(0x8);
++ regmap_write(pericfg, PERI_WK_CTRL1, tmp);
++ regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
++ regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_0P_LS_E);
++
++ /* line-state of u2-port1 */
++ regmap_read(pericfg, PERI_WK_CTRL0, &tmp);
++ tmp &= ~(UWK_CTL1_1P_LS_C(0xf));
++ tmp |= UWK_CTL1_1P_LS_C(0x8);
++ regmap_write(pericfg, PERI_WK_CTRL0, tmp);
++ regmap_write(pericfg, PERI_WK_CTRL0, tmp | UWK_CTL1_1P_LS_E);
++}
++
++static void usb_wakeup_line_state_dis(struct xhci_hcd_mtk *mtk)
++{
++ u32 tmp;
++ struct regmap *pericfg = mtk->pericfg;
++
++ /* line-state of u2-port0 */
++ regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
++ tmp &= ~UWK_CTL1_0P_LS_E;
++ regmap_write(pericfg, PERI_WK_CTRL1, tmp);
++
++ /* line-state of u2-port1 */
++ regmap_read(pericfg, PERI_WK_CTRL0, &tmp);
++ tmp &= ~UWK_CTL1_1P_LS_E;
++ regmap_write(pericfg, PERI_WK_CTRL0, tmp);
++}
++
++static void usb_wakeup_enable(struct xhci_hcd_mtk *mtk)
++{
++ if (mtk->wakeup_src == SSUSB_WK_IP_SLEEP)
++ usb_wakeup_ip_sleep_en(mtk);
++ else if (mtk->wakeup_src == SSUSB_WK_LINE_STATE)
++ usb_wakeup_line_state_en(mtk);
++}
++
++static void usb_wakeup_disable(struct xhci_hcd_mtk *mtk)
++{
++ if (mtk->wakeup_src == SSUSB_WK_IP_SLEEP)
++ usb_wakeup_ip_sleep_dis(mtk);
++ else if (mtk->wakeup_src == SSUSB_WK_LINE_STATE)
++ usb_wakeup_line_state_dis(mtk);
++}
++
++static int usb_wakeup_of_property_parse(struct xhci_hcd_mtk *mtk,
++ struct device_node *dn)
++{
++ struct device *dev = mtk->dev;
++
++ /*
++ * wakeup function is optional, so it is not an error if this property
++ * does not exist, and in such case, no need to get relative
++ * properties anymore.
++ */
++ of_property_read_u32(dn, "mediatek,wakeup-src", &mtk->wakeup_src);
++ if (!mtk->wakeup_src)
++ return 0;
++
++ mtk->wk_deb_p0 = devm_clk_get(dev, "wakeup_deb_p0");
++ if (IS_ERR(mtk->wk_deb_p0)) {
++ dev_err(dev, "fail to get wakeup_deb_p0\n");
++ return PTR_ERR(mtk->wk_deb_p0);
++ }
++
++ mtk->wk_deb_p1 = devm_clk_get(dev, "wakeup_deb_p1");
++ if (IS_ERR(mtk->wk_deb_p1)) {
++ dev_err(dev, "fail to get wakeup_deb_p1\n");
++ return PTR_ERR(mtk->wk_deb_p1);
++ }
++
++ mtk->pericfg = syscon_regmap_lookup_by_phandle(dn,
++ "mediatek,syscon-wakeup");
++ if (IS_ERR(mtk->pericfg)) {
++ dev_err(dev, "fail to get pericfg regs\n");
++ return PTR_ERR(mtk->pericfg);
++ }
++
++ return 0;
++}
++
++static int xhci_mtk_setup(struct usb_hcd *hcd);
++static const struct xhci_driver_overrides xhci_mtk_overrides __initconst = {
++ .extra_priv_size = sizeof(struct xhci_hcd),
++ .reset = xhci_mtk_setup,
++};
++
++static struct hc_driver __read_mostly xhci_mtk_hc_driver;
++
++static int xhci_mtk_phy_init(struct xhci_hcd_mtk *mtk)
++{
++ int i;
++ int ret;
++
++ for (i = 0; i < mtk->num_phys; i++) {
++ ret = phy_init(mtk->phys[i]);
++ if (ret)
++ goto exit_phy;
++ }
++ return 0;
++
++exit_phy:
++ for (; i > 0; i--)
++ phy_exit(mtk->phys[i - 1]);
++
++ return ret;
++}
++
++static int xhci_mtk_phy_exit(struct xhci_hcd_mtk *mtk)
++{
++ int i;
++
++ for (i = 0; i < mtk->num_phys; i++)
++ phy_exit(mtk->phys[i]);
++
++ return 0;
++}
++
++static int xhci_mtk_phy_power_on(struct xhci_hcd_mtk *mtk)
++{
++ int i;
++ int ret;
++
++ for (i = 0; i < mtk->num_phys; i++) {
++ ret = phy_power_on(mtk->phys[i]);
++ if (ret)
++ goto power_off_phy;
++ }
++ return 0;
++
++power_off_phy:
++ for (; i > 0; i--)
++ phy_power_off(mtk->phys[i - 1]);
++
++ return ret;
++}
++
++static void xhci_mtk_phy_power_off(struct xhci_hcd_mtk *mtk)
++{
++ unsigned int i;
++
++ for (i = 0; i < mtk->num_phys; i++)
++ phy_power_off(mtk->phys[i]);
++}
++
++static int xhci_mtk_ldos_enable(struct xhci_hcd_mtk *mtk)
++{
++ int ret;
++
++ ret = regulator_enable(mtk->vbus);
++ if (ret) {
++ dev_err(mtk->dev, "failed to enable vbus\n");
++ return ret;
++ }
++
++ ret = regulator_enable(mtk->vusb33);
++ if (ret) {
++ dev_err(mtk->dev, "failed to enable vusb33\n");
++ regulator_disable(mtk->vbus);
++ return ret;
++ }
++ return 0;
++}
++
++static void xhci_mtk_ldos_disable(struct xhci_hcd_mtk *mtk)
++{
++ regulator_disable(mtk->vbus);
++ regulator_disable(mtk->vusb33);
++}
++
++static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd *xhci)
++{
++ struct usb_hcd *hcd = xhci_to_hcd(xhci);
++ struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
++
++ /*
++ * As of now platform drivers don't provide MSI support so we ensure
++ * here that the generic code does not try to make a pci_dev from our
++ * dev struct in order to setup MSI
++ */
++ xhci->quirks |= XHCI_PLAT;
++ xhci->quirks |= XHCI_MTK_HOST;
++ /*
++ * MTK host controller gives a spurious successful event after a
++ * short transfer. Ignore it.
++ */
++ xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
++ if (mtk->lpm_support)
++ xhci->quirks |= XHCI_LPM_SUPPORT;
++}
++
++/* called during probe() after chip reset completes */
++static int xhci_mtk_setup(struct usb_hcd *hcd)
++{
++ struct xhci_hcd_mtk *mtk = hcd_to_mtk(hcd);
++ int ret;
++
++ if (usb_hcd_is_primary_hcd(hcd)) {
++ ret = xhci_mtk_ssusb_config(mtk);
++ if (ret)
++ return ret;
++ ret = xhci_mtk_sch_init(mtk);
++ if (ret)
++ return ret;
++ }
++
++ return xhci_gen_setup(hcd, xhci_mtk_quirks);
++}
++
++static int xhci_mtk_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct device_node *node = dev->of_node;
++ struct xhci_hcd_mtk *mtk;
++ const struct hc_driver *driver;
++ struct xhci_hcd *xhci;
++ struct resource *res;
++ struct usb_hcd *hcd;
++ struct phy *phy;
++ int phy_num;
++ int ret = -ENODEV;
++ int irq;
++
++ if (usb_disabled())
++ return -ENODEV;
++
++ driver = &xhci_mtk_hc_driver;
++ mtk = devm_kzalloc(dev, sizeof(*mtk), GFP_KERNEL);
++ if (!mtk)
++ return -ENOMEM;
++
++ mtk->dev = dev;
++ mtk->vbus = devm_regulator_get(dev, "vbus");
++ if (IS_ERR(mtk->vbus)) {
++ dev_err(dev, "fail to get vbus\n");
++ return PTR_ERR(mtk->vbus);
++ }
++
++ mtk->vusb33 = devm_regulator_get(dev, "vusb33");
++ if (IS_ERR(mtk->vusb33)) {
++ dev_err(dev, "fail to get vusb33\n");
++ return PTR_ERR(mtk->vusb33);
++ }
++
++ mtk->sys_clk = devm_clk_get(dev, "sys_ck");
++ if (IS_ERR(mtk->sys_clk)) {
++ dev_err(dev, "fail to get sys_ck\n");
++ return PTR_ERR(mtk->sys_clk);
++ }
++
++ mtk->lpm_support = of_property_read_bool(node, "usb3-lpm-capable");
++
++ ret = usb_wakeup_of_property_parse(mtk, node);
++ if (ret)
++ return ret;
++
++ mtk->num_phys = of_count_phandle_with_args(node,
++ "phys", "#phy-cells");
++ if (mtk->num_phys > 0) {
++ mtk->phys = devm_kcalloc(dev, mtk->num_phys,
++ sizeof(*mtk->phys), GFP_KERNEL);
++ if (!mtk->phys)
++ return -ENOMEM;
++ } else {
++ mtk->num_phys = 0;
++ }
++ pm_runtime_enable(dev);
++ pm_runtime_get_sync(dev);
++ device_enable_async_suspend(dev);
++
++ ret = xhci_mtk_ldos_enable(mtk);
++ if (ret)
++ goto disable_pm;
++
++ ret = xhci_mtk_clks_enable(mtk);
++ if (ret)
++ goto disable_ldos;
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0)
++ goto disable_clk;
++
++ /* Initialize dma_mask and coherent_dma_mask to 32-bits */
++ ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
++ if (ret)
++ goto disable_clk;
++
++ if (!dev->dma_mask)
++ dev->dma_mask = &dev->coherent_dma_mask;
++ else
++ dma_set_mask(dev, DMA_BIT_MASK(32));
++
++ hcd = usb_create_hcd(driver, dev, dev_name(dev));
++ if (!hcd) {
++ ret = -ENOMEM;
++ goto disable_clk;
++ }
++
++ /*
++ * USB 2.0 roothub is stored in the platform_device.
++ * Swap it with mtk HCD.
++ */
++ mtk->hcd = platform_get_drvdata(pdev);
++ platform_set_drvdata(pdev, mtk);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ hcd->regs = devm_ioremap_resource(dev, res);
++ if (IS_ERR(hcd->regs)) {
++ ret = PTR_ERR(hcd->regs);
++ goto put_usb2_hcd;
++ }
++ hcd->rsrc_start = res->start;
++ hcd->rsrc_len = resource_size(res);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++ mtk->ippc_regs = devm_ioremap_resource(dev, res);
++ if (IS_ERR(mtk->ippc_regs)) {
++ ret = PTR_ERR(mtk->ippc_regs);
++ goto put_usb2_hcd;
++ }
++
++ for (phy_num = 0; phy_num < mtk->num_phys; phy_num++) {
++ phy = devm_of_phy_get_by_index(dev, node, phy_num);
++ if (IS_ERR(phy)) {
++ ret = PTR_ERR(phy);
++ goto put_usb2_hcd;
++ }
++ mtk->phys[phy_num] = phy;
++ }
++
++ ret = xhci_mtk_phy_init(mtk);
++ if (ret)
++ goto put_usb2_hcd;
++
++ ret = xhci_mtk_phy_power_on(mtk);
++ if (ret)
++ goto exit_phys;
++
++ device_init_wakeup(dev, true);
++
++ xhci = hcd_to_xhci(hcd);
++ xhci->main_hcd = hcd;
++ xhci->shared_hcd = usb_create_shared_hcd(driver, dev,
++ dev_name(dev), hcd);
++ if (!xhci->shared_hcd) {
++ ret = -ENOMEM;
++ goto power_off_phys;
++ }
++
++ if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
++ xhci->shared_hcd->can_do_streams = 1;
++
++ ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
++ if (ret)
++ goto put_usb3_hcd;
++
++ ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
++ if (ret)
++ goto dealloc_usb2_hcd;
++
++ return 0;
++
++dealloc_usb2_hcd:
++ usb_remove_hcd(hcd);
++
++put_usb3_hcd:
++ xhci_mtk_sch_exit(mtk);
++ usb_put_hcd(xhci->shared_hcd);
++
++power_off_phys:
++ xhci_mtk_phy_power_off(mtk);
++ device_init_wakeup(dev, false);
++
++exit_phys:
++ xhci_mtk_phy_exit(mtk);
++
++put_usb2_hcd:
++ usb_put_hcd(hcd);
++
++disable_clk:
++ xhci_mtk_clks_disable(mtk);
++
++disable_ldos:
++ xhci_mtk_ldos_disable(mtk);
++
++disable_pm:
++ pm_runtime_put_sync(dev);
++ pm_runtime_disable(dev);
++ return ret;
++}
++
++static int xhci_mtk_remove(struct platform_device *dev)
++{
++ struct xhci_hcd_mtk *mtk = platform_get_drvdata(dev);
++ struct usb_hcd *hcd = mtk->hcd;
++ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
++
++ usb_remove_hcd(xhci->shared_hcd);
++ xhci_mtk_phy_power_off(mtk);
++ xhci_mtk_phy_exit(mtk);
++ device_init_wakeup(&dev->dev, false);
++
++ usb_remove_hcd(hcd);
++ usb_put_hcd(xhci->shared_hcd);
++ usb_put_hcd(hcd);
++ xhci_mtk_sch_exit(mtk);
++ xhci_mtk_clks_disable(mtk);
++ xhci_mtk_ldos_disable(mtk);
++ pm_runtime_put_sync(&dev->dev);
++ pm_runtime_disable(&dev->dev);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int xhci_mtk_suspend(struct device *dev)
++{
++ struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
++
++ xhci_mtk_host_disable(mtk);
++ xhci_mtk_phy_power_off(mtk);
++ xhci_mtk_clks_disable(mtk);
++ usb_wakeup_enable(mtk);
++ return 0;
++}
++
++static int xhci_mtk_resume(struct device *dev)
++{
++ struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
++
++ usb_wakeup_disable(mtk);
++ xhci_mtk_clks_enable(mtk);
++ xhci_mtk_phy_power_on(mtk);
++ xhci_mtk_host_enable(mtk);
++ return 0;
++}
++
++static const struct dev_pm_ops xhci_mtk_pm_ops = {
++ SET_SYSTEM_SLEEP_PM_OPS(xhci_mtk_suspend, xhci_mtk_resume)
++};
++#define DEV_PM_OPS (&xhci_mtk_pm_ops)
++#else
++#define DEV_PM_OPS NULL
++#endif /* CONFIG_PM */
++
++#ifdef CONFIG_OF
++static const struct of_device_id mtk_xhci_of_match[] = {
++ { .compatible = "mediatek,mt8173-xhci"},
++ { },
++};
++MODULE_DEVICE_TABLE(of, mtk_xhci_of_match);
++#endif
++
++static struct platform_driver mtk_xhci_driver = {
++ .probe = xhci_mtk_probe,
++ .remove = xhci_mtk_remove,
++ .driver = {
++ .name = "xhci-mtk",
++ .pm = DEV_PM_OPS,
++ .of_match_table = of_match_ptr(mtk_xhci_of_match),
++ },
++};
++MODULE_ALIAS("platform:xhci-mtk");
++
++static int __init xhci_mtk_init(void)
++{
++ xhci_init_driver(&xhci_mtk_hc_driver, &xhci_mtk_overrides);
++ return platform_driver_register(&mtk_xhci_driver);
++}
++module_init(xhci_mtk_init);
++
++static void __exit xhci_mtk_exit(void)
++{
++ platform_driver_unregister(&mtk_xhci_driver);
++}
++module_exit(xhci_mtk_exit);
++
++MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>");
++MODULE_DESCRIPTION("MediaTek xHCI Host Controller Driver");
++MODULE_LICENSE("GPL v2");
+diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
+new file mode 100644
+index 0000000..7da677c
+--- /dev/null
++++ b/drivers/usb/host/xhci-mtk.h
+@@ -0,0 +1,162 @@
++/*
++ * Copyright (c) 2015 MediaTek Inc.
++ * Author:
++ * Zhigang.Wei <zhigang.wei@mediatek.com>
++ * Chunfeng.Yun <chunfeng.yun@mediatek.com>
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#ifndef _XHCI_MTK_H_
++#define _XHCI_MTK_H_
++
++#include "xhci.h"
++
++/**
++ * To simplify scheduler algorithm, set a upper limit for ESIT,
++ * if a synchromous ep's ESIT is larger than @XHCI_MTK_MAX_ESIT,
++ * round down to the limit value, that means allocating more
++ * bandwidth to it.
++ */
++#define XHCI_MTK_MAX_ESIT 64
++
++/**
++ * struct mu3h_sch_bw_info: schedule information for bandwidth domain
++ *
++ * @bus_bw: array to keep track of bandwidth already used at each uframes
++ * @bw_ep_list: eps in the bandwidth domain
++ *
++ * treat a HS root port as a bandwidth domain, but treat a SS root port as
++ * two bandwidth domains, one for IN eps and another for OUT eps.
++ */
++struct mu3h_sch_bw_info {
++ u32 bus_bw[XHCI_MTK_MAX_ESIT];
++ struct list_head bw_ep_list;
++};
++
++/**
++ * struct mu3h_sch_ep_info: schedule information for endpoint
++ *
++ * @esit: unit is 125us, equal to 2 << Interval field in ep-context
++ * @num_budget_microframes: number of continuous uframes
++ * (@repeat==1) scheduled within the interval
++ * @bw_cost_per_microframe: bandwidth cost per microframe
++ * @endpoint: linked into bandwidth domain which it belongs to
++ * @ep: address of usb_host_endpoint struct
++ * @offset: which uframe of the interval that transfer should be
++ * scheduled first time within the interval
++ * @repeat: the time gap between two uframes that transfers are
++ * scheduled within a interval. in the simple algorithm, only
++ * assign 0 or 1 to it; 0 means using only one uframe in a
++ * interval, and 1 means using @num_budget_microframes
++ * continuous uframes
++ * @pkts: number of packets to be transferred in the scheduled uframes
++ * @cs_count: number of CS that host will trigger
++ * @burst_mode: burst mode for scheduling. 0: normal burst mode,
++ * distribute the bMaxBurst+1 packets for a single burst
++ * according to @pkts and @repeat, repeate the burst multiple
++ * times; 1: distribute the (bMaxBurst+1)*(Mult+1) packets
++ * according to @pkts and @repeat. normal mode is used by
++ * default
++ */
++struct mu3h_sch_ep_info {
++ u32 esit;
++ u32 num_budget_microframes;
++ u32 bw_cost_per_microframe;
++ struct list_head endpoint;
++ void *ep;
++ /*
++ * mtk xHCI scheduling information put into reserved DWs
++ * in ep context
++ */
++ u32 offset;
++ u32 repeat;
++ u32 pkts;
++ u32 cs_count;
++ u32 burst_mode;
++};
++
++#define MU3C_U3_PORT_MAX 4
++#define MU3C_U2_PORT_MAX 5
++
++/**
++ * struct mu3c_ippc_regs: MTK ssusb ip port control registers
++ * @ip_pw_ctr0~3: ip power and clock control registers
++ * @ip_pw_sts1~2: ip power and clock status registers
++ * @ip_xhci_cap: ip xHCI capability register
++ * @u3_ctrl_p[x]: ip usb3 port x control register, only low 4bytes are used
++ * @u2_ctrl_p[x]: ip usb2 port x control register, only low 4bytes are used
++ * @u2_phy_pll: usb2 phy pll control register
++ */
++struct mu3c_ippc_regs {
++ __le32 ip_pw_ctr0;
++ __le32 ip_pw_ctr1;
++ __le32 ip_pw_ctr2;
++ __le32 ip_pw_ctr3;
++ __le32 ip_pw_sts1;
++ __le32 ip_pw_sts2;
++ __le32 reserved0[3];
++ __le32 ip_xhci_cap;
++ __le32 reserved1[2];
++ __le64 u3_ctrl_p[MU3C_U3_PORT_MAX];
++ __le64 u2_ctrl_p[MU3C_U2_PORT_MAX];
++ __le32 reserved2;
++ __le32 u2_phy_pll;
++ __le32 reserved3[33]; /* 0x80 ~ 0xff */
++};
++
++struct xhci_hcd_mtk {
++ struct device *dev;
++ struct usb_hcd *hcd;
++ struct mu3h_sch_bw_info *sch_array;
++ struct mu3c_ippc_regs __iomem *ippc_regs;
++ int num_u2_ports;
++ int num_u3_ports;
++ struct regulator *vusb33;
++ struct regulator *vbus;
++ struct clk *sys_clk; /* sys and mac clock */
++ struct clk *wk_deb_p0; /* port0's wakeup debounce clock */
++ struct clk *wk_deb_p1;
++ struct regmap *pericfg;
++ struct phy **phys;
++ int num_phys;
++ int wakeup_src;
++ bool lpm_support;
++};
++
++static inline struct xhci_hcd_mtk *hcd_to_mtk(struct usb_hcd *hcd)
++{
++ return dev_get_drvdata(hcd->self.controller);
++}
++
++#if IS_ENABLED(CONFIG_USB_XHCI_MTK)
++int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk);
++void xhci_mtk_sch_exit(struct xhci_hcd_mtk *mtk);
++int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
++ struct usb_host_endpoint *ep);
++void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
++ struct usb_host_endpoint *ep);
++
++#else
++static inline int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd,
++ struct usb_device *udev, struct usb_host_endpoint *ep)
++{
++ return 0;
++}
++
++static inline void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd,
++ struct usb_device *udev, struct usb_host_endpoint *ep)
++{
++}
++
++#endif
++
++#endif /* _XHCI_MTK_H_ */
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index eeaa6c6..f1c21c4 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -68,6 +68,7 @@
+ #include <linux/slab.h>
+ #include "xhci.h"
+ #include "xhci-trace.h"
++#include "xhci-mtk.h"
+
+ /*
+ * Returns zero if the TRB isn't in this segment, otherwise it returns the DMA
+@@ -3075,17 +3076,22 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred,
+ {
+ u32 maxp, total_packet_count;
+
+- if (xhci->hci_version < 0x100)
++ /* MTK xHCI is mostly 0.97 but contains some features from 1.0 */
++ if (xhci->hci_version < 0x100 && !(xhci->quirks & XHCI_MTK_HOST))
+ return ((td_total_len - transferred) >> 10);
+
+- maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
+- total_packet_count = DIV_ROUND_UP(td_total_len, maxp);
+-
+ /* One TRB with a zero-length data packet. */
+ if (num_trbs_left == 0 || (transferred == 0 && trb_buff_len == 0) ||
+ trb_buff_len == td_total_len)
+ return 0;
+
++ /* for MTK xHCI, TD size doesn't include this TRB */
++ if (xhci->quirks & XHCI_MTK_HOST)
++ trb_buff_len = 0;
++
++ maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
++ total_packet_count = DIV_ROUND_UP(td_total_len, maxp);
++
+ /* Queueing functions don't count the current TRB into transferred */
+ return (total_packet_count - ((transferred + trb_buff_len) / maxp));
+ }
+@@ -3473,7 +3479,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
+ field |= 0x1;
+
+ /* xHCI 1.0/1.1 6.4.1.2.1: Transfer Type field */
+- if (xhci->hci_version >= 0x100) {
++ if ((xhci->hci_version >= 0x100) || (xhci->quirks & XHCI_MTK_HOST)) {
+ if (urb->transfer_buffer_length > 0) {
+ if (setup->bRequestType & USB_DIR_IN)
+ field |= TRB_TX_TYPE(TRB_DATA_IN);
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index 3f91270..15fedb2 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -31,6 +31,7 @@
+
+ #include "xhci.h"
+ #include "xhci-trace.h"
++#include "xhci-mtk.h"
+
+ #define DRIVER_AUTHOR "Sarah Sharp"
+ #define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver"
+@@ -634,7 +635,11 @@ int xhci_run(struct usb_hcd *hcd)
+ "// Set the interrupt modulation register");
+ temp = readl(&xhci->ir_set->irq_control);
+ temp &= ~ER_IRQ_INTERVAL_MASK;
+- temp |= (u32) 160;
++ /*
++ * the increment interval is 8 times as much as that defined
++ * in xHCI spec on MTK's controller
++ */
++ temp |= (u32) ((xhci->quirks & XHCI_MTK_HOST) ? 20 : 160);
+ writel(temp, &xhci->ir_set->irq_control);
+
+ /* Set the HCD state before we enable the irqs */
+@@ -1698,6 +1703,9 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
+
+ xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep);
+
++ if (xhci->quirks & XHCI_MTK_HOST)
++ xhci_mtk_drop_ep_quirk(hcd, udev, ep);
++
+ xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x\n",
+ (unsigned int) ep->desc.bEndpointAddress,
+ udev->slot_id,
+@@ -1793,6 +1801,15 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
+ return -ENOMEM;
+ }
+
++ if (xhci->quirks & XHCI_MTK_HOST) {
++ ret = xhci_mtk_add_ep_quirk(hcd, udev, ep);
++ if (ret < 0) {
++ xhci_free_or_cache_endpoint_ring(xhci,
++ virt_dev, ep_index);
++ return ret;
++ }
++ }
++
+ ctrl_ctx->add_flags |= cpu_to_le32(added_ctxs);
+ new_add_flags = le32_to_cpu(ctrl_ctx->add_flags);
+
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 0b94512..40cf36e 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1630,6 +1630,7 @@ struct xhci_hcd {
+ /* For controllers with a broken beyond repair streams implementation */
+ #define XHCI_BROKEN_STREAMS (1 << 19)
+ #define XHCI_PME_STUCK_QUIRK (1 << 20)
++#define XHCI_MTK_HOST (1 << 21)
+ unsigned int num_active_eps;
+ unsigned int limit_active_eps;
+ /* There are two roothubs to keep track of bus suspend info for */
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0020-arm64-dts-mediatek-add-xHCI-usb-phy-for-mt8173.patch b/target/linux/mediatek/patches-4.4/0020-arm64-dts-mediatek-add-xHCI-usb-phy-for-mt8173.patch
new file mode 100644
index 0000000000..d52b8ebe6c
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0020-arm64-dts-mediatek-add-xHCI-usb-phy-for-mt8173.patch
@@ -0,0 +1,114 @@
+From 31a22fbd0d3b187be61c4c5d22b19c95abb327c3 Mon Sep 17 00:00:00 2001
+From: "chunfeng.yun@mediatek.com" <chunfeng.yun@mediatek.com>
+Date: Tue, 17 Nov 2015 17:18:41 +0800
+Subject: [PATCH 20/53] arm64: dts: mediatek: add xHCI & usb phy for mt8173
+
+add xHCI and phy drivers for MT8173-EVB
+
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+---
+ arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 16 ++++++++++
+ arch/arm64/boot/dts/mediatek/mt8173.dtsi | 42 +++++++++++++++++++++++++++
+ 2 files changed, 58 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+index 811cb76..9b1482a 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+@@ -13,6 +13,7 @@
+ */
+
+ /dts-v1/;
++#include <dt-bindings/gpio/gpio.h>
+ #include "mt8173.dtsi"
+
+ / {
+@@ -32,6 +33,15 @@
+ };
+
+ chosen { };
++
++ usb_p1_vbus: regulator@0 {
++ compatible = "regulator-fixed";
++ regulator-name = "usb_vbus";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ gpio = <&pio 130 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
+ };
+
+ &i2c1 {
+@@ -408,3 +418,9 @@
+ &uart0 {
+ status = "okay";
+ };
++
++&usb30 {
++ vusb33-supply = <&mt6397_vusb_reg>;
++ vbus-supply = <&usb_p1_vbus>;
++ mediatek,wakeup-src = <1>;
++};
+diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+index 4dd5f93..c1fd275 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+@@ -14,6 +14,7 @@
+ #include <dt-bindings/clock/mt8173-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/power/mt8173-power.h>
+ #include <dt-bindings/reset-controller/mt8173-resets.h>
+ #include "mt8173-pinfunc.h"
+@@ -510,6 +511,47 @@
+ status = "disabled";
+ };
+
++ usb30: usb@11270000 {
++ compatible = "mediatek,mt8173-xhci";
++ reg = <0 0x11270000 0 0x1000>,
++ <0 0x11280700 0 0x0100>;
++ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_LOW>;
++ power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>;
++ clocks = <&topckgen CLK_TOP_USB30_SEL>,
++ <&pericfg CLK_PERI_USB0>,
++ <&pericfg CLK_PERI_USB1>;
++ clock-names = "sys_ck",
++ "wakeup_deb_p0",
++ "wakeup_deb_p1";
++ phys = <&phy_port0 PHY_TYPE_USB3>,
++ <&phy_port1 PHY_TYPE_USB2>;
++ mediatek,syscon-wakeup = <&pericfg>;
++ status = "okay";
++ };
++
++ u3phy: usb-phy@11290000 {
++ compatible = "mediatek,mt8173-u3phy";
++ reg = <0 0x11290000 0 0x800>;
++ clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>;
++ clock-names = "u3phya_ref";
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++ status = "okay";
++
++ phy_port0: port@11290800 {
++ reg = <0 0x11290800 0 0x800>;
++ #phy-cells = <1>;
++ status = "okay";
++ };
++
++ phy_port1: port@11291000 {
++ reg = <0 0x11291000 0 0x800>;
++ #phy-cells = <1>;
++ status = "okay";
++ };
++ };
++
+ mmsys: clock-controller@14000000 {
+ compatible = "mediatek,mt8173-mmsys", "syscon";
+ reg = <0 0x14000000 0 0x1000>;
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0021-Document-DT-Add-bindings-for-mediatek-MT7623-SoC-Pla.patch b/target/linux/mediatek/patches-4.4/0021-Document-DT-Add-bindings-for-mediatek-MT7623-SoC-Pla.patch
new file mode 100644
index 0000000000..053c4fe220
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0021-Document-DT-Add-bindings-for-mediatek-MT7623-SoC-Pla.patch
@@ -0,0 +1,64 @@
+From 162deec293400cb132161606629654acaec7cb4b Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Tue, 5 Jan 2016 12:13:54 +0100
+Subject: [PATCH 21/53] Document: DT: Add bindings for mediatek MT7623 SoC
+ Platform
+
+This adds a DT binding documentation for the MT7623 SoC from Mediatek.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ Documentation/devicetree/bindings/arm/mediatek.txt | 4 ++++
+ Documentation/devicetree/bindings/serial/mtk-uart.txt | 1 +
+ Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt | 1 +
+ 3 files changed, 6 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/arm/mediatek.txt b/Documentation/devicetree/bindings/arm/mediatek.txt
+index 618a9199..40e9d32 100644
+--- a/Documentation/devicetree/bindings/arm/mediatek.txt
++++ b/Documentation/devicetree/bindings/arm/mediatek.txt
+@@ -10,6 +10,7 @@ compatible: Must contain one of
+ "mediatek,mt6589"
+ "mediatek,mt6592"
+ "mediatek,mt6795"
++ "mediatek,mt7623"
+ "mediatek,mt8127"
+ "mediatek,mt8135"
+ "mediatek,mt8173"
+@@ -29,6 +30,9 @@ Supported boards:
+ - Evaluation board for MT6795(Helio X10):
+ Required root node properties:
+ - compatible = "mediatek,mt6795-evb", "mediatek,mt6795";
++- Evaluation board for MT7623:
++ Required root node properties:
++ - compatible = "mediatek,mt7623-evb", "mediatek,mt7623";
+ - MTK mt8127 tablet moose EVB:
+ Required root node properties:
+ - compatible = "mediatek,mt8127-moose", "mediatek,mt8127";
+diff --git a/Documentation/devicetree/bindings/serial/mtk-uart.txt b/Documentation/devicetree/bindings/serial/mtk-uart.txt
+index 2d47add..474f0cf 100644
+--- a/Documentation/devicetree/bindings/serial/mtk-uart.txt
++++ b/Documentation/devicetree/bindings/serial/mtk-uart.txt
+@@ -2,6 +2,7 @@
+
+ Required properties:
+ - compatible should contain:
++ * "mediatek,mt7623-uart" for MT7623 compatible UARTS
+ * "mediatek,mt8135-uart" for MT8135 compatible UARTS
+ * "mediatek,mt8127-uart" for MT8127 compatible UARTS
+ * "mediatek,mt8173-uart" for MT8173 compatible UARTS
+diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
+index 64083bc..6bacda1b3 100644
+--- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
++++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
+@@ -5,6 +5,7 @@ Required properties:
+ - compatible should contain:
+ * "mediatek,mt6580-timer" for MT6580 compatible timers
+ * "mediatek,mt6589-timer" for MT6589 compatible timers
++ * "mediatek,mt7623-timer" for MT7623 compatible timers
+ * "mediatek,mt8127-timer" for MT8127 compatible timers
+ * "mediatek,mt8135-timer" for MT8135 compatible timers
+ * "mediatek,mt8173-timer" for MT8173 compatible timers
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0022-soc-mediatek-add-compat-string-for-mt7623-to-scpsys.patch b/target/linux/mediatek/patches-4.4/0022-soc-mediatek-add-compat-string-for-mt7623-to-scpsys.patch
new file mode 100644
index 0000000000..6d76ae3a7d
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0022-soc-mediatek-add-compat-string-for-mt7623-to-scpsys.patch
@@ -0,0 +1,26 @@
+From fa5d94d6b4b314f751b1c32bb5a87a80b866d05e Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Tue, 5 Jan 2016 16:52:31 +0100
+Subject: [PATCH 22/53] soc: mediatek: add compat string for mt7623 to scpsys
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/soc/mediatek/mtk-scpsys-mt2701.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/soc/mediatek/mtk-scpsys-mt2701.c b/drivers/soc/mediatek/mtk-scpsys-mt2701.c
+index 339d5b8..3a31946 100644
+--- a/drivers/soc/mediatek/mtk-scpsys-mt2701.c
++++ b/drivers/soc/mediatek/mtk-scpsys-mt2701.c
+@@ -136,6 +136,8 @@ static const struct of_device_id of_scpsys_match_tbl[] = {
+ {
+ .compatible = "mediatek,mt2701-scpsys",
+ }, {
++ .compatible = "mediatek,mt7623-scpsys",
++ }, {
+ /* sentinel */
+ }
+ };
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0023-ARM-dts-mediatek-add-MT7623-basic-support.patch b/target/linux/mediatek/patches-4.4/0023-ARM-dts-mediatek-add-MT7623-basic-support.patch
new file mode 100644
index 0000000000..85ff55128f
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0023-ARM-dts-mediatek-add-MT7623-basic-support.patch
@@ -0,0 +1,1038 @@
+From cfe366d7a20f88c7fc92faaf8b25c24e730bd40b Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Tue, 5 Jan 2016 12:16:17 +0100
+Subject: [PATCH 23/53] ARM: dts: mediatek: add MT7623 basic support
+
+This adds basic chip support for Mediatek MT7623.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/arm/boot/dts/Makefile | 1 +
+ arch/arm/boot/dts/mt7623-evb.dts | 459 +++++++++++++++++++++++++++++++++
+ arch/arm/boot/dts/mt7623.dtsi | 507 +++++++++++++++++++++++++++++++++++++
+ arch/arm/mach-mediatek/Kconfig | 4 +
+ arch/arm/mach-mediatek/mediatek.c | 1 +
+ 5 files changed, 972 insertions(+)
+ create mode 100644 arch/arm/boot/dts/mt7623-evb.dts
+ create mode 100644 arch/arm/boot/dts/mt7623.dtsi
+
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index 30bbc37..2bce370 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -774,6 +774,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
+ mt6580-evbp1.dtb \
+ mt6589-aquaris5.dtb \
+ mt6592-evb.dtb \
++ mt7623-evb.dtb \
+ mt8127-moose.dtb \
+ mt8135-evbp1.dtb
+ dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb
+diff --git a/arch/arm/boot/dts/mt7623-evb.dts b/arch/arm/boot/dts/mt7623-evb.dts
+new file mode 100644
+index 0000000..5e9381d
+--- /dev/null
++++ b/arch/arm/boot/dts/mt7623-evb.dts
+@@ -0,0 +1,459 @@
++/*
++ * Copyright (c) 2016 MediaTek Inc.
++ * Author: John Crispin <blogic@openwrt.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++/dts-v1/;
++
++#include "mt7623.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++ model = "MediaTek MT7623 evaluation board";
++ compatible = "mediatek,mt7623-evb", "mediatek,mt7623";
++
++ chosen {
++ stdout-path = &uart2;
++ };
++
++ memory {
++ reg = <0 0x80000000 0 0x20000000>;
++ };
++
++ usb_p1_vbus: regulator@0 {
++ compatible = "regulator-fixed";
++ regulator-name = "usb_vbus";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ gpio = <&pio 135 GPIO_ACTIVE_HIGH>;
++ enable-active-high;
++ };
++};
++
++&pwrap {
++ pmic: mt6323 {
++ compatible = "mediatek,mt6323";
++ interrupt-parent = <&pio>;
++ interrupts = <150 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++
++ mt6323regulator: mt6323regulator{
++ compatible = "mediatek,mt6323-regulator";
++
++ mt6323_vproc_reg: buck_vproc{
++ regulator-name = "vproc";
++ regulator-min-microvolt = < 700000>;
++ regulator-max-microvolt = <1350000>;
++ regulator-ramp-delay = <12500>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ mt6323_vsys_reg: buck_vsys{
++ regulator-name = "vsys";
++ regulator-min-microvolt = <1400000>;
++ regulator-max-microvolt = <2987500>;
++ regulator-ramp-delay = <25000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ mt6323_vpa_reg: buck_vpa{
++ regulator-name = "vpa";
++ regulator-min-microvolt = < 500000>;
++ regulator-max-microvolt = <3650000>;
++ };
++
++ mt6323_vtcxo_reg: ldo_vtcxo{
++ regulator-name = "vtcxo";
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ regulator-enable-ramp-delay = <90>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ mt6323_vcn28_reg: ldo_vcn28{
++ regulator-name = "vcn28";
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ regulator-enable-ramp-delay = <185>;
++ };
++
++ mt6323_vcn33_bt_reg: ldo_vcn33_bt{
++ regulator-name = "vcn33_bt";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3600000>;
++ regulator-enable-ramp-delay = <185>;
++ };
++
++ mt6323_vcn33_wifi_reg: ldo_vcn33_wifi{
++ regulator-name = "vcn33_wifi";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3600000>;
++ regulator-enable-ramp-delay = <185>;
++ };
++
++ mt6323_va_reg: ldo_va{
++ regulator-name = "va";
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ regulator-enable-ramp-delay = <216>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ mt6323_vcama_reg: ldo_vcama{
++ regulator-name = "vcama";
++ regulator-min-microvolt = <1500000>;
++ regulator-max-microvolt = <2800000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vio28_reg: ldo_vio28{
++ regulator-name = "vio28";
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ regulator-enable-ramp-delay = <216>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ mt6323_vusb_reg: ldo_vusb{
++ regulator-name = "vusb";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-enable-ramp-delay = <216>;
++ regulator-boot-on;
++ };
++
++ mt6323_vmc_reg: ldo_vmc{
++ regulator-name = "vmc";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-enable-ramp-delay = <36>;
++ regulator-boot-on;
++ };
++
++ mt6323_vmch_reg: ldo_vmch{
++ regulator-name = "vmch";
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-enable-ramp-delay = <36>;
++ regulator-boot-on;
++ };
++
++ mt6323_vemc3v3_reg: ldo_vemc3v3{
++ regulator-name = "vemc3v3";
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-enable-ramp-delay = <36>;
++ regulator-boot-on;
++ };
++
++ mt6323_vgp1_reg: ldo_vgp1{
++ regulator-name = "vgp1";
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vgp2_reg: ldo_vgp2{
++ regulator-name = "vgp2";
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <3000000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vgp3_reg: ldo_vgp3{
++ regulator-name = "vgp3";
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vcn18_reg: ldo_vcn18{
++ regulator-name = "vcn18";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vsim1_reg: ldo_vsim1{
++ regulator-name = "vsim1";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3000000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vsim2_reg: ldo_vsim2{
++ regulator-name = "vsim2";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3000000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vrtc_reg: ldo_vrtc{
++ regulator-name = "vrtc";
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ mt6323_vcamaf_reg: ldo_vcamaf{
++ regulator-name = "vcamaf";
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vibr_reg: ldo_vibr{
++ regulator-name = "vibr";
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-enable-ramp-delay = <36>;
++ };
++
++ mt6323_vrf18_reg: ldo_vrf18{
++ regulator-name = "vrf18";
++ regulator-min-microvolt = <1825000>;
++ regulator-max-microvolt = <1825000>;
++ regulator-enable-ramp-delay = <187>;
++ };
++
++ mt6323_vm_reg: ldo_vm{
++ regulator-name = "vm";
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-enable-ramp-delay = <216>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ mt6323_vio18_reg: ldo_vio18{
++ regulator-name = "vio18";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-enable-ramp-delay = <216>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ mt6323_vcamd_reg: ldo_vcamd{
++ regulator-name = "vcamd";
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vcamio_reg: ldo_vcamio{
++ regulator-name = "vcamio";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++ };
++ };
++};
++
++&uart2 {
++ status = "okay";
++};
++
++&mmc0 {
++ status = "okay";
++ pinctrl-names = "default", "state_uhs";
++ pinctrl-0 = <&mmc0_pins_default>;
++ pinctrl-1 = <&mmc0_pins_uhs>;
++ bus-width = <8>;
++ max-frequency = <50000000>;
++ cap-mmc-highspeed;
++ vmmc-supply = <&mt6323_vemc3v3_reg>;
++ vqmmc-supply = <&mt6323_vio18_reg>;
++ non-removable;
++};
++
++&mmc1 {
++ status = "okay";
++ pinctrl-names = "default", "state_uhs";
++ pinctrl-0 = <&mmc1_pins_default>;
++ pinctrl-1 = <&mmc1_pins_uhs>;
++ bus-width = <4>;
++ max-frequency = <50000000>;
++ cap-sd-highspeed;
++ sd-uhs-sdr25;
++// cd-gpios = <&pio 132 0>;
++ vmmc-supply = <&mt6323_vmch_reg>;
++ vqmmc-supply = <&mt6323_vmc_reg>;
++};
++
++&pio {
++ mmc0_pins_default: mmc0default {
++ pins_cmd_dat {
++ pinmux = <MT7623_PIN_111_MSDC0_DAT7_FUNC_MSDC0_DAT7>,
++ <MT7623_PIN_112_MSDC0_DAT6_FUNC_MSDC0_DAT6>,
++ <MT7623_PIN_113_MSDC0_DAT5_FUNC_MSDC0_DAT5>,
++ <MT7623_PIN_114_MSDC0_DAT4_FUNC_MSDC0_DAT4>,
++ <MT7623_PIN_118_MSDC0_DAT3_FUNC_MSDC0_DAT3>,
++ <MT7623_PIN_119_MSDC0_DAT2_FUNC_MSDC0_DAT2>,
++ <MT7623_PIN_120_MSDC0_DAT1_FUNC_MSDC0_DAT1>,
++ <MT7623_PIN_121_MSDC0_DAT0_FUNC_MSDC0_DAT0>,
++ <MT7623_PIN_116_MSDC0_CMD_FUNC_MSDC0_CMD>;
++ input-enable;
++ bias-pull-up;
++ };
++
++ pins_clk {
++ pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_MSDC0_CLK>;
++ bias-pull-down;
++ };
++
++ pins_rst {
++ pinmux = <MT7623_PIN_115_MSDC0_RSTB_FUNC_MSDC0_RSTB>;
++ bias-pull-up;
++ };
++ };
++
++ mmc0_pins_uhs: mmc0 {
++ pins_cmd_dat {
++ pinmux = <MT7623_PIN_111_MSDC0_DAT7_FUNC_MSDC0_DAT7>,
++ <MT7623_PIN_112_MSDC0_DAT6_FUNC_MSDC0_DAT6>,
++ <MT7623_PIN_113_MSDC0_DAT5_FUNC_MSDC0_DAT5>,
++ <MT7623_PIN_114_MSDC0_DAT4_FUNC_MSDC0_DAT4>,
++ <MT7623_PIN_118_MSDC0_DAT3_FUNC_MSDC0_DAT3>,
++ <MT7623_PIN_119_MSDC0_DAT2_FUNC_MSDC0_DAT2>,
++ <MT7623_PIN_120_MSDC0_DAT1_FUNC_MSDC0_DAT1>,
++ <MT7623_PIN_121_MSDC0_DAT0_FUNC_MSDC0_DAT0>,
++ <MT7623_PIN_116_MSDC0_CMD_FUNC_MSDC0_CMD>;
++ input-enable;
++ drive-strength = <MTK_DRIVE_2mA>;
++ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
++ };
++
++ pins_clk {
++ pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_MSDC0_CLK>;
++ drive-strength = <MTK_DRIVE_2mA>;
++ bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
++ };
++
++ pins_rst {
++ pinmux = <MT7623_PIN_115_MSDC0_RSTB_FUNC_MSDC0_RSTB>;
++ bias-pull-up;
++ };
++ };
++
++ mmc1_pins_default: mmc1default {
++ pins_cmd_dat {
++ pinmux = <MT7623_PIN_107_MSDC1_DAT0_FUNC_MSDC1_DAT0>,
++ <MT7623_PIN_108_MSDC1_DAT1_FUNC_MSDC1_DAT1>,
++ <MT7623_PIN_109_MSDC1_DAT2_FUNC_MSDC1_DAT2>,
++ <MT7623_PIN_110_MSDC1_DAT3_FUNC_MSDC1_DAT3>,
++ <MT7623_PIN_105_MSDC1_CMD_FUNC_MSDC1_CMD>;
++ input-enable;
++ drive-strength = <MTK_DRIVE_4mA>;
++ bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
++ };
++
++ pins_clk {
++ pinmux = <MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK>;
++ bias-pull-down;
++ drive-strength = <MTK_DRIVE_4mA>;
++ };
++
++// pins_insert {
++// pinmux = <MT8173_PIN_132_I2S0_DATA1_FUNC_GPIO132>;
++// bias-pull-up;
++// };
++ };
++
++ mmc1_pins_uhs: mmc1 {
++ pins_cmd_dat {
++ pinmux = <MT7623_PIN_107_MSDC1_DAT0_FUNC_MSDC1_DAT0>,
++ <MT7623_PIN_108_MSDC1_DAT1_FUNC_MSDC1_DAT1>,
++ <MT7623_PIN_109_MSDC1_DAT2_FUNC_MSDC1_DAT2>,
++ <MT7623_PIN_110_MSDC1_DAT3_FUNC_MSDC1_DAT3>,
++ <MT7623_PIN_105_MSDC1_CMD_FUNC_MSDC1_CMD>;
++ input-enable;
++ drive-strength = <MTK_DRIVE_4mA>;
++ bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
++ };
++
++ pins_clk {
++ pinmux = <MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK>;
++ drive-strength = <MTK_DRIVE_4mA>;
++ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
++ };
++ };
++
++ eth_default: eth {
++ pins_eth {
++ pinmux = <MT7623_PIN_275_G2_MDC_FUNC_MDC>,
++ <MT7623_PIN_276_G2_MDIO_FUNC_MDIO>,
++ <MT7623_PIN_262_G2_TXEN_FUNC_G2_TXEN>,
++ <MT7623_PIN_263_G2_TXD3_FUNC_G2_TXD3>,
++ <MT7623_PIN_264_G2_TXD2_FUNC_G2_TXD2>,
++ <MT7623_PIN_265_G2_TXD1_FUNC_G2_TXD1>,
++ <MT7623_PIN_266_G2_TXD0_FUNC_G2_TXD0>,
++ <MT7623_PIN_267_G2_TXCLK_FUNC_G2_TXC>,
++ <MT7623_PIN_268_G2_RXCLK_FUNC_G2_RXC>,
++ <MT7623_PIN_269_G2_RXD0_FUNC_G2_RXD0>,
++ <MT7623_PIN_270_G2_RXD1_FUNC_G2_RXD1>,
++ <MT7623_PIN_271_G2_RXD2_FUNC_G2_RXD2>,
++ <MT7623_PIN_272_G2_RXD3_FUNC_G2_RXD3>,
++ <MT7623_PIN_273_ESW_INT_FUNC_ESW_INT>,
++ <MT7623_PIN_274_G2_RXDV_FUNC_G2_RXDV>;
++ };
++
++ pins_eth_rst {
++ pinmux = <MT7623_PIN_15_GPIO15_FUNC_GPIO15>;
++ output-low;
++ };
++ };
++};
++
++&usb1 {
++ vusb33-supply = <&mt6323_vusb_reg>;
++ vbus-supply = <&usb_p1_vbus>;
++// mediatek,wakeup-src = <1>;
++ status = "okay";
++};
++
++&u3phy1 {
++ status = "okay";
++};
++
++&pcie {
++ status = "okay";
++};
++
++&eth {
++ status = "okay";
++};
++
++&gmac1 {
++ mac-address = [00 11 22 33 44 56];
++ status = "okay";
++};
++
++&gmac2 {
++ mac-address = [00 11 22 33 44 55];
++ status = "okay";
++};
++
++&gsw {
++ pinctrl-names = "default";
++ pinctrl-0 = <&eth_default>;
++ mediatek,reset-pin = <&pio 15 0>;
++ status = "okay";
++};
+diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
+new file mode 100644
+index 0000000..1ba7790
+--- /dev/null
++++ b/arch/arm/boot/dts/mt7623.dtsi
+@@ -0,0 +1,507 @@
++/*
++ * Copyright (c) 2016 MediaTek Inc.
++ * Author: John Crispin <blogic@openwrt.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/interrupt-controller/arm-gic.h>
++#include <dt-bindings/clock/mt2701-clk.h>
++#include <dt-bindings/power/mt2701-power.h>
++#include <dt-bindings/phy/phy.h>
++#include <dt-bindings/reset-controller/mt2701-resets.h>
++#include <dt-bindings/pinctrl/mt7623-pinfunc.h>
++#include "skeleton64.dtsi"
++
++
++/ {
++ compatible = "mediatek,mt7623";
++ interrupt-parent = <&sysirq>;
++
++ cpus {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ cpu@0 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a7";
++ reg = <0x0>;
++ };
++ cpu@1 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a7";
++ reg = <0x1>;
++ };
++ cpu@2 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a7";
++ reg = <0x2>;
++ };
++ cpu@3 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a7";
++ reg = <0x3>;
++ };
++ };
++
++ system_clk: dummy13m {
++ compatible = "fixed-clock";
++ clock-frequency = <13000000>;
++ #clock-cells = <0>;
++ };
++
++ rtc_clk: dummy32k {
++ compatible = "fixed-clock";
++ clock-frequency = <32000>;
++ #clock-cells = <0>;
++ clock-output-names = "clk32k";
++ };
++
++ clk26m: dummy26m {
++ compatible = "fixed-clock";
++ clock-frequency = <26000000>;
++ #clock-cells = <0>;
++ clock-output-names = "clk26m";
++ };
++
++ timer {
++ compatible = "arm,armv7-timer";
++ interrupt-parent = <&gic>;
++ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
++ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
++ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
++ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
++ };
++
++ topckgen: power-controller@10000000 {
++ compatible = "mediatek,mt7623-topckgen",
++ "mediatek,mt2701-topckgen",
++ "syscon";
++ reg = <0 0x10000000 0 0x1000>;
++ #clock-cells = <1>;
++ };
++
++ infracfg: power-controller@10001000 {
++ compatible = "mediatek,mt7623-infracfg",
++ "mediatek,mt2701-infracfg",
++ "syscon";
++ reg = <0 0x10001000 0 0x1000>;
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ };
++
++ pericfg: pericfg@10003000 {
++ compatible = "mediatek,mt7623-pericfg",
++ "mediatek,mt2701-pericfg",
++ "syscon";
++ reg = <0 0x10003000 0 0x1000>;
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ };
++
++ pio: pinctrl@10005000 {
++ compatible = "mediatek,mt7623-pinctrl";
++ reg = <0 0x1000b000 0 0x1000>;
++ mediatek,pctl-regmap = <&syscfg_pctl_a>;
++ pins-are-numbered;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&gic>;
++ #interrupt-cells = <2>;
++ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
++ };
++
++ syscfg_pctl_a: syscfg@10005000 {
++ compatible = "mediatek,mt7623-pctl-a-syscfg", "syscon";
++ reg = <0 0x10005000 0 0x1000>;
++ };
++
++ scpsys: scpsys@10006000 {
++ #power-domain-cells = <1>;
++ compatible = "mediatek,mt7623-scpsys",
++ "mediatek,mt2701-scpsys";
++ reg = <0 0x10006000 0 0x1000>;
++ infracfg = <&infracfg>;
++ clocks = <&clk26m>,
++ <&topckgen CLK_TOP_MM_SEL>;
++ clock-names = "mfg", "mm";
++ };
++
++ watchdog: watchdog@10007000 {
++ compatible = "mediatek,mt7623-wdt",
++ "mediatek,mt6589-wdt";
++ reg = <0 0x10007000 0 0x100>;
++ };
++
++ timer: timer@10008000 {
++ compatible = "mediatek,mt7623-timer",
++ "mediatek,mt6577-timer";
++ reg = <0 0x10008000 0 0x80>;
++ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&system_clk>, <&rtc_clk>;
++ clock-names = "system-clk", "rtc-clk";
++ };
++
++ pwrap: pwrap@1000d000 {
++ compatible = "mediatek,mt7623-pwrap",
++ "mediatek,mt2701-pwrap";
++ reg = <0 0x1000d000 0 0x1000>;
++ reg-names = "pwrap";
++ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
++ resets = <&infracfg MT2701_INFRA_PMIC_WRAP_RST>;
++ reset-names = "pwrap";
++ clocks = <&infracfg CLK_INFRA_PMICSPI>,
++ <&infracfg CLK_INFRA_PMICWRAP>;
++ clock-names = "spi", "wrap";
++ };
++
++ sysirq: interrupt-controller@10200100 {
++ compatible = "mediatek,mt7623-sysirq",
++ "mediatek,mt6577-sysirq";
++ interrupt-controller;
++ #interrupt-cells = <3>;
++ interrupt-parent = <&gic>;
++ reg = <0 0x10200100 0 0x1c>;
++ };
++
++ apmixedsys: apmixedsys@10209000 {
++ compatible = "mediatek,mt7623-apmixedsys",
++ "mediatek,mt2701-apmixedsys";
++ reg = <0 0x10209000 0 0x1000>;
++ #clock-cells = <1>;
++ };
++
++ gic: interrupt-controller@10211000 {
++ compatible = "arm,cortex-a7-gic";
++ interrupt-controller;
++ #interrupt-cells = <3>;
++ interrupt-parent = <&gic>;
++ reg = <0 0x10211000 0 0x1000>,
++ <0 0x10212000 0 0x1000>,
++ <0 0x10214000 0 0x2000>,
++ <0 0x10216000 0 0x2000>;
++ };
++
++ i2c0: i2c@11007000 {
++ compatible = "mediatek,mt7623-i2c",
++ "mediatek,mt6577-i2c";
++ reg = <0 0x11007000 0 0x70>,
++ <0 0x11000200 0 0x80>;
++ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_LOW>;
++ clock-div = <16>;
++ clocks = <&pericfg CLK_PERI_I2C0>,
++ <&pericfg CLK_PERI_AP_DMA>;
++ clock-names = "main", "dma";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c1: i2c@11008000 {
++ compatible = "mediatek,mt7623-i2c",
++ "mediatek,mt6577-i2c";
++ reg = <0 0x11008000 0 0x70>,
++ <0 0x11000280 0 0x80>;
++ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_LOW>;
++ clock-div = <16>;
++ clocks = <&pericfg CLK_PERI_I2C1>,
++ <&pericfg CLK_PERI_AP_DMA>;
++ clock-names = "main", "dma";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c2: i2c@11009000 {
++ compatible = "mediatek,mt7623-i2c",
++ "mediatek,mt6577-i2c";
++ reg = <0 0x11009000 0 0x70>,
++ <0 0x11000300 0 0x80>;
++ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_LOW>;
++ clock-div = <16>;
++ clocks = <&pericfg CLK_PERI_I2C2>,
++ <&pericfg CLK_PERI_AP_DMA>;
++ clock-names = "main", "dma";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ uart0: serial@11002000 {
++ compatible = "mediatek,mt7623-uart",
++ "mediatek,mt6577-uart";
++ reg = <0 0x11002000 0 0x400>;
++ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&pericfg CLK_PERI_UART0_SEL>,
++ <&pericfg CLK_PERI_UART0>;
++ clock-names = "baud", "bus";
++ status = "disabled";
++ };
++
++ uart1: serial@11003000 {
++ compatible = "mediatek,mt7623-uart",
++ "mediatek,mt6577-uart";
++ reg = <0 0x11003000 0 0x400>;
++ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&pericfg CLK_PERI_UART1_SEL>,
++ <&pericfg CLK_PERI_UART1>;
++ clock-names = "baud", "bus";
++ status = "disabled";
++ };
++
++ uart2: serial@11004000 {
++ compatible = "mediatek,mt7623-uart",
++ "mediatek,mt6577-uart";
++ reg = <0 0x11004000 0 0x400>;
++ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&pericfg CLK_PERI_UART2_SEL>,
++ <&pericfg CLK_PERI_UART2>;
++ clock-names = "baud", "bus";
++ status = "disabled";
++ };
++
++ uart3: serial@11005000 {
++ compatible = "mediatek,mt7623-uart",
++ "mediatek,mt6577-uart";
++ reg = <0 0x11005000 0 0x400>;
++ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&pericfg CLK_PERI_UART3_SEL>,
++ <&pericfg CLK_PERI_UART3>;
++ clock-names = "baud", "bus";
++ status = "disabled";
++ };
++
++ spi: spi@1100a000 {
++ compatible = "mediatek,mt7623-spi", "mediatek,mt6589-spi";
++ reg = <0 0x1100a000 0 0x1000>;
++ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&pericfg CLK_PERI_SPI0>;
++ clock-names = "main";
++
++ status = "disabled";
++ };
++
++ mmc0: mmc@11230000 {
++ compatible = "mediatek,mt7623-mmc",
++ "mediatek,mt8135-mmc";
++ reg = <0 0x11230000 0 0x1000>;
++ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&pericfg CLK_PERI_MSDC30_0>,
++ <&topckgen CLK_TOP_MSDC30_0_SEL>;
++ clock-names = "source", "hclk";
++ status = "disabled";
++ };
++
++ mmc1: mmc@11240000 {
++ compatible = "mediatek,mt7623-mmc",
++ "mediatek,mt8135-mmc";
++ reg = <0 0x11240000 0 0x1000>;
++ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&pericfg CLK_PERI_MSDC30_1>,
++ <&topckgen CLK_TOP_MSDC30_1_SEL>;
++ clock-names = "source", "hclk";
++ status = "disabled";
++ };
++
++ usb1: usb@1a1c0000 {
++ compatible = "mediatek,mt2701-xhci",
++ "mediatek,mt8173-xhci";
++ reg = <0 0x1a1c0000 0 0x1000>,
++ <0 0x1a1c4700 0 0x0100>;
++ interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&hifsys CLK_HIFSYS_USB0PHY>,
++ <&topckgen CLK_TOP_ETHIF_SEL>;
++ clock-names = "sys_ck", "ethif";
++ power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>;
++ phys = <&phy_port0 PHY_TYPE_USB3>;
++ status = "disabled";
++ };
++
++ u3phy1: usb-phy@1a1c4000 {
++ compatible = "mediatek,mt2701-u3phy",
++ "mediatek,mt8173-u3phy";
++ reg = <0 0x1a1c4000 0 0x0700>;
++ clocks = <&clk26m>;
++ clock-names = "u3phya_ref";
++ #phy-cells = <1>;
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++ status = "disabled";
++
++ phy_port0: phy_port0: port@1a1c4800 {
++ reg = <0 0x1a1c4800 0 0x800>;
++ #phy-cells = <1>;
++ status = "okay";
++ };
++ };
++
++ usb2: usb@1a240000 {
++ compatible = "mediatek,mt2701-xhci",
++ "mediatek,mt8173-xhci";
++ reg = <0 0x1a240000 0 0x1000>,
++ <0 0x1a244700 0 0x0100>;
++ interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&hifsys CLK_HIFSYS_USB1PHY>,
++ <&topckgen CLK_TOP_ETHIF_SEL>;
++ clock-names = "sys_ck", "ethif";
++ power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>;
++ phys = <&u3phy2 0>;
++ status = "disabled";
++ };
++
++ u3phy2: usb-phy@1a244000 {
++ compatible = "mediatek,mt2701-u3phy",
++ "mediatek,mt8173-u3phy";
++ reg = <0 0x1a244000 0 0x0700>,
++ <0 0x1a244800 0 0x0800>;
++ clocks = <&clk26m>;
++ clock-names = "u3phya_ref";
++ #phy-cells = <1>;
++ status = "disabled";
++ };
++
++ hifsys: clock-controller@1a000000 {
++ compatible = "mediatek,mt7623-hifsys",
++ "mediatek,mt2701-hifsys",
++ "syscon";
++ reg = <0 0x1a000000 0 0x1000>;
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ };
++
++ pcie: pcie@1a140000 {
++ compatible = "mediatek,mt7623-pcie";
++ device_type = "pci";
++ reg = <0 0x1a140000 0 0x8000>, /* PCI-Express registers */
++ <0 0x1a149000 0 0x1000>, /* PCI-Express PHY0 */
++ <0 0x1a14a000 0 0x1000>, /* PCI-Express PHY1 */
++ <0 0x1a244000 0 0x1000>; /* PCI-Express PHY2 */
++ reg-names = "pcie", "pcie phy0", "pcie phy1", "pcie phy2";
++ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>,
++ <GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>,
++ <GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>;
++ interrupt-names = "pcie0", "pcie1", "pcie2";
++ clocks = <&topckgen CLK_TOP_ETHIF_SEL>;
++ clock-names = "pcie";
++ power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>;
++ resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>,
++ <&hifsys MT2701_HIFSYS_PCIE1_RST>,
++ <&hifsys MT2701_HIFSYS_PCIE2_RST>;
++ reset-names = "pcie0", "pcie1", "pcie2";
++
++ mediatek,hifsys = <&hifsys>;
++
++ bus-range = <0x00 0xff>;
++ #address-cells = <3>;
++ #size-cells = <2>;
++
++ ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000 /* io space */
++ 0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* pci memory */
++
++ status = "disabled";
++
++ pcie@1,0 {
++ device_type = "pci";
++ reg = <0x0800 0 0 0 0>;
++
++ #address-cells = <3>;
++ #size-cells = <2>;
++ ranges;
++ };
++
++ pcie@2,0{
++ device_type = "pci";
++ reg = <0x1000 0 0 0 0>;
++
++ #address-cells = <3>;
++ #size-cells = <2>;
++ ranges;
++ };
++
++ pcie@3,0{
++ device_type = "pci";
++ reg = <0x1800 0 0 0 0>;
++
++ #address-cells = <3>;
++ #size-cells = <2>;
++ ranges;
++ };
++ };
++
++ ethsys: syscon@1b000000 {
++ #address-cells = <1>;
++ #size-cells = <1>;
++ compatible = "mediatek,mt2701-ethsys", "syscon";
++ reg = <0 0x1b000000 0 0x1000>;
++ #clock-cells = <1>;
++ };
++
++ eth: ethernet@1b100000 {
++ compatible = "mediatek,mt7623-eth";
++ reg = <0 0x1b100000 0 0x10000>;
++
++ clocks = <&topckgen CLK_TOP_ETHIF_SEL>;
++ clock-names = "ethif";
++ interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_LOW>;
++ power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
++
++ mediatek,ethsys = <&ethsys>;
++ mediatek,switch = <&gsw>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ status = "disabled";
++
++ gmac1: mac@0 {
++ compatible = "mediatek,eth-mac";
++ reg = <0>;
++
++ status = "disabled";
++ };
++
++ gmac2: mac@1 {
++ compatible = "mediatek,eth-mac";
++ reg = <1>;
++
++ status = "disabled";
++ };
++
++ mdio-bus {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ phy1f: ethernet-phy@1f {
++ reg = <0x1f>;
++ phy-mode = "rgmii";
++ };
++ };
++ };
++
++ gsw: switch@1b100000 {
++ compatible = "mediatek,mt7623-gsw";
++ reg = <0 0x1b110000 0 0x300000>;
++ interrupt-parent = <&pio>;
++ interrupts = <168 IRQ_TYPE_EDGE_RISING>;
++ clocks = <&apmixedsys CLK_APMIXED_TRGPLL>,
++ <&ethsys CLK_ETHSYS_ESW>,
++ <&ethsys CLK_ETHSYS_GP2>,
++ <&ethsys CLK_ETHSYS_GP1>;
++ clock-names = "trgpll", "esw", "gp2", "gp1";
++ mt7530-supply = <&mt6323_vpa_reg>;
++ mediatek,pctl-regmap = <&syscfg_pctl_a>;
++ mediatek,ethsys = <&ethsys>;
++ status = "disabled";
++ };
++};
+diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
+index 37dd438..7fb605e 100644
+--- a/arch/arm/mach-mediatek/Kconfig
++++ b/arch/arm/mach-mediatek/Kconfig
+@@ -21,6 +21,10 @@ config MACH_MT6592
+ bool "MediaTek MT6592 SoCs support"
+ default ARCH_MEDIATEK
+
++config MACH_MT7623
++ bool "MediaTek MT7623 SoCs support"
++ default ARCH_MEDIATEK
++
+ config MACH_MT8127
+ bool "MediaTek MT8127 SoCs support"
+ default ARCH_MEDIATEK
+diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c
+index d019a08..bcfca37 100644
+--- a/arch/arm/mach-mediatek/mediatek.c
++++ b/arch/arm/mach-mediatek/mediatek.c
+@@ -46,6 +46,7 @@ static void __init mediatek_timer_init(void)
+ static const char * const mediatek_board_dt_compat[] = {
+ "mediatek,mt6589",
+ "mediatek,mt6592",
++ "mediatek,mt7623",
+ "mediatek,mt8127",
+ "mediatek,mt8135",
+ NULL,
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch b/target/linux/mediatek/patches-4.4/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch
new file mode 100644
index 0000000000..227483355a
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch
@@ -0,0 +1,160 @@
+From 5b51a1e93ccaaec4cd90b73ee20cea219af2f151 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 6 Jan 2016 21:55:10 +0100
+Subject: [PATCH 24/53] dt-bindings: add MediaTek PCIe binding documentation
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ .../devicetree/bindings/pci/mediatek-pcie.txt | 140 ++++++++++++++++++++
+ 1 file changed, 140 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pci/mediatek-pcie.txt
+
+diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt
+new file mode 100644
+index 0000000..8fea3ed
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt
+@@ -0,0 +1,140 @@
++Mediatek PCIe controller
++
++Required properties:
++- compatible: Should be one of:
++ - "mediatek,mt2701-pcie"
++ - "mediatek,mt7623-pcie"
++- device_type: Must be "pci"
++- reg: A list of physical base address and length for each set of controller
++ registers. A list of register ranges to use. Must contain an
++ entry for each entry in the reg-names property.
++- reg-names: Must include the following entries:
++ "pcie": PCIe registers
++ "pcie phy0": PCIe PHY0 registers
++ "pcie phy1": PCIe PHY0 registers
++ "pcie phy2": PCIe PHY0 registers
++- interrupts: A list of interrupt outputs of the controller. Must contain an
++ entry for each entry in the interrupt-names property.
++- interrupt-names: Must include the following entries:
++ "pcie0": The interrupt that is asserted for port0
++ "pcie1": The interrupt that is asserted for port1
++ "pcie2": The interrupt that is asserted for port2
++- bus-range: Range of bus numbers associated with this controller
++- #address-cells: Address representation for root ports (must be 3)
++- #size-cells: Size representation for root ports (must be 2)
++- ranges: Describes the translation of addresses for root ports and standard
++ PCI regions. The entries must be 6 cells each.
++ Please refer to the standard PCI bus binding document for a more detailed
++ explanation.
++- #interrupt-cells: Size representation for interrupts (must be 1)
++- clocks: Must contain an entry for each entry in clock-names.
++ See ../clocks/clock-bindings.txt for details.
++- clock-names: Must include the following entries:
++ - pcie0
++ - pcie1
++ - pcie2
++- resets: Must contain an entry for each entry in reset-names.
++ See ../reset/reset.txt for details.
++- reset-names: Must include the following entries:
++ - pcie0
++ - pcie1
++ - pcie2
++- mediatek,hifsys: Must contain a phandle to the HIFSYS syscon range.
++Root ports are defined as subnodes of the PCIe controller node.
++
++Required properties:
++- device_type: Must be "pci"
++- assigned-addresses: Address and size of the port configuration registers
++- reg: PCI bus address of the root port
++- #address-cells: Must be 3
++- #size-cells: Must be 2
++- ranges: Sub-ranges distributed from the PCIe controller node. An empty
++ property is sufficient.
++
++Example:
++
++SoC DTSI:
++
++ hifsys: clock-controller@1a000000 {
++ compatible = "mediatek,mt7623-hifsys",
++ "mediatek,mt2701-hifsys",
++ "syscon";
++ reg = <0 0x1a000000 0 0x1000>;
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ };
++
++ pcie-controller@1a140000 {
++ compatible = "mediatek,mt7623-pcie";
++ device_type = "pci";
++ reg = <0 0x1a140000 0 0x8000>, /* PCI-Express registers */
++ <0 0x1a149000 0 0x1000>, /* PCI-Express PHY0 */
++ <0 0x1a14a000 0 0x1000>, /* PCI-Express PHY1 */
++ <0 0x1a244000 0 0x1000>; /* PCI-Express PHY2 */
++ reg-names = "pcie", "pcie phy0", "pcie phy1", "pcie phy2";
++ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>,
++ <GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>,
++ <GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>;
++ interrupt-names = "pcie0", "pcie1", "pcie2";
++ clocks = <&topckgen CLK_TOP_ETHIF_SEL>;
++ clock-names = "pcie";
++ power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>;
++ resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>,
++ <&hifsys MT2701_HIFSYS_PCIE1_RST>,
++ <&hifsys MT2701_HIFSYS_PCIE2_RST>;
++ reset-names = "pcie0", "pice1", "pcie2";
++
++ bus-range = <0x00 0xff>;
++ #address-cells = <3>;
++ #size-cells = <2>;
++
++ mediatek,hifsys = <&hifsys>;
++
++ ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000 /* io space */
++ 0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* pci memory */
++
++ status = "disabled";
++
++ pcie@1,0 {
++ device_type = "pci";
++ reg = <0x0800 0 0 0 0>;
++
++ #address-cells = <3>;
++ #size-cells = <2>;
++ ranges;
++
++ status = "disabled";
++ };
++
++ pcie@2,0{
++ device_type = "pci";
++ reg = <0x1000 0 0 0 0>;
++
++ #address-cells = <3>;
++ #size-cells = <2>;
++ ranges;
++
++ status = "disabled";
++ };
++
++ pcie@3,0{
++ device_type = "pci";
++ reg = <0x1800 0 0 0 0>;
++
++ #address-cells = <3>;
++ #size-cells = <2>;
++ ranges;
++
++ status = "disabled";
++ };
++ };
++
++Board DTS:
++
++ pcie-controller {
++ status = "okay";
++
++ pci@1,0 {
++ status = "okay";
++ };
++ };
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch b/target/linux/mediatek/patches-4.4/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch
new file mode 100644
index 0000000000..9e12892bc4
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch
@@ -0,0 +1,710 @@
+From fc6d1a9f37cddd79c0c149e3f1394d393ac05772 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Tue, 5 Jan 2016 20:20:04 +0100
+Subject: [PATCH 25/53] PCI: mediatek: add support for PCIe found on
+ MT7623/MT2701
+
+Add PCIe controller support on MediaTek MT2701/MT7623. The driver supports
+a single Root complex (RC) with 3 Root Ports. The SoCs supports a Gen2
+1-lan Link on each port.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/arm/mach-mediatek/Kconfig | 1 +
+ drivers/pci/host/Kconfig | 11 +
+ drivers/pci/host/Makefile | 1 +
+ drivers/pci/host/pcie-mediatek.c | 641 ++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 654 insertions(+)
+ create mode 100644 drivers/pci/host/pcie-mediatek.c
+
+diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
+index 7fb605e..a7fef77 100644
+--- a/arch/arm/mach-mediatek/Kconfig
++++ b/arch/arm/mach-mediatek/Kconfig
+@@ -24,6 +24,7 @@ config MACH_MT6592
+ config MACH_MT7623
+ bool "MediaTek MT7623 SoCs support"
+ default ARCH_MEDIATEK
++ select MIGHT_HAVE_PCI
+
+ config MACH_MT8127
+ bool "MediaTek MT8127 SoCs support"
+diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
+index f131ba9..912f0e1 100644
+--- a/drivers/pci/host/Kconfig
++++ b/drivers/pci/host/Kconfig
+@@ -172,4 +172,15 @@ config PCI_HISI
+ help
+ Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC
+
++config PCIE_MTK
++ bool "Mediatek PCIe Controller"
++ depends on MACH_MT2701 || MACH_MT7623
++ depends on OF
++ depends on PCI
++ help
++ Say Y here if you want to enable PCI controller support on Mediatek MT7623.
++ MT7623 PCIe supports single Root complex (RC) with 3 Root Ports.
++ Each port supports a Gen2 1-lan Link.
++ PCIe include one Host/PCI bridge and 3 PCIe MAC.
++
+ endmenu
+diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
+index 9d4d3c6..3b53374 100644
+--- a/drivers/pci/host/Makefile
++++ b/drivers/pci/host/Makefile
+@@ -20,3 +20,4 @@ obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
+ obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
+ obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
+ obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
++obj-$(CONFIG_PCIE_MTK) += pcie-mediatek.o
+diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c
+new file mode 100644
+index 0000000..ef03952
+--- /dev/null
++++ b/drivers/pci/host/pcie-mediatek.c
+@@ -0,0 +1,641 @@
++/*
++ * Mediatek MT2701/MT7623 SoC PCIE support
++ *
++ * Copyright (C) 2015 Mediatek
++ * Copyright (C) 2015 Ziv Huang <ziv.huang@mediatek.com>
++ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ */
++
++#include <linux/kernel.h>
++#include <linux/pci.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/init.h>
++#include <linux/device.h>
++#include <linux/io.h>
++#include <linux/delay.h>
++#include <asm/irq.h>
++#include <asm/mach/pci.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_pci.h>
++#include <linux/of_platform.h>
++#include <linux/of_irq.h>
++#include <linux/reset.h>
++#include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/pm_runtime.h>
++#include <linux/clk.h>
++#include <linux/regmap.h>
++#include <linux/mfd/syscon.h>
++
++#define MEMORY_BASE 0x80000000
++
++/* PCIE Registers */
++#define PCICFG 0x00
++#define PCIINT 0x08
++#define PCIENA 0x0c
++#define CFGADDR 0x20
++#define CFGDATA 0x24
++#define MEMBASE 0x28
++#define IOBASE 0x2c
++
++/* per Port Registers */
++#define BAR0SETUP 0x10
++#define IMBASEBAR0 0x18
++#define PCIE_CLASS 0x34
++#define PCIE_SISTAT 0x50
++
++#define MTK_PCIE_HIGH_PERF BIT(14)
++#define PCIEP0_BASE 0x2000
++#define PCIEP1_BASE 0x3000
++#define PCIEP2_BASE 0x4000
++
++#define PHY_P0_CTL 0x9000
++#define PHY_P1_CTL 0xa000
++#define PHY_P2_CTL 0x4000
++
++#define RSTCTL_PCIE0_RST BIT(24)
++#define RSTCTL_PCIE1_RST BIT(25)
++#define RSTCTL_PCIE2_RST BIT(26)
++
++#define HIFSYS_SYSCFG1 0x14
++#define HIFSYS_SYSCFG1_PHY2_MASK (0x3 << 20)
++
++#define MTK_PHY_CLK 0xb00
++#define MTK_PHY_CLKDRV_OFFSET BIT(2)
++#define MTK_PHY_CLKDRV_OFFSET_MASK 0xe
++#define MTK_PHY_PLL 0xb04
++#define MTK_PHY_CLKDRV_AMP BIT(30)
++#define MTK_PHY_CLKDRV_AMP_MASK 0xe0000000
++#define MTK_PHY_REFCLK_SEL 0xc00
++#define MTK_PHY_XTAL_EXT_EN (BIT(17) | BIT(12))
++#define MTK_PHY_XTAL_EXT_EN_MASK 0x33000
++#define MTK_PHY_PLL_BC 0xc08
++#define MTK_PHY_PLL_BC_PE2H 0xc0
++#define MTK_PHY_PLL_BC_PE2H_MASK 0x380000
++#define MTK_PHY_PLL_IC 0xc0c
++#define MTK_PHY_PLL_IC_BR_PE2H BIT(28)
++#define MTK_PHY_PLL_IC_BR_PE2H_MASK 0x30000000
++#define MTK_PHY_PLL_IC_PE2H BIT(12)
++#define MTK_PHY_PLL_IC_PE2H_MASK 0xf000
++#define MTK_PHY_PLL_IR 0xc10
++#define MTK_PHY_PLL_IR_PE2H BIT(17)
++#define MTK_PHY_PLL_IR_PE2H_MASK 0xf0000
++#define MTK_PHY_PLL_BP 0xc14
++#define MTK_PHY_PLL_BP_PE2H (BIT(19) | BIT(17))
++#define MTK_PHY_PLL_BP_PE2H_MASK 0xf0000
++#define MTK_PHY_SSC_DELTA1 0xc3c
++#define MTK_PHY_SSC_DELTA1_PE2H (0x3c << 16)
++#define MTK_PHY_SSC_DELTA1_PE2H_MASK 0xffff0000
++#define MTK_PHY_SSC_DELTA 0xc48
++#define MTK_PHY_SSC_DELTA_PE2H 0x36
++#define MTK_PHY_SSC_DELTA_PE2H_MASK 0xffff
++
++#define MAX_PORT_NUM 3
++
++struct mtk_pcie_port {
++ int id;
++ int enable;
++ int irq;
++ u32 link;
++ void __iomem *phy_base;
++ struct reset_control *rstc;
++};
++
++#define mtk_foreach_port(pcie, p) \
++ for ((p) = pcie->port; \
++ (p) != &pcie->port[MAX_PORT_NUM]; (p)++)
++
++struct mtk_pcie {
++ struct device *dev;
++ void __iomem *pcie_base;
++ struct regmap *hifsys;
++
++ struct resource io;
++ struct resource pio;
++ struct resource mem;
++ struct resource prefetch;
++ struct resource busn;
++
++ u32 io_bus_addr;
++ u32 mem_bus_addr;
++
++ struct clk *clk;
++
++ struct mtk_pcie_port port[MAX_PORT_NUM];
++ int pcie_card_link;
++};
++
++static struct mtk_pcie_port_data {
++ u32 base;
++ u32 perst_n;
++ u32 interrupt_en;
++} mtk_pcie_port_data[MAX_PORT_NUM] = {
++ { PCIEP0_BASE, BIT(1), BIT(20) },
++ { PCIEP1_BASE, BIT(2), BIT(21) },
++ { PCIEP2_BASE, BIT(3), BIT(22) },
++};
++
++static const struct mtk_phy_init {
++ uint32_t reg;
++ uint32_t mask;
++ uint32_t val;
++} mtk_phy_init[] = {
++ { MTK_PHY_REFCLK_SEL, MTK_PHY_XTAL_EXT_EN_MASK, MTK_PHY_XTAL_EXT_EN },
++ { MTK_PHY_PLL, MTK_PHY_CLKDRV_AMP_MASK, MTK_PHY_CLKDRV_AMP },
++ { MTK_PHY_CLK, MTK_PHY_CLKDRV_OFFSET_MASK, MTK_PHY_CLKDRV_OFFSET },
++ { MTK_PHY_SSC_DELTA1, MTK_PHY_SSC_DELTA1_PE2H_MASK, MTK_PHY_SSC_DELTA1_PE2H },
++ { MTK_PHY_SSC_DELTA, MTK_PHY_SSC_DELTA_PE2H_MASK, MTK_PHY_SSC_DELTA_PE2H },
++ { MTK_PHY_PLL_IC, MTK_PHY_PLL_IC_BR_PE2H_MASK, MTK_PHY_PLL_IC_BR_PE2H },
++ { MTK_PHY_PLL_BC, MTK_PHY_PLL_BC_PE2H_MASK, MTK_PHY_PLL_BC_PE2H },
++ { MTK_PHY_PLL_IR, MTK_PHY_PLL_IR_PE2H_MASK, MTK_PHY_PLL_IR_PE2H },
++ { MTK_PHY_PLL_IC, MTK_PHY_PLL_IC_PE2H_MASK, MTK_PHY_PLL_IC_PE2H },
++ { MTK_PHY_PLL_BP, MTK_PHY_PLL_BP_PE2H_MASK, MTK_PHY_PLL_BP_PE2H },
++};
++
++static struct mtk_pcie *sys_to_pcie(struct pci_sys_data *sys)
++{
++ return sys->private_data;
++}
++
++static void pcie_w32(struct mtk_pcie *pcie, u32 val, unsigned reg)
++{
++ iowrite32(val, pcie->pcie_base + reg);
++}
++
++static u32 pcie_r32(struct mtk_pcie *pcie, unsigned reg)
++{
++ return ioread32(pcie->pcie_base + reg);
++}
++
++static void pcie_m32(struct mtk_pcie *pcie, u32 mask, u32 val, unsigned reg)
++{
++ u32 v = pcie_r32(pcie, reg);
++
++ v &= mask;
++ v |= val;
++ pcie_w32(pcie, v, reg);
++}
++
++static int pcie_config_read(struct pci_bus *bus, unsigned int devfn, int where,
++ int size, u32 *val)
++{
++ struct mtk_pcie *pcie = sys_to_pcie(bus->sysdata);
++ unsigned int slot = PCI_SLOT(devfn);
++ u8 func = PCI_FUNC(devfn);
++ u32 address;
++ u32 data;
++ u32 num = 0;
++
++ if (bus)
++ num = bus->number;
++
++ address = (((where & 0xf00) >> 8) << 24) |
++ (num << 16) |
++ (slot << 11) |
++ (func << 8) |
++ (where & 0xfc);
++
++ pcie_w32(pcie, address, CFGADDR);
++ data = pcie_r32(pcie, CFGDATA);
++
++ switch (size) {
++ case 1:
++ *val = (data >> ((where & 3) << 3)) & 0xff;
++ break;
++ case 2:
++ *val = (data >> ((where & 3) << 3)) & 0xffff;
++ break;
++ case 4:
++ *val = data;
++ break;
++ }
++
++ return PCIBIOS_SUCCESSFUL;
++}
++
++static int pcie_config_write(struct pci_bus *bus, unsigned int devfn, int where,
++ int size, u32 val)
++{
++ struct mtk_pcie *pcie = sys_to_pcie(bus->sysdata);
++ unsigned int slot = PCI_SLOT(devfn);
++ u8 func = PCI_FUNC(devfn);
++ u32 address;
++ u32 data;
++ u32 num = 0;
++
++ if (bus)
++ num = bus->number;
++
++ address = (((where & 0xf00) >> 8) << 24) |
++ (num << 16) | (slot << 11) | (func << 8) | (where & 0xfc);
++ pcie_w32(pcie, address, CFGADDR);
++ data = pcie_r32(pcie, CFGDATA);
++
++ switch (size) {
++ case 1:
++ data = (data & ~(0xff << ((where & 3) << 3))) |
++ (val << ((where & 3) << 3));
++ break;
++ case 2:
++ data = (data & ~(0xffff << ((where & 3) << 3))) |
++ (val << ((where & 3) << 3));
++ break;
++ case 4:
++ data = val;
++ break;
++ }
++ pcie_w32(pcie, data, CFGDATA);
++
++ return PCIBIOS_SUCCESSFUL;
++}
++
++static struct pci_ops mtk_pcie_ops = {
++ .read = pcie_config_read,
++ .write = pcie_config_write,
++};
++
++static int __init mtk_pcie_setup(int nr, struct pci_sys_data *sys)
++{
++ struct mtk_pcie *pcie = sys_to_pcie(sys);
++
++ request_resource(&ioport_resource, &pcie->pio);
++ request_resource(&iomem_resource, &pcie->mem);
++
++ pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
++ pci_add_resource_offset(&sys->resources, &pcie->pio, sys->io_offset);
++ pci_add_resource(&sys->resources, &pcie->busn);
++
++ return 1;
++}
++
++static struct pci_bus * __init mtk_pcie_scan_bus(int nr,
++ struct pci_sys_data *sys)
++{
++ struct mtk_pcie *pcie = sys_to_pcie(sys);
++ struct pci_bus *bus;
++
++ bus = pci_create_root_bus(pcie->dev, sys->busnr, &mtk_pcie_ops, sys,
++ &sys->resources);
++ if (!bus)
++ return NULL;
++
++ pci_scan_child_bus(bus);
++
++ return bus;
++}
++
++static int __init mtk_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
++{
++ struct mtk_pcie *pcie = sys_to_pcie(dev->bus->sysdata);
++ struct mtk_pcie_port *port;
++ int irq = -1;
++
++ mtk_foreach_port(pcie, port)
++ if (port->id == slot)
++ irq = port->irq;
++
++ return irq;
++}
++
++static void mtk_pcie_configure_phy(struct mtk_pcie *pcie,
++ struct mtk_pcie_port *port)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(mtk_phy_init); i++) {
++ void __iomem *phy_addr = port->phy_base + mtk_phy_init[i].reg;
++ u32 val = ioread32(phy_addr);
++
++ val &= ~mtk_phy_init[i].mask;
++ val |= mtk_phy_init[i].val;
++ iowrite32(val, phy_addr);
++ }
++ usleep_range(5000, 6000);
++}
++
++static void mtk_pcie_configure_rc(struct mtk_pcie *pcie,
++ struct mtk_pcie_port *port,
++ struct pci_bus *bus)
++{
++ u32 val = 0;
++
++ pcie_config_write(bus,
++ port->id << 3,
++ PCI_BASE_ADDRESS_0, 4, MEMORY_BASE);
++
++ pcie_config_read(bus,
++ port->id << 3, PCI_BASE_ADDRESS_0, 4, &val);
++
++ /* Configure RC Credit */
++ pcie_config_read(bus, port->id << 3, 0x73c, 4, &val);
++ val &= ~(0x9fff) << 16;
++ val |= 0x806c << 16;
++ pcie_config_write(bus, port->id << 3, 0x73c, 4, val);
++
++ /* Configure RC FTS number */
++ pcie_config_read(bus, port->id << 3, 0x70c, 4, &val);
++ val &= ~(0xff3) << 8;
++ val |= 0x50 << 8;
++ pcie_config_write(bus, port->id << 3, 0x70c, 4, val);
++}
++
++static int mtk_pcie_preinit(struct mtk_pcie *pcie)
++{
++ struct mtk_pcie_port *port;
++ u32 val = 0;
++ struct pci_bus bus;
++ struct pci_sys_data sys;
++
++ memset(&bus, 0, sizeof(bus));
++ memset(&sys, 0, sizeof(sys));
++ bus.sysdata = (void *)&sys;
++ sys.private_data = (void *)pcie;
++
++ pcibios_min_io = 0;
++ pcibios_min_mem = 0;
++
++ /* The PHY on Port 2 is shared with USB */
++ if (pcie->port[2].enable)
++ regmap_update_bits(pcie->hifsys, HIFSYS_SYSCFG1,
++ HIFSYS_SYSCFG1_PHY2_MASK, 0x0);
++
++ /* PCIe RC Reset */
++ mtk_foreach_port(pcie, port)
++ if (port->enable)
++ reset_control_assert(port->rstc);
++ usleep_range(1000, 2000);
++ mtk_foreach_port(pcie, port)
++ if (port->enable)
++ reset_control_deassert(port->rstc);
++ usleep_range(1000, 2000);
++
++ /* Configure PCIe PHY */
++ mtk_foreach_port(pcie, port)
++ if (port->enable)
++ mtk_pcie_configure_phy(pcie, port);
++
++ /* PCIe EP reset */
++ val = 0;
++ mtk_foreach_port(pcie, port)
++ if (port->enable)
++ val |= mtk_pcie_port_data[port->id].perst_n;
++ pcie_w32(pcie, pcie_r32(pcie, PCICFG) | val, PCICFG);
++ usleep_range(1000, 2000);
++ pcie_w32(pcie, pcie_r32(pcie, PCICFG) & ~val, PCICFG);
++ usleep_range(1000, 2000);
++ msleep(100);
++
++ /* check the link status */
++ val = 0;
++ mtk_foreach_port(pcie, port) {
++ if (port->enable) {
++ u32 base = mtk_pcie_port_data[port->id].base;
++
++ if ((pcie_r32(pcie, base + PCIE_SISTAT) & 0x1))
++ port->link = 1;
++ else
++ reset_control_assert(port->rstc);
++ }
++ }
++
++ mtk_foreach_port(pcie, port)
++ if (port->link)
++ pcie->pcie_card_link++;
++
++ if (!pcie->pcie_card_link)
++ return -ENODEV;
++
++ pcie_w32(pcie, pcie->mem_bus_addr, MEMBASE);
++ pcie_w32(pcie, pcie->io_bus_addr, IOBASE);
++
++ mtk_foreach_port(pcie, port) {
++ if (port->link) {
++ u32 base = mtk_pcie_port_data[port->id].base;
++ u32 inte = mtk_pcie_port_data[port->id].interrupt_en;
++
++ pcie_m32(pcie, 0, inte, PCIENA);
++ pcie_w32(pcie, 0x7fff0001, base + BAR0SETUP);
++ pcie_w32(pcie, MEMORY_BASE, base + IMBASEBAR0);
++ pcie_w32(pcie, 0x06040001, base + PCIE_CLASS);
++ }
++ }
++
++ mtk_foreach_port(pcie, port)
++ if (port->link)
++ mtk_pcie_configure_rc(pcie, port, &bus);
++
++ return 0;
++}
++
++static int mtk_pcie_parse_dt(struct mtk_pcie *pcie)
++{
++ struct device_node *np = pcie->dev->of_node, *port;
++ struct of_pci_range_parser parser;
++ struct of_pci_range range;
++ struct resource res;
++ int err;
++
++ pcie->hifsys = syscon_regmap_lookup_by_phandle(np, "mediatek,hifsys");
++ if (IS_ERR(pcie->hifsys)) {
++ dev_err(pcie->dev, "missing \"mediatek,hifsys\" phandle\n");
++ return PTR_ERR(pcie->hifsys);
++ }
++
++ if (of_pci_range_parser_init(&parser, np)) {
++ dev_err(pcie->dev, "missing \"ranges\" property\n");
++ return -EINVAL;
++ }
++
++ for_each_of_pci_range(&parser, &range) {
++ err = of_pci_range_to_resource(&range, np, &res);
++ if (err < 0) {
++ dev_err(pcie->dev, "failed to read resource range\n");
++ return err;
++ }
++
++ switch (res.flags & IORESOURCE_TYPE_BITS) {
++ case IORESOURCE_IO:
++ memcpy(&pcie->pio, &res, sizeof(res));
++ pcie->pio.start = (resource_size_t)range.pci_addr;
++ pcie->pio.end = (resource_size_t)
++ (range.pci_addr + range.size - 1);
++ pcie->io_bus_addr = (resource_size_t)range.cpu_addr;
++ break;
++
++ case IORESOURCE_MEM:
++ if (res.flags & IORESOURCE_PREFETCH) {
++ memcpy(&pcie->prefetch, &res, sizeof(res));
++ pcie->prefetch.name = "prefetchable";
++ pcie->prefetch.start =
++ (resource_size_t)range.pci_addr;
++ pcie->prefetch.end = (resource_size_t)
++ (range.pci_addr + range.size - 1);
++ } else {
++ memcpy(&pcie->mem, &res, sizeof(res));
++ pcie->mem.name = "non-prefetchable";
++ pcie->mem.start = (resource_size_t)
++ range.pci_addr;
++ pcie->prefetch.end = (resource_size_t)
++ (range.pci_addr + range.size - 1);
++ pcie->mem_bus_addr = (resource_size_t)
++ range.cpu_addr;
++ }
++ break;
++ }
++ }
++
++ err = of_pci_parse_bus_range(np, &pcie->busn);
++ if (err < 0) {
++ dev_err(pcie->dev, "failed to parse ranges property: %d\n",
++ err);
++ pcie->busn.name = np->name;
++ pcie->busn.start = 0;
++ pcie->busn.end = 0xff;
++ pcie->busn.flags = IORESOURCE_BUS;
++ }
++
++ /* parse root ports */
++ for_each_child_of_node(np, port) {
++ unsigned int index;
++ char rst[] = "pcie0";
++
++ err = of_pci_get_devfn(port);
++ if (err < 0) {
++ dev_err(pcie->dev, "failed to parse address: %d\n",
++ err);
++ return err;
++ }
++
++ index = PCI_SLOT(err);
++ if (index > MAX_PORT_NUM) {
++ dev_err(pcie->dev, "invalid port number: %d\n", index);
++ continue;
++ }
++ index--;
++ pcie->port[index].id = index;
++
++ if (!of_device_is_available(port))
++ continue;
++
++ rst[4] += index;
++ pcie->port[index].rstc = devm_reset_control_get(pcie->dev,
++ rst);
++ if (!IS_ERR(pcie->port[index].rstc))
++ pcie->port[index].enable = 1;
++ }
++ return 0;
++}
++
++static int mtk_pcie_get_resources(struct mtk_pcie *pcie)
++{
++ struct platform_device *pdev = to_platform_device(pcie->dev);
++ struct mtk_pcie_port *port;
++ struct resource *res;
++
++ pcie->clk = devm_clk_get(&pdev->dev, "pcie");
++ if (IS_ERR(pcie->clk)) {
++ dev_err(&pdev->dev, "Failed to get pcie clk\n");
++ return PTR_ERR(pcie->clk);
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ pcie->pcie_base = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(pcie->pcie_base)) {
++ dev_err(&pdev->dev, "Failed to get pcie range\n");
++ return PTR_ERR(pcie->pcie_base);
++ }
++
++ mtk_foreach_port(pcie, port) {
++ if (!port->enable)
++ continue;
++ res = platform_get_resource(pdev, IORESOURCE_MEM, port->id + 1);
++ port->phy_base = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(port->phy_base)) {
++ dev_err(&pdev->dev, "Failed to get pcie phy%d range %p\n",
++ port->id, port->phy_base);
++ return PTR_ERR(port->phy_base);
++ }
++ port->irq = platform_get_irq(pdev, port->id);
++ }
++
++ return clk_prepare_enable(pcie->clk);
++}
++
++static int mtk_pcie_probe(struct platform_device *pdev)
++{
++ struct mtk_pcie *pcie;
++ struct hw_pci hw;
++ int ret;
++
++ pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
++ if (!pcie)
++ return -ENOMEM;
++
++ pcie->dev = &pdev->dev;
++ ret = mtk_pcie_parse_dt(pcie);
++ if (ret < 0)
++ return ret;
++
++ pm_runtime_enable(&pdev->dev);
++ pm_runtime_get_sync(&pdev->dev);
++
++ ret = mtk_pcie_get_resources(pcie);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "failed to request resources: %d\n", ret);
++ goto err_out;
++ }
++
++ ret = mtk_pcie_preinit(pcie);
++ if (ret)
++ return ret;
++
++ memset(&hw, 0, sizeof(hw));
++ hw.nr_controllers = 1;
++ hw.private_data = (void **)&pcie;
++ hw.setup = mtk_pcie_setup;
++ hw.map_irq = mtk_pcie_map_irq;
++ hw.scan = mtk_pcie_scan_bus;
++
++ pci_common_init_dev(pcie->dev, &hw);
++ platform_set_drvdata(pdev, pcie);
++
++ return 0;
++
++err_out:
++ clk_disable_unprepare(pcie->clk);
++ pm_runtime_put_sync(&pdev->dev);
++ pm_runtime_disable(&pdev->dev);
++
++ return ret;
++}
++
++static const struct of_device_id mtk_pcie_ids[] = {
++ { .compatible = "mediatek,mt2701-pcie" },
++ { .compatible = "mediatek,mt7623-pcie" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, mtk_pcie_ids);
++
++static struct platform_driver mtk_pcie_driver = {
++ .probe = mtk_pcie_probe,
++ .driver = {
++ .name = "mediatek-pcie",
++ .owner = THIS_MODULE,
++ .of_match_table = of_match_ptr(mtk_pcie_ids),
++ },
++};
++
++static int __init mtk_pcie_init(void)
++{
++ return platform_driver_register(&mtk_pcie_driver);
++}
++
++module_init(mtk_pcie_init);
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0026-scpsys-various-fixes.patch b/target/linux/mediatek/patches-4.4/0026-scpsys-various-fixes.patch
new file mode 100644
index 0000000000..1ff25157e9
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0026-scpsys-various-fixes.patch
@@ -0,0 +1,65 @@
+From f027ce51ff728a22428fb0b7107edf9e1bd61712 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 21 Feb 2016 13:52:12 +0100
+Subject: [PATCH 26/53] scpsys: various fixes
+
+---
+ drivers/clk/mediatek/clk-mt2701.c | 2 ++
+ drivers/soc/mediatek/mtk-scpsys-mt2701.c | 8 --------
+ include/dt-bindings/power/mt2701-power.h | 4 ++--
+ 3 files changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c
+index 0e40bb8..812b347 100644
+--- a/drivers/clk/mediatek/clk-mt2701.c
++++ b/drivers/clk/mediatek/clk-mt2701.c
+@@ -1043,6 +1043,8 @@ static void __init mtk_ethsys_init(struct device_node *node)
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
++
++ mtk_register_reset_controller(node, 1, 0x34);
+ }
+ CLK_OF_DECLARE(mtk_ethsys, "mediatek,mt2701-ethsys", mtk_ethsys_init);
+
+diff --git a/drivers/soc/mediatek/mtk-scpsys-mt2701.c b/drivers/soc/mediatek/mtk-scpsys-mt2701.c
+index 3a31946..19489bc 100644
+--- a/drivers/soc/mediatek/mtk-scpsys-mt2701.c
++++ b/drivers/soc/mediatek/mtk-scpsys-mt2701.c
+@@ -61,14 +61,6 @@ static const struct scp_domain_data scp_domain_data[] = {
+ .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_DISP,
+ .active_wakeup = true,
+ },
+- [MT2701_POWER_DOMAIN_MFG] = {
+- .name = "mfg",
+- .sta_mask = MFG_PWR_STA_MASK,
+- .ctl_offs = SPM_MFG_PWR_CON,
+- .sram_pdn_bits = GENMASK(11, 8),
+- .sram_pdn_ack_bits = GENMASK(12, 12),
+- .active_wakeup = true,
+- },
+ [MT2701_POWER_DOMAIN_VDEC] = {
+ .name = "vdec",
+ .sta_mask = VDE_PWR_STA_MASK,
+diff --git a/include/dt-bindings/power/mt2701-power.h b/include/dt-bindings/power/mt2701-power.h
+index 64cc826..c168597 100644
+--- a/include/dt-bindings/power/mt2701-power.h
++++ b/include/dt-bindings/power/mt2701-power.h
+@@ -16,12 +16,12 @@
+
+ #define MT2701_POWER_DOMAIN_CONN 0
+ #define MT2701_POWER_DOMAIN_DISP 1
+-#define MT2701_POWER_DOMAIN_MFG 2
++//#define MT2701_POWER_DOMAIN_MFG 2
+ #define MT2701_POWER_DOMAIN_VDEC 3
+ #define MT2701_POWER_DOMAIN_ISP 4
+ #define MT2701_POWER_DOMAIN_BDP 5
+ #define MT2701_POWER_DOMAIN_ETH 6
+ #define MT2701_POWER_DOMAIN_HIF 7
+-#define MT2701_POWER_DOMAIN_IFR_MSC 8
++#define MT2701_POWER_DOMAIN_IFR_MSC 2
+
+ #endif /* _DT_BINDINGS_POWER_MT2701_POWER_H */
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0027-soc-mediatek-PMIC-wrap-Clear-the-vldclr-if-state-mac.patch b/target/linux/mediatek/patches-4.4/0027-soc-mediatek-PMIC-wrap-Clear-the-vldclr-if-state-mac.patch
new file mode 100644
index 0000000000..970860cff7
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0027-soc-mediatek-PMIC-wrap-Clear-the-vldclr-if-state-mac.patch
@@ -0,0 +1,74 @@
+From af4a99b856b584b2426757e905e9b6f39906ce05 Mon Sep 17 00:00:00 2001
+From: Henry Chen <henryc.chen@mediatek.com>
+Date: Mon, 4 Jan 2016 20:02:52 +0800
+Subject: [PATCH 27/53] soc: mediatek: PMIC wrap: Clear the vldclr if state
+ machine stay on FSM_VLDCLR state.
+
+Sometimes PMIC is too busy to send data in time to cause pmic wrap timeout,
+because pmic wrap is waiting for FSM_VLDCLR after finishing WACS2_CMD. It
+just return error when issue happened, so the state machine will stay on
+FSM_VLDCLR state when data send back later by PMIC and timeout again in next
+time because pmic wrap waiting for FSM_IDLE state at the beginning of the
+read/write function.
+
+Clear the vldclr when timeout if state machine stay on FSM_VLDCLR.
+
+Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
+Tested-by: Ricky Liang <jcliang@chromium.org>
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 22 ++++++++++++++++++++--
+ 1 file changed, 20 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index 105597a..696071b 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -412,6 +412,20 @@ static bool pwrap_is_fsm_vldclr(struct pmic_wrapper *wrp)
+ return PWRAP_GET_WACS_FSM(val) == PWRAP_WACS_FSM_WFVLDCLR;
+ }
+
++/*
++ * Timeout issue sometimes caused by the last read command
++ * failed because pmic wrap could not got the FSM_VLDCLR
++ * in time after finishing WACS2_CMD. It made state machine
++ * still on FSM_VLDCLR and timeout next time.
++ * Check the status of FSM and clear the vldclr to recovery the
++ * error.
++ */
++static inline void pwrap_leave_fsm_vldclr(struct pmic_wrapper *wrp)
++{
++ if (pwrap_is_fsm_vldclr(wrp))
++ pwrap_writel(wrp, 1, PWRAP_WACS2_VLDCLR);
++}
++
+ static bool pwrap_is_sync_idle(struct pmic_wrapper *wrp)
+ {
+ return pwrap_readl(wrp, PWRAP_WACS2_RDATA) & PWRAP_STATE_SYNC_IDLE0;
+@@ -445,8 +459,10 @@ static int pwrap_write(struct pmic_wrapper *wrp, u32 adr, u32 wdata)
+ int ret;
+
+ ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle);
+- if (ret)
++ if (ret) {
++ pwrap_leave_fsm_vldclr(wrp);
+ return ret;
++ }
+
+ pwrap_writel(wrp, (1 << 31) | ((adr >> 1) << 16) | wdata,
+ PWRAP_WACS2_CMD);
+@@ -459,8 +475,10 @@ static int pwrap_read(struct pmic_wrapper *wrp, u32 adr, u32 *rdata)
+ int ret;
+
+ ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle);
+- if (ret)
++ if (ret) {
++ pwrap_leave_fsm_vldclr(wrp);
+ return ret;
++ }
+
+ pwrap_writel(wrp, (adr >> 1) << 16, PWRAP_WACS2_CMD);
+
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0028-ARM-mediatek-add-MT7623-smp-bringup-code.patch b/target/linux/mediatek/patches-4.4/0028-ARM-mediatek-add-MT7623-smp-bringup-code.patch
new file mode 100644
index 0000000000..80bb4ff3c1
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0028-ARM-mediatek-add-MT7623-smp-bringup-code.patch
@@ -0,0 +1,41 @@
+From 0742887b1d36913ccd5f6fa85649ad5eb0bfb200 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Tue, 5 Jan 2016 17:24:28 +0100
+Subject: [PATCH 28/53] ARM: mediatek: add MT7623 smp bringup code
+
+Add support for booting secondary CPUs on MT7623.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm/mach-mediatek/platsmp.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c
+index 8141f3f..8151400 100644
+--- a/arch/arm/mach-mediatek/platsmp.c
++++ b/arch/arm/mach-mediatek/platsmp.c
+@@ -44,6 +44,12 @@ static const struct mtk_smp_boot_info mtk_mt6589_boot = {
+ { 0x38, 0x3c, 0x40 },
+ };
+
++static const struct mtk_smp_boot_info mtk_mt7623_boot = {
++ 0x10202000, 0x34,
++ { 0x534c4131, 0x4c415332, 0x41534c33 },
++ { 0x38, 0x3c, 0x40 },
++};
++
+ static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = {
+ { .compatible = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot },
+ { .compatible = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot },
+@@ -51,6 +57,7 @@ static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = {
+
+ static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
+ { .compatible = "mediatek,mt6589", .data = &mtk_mt6589_boot },
++ { .compatible = "mediatek,mt7623", .data = &mtk_mt7623_boot },
+ };
+
+ static void __iomem *mtk_smp_base;
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0029-soc-mediatek-PMIC-wrap-clear-the-STAUPD_TRIG-bit-of-.patch b/target/linux/mediatek/patches-4.4/0029-soc-mediatek-PMIC-wrap-clear-the-STAUPD_TRIG-bit-of-.patch
new file mode 100644
index 0000000000..f8a1cd151c
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0029-soc-mediatek-PMIC-wrap-clear-the-STAUPD_TRIG-bit-of-.patch
@@ -0,0 +1,63 @@
+From 5d75662fcdfef08d82710f8c4b71c58d618d4171 Mon Sep 17 00:00:00 2001
+From: Henry Chen <henryc.chen@mediatek.com>
+Date: Thu, 21 Jan 2016 19:04:00 +0800
+Subject: [PATCH 29/53] soc: mediatek: PMIC wrap: clear the STAUPD_TRIG bit of
+ WDT_SRC_EN
+
+Since STAUPD interrupts aren't handled on mt8173, disable watchdog timeout
+monitor of STAUPD to avoid WDT_INT triggered by STAUPD.
+
+Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
+Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index 696071b..0d9b19a 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -60,6 +60,15 @@
+ #define PWRAP_MAN_CMD_OP_OUTD (0x9 << 8)
+ #define PWRAP_MAN_CMD_OP_OUTQ (0xa << 8)
+
++/* macro for Watch Dog Timer Source */
++#define PWRAP_WDT_SRC_EN_STAUPD_TRIG (1 << 25)
++#define PWRAP_WDT_SRC_EN_HARB_STAUPD_DLE (1 << 20)
++#define PWRAP_WDT_SRC_EN_HARB_STAUPD_ALE (1 << 6)
++#define PWRAP_WDT_SRC_MASK_ALL 0xffffffff
++#define PWRAP_WDT_SRC_MASK_NO_STAUPD ~(PWRAP_WDT_SRC_EN_STAUPD_TRIG | \
++ PWRAP_WDT_SRC_EN_HARB_STAUPD_DLE | \
++ PWRAP_WDT_SRC_EN_HARB_STAUPD_ALE)
++
+ /* macro for slave device wrapper registers */
+ #define PWRAP_DEW_BASE 0xbc00
+ #define PWRAP_DEW_EVENT_OUT_EN (PWRAP_DEW_BASE + 0x0)
+@@ -822,7 +831,7 @@ MODULE_DEVICE_TABLE(of, of_pwrap_match_tbl);
+
+ static int pwrap_probe(struct platform_device *pdev)
+ {
+- int ret, irq;
++ int ret, irq, wdt_src;
+ struct pmic_wrapper *wrp;
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *of_id =
+@@ -912,7 +921,13 @@ static int pwrap_probe(struct platform_device *pdev)
+
+ /* Initialize watchdog, may not be done by the bootloader */
+ pwrap_writel(wrp, 0xf, PWRAP_WDT_UNIT);
+- pwrap_writel(wrp, 0xffffffff, PWRAP_WDT_SRC_EN);
++ /*
++ * Since STAUPD was not used on mt8173 platform,
++ * so STAUPD of WDT_SRC which should be turned off
++ */
++ wdt_src = pwrap_is_mt8173(wrp) ?
++ PWRAP_WDT_SRC_MASK_NO_STAUPD : PWRAP_WDT_SRC_MASK_ALL;
++ pwrap_writel(wrp, wdt_src, PWRAP_WDT_SRC_EN);
+ pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
+ pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN);
+
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0030-ARM-mediatek-add-mt2701-smp-bringup-code.patch b/target/linux/mediatek/patches-4.4/0030-ARM-mediatek-add-mt2701-smp-bringup-code.patch
new file mode 100644
index 0000000000..24e59e8e16
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0030-ARM-mediatek-add-mt2701-smp-bringup-code.patch
@@ -0,0 +1,28 @@
+From f6e138ee1a8ddba7b512cafc2ecc7cd1b41781dc Mon Sep 17 00:00:00 2001
+From: Louis Yu <louis.yu@mediatek.com>
+Date: Thu, 7 Jan 2016 20:09:43 +0800
+Subject: [PATCH 30/53] ARM: mediatek: add mt2701 smp bringup code
+
+Add support for booting secondary CPUs on mt2701.
+
+Signed-off-by: Louis Yu <louis.yu@mediatek.com>
+Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
+---
+ arch/arm/mach-mediatek/platsmp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c
+index 8151400..2078f92d5 100644
+--- a/arch/arm/mach-mediatek/platsmp.c
++++ b/arch/arm/mach-mediatek/platsmp.c
+@@ -53,6 +53,7 @@ static const struct mtk_smp_boot_info mtk_mt7623_boot = {
+ static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = {
+ { .compatible = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot },
+ { .compatible = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot },
++ { .compatible = "mediatek,mt2701", .data = &mtk_mt8135_tz_boot },
+ };
+
+ static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0031-dt-bindings-ARM-Mediatek-add-MT2701-7623-string-to-t.patch b/target/linux/mediatek/patches-4.4/0031-dt-bindings-ARM-Mediatek-add-MT2701-7623-string-to-t.patch
new file mode 100644
index 0000000000..b44413681f
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0031-dt-bindings-ARM-Mediatek-add-MT2701-7623-string-to-t.patch
@@ -0,0 +1,28 @@
+From 2e4a714f60266098a2b3553d1b1f83732da90abd Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 20 Jan 2016 13:12:19 +0100
+Subject: [PATCH 31/53] dt-bindings: ARM: Mediatek: add MT2701/7623 string to
+ the PMIC wrapper doc
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Acked-by: Rob Herring <robh@kernel.org>
+Cc: devicetree@vger.kernel.org
+---
+ Documentation/devicetree/bindings/soc/mediatek/pwrap.txt | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt b/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
+index ddeb5b6..107700d 100644
+--- a/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
++++ b/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
+@@ -18,6 +18,7 @@ IP Pairing
+
+ Required properties in pwrap device node.
+ - compatible:
++ "mediatek,mt2701-pwrap" for MT2701/7623 SoCs
+ "mediatek,mt8135-pwrap" for MT8135 SoCs
+ "mediatek,mt8173-pwrap" for MT8173 SoCs
+ - interrupts: IRQ for pwrap in SOC
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0032-soc-mediatek-PMIC-wrap-don-t-duplicate-the-wrapper-d.patch b/target/linux/mediatek/patches-4.4/0032-soc-mediatek-PMIC-wrap-don-t-duplicate-the-wrapper-d.patch
new file mode 100644
index 0000000000..7f389b3e7d
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0032-soc-mediatek-PMIC-wrap-don-t-duplicate-the-wrapper-d.patch
@@ -0,0 +1,98 @@
+From b68e33cc67465ad99299947916678f8ea4418b1c Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 20 Jan 2016 06:42:01 +0100
+Subject: [PATCH 32/53] soc: mediatek: PMIC wrap: don't duplicate the wrapper
+ data
+
+As we add support for more devices struct pmic_wrapper_type will grow and
+we do not really want to start duplicating all the elements in
+struct pmic_wrapper.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 22 ++++++++--------------
+ 1 file changed, 8 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index 0d9b19a..340c4b5 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -376,9 +376,7 @@ struct pmic_wrapper {
+ struct device *dev;
+ void __iomem *base;
+ struct regmap *regmap;
+- int *regs;
+- enum pwrap_type type;
+- u32 arb_en_all;
++ const struct pmic_wrapper_type *master;
+ struct clk *clk_spi;
+ struct clk *clk_wrap;
+ struct reset_control *rstc;
+@@ -389,22 +387,22 @@ struct pmic_wrapper {
+
+ static inline int pwrap_is_mt8135(struct pmic_wrapper *wrp)
+ {
+- return wrp->type == PWRAP_MT8135;
++ return wrp->master->type == PWRAP_MT8135;
+ }
+
+ static inline int pwrap_is_mt8173(struct pmic_wrapper *wrp)
+ {
+- return wrp->type == PWRAP_MT8173;
++ return wrp->master->type == PWRAP_MT8173;
+ }
+
+ static u32 pwrap_readl(struct pmic_wrapper *wrp, enum pwrap_regs reg)
+ {
+- return readl(wrp->base + wrp->regs[reg]);
++ return readl(wrp->base + wrp->master->regs[reg]);
+ }
+
+ static void pwrap_writel(struct pmic_wrapper *wrp, u32 val, enum pwrap_regs reg)
+ {
+- writel(val, wrp->base + wrp->regs[reg]);
++ writel(val, wrp->base + wrp->master->regs[reg]);
+ }
+
+ static bool pwrap_is_fsm_idle(struct pmic_wrapper *wrp)
+@@ -697,7 +695,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
+
+ pwrap_writel(wrp, 1, PWRAP_WRAP_EN);
+
+- pwrap_writel(wrp, wrp->arb_en_all, PWRAP_HIPRIO_ARB_EN);
++ pwrap_writel(wrp, wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN);
+
+ pwrap_writel(wrp, 1, PWRAP_WACS2_EN);
+
+@@ -742,7 +740,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
+ pwrap_writel(wrp, 0x1, PWRAP_CRC_EN);
+ pwrap_writel(wrp, 0x0, PWRAP_SIG_MODE);
+ pwrap_writel(wrp, PWRAP_DEW_CRC_VAL, PWRAP_SIG_ADR);
+- pwrap_writel(wrp, wrp->arb_en_all, PWRAP_HIPRIO_ARB_EN);
++ pwrap_writel(wrp, wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN);
+
+ if (pwrap_is_mt8135(wrp))
+ pwrap_writel(wrp, 0x7, PWRAP_RRARB_EN);
+@@ -836,7 +834,6 @@ static int pwrap_probe(struct platform_device *pdev)
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *of_id =
+ of_match_device(of_pwrap_match_tbl, &pdev->dev);
+- const struct pmic_wrapper_type *type;
+ struct resource *res;
+
+ wrp = devm_kzalloc(&pdev->dev, sizeof(*wrp), GFP_KERNEL);
+@@ -845,10 +842,7 @@ static int pwrap_probe(struct platform_device *pdev)
+
+ platform_set_drvdata(pdev, wrp);
+
+- type = of_id->data;
+- wrp->regs = type->regs;
+- wrp->type = type->type;
+- wrp->arb_en_all = type->arb_en_all;
++ wrp->master = of_id->data;
+ wrp->dev = &pdev->dev;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwrap");
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0033-soc-mediatek-PMIC-wrap-add-wrapper-callbacks-for-ini.patch b/target/linux/mediatek/patches-4.4/0033-soc-mediatek-PMIC-wrap-add-wrapper-callbacks-for-ini.patch
new file mode 100644
index 0000000000..67ef86966c
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0033-soc-mediatek-PMIC-wrap-add-wrapper-callbacks-for-ini.patch
@@ -0,0 +1,127 @@
+From 45ead148322ba7be9de970a2ab6be4ed3f7ca184 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 20 Jan 2016 05:27:17 +0100
+Subject: [PATCH 33/53] soc: mediatek: PMIC wrap: add wrapper callbacks for
+ init_reg_clock
+
+Split init_reg_clock up into SoC specific callbacks. The patch also
+reorders the code to avoid the need for callback function prototypes.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 70 ++++++++++++++++++----------------
+ 1 file changed, 38 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index 340c4b5..b22b664 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -354,24 +354,6 @@ enum pwrap_type {
+ PWRAP_MT8173,
+ };
+
+-struct pmic_wrapper_type {
+- int *regs;
+- enum pwrap_type type;
+- u32 arb_en_all;
+-};
+-
+-static struct pmic_wrapper_type pwrap_mt8135 = {
+- .regs = mt8135_regs,
+- .type = PWRAP_MT8135,
+- .arb_en_all = 0x1ff,
+-};
+-
+-static struct pmic_wrapper_type pwrap_mt8173 = {
+- .regs = mt8173_regs,
+- .type = PWRAP_MT8173,
+- .arb_en_all = 0x3f,
+-};
+-
+ struct pmic_wrapper {
+ struct device *dev;
+ void __iomem *base;
+@@ -385,6 +367,13 @@ struct pmic_wrapper {
+ void __iomem *bridge_base;
+ };
+
++struct pmic_wrapper_type {
++ int *regs;
++ enum pwrap_type type;
++ u32 arb_en_all;
++ int (*init_reg_clock)(struct pmic_wrapper *wrp);
++};
++
+ static inline int pwrap_is_mt8135(struct pmic_wrapper *wrp)
+ {
+ return wrp->master->type == PWRAP_MT8135;
+@@ -578,20 +567,23 @@ static int pwrap_init_sidly(struct pmic_wrapper *wrp)
+ return 0;
+ }
+
+-static int pwrap_init_reg_clock(struct pmic_wrapper *wrp)
++static int pwrap_mt8135_init_reg_clock(struct pmic_wrapper *wrp)
+ {
+- if (pwrap_is_mt8135(wrp)) {
+- pwrap_writel(wrp, 0x4, PWRAP_CSHEXT);
+- pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE);
+- pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ);
+- pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_START);
+- pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_END);
+- } else {
+- pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE);
+- pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ);
+- pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START);
+- pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END);
+- }
++ pwrap_writel(wrp, 0x4, PWRAP_CSHEXT);
++ pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE);
++ pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ);
++ pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_START);
++ pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_END);
++
++ return 0;
++}
++
++static int pwrap_mt8173_init_reg_clock(struct pmic_wrapper *wrp)
++{
++ pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE);
++ pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ);
++ pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START);
++ pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END);
+
+ return 0;
+ }
+@@ -699,7 +691,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
+
+ pwrap_writel(wrp, 1, PWRAP_WACS2_EN);
+
+- ret = pwrap_init_reg_clock(wrp);
++ ret = wrp->master->init_reg_clock(wrp);
+ if (ret)
+ return ret;
+
+@@ -814,6 +806,20 @@ static const struct regmap_config pwrap_regmap_config = {
+ .max_register = 0xffff,
+ };
+
++static struct pmic_wrapper_type pwrap_mt8135 = {
++ .regs = mt8135_regs,
++ .type = PWRAP_MT8135,
++ .arb_en_all = 0x1ff,
++ .init_reg_clock = pwrap_mt8135_init_reg_clock,
++};
++
++static struct pmic_wrapper_type pwrap_mt8173 = {
++ .regs = mt8173_regs,
++ .type = PWRAP_MT8173,
++ .arb_en_all = 0x3f,
++ .init_reg_clock = pwrap_mt8173_init_reg_clock,
++};
++
+ static struct of_device_id of_pwrap_match_tbl[] = {
+ {
+ .compatible = "mediatek,mt8135-pwrap",
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0034-soc-mediatek-PMIC-wrap-split-SoC-specific-init-into-.patch b/target/linux/mediatek/patches-4.4/0034-soc-mediatek-PMIC-wrap-split-SoC-specific-init-into-.patch
new file mode 100644
index 0000000000..aa34aaf368
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0034-soc-mediatek-PMIC-wrap-split-SoC-specific-init-into-.patch
@@ -0,0 +1,127 @@
+From b3cc9f4c4b1164ac6a0700920eca84dff81d13d7 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 20 Jan 2016 10:12:00 +0100
+Subject: [PATCH 34/53] soc: mediatek: PMIC wrap: split SoC specific init into
+ callback
+
+This patch moves the SoC specific wrapper init code into separate callback
+to avoid pwrap_init() getting too large. This is done by adding a new
+element called init_special to pmic_wrapper_type. Each currently supported
+SoC gets its own version of the callback and we copy the code that was
+previously inside pwrap_init() to these new callbacks. Finally we point the
+2 instances of pmic_wrapper_type at the 2 new functions.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 67 +++++++++++++++++++++-------------
+ 1 file changed, 42 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index b22b664..22c89e9 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -372,6 +372,7 @@ struct pmic_wrapper_type {
+ enum pwrap_type type;
+ u32 arb_en_all;
+ int (*init_reg_clock)(struct pmic_wrapper *wrp);
++ int (*init_soc_specific)(struct pmic_wrapper *wrp);
+ };
+
+ static inline int pwrap_is_mt8135(struct pmic_wrapper *wrp)
+@@ -665,6 +666,41 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
+ return 0;
+ }
+
++static int pwrap_mt8135_init_soc_specific(struct pmic_wrapper *wrp)
++{
++ /* enable pwrap events and pwrap bridge in AP side */
++ pwrap_writel(wrp, 0x1, PWRAP_EVENT_IN_EN);
++ pwrap_writel(wrp, 0xffff, PWRAP_EVENT_DST_EN);
++ writel(0x7f, wrp->bridge_base + PWRAP_MT8135_BRIDGE_IORD_ARB_EN);
++ writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WACS3_EN);
++ writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WACS4_EN);
++ writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WDT_UNIT);
++ writel(0xffff, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WDT_SRC_EN);
++ writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_TIMER_EN);
++ writel(0x7ff, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INT_EN);
++
++ /* enable PMIC event out and sources */
++ if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
++ pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
++ dev_err(wrp->dev, "enable dewrap fail\n");
++ return -EFAULT;
++ }
++
++ return 0;
++}
++
++static int pwrap_mt8173_init_soc_specific(struct pmic_wrapper *wrp)
++{
++ /* PMIC_DEWRAP enables */
++ if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
++ pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
++ dev_err(wrp->dev, "enable dewrap fail\n");
++ return -EFAULT;
++ }
++
++ return 0;
++}
++
+ static int pwrap_init(struct pmic_wrapper *wrp)
+ {
+ int ret;
+@@ -743,31 +779,10 @@ static int pwrap_init(struct pmic_wrapper *wrp)
+ pwrap_writel(wrp, 0x5, PWRAP_STAUPD_PRD);
+ pwrap_writel(wrp, 0xff, PWRAP_STAUPD_GRPEN);
+
+- if (pwrap_is_mt8135(wrp)) {
+- /* enable pwrap events and pwrap bridge in AP side */
+- pwrap_writel(wrp, 0x1, PWRAP_EVENT_IN_EN);
+- pwrap_writel(wrp, 0xffff, PWRAP_EVENT_DST_EN);
+- writel(0x7f, wrp->bridge_base + PWRAP_MT8135_BRIDGE_IORD_ARB_EN);
+- writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WACS3_EN);
+- writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WACS4_EN);
+- writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WDT_UNIT);
+- writel(0xffff, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WDT_SRC_EN);
+- writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_TIMER_EN);
+- writel(0x7ff, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INT_EN);
+-
+- /* enable PMIC event out and sources */
+- if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
+- pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
+- dev_err(wrp->dev, "enable dewrap fail\n");
+- return -EFAULT;
+- }
+- } else {
+- /* PMIC_DEWRAP enables */
+- if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
+- pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
+- dev_err(wrp->dev, "enable dewrap fail\n");
+- return -EFAULT;
+- }
++ if (wrp->master->init_soc_specific) {
++ ret = wrp->master->init_soc_specific(wrp);
++ if (ret)
++ return ret;
+ }
+
+ /* Setup the init done registers */
+@@ -811,6 +826,7 @@ static struct pmic_wrapper_type pwrap_mt8135 = {
+ .type = PWRAP_MT8135,
+ .arb_en_all = 0x1ff,
+ .init_reg_clock = pwrap_mt8135_init_reg_clock,
++ .init_soc_specific = pwrap_mt8135_init_soc_specific,
+ };
+
+ static struct pmic_wrapper_type pwrap_mt8173 = {
+@@ -818,6 +834,7 @@ static struct pmic_wrapper_type pwrap_mt8173 = {
+ .type = PWRAP_MT8173,
+ .arb_en_all = 0x3f,
+ .init_reg_clock = pwrap_mt8173_init_reg_clock,
++ .init_soc_specific = pwrap_mt8173_init_soc_specific,
+ };
+
+ static struct of_device_id of_pwrap_match_tbl[] = {
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0035-soc-mediatek-PMIC-wrap-WRAP_INT_EN-needs-a-different.patch b/target/linux/mediatek/patches-4.4/0035-soc-mediatek-PMIC-wrap-WRAP_INT_EN-needs-a-different.patch
new file mode 100644
index 0000000000..9bfc90d504
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0035-soc-mediatek-PMIC-wrap-WRAP_INT_EN-needs-a-different.patch
@@ -0,0 +1,53 @@
+From 824563fe3d8b915714816255489fcfb2792c3a8a Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 20 Jan 2016 10:14:39 +0100
+Subject: [PATCH 35/53] soc: mediatek: PMIC wrap: WRAP_INT_EN needs a
+ different bitmask for MT2701/7623
+
+MT2701 and MT7623 use a different bitmask for PWRAP_INT_EN.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index 22c89e9..9df1135 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -371,6 +371,7 @@ struct pmic_wrapper_type {
+ int *regs;
+ enum pwrap_type type;
+ u32 arb_en_all;
++ u32 int_en_all;
+ int (*init_reg_clock)(struct pmic_wrapper *wrp);
+ int (*init_soc_specific)(struct pmic_wrapper *wrp);
+ };
+@@ -825,6 +826,7 @@ static struct pmic_wrapper_type pwrap_mt8135 = {
+ .regs = mt8135_regs,
+ .type = PWRAP_MT8135,
+ .arb_en_all = 0x1ff,
++ .int_en_all = ~(BIT(31) | BIT(1)),
+ .init_reg_clock = pwrap_mt8135_init_reg_clock,
+ .init_soc_specific = pwrap_mt8135_init_soc_specific,
+ };
+@@ -833,6 +835,7 @@ static struct pmic_wrapper_type pwrap_mt8173 = {
+ .regs = mt8173_regs,
+ .type = PWRAP_MT8173,
+ .arb_en_all = 0x3f,
++ .int_en_all = ~(BIT(31) | BIT(1)),
+ .init_reg_clock = pwrap_mt8173_init_reg_clock,
+ .init_soc_specific = pwrap_mt8173_init_soc_specific,
+ };
+@@ -946,7 +949,7 @@ static int pwrap_probe(struct platform_device *pdev)
+ PWRAP_WDT_SRC_MASK_NO_STAUPD : PWRAP_WDT_SRC_MASK_ALL;
+ pwrap_writel(wrp, wdt_src, PWRAP_WDT_SRC_EN);
+ pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
+- pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN);
++ pwrap_writel(wrp, wrp->master->int_en_all, PWRAP_INT_EN);
+
+ irq = platform_get_irq(pdev, 0);
+ ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt, IRQF_TRIGGER_HIGH,
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0036-soc-mediatek-PMIC-wrap-SPI_WRITE-needs-a-different-b.patch b/target/linux/mediatek/patches-4.4/0036-soc-mediatek-PMIC-wrap-SPI_WRITE-needs-a-different-b.patch
new file mode 100644
index 0000000000..e18f47d0c3
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0036-soc-mediatek-PMIC-wrap-SPI_WRITE-needs-a-different-b.patch
@@ -0,0 +1,66 @@
+From 2028a24d161da25b827b394bdcec4deba5d2efd9 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 20 Jan 2016 10:21:42 +0100
+Subject: [PATCH 36/53] soc: mediatek: PMIC wrap: SPI_WRITE needs a different
+ bitmask for MT2701/7623
+
+Different SoCs will use different bitmask for the SPI_WRITE command. This
+patch defines the bitmask in the pmic_wrapper_type struct. This allows us
+to support new SoCs with a different bitmask to the one currently used.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index 9df1135..8ce1bad 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -372,6 +372,7 @@ struct pmic_wrapper_type {
+ enum pwrap_type type;
+ u32 arb_en_all;
+ u32 int_en_all;
++ u32 spi_w;
+ int (*init_reg_clock)(struct pmic_wrapper *wrp);
+ int (*init_soc_specific)(struct pmic_wrapper *wrp);
+ };
+@@ -511,15 +512,15 @@ static int pwrap_reset_spislave(struct pmic_wrapper *wrp)
+ pwrap_writel(wrp, 1, PWRAP_MAN_EN);
+ pwrap_writel(wrp, 0, PWRAP_DIO_EN);
+
+- pwrap_writel(wrp, PWRAP_MAN_CMD_SPI_WRITE | PWRAP_MAN_CMD_OP_CSL,
++ pwrap_writel(wrp, wrp->master->spi_w | PWRAP_MAN_CMD_OP_CSL,
+ PWRAP_MAN_CMD);
+- pwrap_writel(wrp, PWRAP_MAN_CMD_SPI_WRITE | PWRAP_MAN_CMD_OP_OUTS,
++ pwrap_writel(wrp, wrp->master->spi_w | PWRAP_MAN_CMD_OP_OUTS,
+ PWRAP_MAN_CMD);
+- pwrap_writel(wrp, PWRAP_MAN_CMD_SPI_WRITE | PWRAP_MAN_CMD_OP_CSH,
++ pwrap_writel(wrp, wrp->master->spi_w | PWRAP_MAN_CMD_OP_CSH,
+ PWRAP_MAN_CMD);
+
+ for (i = 0; i < 4; i++)
+- pwrap_writel(wrp, PWRAP_MAN_CMD_SPI_WRITE | PWRAP_MAN_CMD_OP_OUTS,
++ pwrap_writel(wrp, wrp->master->spi_w | PWRAP_MAN_CMD_OP_OUTS,
+ PWRAP_MAN_CMD);
+
+ ret = pwrap_wait_for_state(wrp, pwrap_is_sync_idle);
+@@ -827,6 +828,7 @@ static struct pmic_wrapper_type pwrap_mt8135 = {
+ .type = PWRAP_MT8135,
+ .arb_en_all = 0x1ff,
+ .int_en_all = ~(BIT(31) | BIT(1)),
++ .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
+ .init_reg_clock = pwrap_mt8135_init_reg_clock,
+ .init_soc_specific = pwrap_mt8135_init_soc_specific,
+ };
+@@ -836,6 +838,7 @@ static struct pmic_wrapper_type pwrap_mt8173 = {
+ .type = PWRAP_MT8173,
+ .arb_en_all = 0x3f,
+ .int_en_all = ~(BIT(31) | BIT(1)),
++ .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
+ .init_reg_clock = pwrap_mt8173_init_reg_clock,
+ .init_soc_specific = pwrap_mt8173_init_soc_specific,
+ };
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0037-soc-mediatek-PMIC-wrap-move-wdt_src-into-the-pmic_wr.patch b/target/linux/mediatek/patches-4.4/0037-soc-mediatek-PMIC-wrap-move-wdt_src-into-the-pmic_wr.patch
new file mode 100644
index 0000000000..e5896658e6
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0037-soc-mediatek-PMIC-wrap-move-wdt_src-into-the-pmic_wr.patch
@@ -0,0 +1,66 @@
+From 50bd0c152a0c33000ae88d0828f320eb603fd535 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 20 Jan 2016 10:48:35 +0100
+Subject: [PATCH 37/53] soc: mediatek: PMIC wrap: move wdt_src into the
+ pmic_wrapper_type struct
+
+Different SoCs will use different bitmask for the wdt_src. This patch
+defines the bitmask in the pmic_wrapper_type struct. This allows us to
+support new SoCs with a different bitmask to the one currently used.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index 8ce1bad..aa54df3 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -373,6 +373,7 @@ struct pmic_wrapper_type {
+ u32 arb_en_all;
+ u32 int_en_all;
+ u32 spi_w;
++ u32 wdt_src;
+ int (*init_reg_clock)(struct pmic_wrapper *wrp);
+ int (*init_soc_specific)(struct pmic_wrapper *wrp);
+ };
+@@ -829,6 +830,7 @@ static struct pmic_wrapper_type pwrap_mt8135 = {
+ .arb_en_all = 0x1ff,
+ .int_en_all = ~(BIT(31) | BIT(1)),
+ .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
++ .wdt_src = PWRAP_WDT_SRC_MASK_ALL,
+ .init_reg_clock = pwrap_mt8135_init_reg_clock,
+ .init_soc_specific = pwrap_mt8135_init_soc_specific,
+ };
+@@ -839,6 +841,7 @@ static struct pmic_wrapper_type pwrap_mt8173 = {
+ .arb_en_all = 0x3f,
+ .int_en_all = ~(BIT(31) | BIT(1)),
+ .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
++ .wdt_src = PWRAP_WDT_SRC_MASK_NO_STAUPD,
+ .init_reg_clock = pwrap_mt8173_init_reg_clock,
+ .init_soc_specific = pwrap_mt8173_init_soc_specific,
+ };
+@@ -858,7 +861,7 @@ MODULE_DEVICE_TABLE(of, of_pwrap_match_tbl);
+
+ static int pwrap_probe(struct platform_device *pdev)
+ {
+- int ret, irq, wdt_src;
++ int ret, irq;
+ struct pmic_wrapper *wrp;
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *of_id =
+@@ -948,9 +951,7 @@ static int pwrap_probe(struct platform_device *pdev)
+ * Since STAUPD was not used on mt8173 platform,
+ * so STAUPD of WDT_SRC which should be turned off
+ */
+- wdt_src = pwrap_is_mt8173(wrp) ?
+- PWRAP_WDT_SRC_MASK_NO_STAUPD : PWRAP_WDT_SRC_MASK_ALL;
+- pwrap_writel(wrp, wdt_src, PWRAP_WDT_SRC_EN);
++ pwrap_writel(wrp, wrp->master->wdt_src, PWRAP_WDT_SRC_EN);
+ pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
+ pwrap_writel(wrp, wrp->master->int_en_all, PWRAP_INT_EN);
+
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0038-soc-mediatek-PMIC-wrap-remove-pwrap_is_mt8135-and-pw.patch b/target/linux/mediatek/patches-4.4/0038-soc-mediatek-PMIC-wrap-remove-pwrap_is_mt8135-and-pw.patch
new file mode 100644
index 0000000000..025188347c
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0038-soc-mediatek-PMIC-wrap-remove-pwrap_is_mt8135-and-pw.patch
@@ -0,0 +1,118 @@
+From f08ce6b84d2759fdff2e8ea2cf2b30b3220521ef Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 20 Jan 2016 10:54:18 +0100
+Subject: [PATCH 38/53] soc: mediatek: PMIC wrap: remove pwrap_is_mt8135() and
+ pwrap_is_mt8173()
+
+With more SoCs being added the list of helper functions like these would
+grow. To mitigate this problem we remove the existing helpers and change
+the code to test against the pmic type stored inside the pmic specific
+datastructure that our context structure points at. There is one usage of
+pwrap_is_mt8135() that is ambiguous as the test should not be dependent on
+mt8135, but rather on the existence of a bridge. Add a new element to
+pmic_wrapper_type to indicate if a bridge is present and use this where
+appropriate.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 28 ++++++++++++----------------
+ 1 file changed, 12 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index aa54df3..a2bacda 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -374,20 +374,11 @@ struct pmic_wrapper_type {
+ u32 int_en_all;
+ u32 spi_w;
+ u32 wdt_src;
++ int has_bridge:1;
+ int (*init_reg_clock)(struct pmic_wrapper *wrp);
+ int (*init_soc_specific)(struct pmic_wrapper *wrp);
+ };
+
+-static inline int pwrap_is_mt8135(struct pmic_wrapper *wrp)
+-{
+- return wrp->master->type == PWRAP_MT8135;
+-}
+-
+-static inline int pwrap_is_mt8173(struct pmic_wrapper *wrp)
+-{
+- return wrp->master->type == PWRAP_MT8173;
+-}
+-
+ static u32 pwrap_readl(struct pmic_wrapper *wrp, enum pwrap_regs reg)
+ {
+ return readl(wrp->base + wrp->master->regs[reg]);
+@@ -619,11 +610,14 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
+ pwrap_writel(wrp, 0x1, PWRAP_CIPHER_KEY_SEL);
+ pwrap_writel(wrp, 0x2, PWRAP_CIPHER_IV_SEL);
+
+- if (pwrap_is_mt8135(wrp)) {
++ switch (wrp->master->type) {
++ case PWRAP_MT8135:
+ pwrap_writel(wrp, 1, PWRAP_CIPHER_LOAD);
+ pwrap_writel(wrp, 1, PWRAP_CIPHER_START);
+- } else {
++ break;
++ case PWRAP_MT8173:
+ pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);
++ break;
+ }
+
+ /* Config cipher mode @PMIC */
+@@ -713,7 +707,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
+ if (wrp->rstc_bridge)
+ reset_control_reset(wrp->rstc_bridge);
+
+- if (pwrap_is_mt8173(wrp)) {
++ if (wrp->master->type == PWRAP_MT8173) {
+ /* Enable DCM */
+ pwrap_writel(wrp, 3, PWRAP_DCM_EN);
+ pwrap_writel(wrp, 0, PWRAP_DCM_DBC_PRD);
+@@ -773,7 +767,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
+ pwrap_writel(wrp, PWRAP_DEW_CRC_VAL, PWRAP_SIG_ADR);
+ pwrap_writel(wrp, wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN);
+
+- if (pwrap_is_mt8135(wrp))
++ if (wrp->master->type == PWRAP_MT8135)
+ pwrap_writel(wrp, 0x7, PWRAP_RRARB_EN);
+
+ pwrap_writel(wrp, 0x1, PWRAP_WACS0_EN);
+@@ -793,7 +787,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
+ pwrap_writel(wrp, 1, PWRAP_INIT_DONE0);
+ pwrap_writel(wrp, 1, PWRAP_INIT_DONE1);
+
+- if (pwrap_is_mt8135(wrp)) {
++ if (wrp->master->has_bridge) {
+ writel(1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INIT_DONE3);
+ writel(1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INIT_DONE4);
+ }
+@@ -831,6 +825,7 @@ static struct pmic_wrapper_type pwrap_mt8135 = {
+ .int_en_all = ~(BIT(31) | BIT(1)),
+ .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
+ .wdt_src = PWRAP_WDT_SRC_MASK_ALL,
++ .has_bridge = 1,
+ .init_reg_clock = pwrap_mt8135_init_reg_clock,
+ .init_soc_specific = pwrap_mt8135_init_soc_specific,
+ };
+@@ -842,6 +837,7 @@ static struct pmic_wrapper_type pwrap_mt8173 = {
+ .int_en_all = ~(BIT(31) | BIT(1)),
+ .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
+ .wdt_src = PWRAP_WDT_SRC_MASK_NO_STAUPD,
++ .has_bridge = 0,
+ .init_reg_clock = pwrap_mt8173_init_reg_clock,
+ .init_soc_specific = pwrap_mt8173_init_soc_specific,
+ };
+@@ -889,7 +885,7 @@ static int pwrap_probe(struct platform_device *pdev)
+ return ret;
+ }
+
+- if (pwrap_is_mt8135(wrp)) {
++ if (wrp->master->has_bridge) {
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "pwrap-bridge");
+ wrp->bridge_base = devm_ioremap_resource(wrp->dev, res);
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0039-soc-mediatek-PMIC-wrap-add-a-slave-specific-struct.patch b/target/linux/mediatek/patches-4.4/0039-soc-mediatek-PMIC-wrap-add-a-slave-specific-struct.patch
new file mode 100644
index 0000000000..c76e27bcaa
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0039-soc-mediatek-PMIC-wrap-add-a-slave-specific-struct.patch
@@ -0,0 +1,301 @@
+From 7c6b5e5e36ccd9079a2425dc80507447784b9bb2 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 20 Jan 2016 09:55:08 +0100
+Subject: [PATCH 39/53] soc: mediatek: PMIC wrap: add a slave specific struct
+
+This patch adds a new struct pwrap_slv_type that we use to store the slave
+specific data. The patch adds 2 new helper functions to access the dew
+registers. The slave type is looked up via the wrappers child node.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 159 ++++++++++++++++++++++++----------
+ 1 file changed, 112 insertions(+), 47 deletions(-)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index a2bacda..bcc841e 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -69,33 +69,54 @@
+ PWRAP_WDT_SRC_EN_HARB_STAUPD_DLE | \
+ PWRAP_WDT_SRC_EN_HARB_STAUPD_ALE)
+
+-/* macro for slave device wrapper registers */
+-#define PWRAP_DEW_BASE 0xbc00
+-#define PWRAP_DEW_EVENT_OUT_EN (PWRAP_DEW_BASE + 0x0)
+-#define PWRAP_DEW_DIO_EN (PWRAP_DEW_BASE + 0x2)
+-#define PWRAP_DEW_EVENT_SRC_EN (PWRAP_DEW_BASE + 0x4)
+-#define PWRAP_DEW_EVENT_SRC (PWRAP_DEW_BASE + 0x6)
+-#define PWRAP_DEW_EVENT_FLAG (PWRAP_DEW_BASE + 0x8)
+-#define PWRAP_DEW_READ_TEST (PWRAP_DEW_BASE + 0xa)
+-#define PWRAP_DEW_WRITE_TEST (PWRAP_DEW_BASE + 0xc)
+-#define PWRAP_DEW_CRC_EN (PWRAP_DEW_BASE + 0xe)
+-#define PWRAP_DEW_CRC_VAL (PWRAP_DEW_BASE + 0x10)
+-#define PWRAP_DEW_MON_GRP_SEL (PWRAP_DEW_BASE + 0x12)
+-#define PWRAP_DEW_MON_FLAG_SEL (PWRAP_DEW_BASE + 0x14)
+-#define PWRAP_DEW_EVENT_TEST (PWRAP_DEW_BASE + 0x16)
+-#define PWRAP_DEW_CIPHER_KEY_SEL (PWRAP_DEW_BASE + 0x18)
+-#define PWRAP_DEW_CIPHER_IV_SEL (PWRAP_DEW_BASE + 0x1a)
+-#define PWRAP_DEW_CIPHER_LOAD (PWRAP_DEW_BASE + 0x1c)
+-#define PWRAP_DEW_CIPHER_START (PWRAP_DEW_BASE + 0x1e)
+-#define PWRAP_DEW_CIPHER_RDY (PWRAP_DEW_BASE + 0x20)
+-#define PWRAP_DEW_CIPHER_MODE (PWRAP_DEW_BASE + 0x22)
+-#define PWRAP_DEW_CIPHER_SWRST (PWRAP_DEW_BASE + 0x24)
+-#define PWRAP_MT8173_DEW_CIPHER_IV0 (PWRAP_DEW_BASE + 0x26)
+-#define PWRAP_MT8173_DEW_CIPHER_IV1 (PWRAP_DEW_BASE + 0x28)
+-#define PWRAP_MT8173_DEW_CIPHER_IV2 (PWRAP_DEW_BASE + 0x2a)
+-#define PWRAP_MT8173_DEW_CIPHER_IV3 (PWRAP_DEW_BASE + 0x2c)
+-#define PWRAP_MT8173_DEW_CIPHER_IV4 (PWRAP_DEW_BASE + 0x2e)
+-#define PWRAP_MT8173_DEW_CIPHER_IV5 (PWRAP_DEW_BASE + 0x30)
++/* defines for slave device wrapper registers */
++enum dew_regs {
++ PWRAP_DEW_BASE,
++ PWRAP_DEW_DIO_EN,
++ PWRAP_DEW_READ_TEST,
++ PWRAP_DEW_WRITE_TEST,
++ PWRAP_DEW_CRC_EN,
++ PWRAP_DEW_CRC_VAL,
++ PWRAP_DEW_MON_GRP_SEL,
++ PWRAP_DEW_CIPHER_KEY_SEL,
++ PWRAP_DEW_CIPHER_IV_SEL,
++ PWRAP_DEW_CIPHER_RDY,
++ PWRAP_DEW_CIPHER_MODE,
++ PWRAP_DEW_CIPHER_SWRST,
++
++ /* MT6397 only regs */
++ PWRAP_DEW_EVENT_OUT_EN,
++ PWRAP_DEW_EVENT_SRC_EN,
++ PWRAP_DEW_EVENT_SRC,
++ PWRAP_DEW_EVENT_FLAG,
++ PWRAP_DEW_MON_FLAG_SEL,
++ PWRAP_DEW_EVENT_TEST,
++ PWRAP_DEW_CIPHER_LOAD,
++ PWRAP_DEW_CIPHER_START,
++};
++
++static const u32 mt6397_regs[] = {
++ [PWRAP_DEW_BASE] = 0xbc00,
++ [PWRAP_DEW_EVENT_OUT_EN] = 0xbc00,
++ [PWRAP_DEW_DIO_EN] = 0xbc02,
++ [PWRAP_DEW_EVENT_SRC_EN] = 0xbc04,
++ [PWRAP_DEW_EVENT_SRC] = 0xbc06,
++ [PWRAP_DEW_EVENT_FLAG] = 0xbc08,
++ [PWRAP_DEW_READ_TEST] = 0xbc0a,
++ [PWRAP_DEW_WRITE_TEST] = 0xbc0c,
++ [PWRAP_DEW_CRC_EN] = 0xbc0e,
++ [PWRAP_DEW_CRC_VAL] = 0xbc10,
++ [PWRAP_DEW_MON_GRP_SEL] = 0xbc12,
++ [PWRAP_DEW_MON_FLAG_SEL] = 0xbc14,
++ [PWRAP_DEW_EVENT_TEST] = 0xbc16,
++ [PWRAP_DEW_CIPHER_KEY_SEL] = 0xbc18,
++ [PWRAP_DEW_CIPHER_IV_SEL] = 0xbc1a,
++ [PWRAP_DEW_CIPHER_LOAD] = 0xbc1c,
++ [PWRAP_DEW_CIPHER_START] = 0xbc1e,
++ [PWRAP_DEW_CIPHER_RDY] = 0xbc20,
++ [PWRAP_DEW_CIPHER_MODE] = 0xbc22,
++ [PWRAP_DEW_CIPHER_SWRST] = 0xbc24,
++};
+
+ enum pwrap_regs {
+ PWRAP_MUX_SEL,
+@@ -349,16 +370,26 @@ static int mt8135_regs[] = {
+ [PWRAP_DCM_DBC_PRD] = 0x160,
+ };
+
++enum pmic_type {
++ PMIC_MT6397,
++};
++
+ enum pwrap_type {
+ PWRAP_MT8135,
+ PWRAP_MT8173,
+ };
+
++struct pwrap_slv_type {
++ const u32 *dew_regs;
++ enum pmic_type type;
++};
++
+ struct pmic_wrapper {
+ struct device *dev;
+ void __iomem *base;
+ struct regmap *regmap;
+ const struct pmic_wrapper_type *master;
++ const struct pwrap_slv_type *slave;
+ struct clk *clk_spi;
+ struct clk *clk_wrap;
+ struct reset_control *rstc;
+@@ -544,7 +575,8 @@ static int pwrap_init_sidly(struct pmic_wrapper *wrp)
+
+ for (i = 0; i < 4; i++) {
+ pwrap_writel(wrp, i, PWRAP_SIDLY);
+- pwrap_read(wrp, PWRAP_DEW_READ_TEST, &rdata);
++ pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_READ_TEST],
++ &rdata);
+ if (rdata == PWRAP_DEW_READ_TEST_VAL) {
+ dev_dbg(wrp->dev, "[Read Test] pass, SIDLY=%x\n", i);
+ pass |= 1 << i;
+@@ -593,7 +625,8 @@ static bool pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp)
+ u32 rdata;
+ int ret;
+
+- ret = pwrap_read(wrp, PWRAP_DEW_CIPHER_RDY, &rdata);
++ ret = pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_RDY],
++ &rdata);
+ if (ret)
+ return 0;
+
+@@ -621,12 +654,12 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
+ }
+
+ /* Config cipher mode @PMIC */
+- pwrap_write(wrp, PWRAP_DEW_CIPHER_SWRST, 0x1);
+- pwrap_write(wrp, PWRAP_DEW_CIPHER_SWRST, 0x0);
+- pwrap_write(wrp, PWRAP_DEW_CIPHER_KEY_SEL, 0x1);
+- pwrap_write(wrp, PWRAP_DEW_CIPHER_IV_SEL, 0x2);
+- pwrap_write(wrp, PWRAP_DEW_CIPHER_LOAD, 0x1);
+- pwrap_write(wrp, PWRAP_DEW_CIPHER_START, 0x1);
++ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x1);
++ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x0);
++ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_KEY_SEL], 0x1);
++ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_IV_SEL], 0x2);
++ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_LOAD], 0x1);
++ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_START], 0x1);
+
+ /* wait for cipher data ready@AP */
+ ret = pwrap_wait_for_state(wrp, pwrap_is_cipher_ready);
+@@ -643,7 +676,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
+ }
+
+ /* wait for cipher mode idle */
+- pwrap_write(wrp, PWRAP_DEW_CIPHER_MODE, 0x1);
++ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_MODE], 0x1);
+ ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle);
+ if (ret) {
+ dev_err(wrp->dev, "cipher mode idle fail, ret=%d\n", ret);
+@@ -653,9 +686,11 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
+ pwrap_writel(wrp, 1, PWRAP_CIPHER_MODE);
+
+ /* Write Test */
+- if (pwrap_write(wrp, PWRAP_DEW_WRITE_TEST, PWRAP_DEW_WRITE_TEST_VAL) ||
+- pwrap_read(wrp, PWRAP_DEW_WRITE_TEST, &rdata) ||
+- (rdata != PWRAP_DEW_WRITE_TEST_VAL)) {
++ if (pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_WRITE_TEST],
++ PWRAP_DEW_WRITE_TEST_VAL) ||
++ pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_WRITE_TEST],
++ &rdata) ||
++ (rdata != PWRAP_DEW_WRITE_TEST_VAL)) {
+ dev_err(wrp->dev, "rdata=0x%04X\n", rdata);
+ return -EFAULT;
+ }
+@@ -677,8 +712,10 @@ static int pwrap_mt8135_init_soc_specific(struct pmic_wrapper *wrp)
+ writel(0x7ff, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INT_EN);
+
+ /* enable PMIC event out and sources */
+- if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
+- pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
++ if (pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_EVENT_OUT_EN],
++ 0x1) ||
++ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_EVENT_SRC_EN],
++ 0xffff)) {
+ dev_err(wrp->dev, "enable dewrap fail\n");
+ return -EFAULT;
+ }
+@@ -689,8 +726,10 @@ static int pwrap_mt8135_init_soc_specific(struct pmic_wrapper *wrp)
+ static int pwrap_mt8173_init_soc_specific(struct pmic_wrapper *wrp)
+ {
+ /* PMIC_DEWRAP enables */
+- if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
+- pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
++ if (pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_EVENT_OUT_EN],
++ 0x1) ||
++ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_EVENT_SRC_EN],
++ 0xffff)) {
+ dev_err(wrp->dev, "enable dewrap fail\n");
+ return -EFAULT;
+ }
+@@ -734,7 +773,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
+ return ret;
+
+ /* Enable dual IO mode */
+- pwrap_write(wrp, PWRAP_DEW_DIO_EN, 1);
++ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_DIO_EN], 1);
+
+ /* Check IDLE & INIT_DONE in advance */
+ ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle);
+@@ -746,7 +785,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
+ pwrap_writel(wrp, 1, PWRAP_DIO_EN);
+
+ /* Read Test */
+- pwrap_read(wrp, PWRAP_DEW_READ_TEST, &rdata);
++ pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_READ_TEST], &rdata);
+ if (rdata != PWRAP_DEW_READ_TEST_VAL) {
+ dev_err(wrp->dev, "Read test failed after switch to DIO mode: 0x%04x != 0x%04x\n",
+ PWRAP_DEW_READ_TEST_VAL, rdata);
+@@ -759,12 +798,13 @@ static int pwrap_init(struct pmic_wrapper *wrp)
+ return ret;
+
+ /* Signature checking - using CRC */
+- if (pwrap_write(wrp, PWRAP_DEW_CRC_EN, 0x1))
++ if (pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_EN], 0x1))
+ return -EFAULT;
+
+ pwrap_writel(wrp, 0x1, PWRAP_CRC_EN);
+ pwrap_writel(wrp, 0x0, PWRAP_SIG_MODE);
+- pwrap_writel(wrp, PWRAP_DEW_CRC_VAL, PWRAP_SIG_ADR);
++ pwrap_writel(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_VAL],
++ PWRAP_SIG_ADR);
+ pwrap_writel(wrp, wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN);
+
+ if (wrp->master->type == PWRAP_MT8135)
+@@ -818,6 +858,21 @@ static const struct regmap_config pwrap_regmap_config = {
+ .max_register = 0xffff,
+ };
+
++static const struct pwrap_slv_type pmic_mt6397 = {
++ .dew_regs = mt6397_regs,
++ .type = PMIC_MT6397,
++};
++
++static const struct of_device_id of_slave_match_tbl[] = {
++ {
++ .compatible = "mediatek,mt6397",
++ .data = &pmic_mt6397,
++ }, {
++ /* sentinel */
++ }
++};
++MODULE_DEVICE_TABLE(of, of_slave_match_tbl);
++
+ static struct pmic_wrapper_type pwrap_mt8135 = {
+ .regs = mt8135_regs,
+ .type = PWRAP_MT8135,
+@@ -862,8 +917,17 @@ static int pwrap_probe(struct platform_device *pdev)
+ struct device_node *np = pdev->dev.of_node;
+ const struct of_device_id *of_id =
+ of_match_device(of_pwrap_match_tbl, &pdev->dev);
++ const struct of_device_id *of_slave_id = NULL;
+ struct resource *res;
+
++ if (pdev->dev.of_node->child)
++ of_slave_id = of_match_node(of_slave_match_tbl,
++ pdev->dev.of_node->child);
++ if (!of_slave_id) {
++ dev_dbg(&pdev->dev, "slave pmic should be defined in dts\n");
++ return -EINVAL;
++ }
++
+ wrp = devm_kzalloc(&pdev->dev, sizeof(*wrp), GFP_KERNEL);
+ if (!wrp)
+ return -ENOMEM;
+@@ -871,6 +935,7 @@ static int pwrap_probe(struct platform_device *pdev)
+ platform_set_drvdata(pdev, wrp);
+
+ wrp->master = of_id->data;
++ wrp->slave = of_slave_id->data;
+ wrp->dev = &pdev->dev;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwrap");
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0040-soc-mediatek-PMIC-wrap-add-mt6323-slave-support.patch b/target/linux/mediatek/patches-4.4/0040-soc-mediatek-PMIC-wrap-add-mt6323-slave-support.patch
new file mode 100644
index 0000000000..77f46e7b48
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0040-soc-mediatek-PMIC-wrap-add-mt6323-slave-support.patch
@@ -0,0 +1,98 @@
+From b82474df3eb9fad739b2b74301b68f71011a9dc7 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 20 Jan 2016 11:40:43 +0100
+Subject: [PATCH 40/53] soc: mediatek: PMIC wrap: add mt6323 slave support
+
+Add support for MT6323 slaves. This PMIC can be found on MT2701 and MT7623
+EVB. The only function that we need to touch is pwrap_init_cipher().
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 43 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 43 insertions(+)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index bcc841e..0e4ebb8 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -93,6 +93,27 @@ enum dew_regs {
+ PWRAP_DEW_EVENT_TEST,
+ PWRAP_DEW_CIPHER_LOAD,
+ PWRAP_DEW_CIPHER_START,
++
++ /* MT6323 only regs */
++ PWRAP_DEW_CIPHER_EN,
++ PWRAP_DEW_RDDMY_NO,
++};
++
++static const u32 mt6323_regs[] = {
++ [PWRAP_DEW_BASE] = 0x0000,
++ [PWRAP_DEW_DIO_EN] = 0x018a,
++ [PWRAP_DEW_READ_TEST] = 0x018c,
++ [PWRAP_DEW_WRITE_TEST] = 0x018e,
++ [PWRAP_DEW_CRC_EN] = 0x0192,
++ [PWRAP_DEW_CRC_VAL] = 0x0194,
++ [PWRAP_DEW_MON_GRP_SEL] = 0x0196,
++ [PWRAP_DEW_CIPHER_KEY_SEL] = 0x0198,
++ [PWRAP_DEW_CIPHER_IV_SEL] = 0x019a,
++ [PWRAP_DEW_CIPHER_EN] = 0x019c,
++ [PWRAP_DEW_CIPHER_RDY] = 0x019e,
++ [PWRAP_DEW_CIPHER_MODE] = 0x01a0,
++ [PWRAP_DEW_CIPHER_SWRST] = 0x01a2,
++ [PWRAP_DEW_RDDMY_NO] = 0x01a4,
+ };
+
+ static const u32 mt6397_regs[] = {
+@@ -371,6 +392,7 @@ static int mt8135_regs[] = {
+ };
+
+ enum pmic_type {
++ PMIC_MT6323,
+ PMIC_MT6397,
+ };
+
+@@ -661,6 +683,19 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
+ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_LOAD], 0x1);
+ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_START], 0x1);
+
++ switch (wrp->slave->type) {
++ case PMIC_MT6397:
++ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_LOAD],
++ 0x1);
++ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_START],
++ 0x1);
++ break;
++ case PMIC_MT6323:
++ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_EN],
++ 0x1);
++ break;
++ }
++
+ /* wait for cipher data ready@AP */
+ ret = pwrap_wait_for_state(wrp, pwrap_is_cipher_ready);
+ if (ret) {
+@@ -858,6 +893,11 @@ static const struct regmap_config pwrap_regmap_config = {
+ .max_register = 0xffff,
+ };
+
++static const struct pwrap_slv_type pmic_mt6323 = {
++ .dew_regs = mt6323_regs,
++ .type = PMIC_MT6323,
++};
++
+ static const struct pwrap_slv_type pmic_mt6397 = {
+ .dew_regs = mt6397_regs,
+ .type = PMIC_MT6397,
+@@ -865,6 +905,9 @@ static const struct pwrap_slv_type pmic_mt6397 = {
+
+ static const struct of_device_id of_slave_match_tbl[] = {
+ {
++ .compatible = "mediatek,mt6323",
++ .data = &pmic_mt6323,
++ }, {
+ .compatible = "mediatek,mt6397",
+ .data = &pmic_mt6397,
+ }, {
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0041-soc-mediatek-PMIC-wrap-add-MT2701-7623-support.patch b/target/linux/mediatek/patches-4.4/0041-soc-mediatek-PMIC-wrap-add-MT2701-7623-support.patch
new file mode 100644
index 0000000000..15445a7c3c
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0041-soc-mediatek-PMIC-wrap-add-MT2701-7623-support.patch
@@ -0,0 +1,237 @@
+From 84e83af30688372723a3b5713e914b0867d9a745 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 20 Jan 2016 12:09:14 +0100
+Subject: [PATCH 41/53] soc: mediatek: PMIC wrap: add MT2701/7623 support
+
+Add the registers, callbacks and data structures required to make the
+wrapper work on MT2701 and MT7623.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/soc/mediatek/mtk-pmic-wrap.c | 154 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 154 insertions(+)
+
+diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
+index 0e4ebb8..3c3e56d 100644
+--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
+@@ -52,6 +52,7 @@
+ #define PWRAP_DEW_WRITE_TEST_VAL 0xa55a
+
+ /* macro for manual command */
++#define PWRAP_MAN_CMD_SPI_WRITE_NEW (1 << 14)
+ #define PWRAP_MAN_CMD_SPI_WRITE (1 << 13)
+ #define PWRAP_MAN_CMD_OP_CSH (0x0 << 8)
+ #define PWRAP_MAN_CMD_OP_CSL (0x1 << 8)
+@@ -200,6 +201,13 @@ enum pwrap_regs {
+ PWRAP_DCM_EN,
+ PWRAP_DCM_DBC_PRD,
+
++ /* MT2701 only regs */
++ PWRAP_ADC_CMD_ADDR,
++ PWRAP_PWRAP_ADC_CMD,
++ PWRAP_ADC_RDY_ADDR,
++ PWRAP_ADC_RDATA_ADDR1,
++ PWRAP_ADC_RDATA_ADDR2,
++
+ /* MT8135 only regs */
+ PWRAP_CSHEXT,
+ PWRAP_EVENT_IN_EN,
+@@ -236,6 +244,92 @@ enum pwrap_regs {
+ PWRAP_CIPHER_EN,
+ };
+
++static int mt2701_regs[] = {
++ [PWRAP_MUX_SEL] = 0x0,
++ [PWRAP_WRAP_EN] = 0x4,
++ [PWRAP_DIO_EN] = 0x8,
++ [PWRAP_SIDLY] = 0xc,
++ [PWRAP_RDDMY] = 0x18,
++ [PWRAP_SI_CK_CON] = 0x1c,
++ [PWRAP_CSHEXT_WRITE] = 0x20,
++ [PWRAP_CSHEXT_READ] = 0x24,
++ [PWRAP_CSLEXT_START] = 0x28,
++ [PWRAP_CSLEXT_END] = 0x2c,
++ [PWRAP_STAUPD_PRD] = 0x30,
++ [PWRAP_STAUPD_GRPEN] = 0x34,
++ [PWRAP_STAUPD_MAN_TRIG] = 0x38,
++ [PWRAP_STAUPD_STA] = 0x3c,
++ [PWRAP_WRAP_STA] = 0x44,
++ [PWRAP_HARB_INIT] = 0x48,
++ [PWRAP_HARB_HPRIO] = 0x4c,
++ [PWRAP_HIPRIO_ARB_EN] = 0x50,
++ [PWRAP_HARB_STA0] = 0x54,
++ [PWRAP_HARB_STA1] = 0x58,
++ [PWRAP_MAN_EN] = 0x5c,
++ [PWRAP_MAN_CMD] = 0x60,
++ [PWRAP_MAN_RDATA] = 0x64,
++ [PWRAP_MAN_VLDCLR] = 0x68,
++ [PWRAP_WACS0_EN] = 0x6c,
++ [PWRAP_INIT_DONE0] = 0x70,
++ [PWRAP_WACS0_CMD] = 0x74,
++ [PWRAP_WACS0_RDATA] = 0x78,
++ [PWRAP_WACS0_VLDCLR] = 0x7c,
++ [PWRAP_WACS1_EN] = 0x80,
++ [PWRAP_INIT_DONE1] = 0x84,
++ [PWRAP_WACS1_CMD] = 0x88,
++ [PWRAP_WACS1_RDATA] = 0x8c,
++ [PWRAP_WACS1_VLDCLR] = 0x90,
++ [PWRAP_WACS2_EN] = 0x94,
++ [PWRAP_INIT_DONE2] = 0x98,
++ [PWRAP_WACS2_CMD] = 0x9c,
++ [PWRAP_WACS2_RDATA] = 0xa0,
++ [PWRAP_WACS2_VLDCLR] = 0xa4,
++ [PWRAP_INT_EN] = 0xa8,
++ [PWRAP_INT_FLG_RAW] = 0xac,
++ [PWRAP_INT_FLG] = 0xb0,
++ [PWRAP_INT_CLR] = 0xb4,
++ [PWRAP_SIG_ADR] = 0xb8,
++ [PWRAP_SIG_MODE] = 0xbc,
++ [PWRAP_SIG_VALUE] = 0xc0,
++ [PWRAP_SIG_ERRVAL] = 0xc4,
++ [PWRAP_CRC_EN] = 0xc8,
++ [PWRAP_TIMER_EN] = 0xcc,
++ [PWRAP_TIMER_STA] = 0xd0,
++ [PWRAP_WDT_UNIT] = 0xd4,
++ [PWRAP_WDT_SRC_EN] = 0xd8,
++ [PWRAP_WDT_FLG] = 0xdc,
++ [PWRAP_DEBUG_INT_SEL] = 0xe0,
++ [PWRAP_DVFS_ADR0] = 0xe4,
++ [PWRAP_DVFS_WDATA0] = 0xe8,
++ [PWRAP_DVFS_ADR1] = 0xec,
++ [PWRAP_DVFS_WDATA1] = 0xf0,
++ [PWRAP_DVFS_ADR2] = 0xf4,
++ [PWRAP_DVFS_WDATA2] = 0xf8,
++ [PWRAP_DVFS_ADR3] = 0xfc,
++ [PWRAP_DVFS_WDATA3] = 0x100,
++ [PWRAP_DVFS_ADR4] = 0x104,
++ [PWRAP_DVFS_WDATA4] = 0x108,
++ [PWRAP_DVFS_ADR5] = 0x10c,
++ [PWRAP_DVFS_WDATA5] = 0x110,
++ [PWRAP_DVFS_ADR6] = 0x114,
++ [PWRAP_DVFS_WDATA6] = 0x118,
++ [PWRAP_DVFS_ADR7] = 0x11c,
++ [PWRAP_DVFS_WDATA7] = 0x120,
++ [PWRAP_CIPHER_KEY_SEL] = 0x124,
++ [PWRAP_CIPHER_IV_SEL] = 0x128,
++ [PWRAP_CIPHER_EN] = 0x12c,
++ [PWRAP_CIPHER_RDY] = 0x130,
++ [PWRAP_CIPHER_MODE] = 0x134,
++ [PWRAP_CIPHER_SWRST] = 0x138,
++ [PWRAP_DCM_EN] = 0x13c,
++ [PWRAP_DCM_DBC_PRD] = 0x140,
++ [PWRAP_ADC_CMD_ADDR] = 0x144,
++ [PWRAP_PWRAP_ADC_CMD] = 0x148,
++ [PWRAP_ADC_RDY_ADDR] = 0x14c,
++ [PWRAP_ADC_RDATA_ADDR1] = 0x150,
++ [PWRAP_ADC_RDATA_ADDR2] = 0x154,
++};
++
+ static int mt8173_regs[] = {
+ [PWRAP_MUX_SEL] = 0x0,
+ [PWRAP_WRAP_EN] = 0x4,
+@@ -397,6 +491,7 @@ enum pmic_type {
+ };
+
+ enum pwrap_type {
++ PWRAP_MT2701,
+ PWRAP_MT8135,
+ PWRAP_MT8173,
+ };
+@@ -637,6 +732,31 @@ static int pwrap_mt8173_init_reg_clock(struct pmic_wrapper *wrp)
+ return 0;
+ }
+
++static int pwrap_mt2701_init_reg_clock(struct pmic_wrapper *wrp)
++{
++ switch (wrp->slave->type) {
++ case PMIC_MT6397:
++ pwrap_writel(wrp, 0xc, PWRAP_RDDMY);
++ pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_WRITE);
++ pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_READ);
++ pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START);
++ pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END);
++ break;
++
++ case PMIC_MT6323:
++ pwrap_writel(wrp, 0x8, PWRAP_RDDMY);
++ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_RDDMY_NO],
++ 0x8);
++ pwrap_writel(wrp, 0x5, PWRAP_CSHEXT_WRITE);
++ pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_READ);
++ pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START);
++ pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END);
++ break;
++ }
++
++ return 0;
++}
++
+ static bool pwrap_is_cipher_ready(struct pmic_wrapper *wrp)
+ {
+ return pwrap_readl(wrp, PWRAP_CIPHER_RDY) & 1;
+@@ -670,6 +790,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
+ pwrap_writel(wrp, 1, PWRAP_CIPHER_LOAD);
+ pwrap_writel(wrp, 1, PWRAP_CIPHER_START);
+ break;
++ case PWRAP_MT2701:
+ case PWRAP_MT8173:
+ pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);
+ break;
+@@ -772,6 +893,24 @@ static int pwrap_mt8173_init_soc_specific(struct pmic_wrapper *wrp)
+ return 0;
+ }
+
++static int pwrap_mt2701_init_soc_specific(struct pmic_wrapper *wrp)
++{
++ /* GPS_INTF initialization */
++ switch (wrp->slave->type) {
++ case PMIC_MT6323:
++ pwrap_writel(wrp, 0x076c, PWRAP_ADC_CMD_ADDR);
++ pwrap_writel(wrp, 0x8000, PWRAP_PWRAP_ADC_CMD);
++ pwrap_writel(wrp, 0x072c, PWRAP_ADC_RDY_ADDR);
++ pwrap_writel(wrp, 0x072e, PWRAP_ADC_RDATA_ADDR1);
++ pwrap_writel(wrp, 0x0730, PWRAP_ADC_RDATA_ADDR2);
++ break;
++ default:
++ break;
++ }
++
++ return 0;
++}
++
+ static int pwrap_init(struct pmic_wrapper *wrp)
+ {
+ int ret;
+@@ -916,6 +1055,18 @@ static const struct of_device_id of_slave_match_tbl[] = {
+ };
+ MODULE_DEVICE_TABLE(of, of_slave_match_tbl);
+
++static const struct pmic_wrapper_type pwrap_mt2701 = {
++ .regs = mt2701_regs,
++ .type = PWRAP_MT2701,
++ .arb_en_all = 0x3f,
++ .int_en_all = ~(BIT(31) | BIT(2)),
++ .spi_w = PWRAP_MAN_CMD_SPI_WRITE_NEW,
++ .wdt_src = PWRAP_WDT_SRC_MASK_ALL,
++ .has_bridge = 0,
++ .init_reg_clock = pwrap_mt2701_init_reg_clock,
++ .init_soc_specific = pwrap_mt2701_init_soc_specific,
++};
++
+ static struct pmic_wrapper_type pwrap_mt8135 = {
+ .regs = mt8135_regs,
+ .type = PWRAP_MT8135,
+@@ -942,6 +1093,9 @@ static struct pmic_wrapper_type pwrap_mt8173 = {
+
+ static struct of_device_id of_pwrap_match_tbl[] = {
+ {
++ .compatible = "mediatek,mt2701-pwrap",
++ .data = &pwrap_mt2701,
++ }, {
+ .compatible = "mediatek,mt8135-pwrap",
+ .data = &pwrap_mt8135,
+ }, {
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0042-dt-bindings-mfd-Add-bindings-for-the-MediaTek-MT6323.patch b/target/linux/mediatek/patches-4.4/0042-dt-bindings-mfd-Add-bindings-for-the-MediaTek-MT6323.patch
new file mode 100644
index 0000000000..e7a23f75e1
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0042-dt-bindings-mfd-Add-bindings-for-the-MediaTek-MT6323.patch
@@ -0,0 +1,55 @@
+From 3af0e56f55d7676fab0ba39ef599c64dd6ab4b35 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 10 Jan 2016 17:12:37 +0100
+Subject: [PATCH 42/53] dt-bindings: mfd: Add bindings for the MediaTek MT6323
+ PMIC
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Acked-by: Rob Herring <robh@kernel.org>
+Cc: devicetree@vger.kernel.org
+---
+ Documentation/devicetree/bindings/mfd/mt6397.txt | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt
+index 15043e6..949c85f 100644
+--- a/Documentation/devicetree/bindings/mfd/mt6397.txt
++++ b/Documentation/devicetree/bindings/mfd/mt6397.txt
+@@ -1,6 +1,6 @@
+-MediaTek MT6397 Multifunction Device Driver
++MediaTek MT6397/MT6323 Multifunction Device Driver
+
+-MT6397 is a multifunction device with the following sub modules:
++MT6397/MT6323 is a multifunction device with the following sub modules:
+ - Regulator
+ - RTC
+ - Audio codec
+@@ -8,14 +8,14 @@ MT6397 is a multifunction device with the following sub modules:
+ - Clock
+
+ It is interfaced to host controller using SPI interface by a proprietary hardware
+-called PMIC wrapper or pwrap. MT6397 MFD is a child device of pwrap.
++called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap.
+ See the following for pwarp node definitions:
+ Documentation/devicetree/bindings/soc/pwrap.txt
+
+ This document describes the binding for MFD device and its sub module.
+
+ Required properties:
+-compatible: "mediatek,mt6397"
++compatible: "mediatek,mt6397" or "mediatek,mt6323"
+
+ Optional subnodes:
+
+@@ -26,6 +26,8 @@ Optional subnodes:
+ Required properties:
+ - compatible: "mediatek,mt6397-regulator"
+ see Documentation/devicetree/bindings/regulator/mt6397-regulator.txt
++ - compatible: "mediatek,mt6323-regulator"
++ see Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
+ - codec
+ Required properties:
+ - compatible: "mediatek,mt6397-codec"
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0043-mfd-mt6397-int_con-and-int_status-may-vary-in-locati.patch b/target/linux/mediatek/patches-4.4/0043-mfd-mt6397-int_con-and-int_status-may-vary-in-locati.patch
new file mode 100644
index 0000000000..113c8de7b4
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0043-mfd-mt6397-int_con-and-int_status-may-vary-in-locati.patch
@@ -0,0 +1,104 @@
+From f3d5ef8f5422de25f1c8a96b313baf60e4ce1081 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Fri, 8 Jan 2016 08:33:17 +0100
+Subject: [PATCH 43/53] mfd: mt6397: int_con and int_status may vary in
+ location
+
+MT6323 has the INT_CON and INT_STATUS located at a different position.
+Make the registers locations configurable.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/mfd/mt6397-core.c | 27 +++++++++++++++++----------
+ include/linux/mfd/mt6397/core.h | 2 ++
+ 2 files changed, 19 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
+index 1749c1c..75ad0fe 100644
+--- a/drivers/mfd/mt6397-core.c
++++ b/drivers/mfd/mt6397-core.c
+@@ -69,8 +69,10 @@ static void mt6397_irq_sync_unlock(struct irq_data *data)
+ {
+ struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
+
+- regmap_write(mt6397->regmap, MT6397_INT_CON0, mt6397->irq_masks_cur[0]);
+- regmap_write(mt6397->regmap, MT6397_INT_CON1, mt6397->irq_masks_cur[1]);
++ regmap_write(mt6397->regmap, mt6397->int_con[0],
++ mt6397->irq_masks_cur[0]);
++ regmap_write(mt6397->regmap, mt6397->int_con[1],
++ mt6397->irq_masks_cur[1]);
+
+ mutex_unlock(&mt6397->irqlock);
+ }
+@@ -147,8 +149,8 @@ static irqreturn_t mt6397_irq_thread(int irq, void *data)
+ {
+ struct mt6397_chip *mt6397 = data;
+
+- mt6397_irq_handle_reg(mt6397, MT6397_INT_STATUS0, 0);
+- mt6397_irq_handle_reg(mt6397, MT6397_INT_STATUS1, 16);
++ mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
++ mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
+
+ return IRQ_HANDLED;
+ }
+@@ -177,8 +179,8 @@ static int mt6397_irq_init(struct mt6397_chip *mt6397)
+ mutex_init(&mt6397->irqlock);
+
+ /* Mask all interrupt sources */
+- regmap_write(mt6397->regmap, MT6397_INT_CON0, 0x0);
+- regmap_write(mt6397->regmap, MT6397_INT_CON1, 0x0);
++ regmap_write(mt6397->regmap, mt6397->int_con[0], 0x0);
++ regmap_write(mt6397->regmap, mt6397->int_con[1], 0x0);
+
+ mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node,
+ MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397);
+@@ -203,8 +205,8 @@ static int mt6397_irq_suspend(struct device *dev)
+ {
+ struct mt6397_chip *chip = dev_get_drvdata(dev);
+
+- regmap_write(chip->regmap, MT6397_INT_CON0, chip->wake_mask[0]);
+- regmap_write(chip->regmap, MT6397_INT_CON1, chip->wake_mask[1]);
++ regmap_write(chip->regmap, chip->int_con[0], chip->wake_mask[0]);
++ regmap_write(chip->regmap, chip->int_con[1], chip->wake_mask[1]);
+
+ enable_irq_wake(chip->irq);
+
+@@ -215,8 +217,8 @@ static int mt6397_irq_resume(struct device *dev)
+ {
+ struct mt6397_chip *chip = dev_get_drvdata(dev);
+
+- regmap_write(chip->regmap, MT6397_INT_CON0, chip->irq_masks_cur[0]);
+- regmap_write(chip->regmap, MT6397_INT_CON1, chip->irq_masks_cur[1]);
++ regmap_write(chip->regmap, chip->int_con[0], chip->irq_masks_cur[0]);
++ regmap_write(chip->regmap, chip->int_con[1], chip->irq_masks_cur[1]);
+
+ disable_irq_wake(chip->irq);
+
+@@ -237,6 +239,11 @@ static int mt6397_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ mt6397->dev = &pdev->dev;
++ mt6397->int_con[0] = MT6397_INT_CON0;
++ mt6397->int_con[1] = MT6397_INT_CON1;
++ mt6397->int_status[0] = MT6397_INT_STATUS0;
++ mt6397->int_status[1] = MT6397_INT_STATUS1;
++
+ /*
+ * mt6397 MFD is child device of soc pmic wrapper.
+ * Regmap is set from its parent.
+diff --git a/include/linux/mfd/mt6397/core.h b/include/linux/mfd/mt6397/core.h
+index 45b8e8a..d678f52 100644
+--- a/include/linux/mfd/mt6397/core.h
++++ b/include/linux/mfd/mt6397/core.h
+@@ -60,6 +60,8 @@ struct mt6397_chip {
+ u16 wake_mask[2];
+ u16 irq_masks_cur[2];
+ u16 irq_masks_cache[2];
++ u16 int_con[2];
++ u16 int_status[2];
+ };
+
+ #endif /* __MFD_MT6397_CORE_H__ */
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0044-mfd-mt6397-add-support-for-different-Slave-types.patch b/target/linux/mediatek/patches-4.4/0044-mfd-mt6397-add-support-for-different-Slave-types.patch
new file mode 100644
index 0000000000..30576b76b7
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0044-mfd-mt6397-add-support-for-different-Slave-types.patch
@@ -0,0 +1,105 @@
+From d29ee5f0472ea3e964e698e3e9e87a83b4465e9c Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Fri, 8 Jan 2016 08:41:52 +0100
+Subject: [PATCH 44/53] mfd: mt6397: add support for different Slave types
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/mfd/mt6397-core.c | 58 ++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 41 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
+index 75ad0fe..aa91606 100644
+--- a/drivers/mfd/mt6397-core.c
++++ b/drivers/mfd/mt6397-core.c
+@@ -24,6 +24,9 @@
+ #define MT6397_RTC_BASE 0xe000
+ #define MT6397_RTC_SIZE 0x3e
+
++#define MT6391_CID_CODE 0x91
++#define MT6397_CID_CODE 0x97
++
+ static const struct resource mt6397_rtc_resources[] = {
+ {
+ .start = MT6397_RTC_BASE,
+@@ -232,39 +235,60 @@ static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend,
+ static int mt6397_probe(struct platform_device *pdev)
+ {
+ int ret;
+- struct mt6397_chip *mt6397;
++ unsigned int id;
++ struct mt6397_chip *pmic;
+
+- mt6397 = devm_kzalloc(&pdev->dev, sizeof(*mt6397), GFP_KERNEL);
+- if (!mt6397)
++ pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
++ if (!pmic)
+ return -ENOMEM;
+
+- mt6397->dev = &pdev->dev;
+- mt6397->int_con[0] = MT6397_INT_CON0;
+- mt6397->int_con[1] = MT6397_INT_CON1;
+- mt6397->int_status[0] = MT6397_INT_STATUS0;
+- mt6397->int_status[1] = MT6397_INT_STATUS1;
++ pmic->dev = &pdev->dev;
+
+ /*
+ * mt6397 MFD is child device of soc pmic wrapper.
+ * Regmap is set from its parent.
+ */
+- mt6397->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+- if (!mt6397->regmap)
++ pmic->regmap = dev_get_regmap(pdev->dev.parent, NULL);
++ if (!pmic->regmap)
+ return -ENODEV;
+
+- platform_set_drvdata(pdev, mt6397);
++ platform_set_drvdata(pdev, pmic);
++
++ ret = regmap_read(pmic->regmap, MT6397_CID, &id);
++ if (ret) {
++ dev_err(pmic->dev, "Failed to read chip id: %d\n", ret);
++ goto fail_irq;
++ }
++
++ switch (id & 0xff) {
++ case MT6397_CID_CODE:
++ case MT6391_CID_CODE:
++ pmic->int_con[0] = MT6397_INT_CON0;
++ pmic->int_con[1] = MT6397_INT_CON1;
++ pmic->int_status[0] = MT6397_INT_STATUS0;
++ pmic->int_status[1] = MT6397_INT_STATUS1;
++ ret = mfd_add_devices(&pdev->dev, -1, mt6397_devs,
++ ARRAY_SIZE(mt6397_devs), NULL, 0, NULL);
++ break;
++
++ default:
++ dev_err(&pdev->dev, "unsupported chip: %d\n", id);
++ ret = -ENODEV;
++ break;
++ }
+
+- mt6397->irq = platform_get_irq(pdev, 0);
+- if (mt6397->irq > 0) {
+- ret = mt6397_irq_init(mt6397);
++ pmic->irq = platform_get_irq(pdev, 0);
++ if (pmic->irq > 0) {
++ ret = mt6397_irq_init(pmic);
+ if (ret)
+ return ret;
+ }
+
+- ret = mfd_add_devices(&pdev->dev, -1, mt6397_devs,
+- ARRAY_SIZE(mt6397_devs), NULL, 0, NULL);
+- if (ret)
++fail_irq:
++ if (ret) {
++ irq_domain_remove(pmic->irq_domain);
+ dev_err(&pdev->dev, "failed to add child devices: %d\n", ret);
++ }
+
+ return ret;
+ }
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0045-mfd-mt6397-add-MT6323-support-to-MT6397-driver.patch b/target/linux/mediatek/patches-4.4/0045-mfd-mt6397-add-MT6323-support-to-MT6397-driver.patch
new file mode 100644
index 0000000000..7831eb613e
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0045-mfd-mt6397-add-MT6323-support-to-MT6397-driver.patch
@@ -0,0 +1,530 @@
+From 926910e33f5de67f229ac089ab5f3de1bfd117f9 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Fri, 8 Jan 2016 04:09:43 +0100
+Subject: [PATCH 45/53] mfd: mt6397: add MT6323 support to MT6397 driver
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/mfd/mt6397-core.c | 20 ++
+ include/linux/mfd/mt6323/core.h | 36 +++
+ include/linux/mfd/mt6323/registers.h | 408 ++++++++++++++++++++++++++++++++++
+ 3 files changed, 464 insertions(+)
+ create mode 100644 include/linux/mfd/mt6323/core.h
+ create mode 100644 include/linux/mfd/mt6323/registers.h
+
+diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
+index aa91606..8234cd3 100644
+--- a/drivers/mfd/mt6397-core.c
++++ b/drivers/mfd/mt6397-core.c
+@@ -19,11 +19,14 @@
+ #include <linux/regmap.h>
+ #include <linux/mfd/core.h>
+ #include <linux/mfd/mt6397/core.h>
++#include <linux/mfd/mt6323/core.h>
+ #include <linux/mfd/mt6397/registers.h>
++#include <linux/mfd/mt6323/registers.h>
+
+ #define MT6397_RTC_BASE 0xe000
+ #define MT6397_RTC_SIZE 0x3e
+
++#define MT6323_CID_CODE 0x23
+ #define MT6391_CID_CODE 0x91
+ #define MT6397_CID_CODE 0x97
+
+@@ -40,6 +43,13 @@ static const struct resource mt6397_rtc_resources[] = {
+ },
+ };
+
++static const struct mfd_cell mt6323_devs[] = {
++ {
++ .name = "mt6323-regulator",
++ .of_compatible = "mediatek,mt6323-regulator"
++ },
++};
++
+ static const struct mfd_cell mt6397_devs[] = {
+ {
+ .name = "mt6397-rtc",
+@@ -261,6 +271,15 @@ static int mt6397_probe(struct platform_device *pdev)
+ }
+
+ switch (id & 0xff) {
++ case MT6323_CID_CODE:
++ pmic->int_con[0] = MT6323_INT_CON0;
++ pmic->int_con[1] = MT6323_INT_CON1;
++ pmic->int_status[0] = MT6323_INT_STATUS0;
++ pmic->int_status[1] = MT6323_INT_STATUS1;
++ ret = mfd_add_devices(&pdev->dev, -1, mt6323_devs,
++ ARRAY_SIZE(mt6323_devs), NULL, 0, NULL);
++ break;
++
+ case MT6397_CID_CODE:
+ case MT6391_CID_CODE:
+ pmic->int_con[0] = MT6397_INT_CON0;
+@@ -302,6 +321,7 @@ static int mt6397_remove(struct platform_device *pdev)
+
+ static const struct of_device_id mt6397_of_match[] = {
+ { .compatible = "mediatek,mt6397" },
++ { .compatible = "mediatek,mt6323" },
+ { }
+ };
+ MODULE_DEVICE_TABLE(of, mt6397_of_match);
+diff --git a/include/linux/mfd/mt6323/core.h b/include/linux/mfd/mt6323/core.h
+new file mode 100644
+index 0000000..06d0ec3
+--- /dev/null
++++ b/include/linux/mfd/mt6323/core.h
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (c) 2016 Chen Zhong <chen.zhong@mediatek.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __MFD_MT6323_CORE_H__
++#define __MFD_MT6323_CORE_H__
++
++enum MT6323_IRQ_STATUS_numbers {
++ MT6323_IRQ_STATUS_SPKL_AB = 0,
++ MT6323_IRQ_STATUS_SPKL,
++ MT6323_IRQ_STATUS_BAT_L,
++ MT6323_IRQ_STATUS_BAT_H,
++ MT6323_IRQ_STATUS_WATCHDOG,
++ MT6323_IRQ_STATUS_PWRKEY,
++ MT6323_IRQ_STATUS_THR_L,
++ MT6323_IRQ_STATUS_THR_H,
++ MT6323_IRQ_STATUS_VBATON_UNDET,
++ MT6323_IRQ_STATUS_BVALID_DET,
++ MT6323_IRQ_STATUS_CHRDET,
++ MT6323_IRQ_STATUS_OV,
++ MT6323_IRQ_STATUS_LDO = 16,
++ MT6323_IRQ_STATUS_FCHRKEY,
++ MT6323_IRQ_STATUS_ACCDET,
++ MT6323_IRQ_STATUS_AUDIO,
++ MT6323_IRQ_STATUS_RTC,
++ MT6323_IRQ_STATUS_VPROC,
++ MT6323_IRQ_STATUS_VSYS,
++ MT6323_IRQ_STATUS_VPA,
++ MT6323_IRQ_STATUS_NR,
++};
++
++#endif /* __MFD_MT6323_CORE_H__ */
+diff --git a/include/linux/mfd/mt6323/registers.h b/include/linux/mfd/mt6323/registers.h
+new file mode 100644
+index 0000000..160f3c0
+--- /dev/null
++++ b/include/linux/mfd/mt6323/registers.h
+@@ -0,0 +1,408 @@
++/*
++ * Copyright (c) 2016 Chen Zhong <chen.zhong@mediatek.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __MFD_MT6323_REGISTERS_H__
++#define __MFD_MT6323_REGISTERS_H__
++
++/* PMIC Registers */
++#define MT6323_CHR_CON0 0x0000
++#define MT6323_CHR_CON1 0x0002
++#define MT6323_CHR_CON2 0x0004
++#define MT6323_CHR_CON3 0x0006
++#define MT6323_CHR_CON4 0x0008
++#define MT6323_CHR_CON5 0x000A
++#define MT6323_CHR_CON6 0x000C
++#define MT6323_CHR_CON7 0x000E
++#define MT6323_CHR_CON8 0x0010
++#define MT6323_CHR_CON9 0x0012
++#define MT6323_CHR_CON10 0x0014
++#define MT6323_CHR_CON11 0x0016
++#define MT6323_CHR_CON12 0x0018
++#define MT6323_CHR_CON13 0x001A
++#define MT6323_CHR_CON14 0x001C
++#define MT6323_CHR_CON15 0x001E
++#define MT6323_CHR_CON16 0x0020
++#define MT6323_CHR_CON17 0x0022
++#define MT6323_CHR_CON18 0x0024
++#define MT6323_CHR_CON19 0x0026
++#define MT6323_CHR_CON20 0x0028
++#define MT6323_CHR_CON21 0x002A
++#define MT6323_CHR_CON22 0x002C
++#define MT6323_CHR_CON23 0x002E
++#define MT6323_CHR_CON24 0x0030
++#define MT6323_CHR_CON25 0x0032
++#define MT6323_CHR_CON26 0x0034
++#define MT6323_CHR_CON27 0x0036
++#define MT6323_CHR_CON28 0x0038
++#define MT6323_CHR_CON29 0x003A
++#define MT6323_STRUP_CON0 0x003C
++#define MT6323_STRUP_CON2 0x003E
++#define MT6323_STRUP_CON3 0x0040
++#define MT6323_STRUP_CON4 0x0042
++#define MT6323_STRUP_CON5 0x0044
++#define MT6323_STRUP_CON6 0x0046
++#define MT6323_STRUP_CON7 0x0048
++#define MT6323_STRUP_CON8 0x004A
++#define MT6323_STRUP_CON9 0x004C
++#define MT6323_STRUP_CON10 0x004E
++#define MT6323_STRUP_CON11 0x0050
++#define MT6323_SPK_CON0 0x0052
++#define MT6323_SPK_CON1 0x0054
++#define MT6323_SPK_CON2 0x0056
++#define MT6323_SPK_CON6 0x005E
++#define MT6323_SPK_CON7 0x0060
++#define MT6323_SPK_CON8 0x0062
++#define MT6323_SPK_CON9 0x0064
++#define MT6323_SPK_CON10 0x0066
++#define MT6323_SPK_CON11 0x0068
++#define MT6323_SPK_CON12 0x006A
++#define MT6323_CID 0x0100
++#define MT6323_TOP_CKPDN0 0x0102
++#define MT6323_TOP_CKPDN0_SET 0x0104
++#define MT6323_TOP_CKPDN0_CLR 0x0106
++#define MT6323_TOP_CKPDN1 0x0108
++#define MT6323_TOP_CKPDN1_SET 0x010A
++#define MT6323_TOP_CKPDN1_CLR 0x010C
++#define MT6323_TOP_CKPDN2 0x010E
++#define MT6323_TOP_CKPDN2_SET 0x0110
++#define MT6323_TOP_CKPDN2_CLR 0x0112
++#define MT6323_TOP_RST_CON 0x0114
++#define MT6323_TOP_RST_CON_SET 0x0116
++#define MT6323_TOP_RST_CON_CLR 0x0118
++#define MT6323_TOP_RST_MISC 0x011A
++#define MT6323_TOP_RST_MISC_SET 0x011C
++#define MT6323_TOP_RST_MISC_CLR 0x011E
++#define MT6323_TOP_CKCON0 0x0120
++#define MT6323_TOP_CKCON0_SET 0x0122
++#define MT6323_TOP_CKCON0_CLR 0x0124
++#define MT6323_TOP_CKCON1 0x0126
++#define MT6323_TOP_CKCON1_SET 0x0128
++#define MT6323_TOP_CKCON1_CLR 0x012A
++#define MT6323_TOP_CKTST0 0x012C
++#define MT6323_TOP_CKTST1 0x012E
++#define MT6323_TOP_CKTST2 0x0130
++#define MT6323_TEST_OUT 0x0132
++#define MT6323_TEST_CON0 0x0134
++#define MT6323_TEST_CON1 0x0136
++#define MT6323_EN_STATUS0 0x0138
++#define MT6323_EN_STATUS1 0x013A
++#define MT6323_OCSTATUS0 0x013C
++#define MT6323_OCSTATUS1 0x013E
++#define MT6323_PGSTATUS 0x0140
++#define MT6323_CHRSTATUS 0x0142
++#define MT6323_TDSEL_CON 0x0144
++#define MT6323_RDSEL_CON 0x0146
++#define MT6323_SMT_CON0 0x0148
++#define MT6323_SMT_CON1 0x014A
++#define MT6323_SMT_CON2 0x014C
++#define MT6323_SMT_CON3 0x014E
++#define MT6323_SMT_CON4 0x0150
++#define MT6323_DRV_CON0 0x0152
++#define MT6323_DRV_CON1 0x0154
++#define MT6323_DRV_CON2 0x0156
++#define MT6323_DRV_CON3 0x0158
++#define MT6323_DRV_CON4 0x015A
++#define MT6323_SIMLS1_CON 0x015C
++#define MT6323_SIMLS2_CON 0x015E
++#define MT6323_INT_CON0 0x0160
++#define MT6323_INT_CON0_SET 0x0162
++#define MT6323_INT_CON0_CLR 0x0164
++#define MT6323_INT_CON1 0x0166
++#define MT6323_INT_CON1_SET 0x0168
++#define MT6323_INT_CON1_CLR 0x016A
++#define MT6323_INT_MISC_CON 0x016C
++#define MT6323_INT_MISC_CON_SET 0x016E
++#define MT6323_INT_MISC_CON_CLR 0x0170
++#define MT6323_INT_STATUS0 0x0172
++#define MT6323_INT_STATUS1 0x0174
++#define MT6323_OC_GEAR_0 0x0176
++#define MT6323_OC_GEAR_1 0x0178
++#define MT6323_OC_GEAR_2 0x017A
++#define MT6323_OC_CTL_VPROC 0x017C
++#define MT6323_OC_CTL_VSYS 0x017E
++#define MT6323_OC_CTL_VPA 0x0180
++#define MT6323_FQMTR_CON0 0x0182
++#define MT6323_FQMTR_CON1 0x0184
++#define MT6323_FQMTR_CON2 0x0186
++#define MT6323_RG_SPI_CON 0x0188
++#define MT6323_DEW_DIO_EN 0x018A
++#define MT6323_DEW_READ_TEST 0x018C
++#define MT6323_DEW_WRITE_TEST 0x018E
++#define MT6323_DEW_CRC_SWRST 0x0190
++#define MT6323_DEW_CRC_EN 0x0192
++#define MT6323_DEW_CRC_VAL 0x0194
++#define MT6323_DEW_DBG_MON_SEL 0x0196
++#define MT6323_DEW_CIPHER_KEY_SEL 0x0198
++#define MT6323_DEW_CIPHER_IV_SEL 0x019A
++#define MT6323_DEW_CIPHER_EN 0x019C
++#define MT6323_DEW_CIPHER_RDY 0x019E
++#define MT6323_DEW_CIPHER_MODE 0x01A0
++#define MT6323_DEW_CIPHER_SWRST 0x01A2
++#define MT6323_DEW_RDDMY_NO 0x01A4
++#define MT6323_DEW_RDATA_DLY_SEL 0x01A6
++#define MT6323_BUCK_CON0 0x0200
++#define MT6323_BUCK_CON1 0x0202
++#define MT6323_BUCK_CON2 0x0204
++#define MT6323_BUCK_CON3 0x0206
++#define MT6323_BUCK_CON4 0x0208
++#define MT6323_BUCK_CON5 0x020A
++#define MT6323_VPROC_CON0 0x020C
++#define MT6323_VPROC_CON1 0x020E
++#define MT6323_VPROC_CON2 0x0210
++#define MT6323_VPROC_CON3 0x0212
++#define MT6323_VPROC_CON4 0x0214
++#define MT6323_VPROC_CON5 0x0216
++#define MT6323_VPROC_CON7 0x021A
++#define MT6323_VPROC_CON8 0x021C
++#define MT6323_VPROC_CON9 0x021E
++#define MT6323_VPROC_CON10 0x0220
++#define MT6323_VPROC_CON11 0x0222
++#define MT6323_VPROC_CON12 0x0224
++#define MT6323_VPROC_CON13 0x0226
++#define MT6323_VPROC_CON14 0x0228
++#define MT6323_VPROC_CON15 0x022A
++#define MT6323_VPROC_CON18 0x0230
++#define MT6323_VSYS_CON0 0x0232
++#define MT6323_VSYS_CON1 0x0234
++#define MT6323_VSYS_CON2 0x0236
++#define MT6323_VSYS_CON3 0x0238
++#define MT6323_VSYS_CON4 0x023A
++#define MT6323_VSYS_CON5 0x023C
++#define MT6323_VSYS_CON7 0x0240
++#define MT6323_VSYS_CON8 0x0242
++#define MT6323_VSYS_CON9 0x0244
++#define MT6323_VSYS_CON10 0x0246
++#define MT6323_VSYS_CON11 0x0248
++#define MT6323_VSYS_CON12 0x024A
++#define MT6323_VSYS_CON13 0x024C
++#define MT6323_VSYS_CON14 0x024E
++#define MT6323_VSYS_CON15 0x0250
++#define MT6323_VSYS_CON18 0x0256
++#define MT6323_VPA_CON0 0x0300
++#define MT6323_VPA_CON1 0x0302
++#define MT6323_VPA_CON2 0x0304
++#define MT6323_VPA_CON3 0x0306
++#define MT6323_VPA_CON4 0x0308
++#define MT6323_VPA_CON5 0x030A
++#define MT6323_VPA_CON7 0x030E
++#define MT6323_VPA_CON8 0x0310
++#define MT6323_VPA_CON9 0x0312
++#define MT6323_VPA_CON10 0x0314
++#define MT6323_VPA_CON11 0x0316
++#define MT6323_VPA_CON12 0x0318
++#define MT6323_VPA_CON14 0x031C
++#define MT6323_VPA_CON16 0x0320
++#define MT6323_VPA_CON17 0x0322
++#define MT6323_VPA_CON18 0x0324
++#define MT6323_VPA_CON19 0x0326
++#define MT6323_VPA_CON20 0x0328
++#define MT6323_BUCK_K_CON0 0x032A
++#define MT6323_BUCK_K_CON1 0x032C
++#define MT6323_BUCK_K_CON2 0x032E
++#define MT6323_ISINK0_CON0 0x0330
++#define MT6323_ISINK0_CON1 0x0332
++#define MT6323_ISINK0_CON2 0x0334
++#define MT6323_ISINK0_CON3 0x0336
++#define MT6323_ISINK1_CON0 0x0338
++#define MT6323_ISINK1_CON1 0x033A
++#define MT6323_ISINK1_CON2 0x033C
++#define MT6323_ISINK1_CON3 0x033E
++#define MT6323_ISINK2_CON0 0x0340
++#define MT6323_ISINK2_CON1 0x0342
++#define MT6323_ISINK2_CON2 0x0344
++#define MT6323_ISINK2_CON3 0x0346
++#define MT6323_ISINK3_CON0 0x0348
++#define MT6323_ISINK3_CON1 0x034A
++#define MT6323_ISINK3_CON2 0x034C
++#define MT6323_ISINK3_CON3 0x034E
++#define MT6323_ISINK_ANA0 0x0350
++#define MT6323_ISINK_ANA1 0x0352
++#define MT6323_ISINK_PHASE_DLY 0x0354
++#define MT6323_ISINK_EN_CTRL 0x0356
++#define MT6323_ANALDO_CON0 0x0400
++#define MT6323_ANALDO_CON1 0x0402
++#define MT6323_ANALDO_CON2 0x0404
++#define MT6323_ANALDO_CON3 0x0406
++#define MT6323_ANALDO_CON4 0x0408
++#define MT6323_ANALDO_CON5 0x040A
++#define MT6323_ANALDO_CON6 0x040C
++#define MT6323_ANALDO_CON7 0x040E
++#define MT6323_ANALDO_CON8 0x0410
++#define MT6323_ANALDO_CON10 0x0412
++#define MT6323_ANALDO_CON15 0x0414
++#define MT6323_ANALDO_CON16 0x0416
++#define MT6323_ANALDO_CON17 0x0418
++#define MT6323_ANALDO_CON18 0x041A
++#define MT6323_ANALDO_CON19 0x041C
++#define MT6323_ANALDO_CON20 0x041E
++#define MT6323_ANALDO_CON21 0x0420
++#define MT6323_DIGLDO_CON0 0x0500
++#define MT6323_DIGLDO_CON2 0x0502
++#define MT6323_DIGLDO_CON3 0x0504
++#define MT6323_DIGLDO_CON5 0x0506
++#define MT6323_DIGLDO_CON6 0x0508
++#define MT6323_DIGLDO_CON7 0x050A
++#define MT6323_DIGLDO_CON8 0x050C
++#define MT6323_DIGLDO_CON9 0x050E
++#define MT6323_DIGLDO_CON10 0x0510
++#define MT6323_DIGLDO_CON11 0x0512
++#define MT6323_DIGLDO_CON12 0x0514
++#define MT6323_DIGLDO_CON13 0x0516
++#define MT6323_DIGLDO_CON14 0x0518
++#define MT6323_DIGLDO_CON15 0x051A
++#define MT6323_DIGLDO_CON16 0x051C
++#define MT6323_DIGLDO_CON17 0x051E
++#define MT6323_DIGLDO_CON18 0x0520
++#define MT6323_DIGLDO_CON19 0x0522
++#define MT6323_DIGLDO_CON20 0x0524
++#define MT6323_DIGLDO_CON21 0x0526
++#define MT6323_DIGLDO_CON23 0x0528
++#define MT6323_DIGLDO_CON24 0x052A
++#define MT6323_DIGLDO_CON26 0x052C
++#define MT6323_DIGLDO_CON27 0x052E
++#define MT6323_DIGLDO_CON28 0x0530
++#define MT6323_DIGLDO_CON29 0x0532
++#define MT6323_DIGLDO_CON30 0x0534
++#define MT6323_DIGLDO_CON31 0x0536
++#define MT6323_DIGLDO_CON32 0x0538
++#define MT6323_DIGLDO_CON33 0x053A
++#define MT6323_DIGLDO_CON34 0x053C
++#define MT6323_DIGLDO_CON35 0x053E
++#define MT6323_DIGLDO_CON36 0x0540
++#define MT6323_DIGLDO_CON39 0x0542
++#define MT6323_DIGLDO_CON40 0x0544
++#define MT6323_DIGLDO_CON41 0x0546
++#define MT6323_DIGLDO_CON42 0x0548
++#define MT6323_DIGLDO_CON43 0x054A
++#define MT6323_DIGLDO_CON44 0x054C
++#define MT6323_DIGLDO_CON45 0x054E
++#define MT6323_DIGLDO_CON46 0x0550
++#define MT6323_DIGLDO_CON47 0x0552
++#define MT6323_DIGLDO_CON48 0x0554
++#define MT6323_DIGLDO_CON49 0x0556
++#define MT6323_DIGLDO_CON50 0x0558
++#define MT6323_DIGLDO_CON51 0x055A
++#define MT6323_DIGLDO_CON52 0x055C
++#define MT6323_DIGLDO_CON53 0x055E
++#define MT6323_DIGLDO_CON54 0x0560
++#define MT6323_EFUSE_CON0 0x0600
++#define MT6323_EFUSE_CON1 0x0602
++#define MT6323_EFUSE_CON2 0x0604
++#define MT6323_EFUSE_CON3 0x0606
++#define MT6323_EFUSE_CON4 0x0608
++#define MT6323_EFUSE_CON5 0x060A
++#define MT6323_EFUSE_CON6 0x060C
++#define MT6323_EFUSE_VAL_0_15 0x060E
++#define MT6323_EFUSE_VAL_16_31 0x0610
++#define MT6323_EFUSE_VAL_32_47 0x0612
++#define MT6323_EFUSE_VAL_48_63 0x0614
++#define MT6323_EFUSE_VAL_64_79 0x0616
++#define MT6323_EFUSE_VAL_80_95 0x0618
++#define MT6323_EFUSE_VAL_96_111 0x061A
++#define MT6323_EFUSE_VAL_112_127 0x061C
++#define MT6323_EFUSE_VAL_128_143 0x061E
++#define MT6323_EFUSE_VAL_144_159 0x0620
++#define MT6323_EFUSE_VAL_160_175 0x0622
++#define MT6323_EFUSE_VAL_176_191 0x0624
++#define MT6323_EFUSE_DOUT_0_15 0x0626
++#define MT6323_EFUSE_DOUT_16_31 0x0628
++#define MT6323_EFUSE_DOUT_32_47 0x062A
++#define MT6323_EFUSE_DOUT_48_63 0x062C
++#define MT6323_EFUSE_DOUT_64_79 0x062E
++#define MT6323_EFUSE_DOUT_80_95 0x0630
++#define MT6323_EFUSE_DOUT_96_111 0x0632
++#define MT6323_EFUSE_DOUT_112_127 0x0634
++#define MT6323_EFUSE_DOUT_128_143 0x0636
++#define MT6323_EFUSE_DOUT_144_159 0x0638
++#define MT6323_EFUSE_DOUT_160_175 0x063A
++#define MT6323_EFUSE_DOUT_176_191 0x063C
++#define MT6323_EFUSE_CON7 0x063E
++#define MT6323_EFUSE_CON8 0x0640
++#define MT6323_EFUSE_CON9 0x0642
++#define MT6323_RTC_MIX_CON0 0x0644
++#define MT6323_RTC_MIX_CON1 0x0646
++#define MT6323_AUDTOP_CON0 0x0700
++#define MT6323_AUDTOP_CON1 0x0702
++#define MT6323_AUDTOP_CON2 0x0704
++#define MT6323_AUDTOP_CON3 0x0706
++#define MT6323_AUDTOP_CON4 0x0708
++#define MT6323_AUDTOP_CON5 0x070A
++#define MT6323_AUDTOP_CON6 0x070C
++#define MT6323_AUDTOP_CON7 0x070E
++#define MT6323_AUDTOP_CON8 0x0710
++#define MT6323_AUDTOP_CON9 0x0712
++#define MT6323_AUXADC_ADC0 0x0714
++#define MT6323_AUXADC_ADC1 0x0716
++#define MT6323_AUXADC_ADC2 0x0718
++#define MT6323_AUXADC_ADC3 0x071A
++#define MT6323_AUXADC_ADC4 0x071C
++#define MT6323_AUXADC_ADC5 0x071E
++#define MT6323_AUXADC_ADC6 0x0720
++#define MT6323_AUXADC_ADC7 0x0722
++#define MT6323_AUXADC_ADC8 0x0724
++#define MT6323_AUXADC_ADC9 0x0726
++#define MT6323_AUXADC_ADC10 0x0728
++#define MT6323_AUXADC_ADC11 0x072A
++#define MT6323_AUXADC_ADC12 0x072C
++#define MT6323_AUXADC_ADC13 0x072E
++#define MT6323_AUXADC_ADC14 0x0730
++#define MT6323_AUXADC_ADC15 0x0732
++#define MT6323_AUXADC_ADC16 0x0734
++#define MT6323_AUXADC_ADC17 0x0736
++#define MT6323_AUXADC_ADC18 0x0738
++#define MT6323_AUXADC_ADC19 0x073A
++#define MT6323_AUXADC_ADC20 0x073C
++#define MT6323_AUXADC_RSV1 0x073E
++#define MT6323_AUXADC_RSV2 0x0740
++#define MT6323_AUXADC_CON0 0x0742
++#define MT6323_AUXADC_CON1 0x0744
++#define MT6323_AUXADC_CON2 0x0746
++#define MT6323_AUXADC_CON3 0x0748
++#define MT6323_AUXADC_CON4 0x074A
++#define MT6323_AUXADC_CON5 0x074C
++#define MT6323_AUXADC_CON6 0x074E
++#define MT6323_AUXADC_CON7 0x0750
++#define MT6323_AUXADC_CON8 0x0752
++#define MT6323_AUXADC_CON9 0x0754
++#define MT6323_AUXADC_CON10 0x0756
++#define MT6323_AUXADC_CON11 0x0758
++#define MT6323_AUXADC_CON12 0x075A
++#define MT6323_AUXADC_CON13 0x075C
++#define MT6323_AUXADC_CON14 0x075E
++#define MT6323_AUXADC_CON15 0x0760
++#define MT6323_AUXADC_CON16 0x0762
++#define MT6323_AUXADC_CON17 0x0764
++#define MT6323_AUXADC_CON18 0x0766
++#define MT6323_AUXADC_CON19 0x0768
++#define MT6323_AUXADC_CON20 0x076A
++#define MT6323_AUXADC_CON21 0x076C
++#define MT6323_AUXADC_CON22 0x076E
++#define MT6323_AUXADC_CON23 0x0770
++#define MT6323_AUXADC_CON24 0x0772
++#define MT6323_AUXADC_CON25 0x0774
++#define MT6323_AUXADC_CON26 0x0776
++#define MT6323_AUXADC_CON27 0x0778
++#define MT6323_ACCDET_CON0 0x077A
++#define MT6323_ACCDET_CON1 0x077C
++#define MT6323_ACCDET_CON2 0x077E
++#define MT6323_ACCDET_CON3 0x0780
++#define MT6323_ACCDET_CON4 0x0782
++#define MT6323_ACCDET_CON5 0x0784
++#define MT6323_ACCDET_CON6 0x0786
++#define MT6323_ACCDET_CON7 0x0788
++#define MT6323_ACCDET_CON8 0x078A
++#define MT6323_ACCDET_CON9 0x078C
++#define MT6323_ACCDET_CON10 0x078E
++#define MT6323_ACCDET_CON11 0x0790
++#define MT6323_ACCDET_CON12 0x0792
++#define MT6323_ACCDET_CON13 0x0794
++#define MT6323_ACCDET_CON14 0x0796
++#define MT6323_ACCDET_CON15 0x0798
++#define MT6323_ACCDET_CON16 0x079A
++
++#endif /* __MFD_MT6323_REGISTERS_H__ */
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0046-regulator-Add-document-for-MT6323-regulator.patch b/target/linux/mediatek/patches-4.4/0046-regulator-Add-document-for-MT6323-regulator.patch
new file mode 100644
index 0000000000..b6b237dc45
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0046-regulator-Add-document-for-MT6323-regulator.patch
@@ -0,0 +1,260 @@
+From 3900467f0f0470f889b9e6cdfd7dc4cf460e8d41 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 10 Jan 2016 17:31:46 +0100
+Subject: [PATCH 46/53] regulator: Add document for MT6323 regulator
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Cc: devicetree@vger.kernel.org
+---
+ .../bindings/regulator/mt6323-regulator.txt | 239 ++++++++++++++++++++
+ 1 file changed, 239 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
+
+diff --git a/Documentation/devicetree/bindings/regulator/mt6323-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
+new file mode 100644
+index 0000000..9fd95e7
+--- /dev/null
++++ b/Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
+@@ -0,0 +1,239 @@
++Mediatek MT6323 Regulator Driver
++
++All voltage regulators are defined as subnodes of the regulators node. A list
++of regulators provided by this controller are defined as subnodes of the
++PMIC's node. Each regulator is named according to its regulator type,
++buck_<name> and ldo_<name>. The definition for each of these nodes is defined
++using the standard binding for regulators at
++Documentation/devicetree/bindings/regulator/regulator.txt.
++
++The valid names for regulators are::
++BUCK:
++ buck_vproc, buck_vsys, buck_vpa
++LDO:
++ ldo_vtcxo, ldo_vcn28, ldo_vcn33_bt, ldo_vcn33_wifi, ldo_va, ldo_vcama,
++ ldo_vio28, ldo_vusb, ldo_vmc, ldo_vmch, ldo_vemc3v3, ldo_vgp1, ldo_vgp2,
++ ldo_vgp3, ldo_vcn18, ldo_vsim1, ldo_vsim2, ldo_vrtc, ldo_vcamaf, ldo_vibr,
++ ldo_vrf18, ldo_vm, ldo_vio18, ldo_vcamd, ldo_vcamio
++
++Example:
++
++ pmic: mt6323 {
++ compatible = "mediatek,mt6323";
++
++ mt6323regulator: regulators {
++ mt6323_vproc_reg: buck_vproc{
++ regulator-name = "vproc";
++ regulator-min-microvolt = < 700000>;
++ regulator-max-microvolt = <1350000>;
++ regulator-ramp-delay = <12500>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ mt6323_vsys_reg: buck_vsys{
++ regulator-name = "vsys";
++ regulator-min-microvolt = <1400000>;
++ regulator-max-microvolt = <2987500>;
++ regulator-ramp-delay = <25000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ mt6323_vpa_reg: buck_vpa{
++ regulator-name = "vpa";
++ regulator-min-microvolt = < 500000>;
++ regulator-max-microvolt = <3650000>;
++ };
++
++ mt6323_vtcxo_reg: ldo_vtcxo{
++ regulator-name = "vtcxo";
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ regulator-enable-ramp-delay = <90>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ mt6323_vcn28_reg: ldo_vcn28{
++ regulator-name = "vcn28";
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ regulator-enable-ramp-delay = <185>;
++ };
++
++ mt6323_vcn33_bt_reg: ldo_vcn33_bt{
++ regulator-name = "vcn33_bt";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3600000>;
++ regulator-enable-ramp-delay = <185>;
++ };
++
++ mt6323_vcn33_wifi_reg: ldo_vcn33_wifi{
++ regulator-name = "vcn33_wifi";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3600000>;
++ regulator-enable-ramp-delay = <185>;
++ };
++
++ mt6323_va_reg: ldo_va{
++ regulator-name = "va";
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ regulator-enable-ramp-delay = <216>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ mt6323_vcama_reg: ldo_vcama{
++ regulator-name = "vcama";
++ regulator-min-microvolt = <1500000>;
++ regulator-max-microvolt = <2800000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vio28_reg: ldo_vio28{
++ regulator-name = "vio28";
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ regulator-enable-ramp-delay = <216>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ mt6323_vusb_reg: ldo_vusb{
++ regulator-name = "vusb";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-enable-ramp-delay = <216>;
++ regulator-boot-on;
++ };
++
++ mt6323_vmc_reg: ldo_vmc{
++ regulator-name = "vmc";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-enable-ramp-delay = <36>;
++ regulator-boot-on;
++ };
++
++ mt6323_vmch_reg: ldo_vmch{
++ regulator-name = "vmch";
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-enable-ramp-delay = <36>;
++ regulator-boot-on;
++ };
++
++ mt6323_vemc3v3_reg: ldo_vemc3v3{
++ regulator-name = "vemc3v3";
++ regulator-min-microvolt = <3000000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-enable-ramp-delay = <36>;
++ regulator-boot-on;
++ };
++
++ mt6323_vgp1_reg: ldo_vgp1{
++ regulator-name = "vgp1";
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vgp2_reg: ldo_vgp2{
++ regulator-name = "vgp2";
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <3000000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vgp3_reg: ldo_vgp3{
++ regulator-name = "vgp3";
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vcn18_reg: ldo_vcn18{
++ regulator-name = "vcn18";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vsim1_reg: ldo_vsim1{
++ regulator-name = "vsim1";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3000000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vsim2_reg: ldo_vsim2{
++ regulator-name = "vsim2";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3000000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vrtc_reg: ldo_vrtc{
++ regulator-name = "vrtc";
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ mt6323_vcamaf_reg: ldo_vcamaf{
++ regulator-name = "vcamaf";
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vibr_reg: ldo_vibr{
++ regulator-name = "vibr";
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-enable-ramp-delay = <36>;
++ };
++
++ mt6323_vrf18_reg: ldo_vrf18{
++ regulator-name = "vrf18";
++ regulator-min-microvolt = <1825000>;
++ regulator-max-microvolt = <1825000>;
++ regulator-enable-ramp-delay = <187>;
++ };
++
++ mt6323_vm_reg: ldo_vm{
++ regulator-name = "vm";
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-enable-ramp-delay = <216>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ mt6323_vio18_reg: ldo_vio18{
++ regulator-name = "vio18";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-enable-ramp-delay = <216>;
++ regulator-always-on;
++ regulator-boot-on;
++ };
++
++ mt6323_vcamd_reg: ldo_vcamd{
++ regulator-name = "vcamd";
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++
++ mt6323_vcamio_reg: ldo_vcamio{
++ regulator-name = "vcamio";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-enable-ramp-delay = <216>;
++ };
++ };
++ };
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0047-regulator-mt6323-Add-support-for-MT6323-regulator.patch b/target/linux/mediatek/patches-4.4/0047-regulator-mt6323-Add-support-for-MT6323-regulator.patch
new file mode 100644
index 0000000000..36702dca34
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0047-regulator-mt6323-Add-support-for-MT6323-regulator.patch
@@ -0,0 +1,551 @@
+From eb0a8e236431bf233267299ba797e2269b6e19ea Mon Sep 17 00:00:00 2001
+From: Chen Zhong <chen.zhong@mediatek.com>
+Date: Fri, 8 Jan 2016 04:17:37 +0100
+Subject: [PATCH 47/53] regulator: mt6323: Add support for MT6323 regulator
+
+The MT6323 is a regulator found on boards based on MediaTek MT7623 and
+probably other SoCs. It is a so called pmic and connects as a slave to
+SoC using SPI, wrapped inside the pmic-wrapper.
+
+Signed-off-by: Chen Zhong <chen.zhong@mediatek.com>
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/regulator/Kconfig | 9 +
+ drivers/regulator/Makefile | 1 +
+ drivers/regulator/mt6323-regulator.c | 432 ++++++++++++++++++++++++++++
+ include/linux/regulator/mt6323-regulator.h | 52 ++++
+ 4 files changed, 494 insertions(+)
+ create mode 100644 drivers/regulator/mt6323-regulator.c
+ create mode 100644 include/linux/regulator/mt6323-regulator.h
+
+diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
+index 8df0b0e..4aec931 100644
+--- a/drivers/regulator/Kconfig
++++ b/drivers/regulator/Kconfig
+@@ -452,6 +452,15 @@ config REGULATOR_MT6311
+ This driver supports the control of different power rails of device
+ through regulator interface.
+
++config REGULATOR_MT6323
++ tristate "MediaTek MT6323 PMIC"
++ depends on MFD_MT6397
++ help
++ Say y here to select this option to enable the power regulator of
++ MediaTek MT6323 PMIC.
++ This driver supports the control of different power rails of device
++ through regulator interface.
++
+ config REGULATOR_MT6397
+ tristate "MediaTek MT6397 PMIC"
+ depends on MFD_MT6397
+diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
+index 0f81749..b42a84e 100644
+--- a/drivers/regulator/Makefile
++++ b/drivers/regulator/Makefile
+@@ -60,6 +60,7 @@ obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
+ obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
+ obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
+ obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
++obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
+ obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
+ obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
+ obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
+diff --git a/drivers/regulator/mt6323-regulator.c b/drivers/regulator/mt6323-regulator.c
+new file mode 100644
+index 0000000..28ebbda
+--- /dev/null
++++ b/drivers/regulator/mt6323-regulator.c
+@@ -0,0 +1,432 @@
++/*
++ * Copyright (c) 2016 MediaTek Inc.
++ * Author: Chen Zhong <chen.zhong@mediatek.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.h>
++#include <linux/mfd/mt6397/core.h>
++#include <linux/mfd/mt6323/registers.h>
++#include <linux/regulator/driver.h>
++#include <linux/regulator/machine.h>
++#include <linux/regulator/mt6323-regulator.h>
++#include <linux/regulator/of_regulator.h>
++
++#define MT6323_LDO_MODE_NORMAL 0
++#define MT6323_LDO_MODE_LP 1
++
++/*
++ * MT6323 regulators' information
++ *
++ * @desc: standard fields of regulator description.
++ * @qi: Mask for query enable signal status of regulators
++ * @vselon_reg: Register sections for hardware control mode of bucks
++ * @vselctrl_reg: Register for controlling the buck control mode.
++ * @vselctrl_mask: Mask for query buck's voltage control mode.
++ */
++struct mt6323_regulator_info {
++ struct regulator_desc desc;
++ u32 qi;
++ u32 vselon_reg;
++ u32 vselctrl_reg;
++ u32 vselctrl_mask;
++ u32 modeset_reg;
++ u32 modeset_mask;
++};
++
++#define MT6323_BUCK(match, vreg, min, max, step, volt_ranges, enreg, \
++ vosel, vosel_mask, voselon, vosel_ctrl) \
++[MT6323_ID_##vreg] = { \
++ .desc = { \
++ .name = #vreg, \
++ .of_match = of_match_ptr(match), \
++ .ops = &mt6323_volt_range_ops, \
++ .type = REGULATOR_VOLTAGE, \
++ .id = MT6323_ID_##vreg, \
++ .owner = THIS_MODULE, \
++ .n_voltages = (max - min)/step + 1, \
++ .linear_ranges = volt_ranges, \
++ .n_linear_ranges = ARRAY_SIZE(volt_ranges), \
++ .vsel_reg = vosel, \
++ .vsel_mask = vosel_mask, \
++ .enable_reg = enreg, \
++ .enable_mask = BIT(0), \
++ }, \
++ .qi = BIT(13), \
++ .vselon_reg = voselon, \
++ .vselctrl_reg = vosel_ctrl, \
++ .vselctrl_mask = BIT(1), \
++}
++
++#define MT6323_LDO(match, vreg, ldo_volt_table, enreg, enbit, vosel, \
++ vosel_mask, _modeset_reg, _modeset_mask) \
++[MT6323_ID_##vreg] = { \
++ .desc = { \
++ .name = #vreg, \
++ .of_match = of_match_ptr(match), \
++ .ops = &mt6323_volt_table_ops, \
++ .type = REGULATOR_VOLTAGE, \
++ .id = MT6323_ID_##vreg, \
++ .owner = THIS_MODULE, \
++ .n_voltages = ARRAY_SIZE(ldo_volt_table), \
++ .volt_table = ldo_volt_table, \
++ .vsel_reg = vosel, \
++ .vsel_mask = vosel_mask, \
++ .enable_reg = enreg, \
++ .enable_mask = BIT(enbit), \
++ }, \
++ .qi = BIT(15), \
++ .modeset_reg = _modeset_reg, \
++ .modeset_mask = _modeset_mask, \
++}
++
++#define MT6323_REG_FIXED(match, vreg, enreg, enbit, volt, \
++ _modeset_reg, _modeset_mask) \
++[MT6323_ID_##vreg] = { \
++ .desc = { \
++ .name = #vreg, \
++ .of_match = of_match_ptr(match), \
++ .ops = &mt6323_volt_fixed_ops, \
++ .type = REGULATOR_VOLTAGE, \
++ .id = MT6323_ID_##vreg, \
++ .owner = THIS_MODULE, \
++ .n_voltages = 1, \
++ .enable_reg = enreg, \
++ .enable_mask = BIT(enbit), \
++ .min_uV = volt, \
++ }, \
++ .qi = BIT(15), \
++ .modeset_reg = _modeset_reg, \
++ .modeset_mask = _modeset_mask, \
++}
++
++static const struct regulator_linear_range buck_volt_range1[] = {
++ REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250),
++};
++
++static const struct regulator_linear_range buck_volt_range2[] = {
++ REGULATOR_LINEAR_RANGE(1400000, 0, 0x7f, 12500),
++};
++
++static const struct regulator_linear_range buck_volt_range3[] = {
++ REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000),
++};
++
++static const u32 ldo_volt_table1[] = {
++ 3300000, 3400000, 3500000, 3600000,
++};
++
++static const u32 ldo_volt_table2[] = {
++ 1500000, 1800000, 2500000, 2800000,
++};
++
++static const u32 ldo_volt_table3[] = {
++ 1800000, 3300000,
++};
++
++static const u32 ldo_volt_table4[] = {
++ 3000000, 3300000,
++};
++
++static const u32 ldo_volt_table5[] = {
++ 1200000, 1300000, 1500000, 1800000, 2000000, 2800000, 3000000, 3300000,
++};
++
++static const u32 ldo_volt_table6[] = {
++ 1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 2000000,
++};
++
++static const u32 ldo_volt_table7[] = {
++ 1200000, 1300000, 1500000, 1800000,
++};
++
++static const u32 ldo_volt_table8[] = {
++ 1800000, 3000000,
++};
++
++static const u32 ldo_volt_table9[] = {
++ 1200000, 1350000, 1500000, 1800000,
++};
++
++static const u32 ldo_volt_table10[] = {
++ 1200000, 1300000, 1500000, 1800000,
++};
++
++static int mt6323_get_status(struct regulator_dev *rdev)
++{
++ int ret;
++ u32 regval;
++ struct mt6323_regulator_info *info = rdev_get_drvdata(rdev);
++
++ ret = regmap_read(rdev->regmap, info->desc.enable_reg, &regval);
++ if (ret != 0) {
++ dev_err(&rdev->dev, "Failed to get enable reg: %d\n", ret);
++ return ret;
++ }
++
++ return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
++}
++
++static int mt6323_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode)
++{
++ int ret, val = 0;
++ struct mt6323_regulator_info *info = rdev_get_drvdata(rdev);
++
++ if (!info->modeset_mask) {
++ dev_err(&rdev->dev, "regulator %s doesn't support set_mode\n",
++ info->desc.name);
++ return -EINVAL;
++ }
++
++ switch (mode) {
++ case REGULATOR_MODE_STANDBY:
++ val = MT6323_LDO_MODE_LP;
++ break;
++ case REGULATOR_MODE_NORMAL:
++ val = MT6323_LDO_MODE_NORMAL;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ val <<= ffs(info->modeset_mask) - 1;
++
++ ret = regmap_update_bits(rdev->regmap, info->modeset_reg,
++ info->modeset_mask, val);
++
++ return ret;
++}
++
++static unsigned int mt6323_ldo_get_mode(struct regulator_dev *rdev)
++{
++ unsigned int val;
++ unsigned int mode;
++ int ret;
++ struct mt6323_regulator_info *info = rdev_get_drvdata(rdev);
++
++ if (!info->modeset_mask) {
++ dev_err(&rdev->dev, "regulator %s doesn't support get_mode\n",
++ info->desc.name);
++ return -EINVAL;
++ }
++
++ ret = regmap_read(rdev->regmap, info->modeset_reg, &val);
++ if (ret < 0)
++ return ret;
++
++ val &= info->modeset_mask;
++ val >>= ffs(info->modeset_mask) - 1;
++
++ if (val & 0x1)
++ mode = REGULATOR_MODE_STANDBY;
++ else
++ mode = REGULATOR_MODE_NORMAL;
++
++ return mode;
++}
++
++static struct regulator_ops mt6323_volt_range_ops = {
++ .list_voltage = regulator_list_voltage_linear_range,
++ .map_voltage = regulator_map_voltage_linear_range,
++ .set_voltage_sel = regulator_set_voltage_sel_regmap,
++ .get_voltage_sel = regulator_get_voltage_sel_regmap,
++ .set_voltage_time_sel = regulator_set_voltage_time_sel,
++ .enable = regulator_enable_regmap,
++ .disable = regulator_disable_regmap,
++ .is_enabled = regulator_is_enabled_regmap,
++ .get_status = mt6323_get_status,
++};
++
++static struct regulator_ops mt6323_volt_table_ops = {
++ .list_voltage = regulator_list_voltage_table,
++ .map_voltage = regulator_map_voltage_iterate,
++ .set_voltage_sel = regulator_set_voltage_sel_regmap,
++ .get_voltage_sel = regulator_get_voltage_sel_regmap,
++ .set_voltage_time_sel = regulator_set_voltage_time_sel,
++ .enable = regulator_enable_regmap,
++ .disable = regulator_disable_regmap,
++ .is_enabled = regulator_is_enabled_regmap,
++ .get_status = mt6323_get_status,
++ .set_mode = mt6323_ldo_set_mode,
++ .get_mode = mt6323_ldo_get_mode,
++};
++
++static struct regulator_ops mt6323_volt_fixed_ops = {
++ .list_voltage = regulator_list_voltage_linear,
++ .enable = regulator_enable_regmap,
++ .disable = regulator_disable_regmap,
++ .is_enabled = regulator_is_enabled_regmap,
++ .get_status = mt6323_get_status,
++ .set_mode = mt6323_ldo_set_mode,
++ .get_mode = mt6323_ldo_get_mode,
++};
++
++/* The array is indexed by id(MT6323_ID_XXX) */
++static struct mt6323_regulator_info mt6323_regulators[] = {
++ MT6323_BUCK("buck_vproc", VPROC, 700000, 1493750, 6250,
++ buck_volt_range1, MT6323_VPROC_CON7, MT6323_VPROC_CON9, 0x7f,
++ MT6323_VPROC_CON10, MT6323_VPROC_CON5),
++ MT6323_BUCK("buck_vsys", VSYS, 1400000, 2987500, 12500,
++ buck_volt_range2, MT6323_VSYS_CON7, MT6323_VSYS_CON9, 0x7f,
++ MT6323_VSYS_CON10, MT6323_VSYS_CON5),
++ MT6323_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
++ buck_volt_range3, MT6323_VPA_CON7, MT6323_VPA_CON9,
++ 0x3f, MT6323_VPA_CON10, MT6323_VPA_CON5),
++ MT6323_REG_FIXED("ldo_vtcxo", VTCXO, MT6323_ANALDO_CON1, 10, 2800000,
++ MT6323_ANALDO_CON1, 0x2),
++ MT6323_REG_FIXED("ldo_vcn28", VCN28, MT6323_ANALDO_CON19, 12, 2800000,
++ MT6323_ANALDO_CON20, 0x2),
++ MT6323_LDO("ldo_vcn33_bt", VCN33_BT, ldo_volt_table1,
++ MT6323_ANALDO_CON16, 7, MT6323_ANALDO_CON16, 0xC,
++ MT6323_ANALDO_CON21, 0x2),
++ MT6323_LDO("ldo_vcn33_wifi", VCN33_WIFI, ldo_volt_table1,
++ MT6323_ANALDO_CON17, 12, MT6323_ANALDO_CON16, 0xC,
++ MT6323_ANALDO_CON21, 0x2),
++ MT6323_REG_FIXED("ldo_va", VA, MT6323_ANALDO_CON2, 14, 2800000,
++ MT6323_ANALDO_CON2, 0x2),
++ MT6323_LDO("ldo_vcama", VCAMA, ldo_volt_table2,
++ MT6323_ANALDO_CON4, 15, MT6323_ANALDO_CON10, 0x60, -1, 0),
++ MT6323_REG_FIXED("ldo_vio28", VIO28, MT6323_DIGLDO_CON0, 14, 2800000,
++ MT6323_DIGLDO_CON0, 0x2),
++ MT6323_REG_FIXED("ldo_vusb", VUSB, MT6323_DIGLDO_CON2, 14, 3300000,
++ MT6323_DIGLDO_CON2, 0x2),
++ MT6323_LDO("ldo_vmc", VMC, ldo_volt_table3,
++ MT6323_DIGLDO_CON3, 12, MT6323_DIGLDO_CON24, 0x10,
++ MT6323_DIGLDO_CON3, 0x2),
++ MT6323_LDO("ldo_vmch", VMCH, ldo_volt_table4,
++ MT6323_DIGLDO_CON5, 14, MT6323_DIGLDO_CON26, 0x80,
++ MT6323_DIGLDO_CON5, 0x2),
++ MT6323_LDO("ldo_vemc3v3", VEMC3V3, ldo_volt_table4,
++ MT6323_DIGLDO_CON6, 14, MT6323_DIGLDO_CON27, 0x80,
++ MT6323_DIGLDO_CON6, 0x2),
++ MT6323_LDO("ldo_vgp1", VGP1, ldo_volt_table5,
++ MT6323_DIGLDO_CON7, 15, MT6323_DIGLDO_CON28, 0xE0,
++ MT6323_DIGLDO_CON7, 0x2),
++ MT6323_LDO("ldo_vgp2", VGP2, ldo_volt_table6,
++ MT6323_DIGLDO_CON8, 15, MT6323_DIGLDO_CON29, 0xE0,
++ MT6323_DIGLDO_CON8, 0x2),
++ MT6323_LDO("ldo_vgp3", VGP3, ldo_volt_table7,
++ MT6323_DIGLDO_CON9, 15, MT6323_DIGLDO_CON30, 0x60,
++ MT6323_DIGLDO_CON9, 0x2),
++ MT6323_REG_FIXED("ldo_vcn18", VCN18, MT6323_DIGLDO_CON11, 14, 1800000,
++ MT6323_DIGLDO_CON11, 0x2),
++ MT6323_LDO("ldo_vsim1", VSIM1, ldo_volt_table8,
++ MT6323_DIGLDO_CON13, 15, MT6323_DIGLDO_CON34, 0x20,
++ MT6323_DIGLDO_CON13, 0x2),
++ MT6323_LDO("ldo_vsim2", VSIM2, ldo_volt_table8,
++ MT6323_DIGLDO_CON14, 15, MT6323_DIGLDO_CON35, 0x20,
++ MT6323_DIGLDO_CON14, 0x2),
++ MT6323_REG_FIXED("ldo_vrtc", VRTC, MT6323_DIGLDO_CON15, 8, 2800000,
++ -1, 0),
++ MT6323_LDO("ldo_vcamaf", VCAMAF, ldo_volt_table5,
++ MT6323_DIGLDO_CON31, 15, MT6323_DIGLDO_CON32, 0xE0,
++ MT6323_DIGLDO_CON31, 0x2),
++ MT6323_LDO("ldo_vibr", VIBR, ldo_volt_table5,
++ MT6323_DIGLDO_CON39, 15, MT6323_DIGLDO_CON40, 0xE0,
++ MT6323_DIGLDO_CON39, 0x2),
++ MT6323_REG_FIXED("ldo_vrf18", VRF18, MT6323_DIGLDO_CON45, 15, 1825000,
++ MT6323_DIGLDO_CON45, 0x2),
++ MT6323_LDO("ldo_vm", VM, ldo_volt_table9,
++ MT6323_DIGLDO_CON47, 14, MT6323_DIGLDO_CON48, 0x30,
++ MT6323_DIGLDO_CON47, 0x2),
++ MT6323_REG_FIXED("ldo_vio18", VIO18, MT6323_DIGLDO_CON49, 14, 1800000,
++ MT6323_DIGLDO_CON49, 0x2),
++ MT6323_LDO("ldo_vcamd", VCAMD, ldo_volt_table10,
++ MT6323_DIGLDO_CON51, 14, MT6323_DIGLDO_CON52, 0x60,
++ MT6323_DIGLDO_CON51, 0x2),
++ MT6323_REG_FIXED("ldo_vcamio", VCAMIO, MT6323_DIGLDO_CON53, 14, 1800000,
++ MT6323_DIGLDO_CON53, 0x2),
++};
++
++static int mt6323_set_buck_vosel_reg(struct platform_device *pdev)
++{
++ struct mt6397_chip *mt6323 = dev_get_drvdata(pdev->dev.parent);
++ int i;
++ u32 regval;
++
++ for (i = 0; i < MT6323_MAX_REGULATOR; i++) {
++ if (mt6323_regulators[i].vselctrl_reg) {
++ if (regmap_read(mt6323->regmap,
++ mt6323_regulators[i].vselctrl_reg,
++ &regval) < 0) {
++ dev_err(&pdev->dev,
++ "Failed to read buck ctrl\n");
++ return -EIO;
++ }
++
++ if (regval & mt6323_regulators[i].vselctrl_mask) {
++ mt6323_regulators[i].desc.vsel_reg =
++ mt6323_regulators[i].vselon_reg;
++ }
++ }
++ }
++
++ return 0;
++}
++
++static int mt6323_regulator_probe(struct platform_device *pdev)
++{
++ struct mt6397_chip *mt6323 = dev_get_drvdata(pdev->dev.parent);
++ struct regulator_config config = {};
++ struct regulator_dev *rdev;
++ int i;
++ u32 reg_value;
++
++ /* Query buck controller to select activated voltage register part */
++ if (mt6323_set_buck_vosel_reg(pdev))
++ return -EIO;
++
++ /* Read PMIC chip revision to update constraints and voltage table */
++ if (regmap_read(mt6323->regmap, MT6323_CID, &reg_value) < 0) {
++ dev_err(&pdev->dev, "Failed to read Chip ID\n");
++ return -EIO;
++ }
++ dev_info(&pdev->dev, "Chip ID = 0x%x\n", reg_value);
++
++ for (i = 0; i < MT6323_MAX_REGULATOR; i++) {
++ config.dev = &pdev->dev;
++ config.driver_data = &mt6323_regulators[i];
++ config.regmap = mt6323->regmap;
++ rdev = devm_regulator_register(&pdev->dev,
++ &mt6323_regulators[i].desc, &config);
++ if (IS_ERR(rdev)) {
++ dev_err(&pdev->dev, "failed to register %s\n",
++ mt6323_regulators[i].desc.name);
++ return PTR_ERR(rdev);
++ }
++ }
++ return 0;
++}
++
++static const struct platform_device_id mt6323_platform_ids[] = {
++ {"mt6323-regulator", 0},
++ { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(platform, mt6323_platform_ids);
++
++static const struct of_device_id mt6323_of_match[] = {
++ { .compatible = "mediatek,mt6323-regulator", },
++ { /* sentinel */ },
++};
++MODULE_DEVICE_TABLE(of, mt6323_of_match);
++
++static struct platform_driver mt6323_regulator_driver = {
++ .driver = {
++ .name = "mt6323-regulator",
++ .of_match_table = of_match_ptr(mt6323_of_match),
++ },
++ .probe = mt6323_regulator_probe,
++ .id_table = mt6323_platform_ids,
++};
++
++module_platform_driver(mt6323_regulator_driver);
++
++MODULE_AUTHOR("Chen Zhong <chen.zhong@mediatek.com>");
++MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6397 PMIC");
++MODULE_LICENSE("GPL v2");
+diff --git a/include/linux/regulator/mt6323-regulator.h b/include/linux/regulator/mt6323-regulator.h
+new file mode 100644
+index 0000000..67011cd
+--- /dev/null
++++ b/include/linux/regulator/mt6323-regulator.h
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (c) 2016 MediaTek Inc.
++ * Author: Chen Zhong <chen.zhong@mediatek.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef __LINUX_REGULATOR_MT6323_H
++#define __LINUX_REGULATOR_MT6323_H
++
++enum {
++ MT6323_ID_VPROC = 0,
++ MT6323_ID_VSYS,
++ MT6323_ID_VPA,
++ MT6323_ID_VTCXO,
++ MT6323_ID_VCN28,
++ MT6323_ID_VCN33_BT,
++ MT6323_ID_VCN33_WIFI,
++ MT6323_ID_VA,
++ MT6323_ID_VCAMA,
++ MT6323_ID_VIO28 = 9,
++ MT6323_ID_VUSB,
++ MT6323_ID_VMC,
++ MT6323_ID_VMCH,
++ MT6323_ID_VEMC3V3,
++ MT6323_ID_VGP1,
++ MT6323_ID_VGP2,
++ MT6323_ID_VGP3,
++ MT6323_ID_VCN18,
++ MT6323_ID_VSIM1,
++ MT6323_ID_VSIM2,
++ MT6323_ID_VRTC,
++ MT6323_ID_VCAMAF,
++ MT6323_ID_VIBR,
++ MT6323_ID_VRF18,
++ MT6323_ID_VM,
++ MT6323_ID_VIO18,
++ MT6323_ID_VCAMD,
++ MT6323_ID_VCAMIO,
++ MT6323_ID_RG_MAX,
++};
++
++#define MT6323_MAX_REGULATOR MT6323_ID_RG_MAX
++
++#endif /* __LINUX_REGULATOR_MT6323_H */
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0048-net-next-mediatek-document-MediaTek-SoC-ethernet-bin.patch b/target/linux/mediatek/patches-4.4/0048-net-next-mediatek-document-MediaTek-SoC-ethernet-bin.patch
new file mode 100644
index 0000000000..43e8795ae0
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0048-net-next-mediatek-document-MediaTek-SoC-ethernet-bin.patch
@@ -0,0 +1,103 @@
+From 32f95a0bc03886b38a53569466d5bee4a6d66875 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 2 Mar 2016 07:18:52 +0100
+Subject: [PATCH 48/53] net-next: mediatek: document MediaTek SoC ethernet
+ binding
+
+This adds the binding documentation for the MediaTek Ethernet
+controller.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Acked-by: Rob Herring <robh@kernel.org>
+Cc: devicetree@vger.kernel.org
+---
+ .../devicetree/bindings/net/mediatek-net.txt | 77 ++++++++++++++++++++
+ 1 file changed, 77 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/net/mediatek-net.txt
+
+diff --git a/Documentation/devicetree/bindings/net/mediatek-net.txt b/Documentation/devicetree/bindings/net/mediatek-net.txt
+new file mode 100644
+index 0000000..5ca7929
+--- /dev/null
++++ b/Documentation/devicetree/bindings/net/mediatek-net.txt
+@@ -0,0 +1,77 @@
++MediaTek Frame Engine Ethernet controller
++=========================================
++
++The frame engine ethernet controller can be found on MediaTek SoCs. These SoCs
++have dual GMAC each represented by a child node..
++
++* Ethernet controller node
++
++Required properties:
++- compatible: Should be "mediatek,mt7623-eth"
++- reg: Address and length of the register set for the device
++- interrupts: Should contain the frame engines interrupt
++- clocks: the clock used by the core
++- clock-names: the names of the clock listed in the clocks property. These are
++ "ethif", "esw", "gp2", "gp1"
++- power-domains: phandle to the power domain that the ethernet is part of
++- resets: Should contain a phandle to the ethsys reset signal
++- reset-names: Should contain the reset signal name "eth"
++- mediatek,ethsys: phandle to the syscon node that handles the port setup
++- mediatek,pctl: phandle to the syscon node that handles the ports slew rate
++ and driver current
++
++Optional properties:
++- interrupt-parent: Should be the phandle for the interrupt controller
++ that services interrupts for this device
++
++
++* Ethernet MAC node
++
++Required properties:
++- compatible: Should be "mediatek,eth-mac"
++- reg: The number of the MAC
++- phy-handle: see ethernet.txt file in the same directory.
++
++Example:
++
++eth: ethernet@1b100000 {
++ compatible = "mediatek,mt7623-eth";
++ reg = <0 0x1b100000 0 0x20000>;
++ clocks = <&topckgen CLK_TOP_ETHIF_SEL>,
++ <&ethsys CLK_ETHSYS_ESW>,
++ <&ethsys CLK_ETHSYS_GP2>,
++ <&ethsys CLK_ETHSYS_GP1>;
++ clock-names = "ethif", "esw", "gp2", "gp1";
++ interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_LOW>;
++ power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
++ resets = <&ethsys MT2701_ETHSYS_ETH_RST>;
++ reset-names = "eth";
++ mediatek,ethsys = <&ethsys>;
++ mediatek,pctl = <&syscfg_pctl_a>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ gmac1: mac@0 {
++ compatible = "mediatek,eth-mac";
++ reg = <0>;
++ phy-handle = <&phy0>;
++ };
++
++ gmac2: mac@1 {
++ compatible = "mediatek,eth-mac";
++ reg = <1>;
++ phy-handle = <&phy1>;
++ };
++
++ mdio-bus {
++ phy0: ethernet-phy@0 {
++ reg = <0>;
++ phy-mode = "rgmii";
++ };
++
++ phy1: ethernet-phy@1 {
++ reg = <1>;
++ phy-mode = "rgmii";
++ };
++ };
++};
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0049-net-next-mediatek-add-support-for-MT7623-ethernet.patch b/target/linux/mediatek/patches-4.4/0049-net-next-mediatek-add-support-for-MT7623-ethernet.patch
new file mode 100644
index 0000000000..5bfc00f068
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0049-net-next-mediatek-add-support-for-MT7623-ethernet.patch
@@ -0,0 +1,2271 @@
+From 873a5623ef43181f07b58328131e98fee5bc3d64 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 2 Mar 2016 04:27:10 +0100
+Subject: [PATCH 49/53] net-next: mediatek: add support for MT7623 ethernet
+
+Add ethernet support for MediaTek SoCs from the MT7623 family. These have
+dual GMAC. Depending on the exact version, there might be a built-in
+Gigabit switch (MT7530). The core does not have the typical DMA ring setup.
+Instead there is a linked list that we add descriptors to. There is only
+one linked list that both MACs use together. There is a special field
+inside the TX descriptors called the VQID. This allows us to assign packets
+to different internal queues. By using a separate id for each MAC we are
+able to get deterministic results for BQL. Additionally we need to
+provide the core with a block of scratch memory that is the same size as
+the RX ring and data buffer. This is really needed to make the HW datapath
+work. Although the driver does not support this yet, we still need to
+assign the memory and tell the core about it for RX to work.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: Michael Lee <igvtee@gmail.com>
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1807 +++++++++++++++++++++++++++
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 421 +++++++
+ 2 files changed, 2228 insertions(+)
+ create mode 100644 drivers/net/ethernet/mediatek/mtk_eth_soc.c
+ create mode 100644 drivers/net/ethernet/mediatek/mtk_eth_soc.h
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+new file mode 100644
+index 0000000..ba3afa5
+--- /dev/null
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -0,0 +1,1807 @@
++/* This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * Copyright (C) 2009-2016 John Crispin <blogic@openwrt.org>
++ * Copyright (C) 2009-2016 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2013-2016 Michael Lee <igvtee@gmail.com>
++ */
++
++#include <linux/of_device.h>
++#include <linux/of_mdio.h>
++#include <linux/of_net.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
++#include <linux/clk.h>
++#include <linux/if_vlan.h>
++#include <linux/reset.h>
++#include <linux/tcp.h>
++
++#include "mtk_eth_soc.h"
++
++static int mtk_msg_level = -1;
++module_param_named(msg_level, mtk_msg_level, int, 0);
++MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)");
++
++#define MTK_ETHTOOL_STAT(x) { #x, \
++ offsetof(struct mtk_hw_stats, x) / sizeof(u64) }
++
++/* strings used by ethtool */
++static const struct mtk_ethtool_stats {
++ char str[ETH_GSTRING_LEN];
++ u32 offset;
++} mtk_ethtool_stats[] = {
++ MTK_ETHTOOL_STAT(tx_bytes),
++ MTK_ETHTOOL_STAT(tx_packets),
++ MTK_ETHTOOL_STAT(tx_skip),
++ MTK_ETHTOOL_STAT(tx_collisions),
++ MTK_ETHTOOL_STAT(rx_bytes),
++ MTK_ETHTOOL_STAT(rx_packets),
++ MTK_ETHTOOL_STAT(rx_overflow),
++ MTK_ETHTOOL_STAT(rx_fcs_errors),
++ MTK_ETHTOOL_STAT(rx_short_errors),
++ MTK_ETHTOOL_STAT(rx_long_errors),
++ MTK_ETHTOOL_STAT(rx_checksum_errors),
++ MTK_ETHTOOL_STAT(rx_flow_control_packets),
++};
++
++void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg)
++{
++ __raw_writel(val, eth->base + reg);
++}
++
++u32 mtk_r32(struct mtk_eth *eth, unsigned reg)
++{
++ return __raw_readl(eth->base + reg);
++}
++
++static int mtk_mdio_busy_wait(struct mtk_eth *eth)
++{
++ unsigned long t_start = jiffies;
++
++ while (1) {
++ if (!(mtk_r32(eth, MTK_PHY_IAC) & PHY_IAC_ACCESS))
++ return 0;
++ if (time_after(jiffies, t_start + PHY_IAC_TIMEOUT))
++ break;
++ usleep_range(10, 20);
++ }
++
++ dev_err(eth->dev, "mdio: MDIO timeout\n");
++ return -1;
++}
++
++u32 _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr,
++ u32 phy_register, u32 write_data)
++{
++ if (mtk_mdio_busy_wait(eth))
++ return -1;
++
++ write_data &= 0xffff;
++
++ mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_WRITE |
++ (phy_register << PHY_IAC_REG_SHIFT) |
++ (phy_addr << PHY_IAC_ADDR_SHIFT) | write_data,
++ MTK_PHY_IAC);
++
++ if (mtk_mdio_busy_wait(eth))
++ return -1;
++
++ return 0;
++}
++
++u32 _mtk_mdio_read(struct mtk_eth *eth, int phy_addr, int phy_reg)
++{
++ u32 d;
++
++ if (mtk_mdio_busy_wait(eth))
++ return 0xffff;
++
++ mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_READ |
++ (phy_reg << PHY_IAC_REG_SHIFT) |
++ (phy_addr << PHY_IAC_ADDR_SHIFT),
++ MTK_PHY_IAC);
++
++ if (mtk_mdio_busy_wait(eth))
++ return 0xffff;
++
++ d = mtk_r32(eth, MTK_PHY_IAC) & 0xffff;
++
++ return d;
++}
++
++static int mtk_mdio_write(struct mii_bus *bus, int phy_addr,
++ int phy_reg, u16 val)
++{
++ struct mtk_eth *eth = bus->priv;
++
++ return _mtk_mdio_write(eth, phy_addr, phy_reg, val);
++}
++
++static int mtk_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
++{
++ struct mtk_eth *eth = bus->priv;
++
++ return _mtk_mdio_read(eth, phy_addr, phy_reg);
++}
++
++static void mtk_phy_link_adjust(struct net_device *dev)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++ u32 mcr = MAC_MCR_MAX_RX_1536 | MAC_MCR_IPG_CFG |
++ MAC_MCR_FORCE_MODE | MAC_MCR_TX_EN |
++ MAC_MCR_RX_EN | MAC_MCR_BACKOFF_EN |
++ MAC_MCR_BACKPR_EN;
++
++ switch (mac->phy_dev->speed) {
++ case SPEED_1000:
++ mcr |= MAC_MCR_SPEED_1000;
++ break;
++ case SPEED_100:
++ mcr |= MAC_MCR_SPEED_100;
++ break;
++ };
++
++ if (mac->phy_dev->link)
++ mcr |= MAC_MCR_FORCE_LINK;
++
++ if (mac->phy_dev->duplex)
++ mcr |= MAC_MCR_FORCE_DPX;
++
++ if (mac->phy_dev->pause)
++ mcr |= MAC_MCR_FORCE_RX_FC | MAC_MCR_FORCE_TX_FC;
++
++ mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
++
++ if (mac->phy_dev->link)
++ netif_carrier_on(dev);
++ else
++ netif_carrier_off(dev);
++}
++
++static int mtk_phy_connect_node(struct mtk_eth *eth, struct mtk_mac *mac,
++ struct device_node *phy_node)
++{
++ const __be32 *_addr = NULL;
++ struct phy_device *phydev;
++ int phy_mode, addr;
++
++ _addr = of_get_property(phy_node, "reg", NULL);
++
++ if (!_addr || (be32_to_cpu(*_addr) >= 0x20)) {
++ pr_err("%s: invalid phy address\n", phy_node->name);
++ return -EINVAL;
++ }
++ addr = be32_to_cpu(*_addr);
++ phy_mode = of_get_phy_mode(phy_node);
++ if (phy_mode < 0) {
++ dev_err(eth->dev, "incorrect phy-mode %d\n", phy_mode);
++ return -EINVAL;
++ }
++
++ phydev = of_phy_connect(eth->netdev[mac->id], phy_node,
++ mtk_phy_link_adjust, 0, phy_mode);
++ if (IS_ERR(phydev)) {
++ dev_err(eth->dev, "could not connect to PHY\n");
++ return PTR_ERR(phydev);
++ }
++
++ dev_info(eth->dev,
++ "connected mac %d to PHY at %s [uid=%08x, driver=%s]\n",
++ mac->id, phydev_name(phydev), phydev->phy_id,
++ phydev->drv->name);
++
++ mac->phy_dev = phydev;
++
++ return 0;
++}
++
++static int mtk_phy_connect(struct mtk_mac *mac)
++{
++ struct mtk_eth *eth = mac->hw;
++ struct device_node *np;
++ u32 val, ge_mode;
++
++ np = of_parse_phandle(mac->of_node, "phy-handle", 0);
++ if (!np)
++ return -ENODEV;
++
++ switch (of_get_phy_mode(np)) {
++ case PHY_INTERFACE_MODE_RGMII:
++ ge_mode = 0;
++ break;
++ case PHY_INTERFACE_MODE_MII:
++ ge_mode = 1;
++ break;
++ case PHY_INTERFACE_MODE_RMII:
++ ge_mode = 2;
++ break;
++ default:
++ dev_err(eth->dev, "invalid phy_mode\n");
++ return -1;
++ }
++
++ /* put the gmac into the right mode */
++ regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
++ val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id);
++ val |= SYSCFG0_GE_MODE(ge_mode, mac->id);
++ regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
++
++ mtk_phy_connect_node(eth, mac, np);
++ mac->phy_dev->autoneg = AUTONEG_ENABLE;
++ mac->phy_dev->speed = 0;
++ mac->phy_dev->duplex = 0;
++ mac->phy_dev->supported &= PHY_BASIC_FEATURES;
++ mac->phy_dev->advertising = mac->phy_dev->supported |
++ ADVERTISED_Autoneg;
++ phy_start_aneg(mac->phy_dev);
++
++ return 0;
++}
++
++static int mtk_mdio_init(struct mtk_eth *eth)
++{
++ struct device_node *mii_np;
++ int err;
++
++ mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus");
++ if (!mii_np) {
++ dev_err(eth->dev, "no %s child node found", "mdio-bus");
++ return -ENODEV;
++ }
++
++ if (!of_device_is_available(mii_np)) {
++ err = 0;
++ goto err_put_node;
++ }
++
++ eth->mii_bus = mdiobus_alloc();
++ if (!eth->mii_bus) {
++ err = -ENOMEM;
++ goto err_put_node;
++ }
++
++ eth->mii_bus->name = "mdio";
++ eth->mii_bus->read = mtk_mdio_read;
++ eth->mii_bus->write = mtk_mdio_write;
++ eth->mii_bus->priv = eth;
++ eth->mii_bus->parent = eth->dev;
++
++ snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%s", mii_np->name);
++ err = of_mdiobus_register(eth->mii_bus, mii_np);
++ if (err)
++ goto err_free_bus;
++
++ return 0;
++
++err_free_bus:
++ kfree(eth->mii_bus);
++
++err_put_node:
++ of_node_put(mii_np);
++ eth->mii_bus = NULL;
++ return err;
++}
++
++static void mtk_mdio_cleanup(struct mtk_eth *eth)
++{
++ if (!eth->mii_bus)
++ return;
++
++ mdiobus_unregister(eth->mii_bus);
++ of_node_put(eth->mii_bus->dev.of_node);
++ kfree(eth->mii_bus);
++}
++
++static inline void mtk_irq_disable(struct mtk_eth *eth, u32 mask)
++{
++ u32 val;
++
++ val = mtk_r32(eth, MTK_QDMA_INT_MASK);
++ mtk_w32(eth, val & ~mask, MTK_QDMA_INT_MASK);
++ /* flush write */
++ mtk_r32(eth, MTK_QDMA_INT_MASK);
++}
++
++static inline void mtk_irq_enable(struct mtk_eth *eth, u32 mask)
++{
++ u32 val;
++
++ val = mtk_r32(eth, MTK_QDMA_INT_MASK);
++ mtk_w32(eth, val | mask, MTK_QDMA_INT_MASK);
++ /* flush write */
++ mtk_r32(eth, MTK_QDMA_INT_MASK);
++}
++
++static int mtk_set_mac_address(struct net_device *dev, void *p)
++{
++ int ret = eth_mac_addr(dev, p);
++ struct mtk_mac *mac = netdev_priv(dev);
++ const char *macaddr = dev->dev_addr;
++ unsigned long flags;
++
++ if (ret)
++ return ret;
++
++ spin_lock_irqsave(&mac->hw->page_lock, flags);
++ mtk_w32(mac->hw, (macaddr[0] << 8) | macaddr[1],
++ MTK_GDMA_MAC_ADRH(mac->id));
++ mtk_w32(mac->hw, (macaddr[2] << 24) | (macaddr[3] << 16) |
++ (macaddr[4] << 8) | macaddr[5],
++ MTK_GDMA_MAC_ADRL(mac->id));
++ spin_unlock_irqrestore(&mac->hw->page_lock, flags);
++
++ return 0;
++}
++
++void mtk_stats_update_mac(struct mtk_mac *mac)
++{
++ struct mtk_hw_stats *hw_stats = mac->hw_stats;
++ unsigned int base = MTK_GDM1_TX_GBCNT;
++ u64 stats;
++
++ base += hw_stats->reg_offset;
++
++ u64_stats_update_begin(&hw_stats->syncp);
++
++ hw_stats->rx_bytes += mtk_r32(mac->hw, base);
++ stats = mtk_r32(mac->hw, base + 0x04);
++ if (stats)
++ hw_stats->rx_bytes += (stats << 32);
++ hw_stats->rx_packets += mtk_r32(mac->hw, base + 0x08);
++ hw_stats->rx_overflow += mtk_r32(mac->hw, base + 0x10);
++ hw_stats->rx_fcs_errors += mtk_r32(mac->hw, base + 0x14);
++ hw_stats->rx_short_errors += mtk_r32(mac->hw, base + 0x18);
++ hw_stats->rx_long_errors += mtk_r32(mac->hw, base + 0x1c);
++ hw_stats->rx_checksum_errors += mtk_r32(mac->hw, base + 0x20);
++ hw_stats->rx_flow_control_packets +=
++ mtk_r32(mac->hw, base + 0x24);
++ hw_stats->tx_skip += mtk_r32(mac->hw, base + 0x28);
++ hw_stats->tx_collisions += mtk_r32(mac->hw, base + 0x2c);
++ hw_stats->tx_bytes += mtk_r32(mac->hw, base + 0x30);
++ stats = mtk_r32(mac->hw, base + 0x34);
++ if (stats)
++ hw_stats->tx_bytes += (stats << 32);
++ hw_stats->tx_packets += mtk_r32(mac->hw, base + 0x38);
++ u64_stats_update_end(&hw_stats->syncp);
++}
++
++static void mtk_stats_update(struct mtk_eth *eth)
++{
++ int i;
++
++ for (i = 0; i < MTK_MAC_COUNT; i++) {
++ if (!eth->mac[i] || !eth->mac[i]->hw_stats)
++ continue;
++ if (spin_trylock(&eth->mac[i]->hw_stats->stats_lock)) {
++ mtk_stats_update_mac(eth->mac[i]);
++ spin_unlock(&eth->mac[i]->hw_stats->stats_lock);
++ }
++ }
++}
++
++static struct rtnl_link_stats64 *mtk_get_stats64(struct net_device *dev,
++ struct rtnl_link_stats64 *storage)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++ struct mtk_hw_stats *hw_stats = mac->hw_stats;
++ unsigned int start;
++
++ if (netif_running(dev) && netif_device_present(dev)) {
++ if (spin_trylock(&hw_stats->stats_lock)) {
++ mtk_stats_update_mac(mac);
++ spin_unlock(&hw_stats->stats_lock);
++ }
++ }
++
++ do {
++ start = u64_stats_fetch_begin_irq(&hw_stats->syncp);
++ storage->rx_packets = hw_stats->rx_packets;
++ storage->tx_packets = hw_stats->tx_packets;
++ storage->rx_bytes = hw_stats->rx_bytes;
++ storage->tx_bytes = hw_stats->tx_bytes;
++ storage->collisions = hw_stats->tx_collisions;
++ storage->rx_length_errors = hw_stats->rx_short_errors +
++ hw_stats->rx_long_errors;
++ storage->rx_over_errors = hw_stats->rx_overflow;
++ storage->rx_crc_errors = hw_stats->rx_fcs_errors;
++ storage->rx_errors = hw_stats->rx_checksum_errors;
++ storage->tx_aborted_errors = hw_stats->tx_skip;
++ } while (u64_stats_fetch_retry_irq(&hw_stats->syncp, start));
++
++ storage->tx_errors = dev->stats.tx_errors;
++ storage->rx_dropped = dev->stats.rx_dropped;
++ storage->tx_dropped = dev->stats.tx_dropped;
++
++ return storage;
++}
++
++static inline int mtk_max_frag_size(int mtu)
++{
++ /* make sure buf_size will be at least MTK_MAX_RX_LENGTH */
++ if (mtu + MTK_RX_ETH_HLEN < MTK_MAX_RX_LENGTH)
++ mtu = MTK_MAX_RX_LENGTH - MTK_RX_ETH_HLEN;
++
++ return SKB_DATA_ALIGN(MTK_RX_HLEN + mtu) +
++ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
++}
++
++static inline int mtk_max_buf_size(int frag_size)
++{
++ int buf_size = frag_size - NET_SKB_PAD - NET_IP_ALIGN -
++ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
++
++ WARN_ON(buf_size < MTK_MAX_RX_LENGTH);
++
++ return buf_size;
++}
++
++static inline void mtk_rx_get_desc(struct mtk_rx_dma *rxd,
++ struct mtk_rx_dma *dma_rxd)
++{
++ rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
++ rxd->rxd2 = READ_ONCE(dma_rxd->rxd2);
++ rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
++ rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
++}
++
++/* the qdma core needs scratch memory to be setup */
++static int mtk_init_fq_dma(struct mtk_eth *eth)
++{
++ unsigned int phy_ring_head, phy_ring_tail;
++ int cnt = MTK_DMA_SIZE;
++ dma_addr_t dma_addr;
++ int i;
++
++ eth->scratch_ring = dma_alloc_coherent(eth->dev,
++ cnt * sizeof(struct mtk_tx_dma),
++ &phy_ring_head,
++ GFP_ATOMIC | __GFP_ZERO);
++ if (unlikely(!eth->scratch_ring))
++ return -ENOMEM;
++
++ eth->scratch_head = kcalloc(cnt, MTK_QDMA_PAGE_SIZE,
++ GFP_KERNEL);
++ dma_addr = dma_map_single(eth->dev,
++ eth->scratch_head, cnt * MTK_QDMA_PAGE_SIZE,
++ DMA_FROM_DEVICE);
++ if (unlikely(dma_mapping_error(eth->dev, dma_addr)))
++ return -ENOMEM;
++
++ memset(eth->scratch_ring, 0x0, sizeof(struct mtk_tx_dma) * cnt);
++ phy_ring_tail = phy_ring_head +
++ (sizeof(struct mtk_tx_dma) * (cnt - 1));
++
++ for (i = 0; i < cnt; i++) {
++ eth->scratch_ring[i].txd1 =
++ (dma_addr + (i * MTK_QDMA_PAGE_SIZE));
++ if (i < cnt - 1)
++ eth->scratch_ring[i].txd2 = (phy_ring_head +
++ ((i + 1) * sizeof(struct mtk_tx_dma)));
++ eth->scratch_ring[i].txd3 = TX_DMA_SDL(MTK_QDMA_PAGE_SIZE);
++ }
++
++ mtk_w32(eth, phy_ring_head, MTK_QDMA_FQ_HEAD);
++ mtk_w32(eth, phy_ring_tail, MTK_QDMA_FQ_TAIL);
++ mtk_w32(eth, (cnt << 16) | cnt, MTK_QDMA_FQ_CNT);
++ mtk_w32(eth, MTK_QDMA_PAGE_SIZE << 16, MTK_QDMA_FQ_BLEN);
++
++ return 0;
++}
++
++static inline void *mtk_qdma_phys_to_virt(struct mtk_tx_ring *ring, u32 desc)
++{
++ void *ret = ring->dma;
++
++ return ret + (desc - ring->phys);
++}
++
++static inline struct mtk_tx_buf *mtk_desc_to_tx_buf(struct mtk_tx_ring *ring,
++ struct mtk_tx_dma *txd)
++{
++ int idx = txd - ring->dma;
++
++ return &ring->buf[idx];
++}
++
++static void mtk_tx_unmap(struct device *dev, struct mtk_tx_buf *tx_buf)
++{
++ if (tx_buf->flags & MTK_TX_FLAGS_SINGLE0) {
++ dma_unmap_single(dev,
++ dma_unmap_addr(tx_buf, dma_addr0),
++ dma_unmap_len(tx_buf, dma_len0),
++ DMA_TO_DEVICE);
++ } else if (tx_buf->flags & MTK_TX_FLAGS_PAGE0) {
++ dma_unmap_page(dev,
++ dma_unmap_addr(tx_buf, dma_addr0),
++ dma_unmap_len(tx_buf, dma_len0),
++ DMA_TO_DEVICE);
++ }
++ tx_buf->flags = 0;
++ if (tx_buf->skb &&
++ (tx_buf->skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC))
++ dev_kfree_skb_any(tx_buf->skb);
++ tx_buf->skb = NULL;
++}
++
++static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
++ int tx_num, struct mtk_tx_ring *ring, bool gso)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++ struct mtk_eth *eth = mac->hw;
++ struct mtk_tx_dma *itxd, *txd;
++ struct mtk_tx_buf *tx_buf;
++ unsigned long flags;
++ dma_addr_t mapped_addr;
++ unsigned int nr_frags;
++ int i, n_desc = 1;
++ u32 txd4 = 0;
++
++ itxd = ring->next_free;
++ if (itxd == ring->last_free)
++ return -ENOMEM;
++
++ /* set the forward port */
++ txd4 |= (mac->id + 1) << TX_DMA_FPORT_SHIFT;
++
++ tx_buf = mtk_desc_to_tx_buf(ring, itxd);
++ memset(tx_buf, 0, sizeof(*tx_buf));
++
++ if (gso)
++ txd4 |= TX_DMA_TSO;
++
++ /* TX Checksum offload */
++ if (skb->ip_summed == CHECKSUM_PARTIAL)
++ txd4 |= TX_DMA_CHKSUM;
++
++ /* VLAN header offload */
++ if (skb_vlan_tag_present(skb))
++ txd4 |= TX_DMA_INS_VLAN | skb_vlan_tag_get(skb);
++
++ mapped_addr = dma_map_single(&dev->dev, skb->data,
++ skb_headlen(skb), DMA_TO_DEVICE);
++ if (unlikely(dma_mapping_error(&dev->dev, mapped_addr)))
++ return -ENOMEM;
++
++ /* normally we can rely on the stack not calling this more than once,
++ * however we have 2 queues running ont he same ring so we need to lock
++ * the ring access
++ */
++ spin_lock_irqsave(&eth->page_lock, flags);
++ WRITE_ONCE(itxd->txd1, mapped_addr);
++ tx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
++ dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr);
++ dma_unmap_len_set(tx_buf, dma_len0, skb_headlen(skb));
++
++ /* TX SG offload */
++ txd = itxd;
++ nr_frags = skb_shinfo(skb)->nr_frags;
++ for (i = 0; i < nr_frags; i++) {
++ struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
++ unsigned int offset = 0;
++ int frag_size = skb_frag_size(frag);
++
++ while (frag_size) {
++ bool last_frag = false;
++ unsigned int frag_map_size;
++
++ txd = mtk_qdma_phys_to_virt(ring, txd->txd2);
++ if (txd == ring->last_free)
++ goto err_dma;
++
++ n_desc++;
++ frag_map_size = min(frag_size, MTK_TX_DMA_BUF_LEN);
++ mapped_addr = skb_frag_dma_map(&dev->dev, frag, offset,
++ frag_map_size,
++ DMA_TO_DEVICE);
++ if (unlikely(dma_mapping_error(&dev->dev, mapped_addr)))
++ goto err_dma;
++
++ if (i == nr_frags - 1 &&
++ (frag_size - frag_map_size) == 0)
++ last_frag = true;
++
++ WRITE_ONCE(txd->txd1, mapped_addr);
++ WRITE_ONCE(txd->txd3, (TX_DMA_SWC |
++ TX_DMA_PLEN0(frag_map_size) |
++ last_frag * TX_DMA_LS0) |
++ mac->id);
++ WRITE_ONCE(txd->txd4, 0);
++
++ tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC;
++ tx_buf = mtk_desc_to_tx_buf(ring, txd);
++ memset(tx_buf, 0, sizeof(*tx_buf));
++
++ tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
++ dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr);
++ dma_unmap_len_set(tx_buf, dma_len0, frag_map_size);
++ frag_size -= frag_map_size;
++ offset += frag_map_size;
++ }
++ }
++
++ /* store skb to cleanup */
++ tx_buf->skb = skb;
++
++ WRITE_ONCE(itxd->txd4, txd4);
++ WRITE_ONCE(itxd->txd3, (TX_DMA_SWC | TX_DMA_PLEN0(skb_headlen(skb)) |
++ (!nr_frags * TX_DMA_LS0)));
++
++ spin_unlock_irqrestore(&eth->page_lock, flags);
++
++ netdev_sent_queue(dev, skb->len);
++ skb_tx_timestamp(skb);
++
++ ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2);
++ atomic_sub(n_desc, &ring->free_count);
++
++ /* make sure that all changes to the dma ring are flushed before we
++ * continue
++ */
++ wmb();
++
++ if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) || !skb->xmit_more)
++ mtk_w32(eth, txd->txd2, MTK_QTX_CTX_PTR);
++
++ return 0;
++
++err_dma:
++ do {
++ tx_buf = mtk_desc_to_tx_buf(ring, txd);
++
++ /* unmap dma */
++ mtk_tx_unmap(&dev->dev, tx_buf);
++
++ itxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
++ itxd = mtk_qdma_phys_to_virt(ring, itxd->txd2);
++ } while (itxd != txd);
++
++ return -ENOMEM;
++}
++
++static inline int mtk_cal_txd_req(struct sk_buff *skb)
++{
++ int i, nfrags;
++ struct skb_frag_struct *frag;
++
++ nfrags = 1;
++ if (skb_is_gso(skb)) {
++ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
++ frag = &skb_shinfo(skb)->frags[i];
++ nfrags += DIV_ROUND_UP(frag->size, MTK_TX_DMA_BUF_LEN);
++ }
++ } else {
++ nfrags += skb_shinfo(skb)->nr_frags;
++ }
++
++ return DIV_ROUND_UP(nfrags, 2);
++}
++
++static int mtk_start_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++ struct mtk_eth *eth = mac->hw;
++ struct mtk_tx_ring *ring = &eth->tx_ring;
++ struct net_device_stats *stats = &dev->stats;
++ bool gso = false;
++ int tx_num;
++
++ tx_num = mtk_cal_txd_req(skb);
++ if (unlikely(atomic_read(&ring->free_count) <= tx_num)) {
++ netif_stop_queue(dev);
++ netif_err(eth, tx_queued, dev,
++ "Tx Ring full when queue awake!\n");
++ return NETDEV_TX_BUSY;
++ }
++
++ /* TSO: fill MSS info in tcp checksum field */
++ if (skb_is_gso(skb)) {
++ if (skb_cow_head(skb, 0)) {
++ netif_warn(eth, tx_err, dev,
++ "GSO expand head fail.\n");
++ goto drop;
++ }
++
++ if (skb_shinfo(skb)->gso_type &
++ (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
++ gso = true;
++ tcp_hdr(skb)->check = htons(skb_shinfo(skb)->gso_size);
++ }
++ }
++
++ if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0)
++ goto drop;
++
++ if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) {
++ netif_stop_queue(dev);
++ if (unlikely(atomic_read(&ring->free_count) >
++ ring->thresh))
++ netif_wake_queue(dev);
++ }
++
++ return NETDEV_TX_OK;
++
++drop:
++ stats->tx_dropped++;
++ dev_kfree_skb(skb);
++ return NETDEV_TX_OK;
++}
++
++static int mtk_poll_rx(struct napi_struct *napi, int budget,
++ struct mtk_eth *eth, u32 rx_intr)
++{
++ struct mtk_rx_ring *ring = &eth->rx_ring;
++ int idx = ring->calc_idx;
++ struct sk_buff *skb;
++ u8 *data, *new_data;
++ struct mtk_rx_dma *rxd, trxd;
++ int done = 0;
++
++ while (done < budget) {
++ struct net_device *netdev;
++ unsigned int pktlen;
++ dma_addr_t dma_addr;
++ int mac = 0;
++
++ idx = NEXT_RX_DESP_IDX(idx);
++ rxd = &ring->dma[idx];
++ data = ring->data[idx];
++
++ mtk_rx_get_desc(&trxd, rxd);
++ if (!(trxd.rxd2 & RX_DMA_DONE))
++ break;
++
++ /* find out which mac the packet come from. values start at 1 */
++ mac = (trxd.rxd4 >> RX_DMA_FPORT_SHIFT) &
++ RX_DMA_FPORT_MASK;
++ mac--;
++
++ netdev = eth->netdev[mac];
++
++ /* alloc new buffer */
++ new_data = napi_alloc_frag(ring->frag_size);
++ if (unlikely(!new_data)) {
++ netdev->stats.rx_dropped++;
++ goto release_desc;
++ }
++ dma_addr = dma_map_single(&eth->netdev[mac]->dev,
++ new_data + NET_SKB_PAD,
++ ring->buf_size,
++ DMA_FROM_DEVICE);
++ if (unlikely(dma_mapping_error(&netdev->dev, dma_addr))) {
++ skb_free_frag(new_data);
++ goto release_desc;
++ }
++
++ /* receive data */
++ skb = build_skb(data, ring->frag_size);
++ if (unlikely(!skb)) {
++ put_page(virt_to_head_page(new_data));
++ goto release_desc;
++ }
++ skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
++
++ dma_unmap_single(&netdev->dev, trxd.rxd1,
++ ring->buf_size, DMA_FROM_DEVICE);
++ pktlen = RX_DMA_GET_PLEN0(trxd.rxd2);
++ skb->dev = netdev;
++ skb_put(skb, pktlen);
++ if (trxd.rxd4 & RX_DMA_L4_VALID)
++ skb->ip_summed = CHECKSUM_UNNECESSARY;
++ else
++ skb_checksum_none_assert(skb);
++ skb->protocol = eth_type_trans(skb, netdev);
++
++ if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX &&
++ RX_DMA_VID(trxd.rxd3))
++ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
++ RX_DMA_VID(trxd.rxd3));
++ napi_gro_receive(napi, skb);
++
++ ring->data[idx] = new_data;
++ rxd->rxd1 = (unsigned int)dma_addr;
++
++release_desc:
++ rxd->rxd2 = RX_DMA_PLEN0(ring->buf_size);
++
++ ring->calc_idx = idx;
++ /* make sure that all changes to the dma ring are flushed before
++ * we continue
++ */
++ wmb();
++ mtk_w32(eth, ring->calc_idx, MTK_QRX_CRX_IDX0);
++ done++;
++ }
++
++ if (done < budget)
++ mtk_w32(eth, rx_intr, MTK_QMTK_INT_STATUS);
++
++ return done;
++}
++
++static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again)
++{
++ struct mtk_tx_ring *ring = &eth->tx_ring;
++ struct mtk_tx_dma *desc;
++ struct sk_buff *skb;
++ struct mtk_tx_buf *tx_buf;
++ int total = 0, done[MTK_MAX_DEVS];
++ unsigned int bytes[MTK_MAX_DEVS];
++ u32 cpu, dma;
++ static int condition;
++ int i;
++
++ memset(done, 0, sizeof(done));
++ memset(bytes, 0, sizeof(bytes));
++
++ cpu = mtk_r32(eth, MTK_QTX_CRX_PTR);
++ dma = mtk_r32(eth, MTK_QTX_DRX_PTR);
++
++ desc = mtk_qdma_phys_to_virt(ring, cpu);
++
++ while ((cpu != dma) && budget) {
++ u32 next_cpu = desc->txd2;
++ int mac;
++
++ desc = mtk_qdma_phys_to_virt(ring, desc->txd2);
++ if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0)
++ break;
++
++ mac = (desc->txd4 >> TX_DMA_FPORT_SHIFT) &
++ TX_DMA_FPORT_MASK;
++ mac--;
++
++ tx_buf = mtk_desc_to_tx_buf(ring, desc);
++ skb = tx_buf->skb;
++ if (!skb) {
++ condition = 1;
++ break;
++ }
++
++ if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) {
++ bytes[mac] += skb->len;
++ done[mac]++;
++ budget--;
++ }
++ mtk_tx_unmap(eth->dev, tx_buf);
++
++ ring->last_free->txd2 = next_cpu;
++ ring->last_free = desc;
++ atomic_inc(&ring->free_count);
++
++ cpu = next_cpu;
++ }
++
++ mtk_w32(eth, cpu, MTK_QTX_CRX_PTR);
++
++ for (i = 0; i < MTK_MAC_COUNT; i++) {
++ if (!eth->netdev[i] || !done[i])
++ continue;
++ netdev_completed_queue(eth->netdev[i], done[i], bytes[i]);
++ total += done[i];
++ }
++
++ /* read hw index again make sure no new tx packet */
++ if (cpu != dma || cpu != mtk_r32(eth, MTK_QTX_DRX_PTR))
++ *tx_again = true;
++ else
++ mtk_w32(eth, MTK_TX_DONE_INT, MTK_QMTK_INT_STATUS);
++
++ if (!total)
++ return 0;
++
++ for (i = 0; i < MTK_MAC_COUNT; i++) {
++ if (!eth->netdev[i] ||
++ unlikely(!netif_queue_stopped(eth->netdev[i])))
++ continue;
++ if (atomic_read(&ring->free_count) > ring->thresh)
++ netif_wake_queue(eth->netdev[i]);
++ }
++
++ return total;
++}
++
++static int mtk_poll(struct napi_struct *napi, int budget)
++{
++ struct mtk_eth *eth = container_of(napi, struct mtk_eth, rx_napi);
++ u32 status, status2, mask, tx_intr, rx_intr, status_intr;
++ int tx_done, rx_done;
++ bool tx_again = false;
++
++ status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
++ status2 = mtk_r32(eth, MTK_INT_STATUS2);
++ tx_intr = MTK_TX_DONE_INT;
++ rx_intr = MTK_RX_DONE_INT;
++ status_intr = (MTK_GDM1_AF | MTK_GDM2_AF);
++ tx_done = 0;
++ rx_done = 0;
++ tx_again = 0;
++
++ if (status & tx_intr)
++ tx_done = mtk_poll_tx(eth, budget, &tx_again);
++
++ if (status & rx_intr)
++ rx_done = mtk_poll_rx(napi, budget, eth, rx_intr);
++
++ if (unlikely(status2 & status_intr)) {
++ mtk_stats_update(eth);
++ mtk_w32(eth, status_intr, MTK_INT_STATUS2);
++ }
++
++ if (unlikely(netif_msg_intr(eth))) {
++ mask = mtk_r32(eth, MTK_QDMA_INT_MASK);
++ netdev_info(eth->netdev[0],
++ "done tx %d, rx %d, intr 0x%08x/0x%x\n",
++ tx_done, rx_done, status, mask);
++ }
++
++ if (tx_again || rx_done == budget)
++ return budget;
++
++ status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
++ if (status & (tx_intr | rx_intr))
++ return budget;
++
++ napi_complete(napi);
++ mtk_irq_enable(eth, tx_intr | rx_intr);
++
++ return rx_done;
++}
++
++static int mtk_tx_alloc(struct mtk_eth *eth)
++{
++ struct mtk_tx_ring *ring = &eth->tx_ring;
++ int i, sz = sizeof(*ring->dma);
++
++ ring->buf = kcalloc(MTK_DMA_SIZE, sizeof(*ring->buf),
++ GFP_KERNEL);
++ if (!ring->buf)
++ goto no_tx_mem;
++
++ ring->dma = dma_alloc_coherent(eth->dev,
++ MTK_DMA_SIZE * sz,
++ &ring->phys,
++ GFP_ATOMIC | __GFP_ZERO);
++ if (!ring->dma)
++ goto no_tx_mem;
++
++ memset(ring->dma, 0, MTK_DMA_SIZE * sz);
++ for (i = 0; i < MTK_DMA_SIZE; i++) {
++ int next = (i + 1) % MTK_DMA_SIZE;
++ u32 next_ptr = ring->phys + next * sz;
++
++ ring->dma[i].txd2 = next_ptr;
++ ring->dma[i].txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
++ }
++
++ atomic_set(&ring->free_count, MTK_DMA_SIZE - 2);
++ ring->next_free = &ring->dma[0];
++ ring->last_free = &ring->dma[MTK_DMA_SIZE - 2];
++ ring->thresh = max((unsigned long)MTK_DMA_SIZE >> 2,
++ MAX_SKB_FRAGS);
++
++ /* make sure that all changes to the dma ring are flushed before we
++ * continue
++ */
++ wmb();
++
++ mtk_w32(eth, ring->phys, MTK_QTX_CTX_PTR);
++ mtk_w32(eth, ring->phys, MTK_QTX_DTX_PTR);
++ mtk_w32(eth,
++ ring->phys + ((MTK_DMA_SIZE - 1) * sz),
++ MTK_QTX_CRX_PTR);
++ mtk_w32(eth,
++ ring->phys + ((MTK_DMA_SIZE - 1) * sz),
++ MTK_QTX_DRX_PTR);
++
++ return 0;
++
++no_tx_mem:
++ return -ENOMEM;
++}
++
++static void mtk_tx_clean(struct mtk_eth *eth)
++{
++ struct mtk_tx_ring *ring = &eth->tx_ring;
++ int i;
++
++ if (ring->buf) {
++ for (i = 0; i < MTK_DMA_SIZE; i++)
++ mtk_tx_unmap(eth->dev, &ring->buf[i]);
++ kfree(ring->buf);
++ ring->buf = NULL;
++ }
++
++ if (ring->dma) {
++ dma_free_coherent(eth->dev,
++ MTK_DMA_SIZE * sizeof(*ring->dma),
++ ring->dma,
++ ring->phys);
++ ring->dma = NULL;
++ }
++}
++
++static int mtk_rx_alloc(struct mtk_eth *eth)
++{
++ struct mtk_rx_ring *ring = &eth->rx_ring;
++ int i;
++
++ ring->frag_size = mtk_max_frag_size(ETH_DATA_LEN);
++ ring->buf_size = mtk_max_buf_size(ring->frag_size);
++ ring->data = kcalloc(MTK_DMA_SIZE, sizeof(*ring->data),
++ GFP_KERNEL);
++ if (!ring->data)
++ return -ENOMEM;
++
++ for (i = 0; i < MTK_DMA_SIZE; i++) {
++ ring->data[i] = netdev_alloc_frag(ring->frag_size);
++ if (!ring->data[i])
++ return -ENOMEM;
++ }
++
++ ring->dma = dma_alloc_coherent(eth->dev,
++ MTK_DMA_SIZE * sizeof(*ring->dma),
++ &ring->phys,
++ GFP_ATOMIC | __GFP_ZERO);
++ if (!ring->dma)
++ return -ENOMEM;
++
++ for (i = 0; i < MTK_DMA_SIZE; i++) {
++ dma_addr_t dma_addr = dma_map_single(eth->dev,
++ ring->data[i] + NET_SKB_PAD,
++ ring->buf_size,
++ DMA_FROM_DEVICE);
++ if (unlikely(dma_mapping_error(eth->dev, dma_addr)))
++ return -ENOMEM;
++ ring->dma[i].rxd1 = (unsigned int)dma_addr;
++
++ ring->dma[i].rxd2 = RX_DMA_PLEN0(ring->buf_size);
++ }
++ ring->calc_idx = MTK_DMA_SIZE - 1;
++ /* make sure that all changes to the dma ring are flushed before we
++ * continue
++ */
++ wmb();
++
++ mtk_w32(eth, eth->rx_ring.phys, MTK_QRX_BASE_PTR0);
++ mtk_w32(eth, MTK_DMA_SIZE, MTK_QRX_MAX_CNT0);
++ mtk_w32(eth, eth->rx_ring.calc_idx, MTK_QRX_CRX_IDX0);
++ mtk_w32(eth, MTK_PST_DRX_IDX0, MTK_QDMA_RST_IDX);
++ mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES, MTK_QTX_CFG(0));
++
++ return 0;
++}
++
++static void mtk_rx_clean(struct mtk_eth *eth)
++{
++ struct mtk_rx_ring *ring = &eth->rx_ring;
++ int i;
++
++ if (ring->data && ring->dma) {
++ for (i = 0; i < MTK_DMA_SIZE; i++) {
++ if (!ring->data[i])
++ continue;
++ if (!ring->dma[i].rxd1)
++ continue;
++ dma_unmap_single(eth->dev,
++ ring->dma[i].rxd1,
++ ring->buf_size,
++ DMA_FROM_DEVICE);
++ skb_free_frag(ring->data[i]);
++ }
++ kfree(ring->data);
++ ring->data = NULL;
++ }
++
++ if (ring->dma) {
++ dma_free_coherent(eth->dev,
++ MTK_DMA_SIZE * sizeof(*ring->dma),
++ ring->dma,
++ ring->phys);
++ ring->dma = NULL;
++ }
++}
++
++/* wait for DMA to finish whatever it is doing before we start using it again */
++static int mtk_dma_busy_wait(struct mtk_eth *eth)
++{
++ unsigned long t_start = jiffies;
++
++ while (1) {
++ if (!(mtk_r32(eth, MTK_QDMA_GLO_CFG) &
++ (MTK_RX_DMA_BUSY | MTK_TX_DMA_BUSY)))
++ return 0;
++ if (time_after(jiffies, t_start + MTK_DMA_BUSY_TIMEOUT))
++ break;
++ }
++
++ dev_err(eth->dev, "DMA init timeout\n");
++ return -1;
++}
++
++static int mtk_dma_init(struct mtk_eth *eth)
++{
++ int err;
++
++ if (mtk_dma_busy_wait(eth))
++ return -EBUSY;
++
++ /* QDMA needs scratch memory for internal reordering of the
++ * descriptors
++ */
++ err = mtk_init_fq_dma(eth);
++ if (err)
++ return err;
++
++ err = mtk_tx_alloc(eth);
++ if (err)
++ return err;
++
++ err = mtk_rx_alloc(eth);
++ if (err)
++ return err;
++
++ /* Enable random early drop and set drop threshold automatically */
++ mtk_w32(eth, FC_THRES_DROP_MODE | FC_THRES_DROP_EN | FC_THRES_MIN,
++ MTK_QDMA_FC_THRES);
++ mtk_w32(eth, 0x0, MTK_QDMA_HRED2);
++
++ return 0;
++}
++
++static void mtk_dma_free(struct mtk_eth *eth)
++{
++ int i;
++
++ for (i = 0; i < MTK_MAC_COUNT; i++)
++ if (eth->netdev[i])
++ netdev_reset_queue(eth->netdev[i]);
++ mtk_tx_clean(eth);
++ mtk_rx_clean(eth);
++ kfree(eth->scratch_head);
++}
++
++static void mtk_tx_timeout(struct net_device *dev)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++ struct mtk_eth *eth = mac->hw;
++
++ eth->netdev[mac->id]->stats.tx_errors++;
++ netif_err(eth, tx_err, dev,
++ "transmit timed out\n");
++ schedule_work(&mac->pending_work);
++}
++
++static irqreturn_t mtk_handle_irq(int irq, void *_eth)
++{
++ struct mtk_eth *eth = _eth;
++ u32 status;
++
++ status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
++ if (unlikely(!status))
++ return IRQ_NONE;
++
++ if (likely(status & (MTK_RX_DONE_INT | MTK_TX_DONE_INT))) {
++ if (likely(napi_schedule_prep(&eth->rx_napi)))
++ __napi_schedule(&eth->rx_napi);
++ } else {
++ mtk_w32(eth, status, MTK_QMTK_INT_STATUS);
++ }
++ mtk_irq_disable(eth, (MTK_RX_DONE_INT | MTK_TX_DONE_INT));
++
++ return IRQ_HANDLED;
++}
++
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void mtk_poll_controller(struct net_device *dev)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++ struct mtk_eth *eth = mac->hw;
++ u32 int_mask = MTK_TX_DONE_INT | MTK_RX_DONE_INT;
++
++ mtk_irq_disable(eth, int_mask);
++ mtk_handle_irq(dev->irq, dev);
++ mtk_irq_enable(eth, int_mask);
++}
++#endif
++
++static int mtk_start_dma(struct mtk_eth *eth)
++{
++ int err;
++
++ err = mtk_dma_init(eth);
++ if (err) {
++ mtk_dma_free(eth);
++ return err;
++ }
++
++ mtk_w32(eth,
++ MTK_TX_WB_DDONE | MTK_RX_DMA_EN | MTK_TX_DMA_EN |
++ MTK_RX_2B_OFFSET | MTK_DMA_SIZE_16DWORDS |
++ MTK_RX_BT_32DWORDS,
++ MTK_QDMA_GLO_CFG);
++
++ return 0;
++}
++
++static int mtk_open(struct net_device *dev)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++ struct mtk_eth *eth = mac->hw;
++
++ /* we run 2 netdevs on the same dma ring so we only bring it up once */
++ if (!atomic_read(&eth->dma_refcnt)) {
++ int err = mtk_start_dma(eth);
++
++ if (err)
++ return err;
++
++ napi_enable(&eth->rx_napi);
++ mtk_irq_enable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT);
++ }
++ atomic_inc(&eth->dma_refcnt);
++
++ phy_start(mac->phy_dev);
++ netif_start_queue(dev);
++
++ return 0;
++}
++
++static void mtk_stop_dma(struct mtk_eth *eth, u32 glo_cfg)
++{
++ unsigned long flags;
++ u32 val;
++ int i;
++
++ /* stop the dma engine */
++ spin_lock_irqsave(&eth->page_lock, flags);
++ val = mtk_r32(eth, glo_cfg);
++ mtk_w32(eth, val & ~(MTK_TX_WB_DDONE | MTK_RX_DMA_EN | MTK_TX_DMA_EN),
++ glo_cfg);
++ spin_unlock_irqrestore(&eth->page_lock, flags);
++
++ /* wait for dma stop */
++ for (i = 0; i < 10; i++) {
++ val = mtk_r32(eth, glo_cfg);
++ if (val & (MTK_TX_DMA_BUSY | MTK_RX_DMA_BUSY)) {
++ msleep(20);
++ continue;
++ }
++ break;
++ }
++}
++
++static int mtk_stop(struct net_device *dev)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++ struct mtk_eth *eth = mac->hw;
++
++ netif_tx_disable(dev);
++ phy_stop(mac->phy_dev);
++
++ /* only shutdown DMA if this is the last user */
++ if (!atomic_dec_and_test(&eth->dma_refcnt))
++ return 0;
++
++ mtk_irq_disable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT);
++ napi_disable(&eth->rx_napi);
++
++ mtk_stop_dma(eth, MTK_QDMA_GLO_CFG);
++
++ mtk_dma_free(eth);
++
++ return 0;
++}
++
++static int __init mtk_hw_init(struct mtk_eth *eth)
++{
++ int err, i;
++
++ /* reset the frame engine */
++ reset_control_assert(eth->rstc);
++ usleep_range(10, 20);
++ reset_control_deassert(eth->rstc);
++ usleep_range(10, 20);
++
++ /* Set GE2 driving and slew rate */
++ regmap_write(eth->pctl, GPIO_DRV_SEL10, 0xa00);
++
++ /* set GE2 TDSEL */
++ regmap_write(eth->pctl, GPIO_OD33_CTRL8, 0x5);
++
++ /* set GE2 TUNE */
++ regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0);
++
++ /* GE1, Force 1000M/FD, FC ON */
++ mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(0));
++
++ /* GE2, Force 1000M/FD, FC ON */
++ mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(1));
++
++ /* Enable RX VLan Offloading */
++ mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
++
++ err = devm_request_irq(eth->dev, eth->irq, mtk_handle_irq, 0,
++ dev_name(eth->dev), eth);
++ if (err)
++ return err;
++
++ err = mtk_mdio_init(eth);
++ if (err)
++ return err;
++
++ /* disable delay and normal interrupt */
++ mtk_w32(eth, 0, MTK_QDMA_DELAY_INT);
++ mtk_irq_disable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT);
++ mtk_w32(eth, RST_GL_PSE, MTK_RST_GL);
++ mtk_w32(eth, 0, MTK_RST_GL);
++
++ /* FE int grouping */
++ mtk_w32(eth, 0, MTK_FE_INT_GRP);
++
++ for (i = 0; i < 2; i++) {
++ u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
++
++ /* setup the forward port to send frame to QDMA */
++ val &= ~0xffff;
++ val |= 0x5555;
++
++ /* Enable RX checksum */
++ val |= MTK_GDMA_ICS_EN | MTK_GDMA_TCS_EN | MTK_GDMA_UCS_EN;
++
++ /* setup the mac dma */
++ mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
++ }
++
++ return 0;
++}
++
++static int __init mtk_init(struct net_device *dev)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++ struct mtk_eth *eth = mac->hw;
++ const char *mac_addr;
++
++ mac_addr = of_get_mac_address(mac->of_node);
++ if (mac_addr)
++ ether_addr_copy(dev->dev_addr, mac_addr);
++
++ /* If the mac address is invalid, use random mac address */
++ if (!is_valid_ether_addr(dev->dev_addr)) {
++ random_ether_addr(dev->dev_addr);
++ dev_err(eth->dev, "generated random MAC address %pM\n",
++ dev->dev_addr);
++ dev->addr_assign_type = NET_ADDR_RANDOM;
++ }
++
++ return mtk_phy_connect(mac);
++}
++
++static void mtk_uninit(struct net_device *dev)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++ struct mtk_eth *eth = mac->hw;
++
++ phy_disconnect(mac->phy_dev);
++ mtk_mdio_cleanup(eth);
++ mtk_irq_disable(eth, ~0);
++ free_irq(dev->irq, dev);
++}
++
++static int mtk_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++
++ switch (cmd) {
++ case SIOCGMIIPHY:
++ case SIOCGMIIREG:
++ case SIOCSMIIREG:
++ return phy_mii_ioctl(mac->phy_dev, ifr, cmd);
++ default:
++ break;
++ }
++
++ return -EOPNOTSUPP;
++}
++
++static void mtk_pending_work(struct work_struct *work)
++{
++ struct mtk_mac *mac = container_of(work, struct mtk_mac, pending_work);
++ struct mtk_eth *eth = mac->hw;
++ struct net_device *dev = eth->netdev[mac->id];
++ int err;
++
++ rtnl_lock();
++ mtk_stop(dev);
++
++ err = mtk_open(dev);
++ if (err) {
++ netif_alert(eth, ifup, dev,
++ "Driver up/down cycle failed, closing device.\n");
++ dev_close(dev);
++ }
++ rtnl_unlock();
++}
++
++static int mtk_cleanup(struct mtk_eth *eth)
++{
++ int i;
++
++ for (i = 0; i < MTK_MAC_COUNT; i++) {
++ struct mtk_mac *mac = netdev_priv(eth->netdev[i]);
++
++ if (!eth->netdev[i])
++ continue;
++
++ unregister_netdev(eth->netdev[i]);
++ free_netdev(eth->netdev[i]);
++ cancel_work_sync(&mac->pending_work);
++ }
++
++ return 0;
++}
++
++static int mtk_get_settings(struct net_device *dev,
++ struct ethtool_cmd *cmd)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++ int err;
++
++ err = phy_read_status(mac->phy_dev);
++ if (err)
++ return -ENODEV;
++
++ return phy_ethtool_gset(mac->phy_dev, cmd);
++}
++
++static int mtk_set_settings(struct net_device *dev,
++ struct ethtool_cmd *cmd)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++
++ if (cmd->phy_address != mac->phy_dev->mdio.addr) {
++ mac->phy_dev = mdiobus_get_phy(mac->hw->mii_bus,
++ cmd->phy_address);
++ if (!mac->phy_dev)
++ return -ENODEV;
++ }
++
++ return phy_ethtool_sset(mac->phy_dev, cmd);
++}
++
++static void mtk_get_drvinfo(struct net_device *dev,
++ struct ethtool_drvinfo *info)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++
++ strlcpy(info->driver, mac->hw->dev->driver->name, sizeof(info->driver));
++ strlcpy(info->bus_info, dev_name(mac->hw->dev), sizeof(info->bus_info));
++ info->n_stats = ARRAY_SIZE(mtk_ethtool_stats);
++}
++
++static u32 mtk_get_msglevel(struct net_device *dev)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++
++ return mac->hw->msg_enable;
++}
++
++static void mtk_set_msglevel(struct net_device *dev, u32 value)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++
++ mac->hw->msg_enable = value;
++}
++
++static int mtk_nway_reset(struct net_device *dev)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++
++ return genphy_restart_aneg(mac->phy_dev);
++}
++
++static u32 mtk_get_link(struct net_device *dev)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++ int err;
++
++ err = genphy_update_link(mac->phy_dev);
++ if (err)
++ return ethtool_op_get_link(dev);
++
++ return mac->phy_dev->link;
++}
++
++static void mtk_get_strings(struct net_device *dev, u32 stringset, u8 *data)
++{
++ int i;
++
++ switch (stringset) {
++ case ETH_SS_STATS:
++ for (i = 0; i < ARRAY_SIZE(mtk_ethtool_stats); i++) {
++ memcpy(data, mtk_ethtool_stats[i].str, ETH_GSTRING_LEN);
++ data += ETH_GSTRING_LEN;
++ }
++ break;
++ }
++}
++
++static int mtk_get_sset_count(struct net_device *dev, int sset)
++{
++ switch (sset) {
++ case ETH_SS_STATS:
++ return ARRAY_SIZE(mtk_ethtool_stats);
++ default:
++ return -EOPNOTSUPP;
++ }
++}
++
++static void mtk_get_ethtool_stats(struct net_device *dev,
++ struct ethtool_stats *stats, u64 *data)
++{
++ struct mtk_mac *mac = netdev_priv(dev);
++ struct mtk_hw_stats *hwstats = mac->hw_stats;
++ u64 *data_src, *data_dst;
++ unsigned int start;
++ int i;
++
++ if (netif_running(dev) && netif_device_present(dev)) {
++ if (spin_trylock(&hwstats->stats_lock)) {
++ mtk_stats_update_mac(mac);
++ spin_unlock(&hwstats->stats_lock);
++ }
++ }
++
++ do {
++ data_src = (u64*)hwstats;
++ data_dst = data;
++ start = u64_stats_fetch_begin_irq(&hwstats->syncp);
++
++ for (i = 0; i < ARRAY_SIZE(mtk_ethtool_stats); i++)
++ *data_dst++ = *(data_src + mtk_ethtool_stats[i].offset);
++ } while (u64_stats_fetch_retry_irq(&hwstats->syncp, start));
++}
++
++static struct ethtool_ops mtk_ethtool_ops = {
++ .get_settings = mtk_get_settings,
++ .set_settings = mtk_set_settings,
++ .get_drvinfo = mtk_get_drvinfo,
++ .get_msglevel = mtk_get_msglevel,
++ .set_msglevel = mtk_set_msglevel,
++ .nway_reset = mtk_nway_reset,
++ .get_link = mtk_get_link,
++ .get_strings = mtk_get_strings,
++ .get_sset_count = mtk_get_sset_count,
++ .get_ethtool_stats = mtk_get_ethtool_stats,
++};
++
++static const struct net_device_ops mtk_netdev_ops = {
++ .ndo_init = mtk_init,
++ .ndo_uninit = mtk_uninit,
++ .ndo_open = mtk_open,
++ .ndo_stop = mtk_stop,
++ .ndo_start_xmit = mtk_start_xmit,
++ .ndo_set_mac_address = mtk_set_mac_address,
++ .ndo_validate_addr = eth_validate_addr,
++ .ndo_do_ioctl = mtk_do_ioctl,
++ .ndo_change_mtu = eth_change_mtu,
++ .ndo_tx_timeout = mtk_tx_timeout,
++ .ndo_get_stats64 = mtk_get_stats64,
++#ifdef CONFIG_NET_POLL_CONTROLLER
++ .ndo_poll_controller = mtk_poll_controller,
++#endif
++};
++
++static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
++{
++ struct mtk_mac *mac;
++ const __be32 *_id = of_get_property(np, "reg", NULL);
++ int id, err;
++
++ if (!_id) {
++ dev_err(eth->dev, "missing mac id\n");
++ return -EINVAL;
++ }
++
++ id = be32_to_cpup(_id);
++ if (id >= MTK_MAC_COUNT) {
++ dev_err(eth->dev, "%d is not a valid mac id\n", id);
++ return -EINVAL;
++ }
++
++ if (eth->netdev[id]) {
++ dev_err(eth->dev, "duplicate mac id found: %d\n", id);
++ return -EINVAL;
++ }
++
++ eth->netdev[id] = alloc_etherdev(sizeof(*mac));
++ if (!eth->netdev[id]) {
++ dev_err(eth->dev, "alloc_etherdev failed\n");
++ return -ENOMEM;
++ }
++ mac = netdev_priv(eth->netdev[id]);
++ eth->mac[id] = mac;
++ mac->id = id;
++ mac->hw = eth;
++ mac->of_node = np;
++ INIT_WORK(&mac->pending_work, mtk_pending_work);
++
++ mac->hw_stats = devm_kzalloc(eth->dev,
++ sizeof(*mac->hw_stats),
++ GFP_KERNEL);
++ if (!mac->hw_stats) {
++ dev_err(eth->dev, "failed to allocate counter memory\n");
++ err = -ENOMEM;
++ goto free_netdev;
++ }
++ spin_lock_init(&mac->hw_stats->stats_lock);
++ mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
++
++ SET_NETDEV_DEV(eth->netdev[id], eth->dev);
++ eth->netdev[id]->netdev_ops = &mtk_netdev_ops;
++ eth->netdev[id]->base_addr = (unsigned long)eth->base;
++ eth->netdev[id]->vlan_features = MTK_HW_FEATURES &
++ ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX);
++ eth->netdev[id]->features |= MTK_HW_FEATURES;
++ eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops;
++
++ err = register_netdev(eth->netdev[id]);
++ if (err) {
++ dev_err(eth->dev, "error bringing up device\n");
++ goto free_netdev;
++ }
++ eth->netdev[id]->irq = eth->irq;
++ netif_info(eth, probe, eth->netdev[id],
++ "mediatek frame engine at 0x%08lx, irq %d\n",
++ eth->netdev[id]->base_addr, eth->netdev[id]->irq);
++
++ return 0;
++
++free_netdev:
++ free_netdev(eth->netdev[id]);
++ return err;
++}
++
++static int mtk_probe(struct platform_device *pdev)
++{
++ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ struct device_node *mac_np;
++ const struct of_device_id *match;
++ struct mtk_soc_data *soc;
++ struct mtk_eth *eth;
++ int err;
++
++ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
++ pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
++
++ device_reset(&pdev->dev);
++
++ match = of_match_device(of_mtk_match, &pdev->dev);
++ soc = (struct mtk_soc_data *)match->data;
++
++ eth = devm_kzalloc(&pdev->dev, sizeof(*eth), GFP_KERNEL);
++ if (!eth)
++ return -ENOMEM;
++
++ eth->base = devm_ioremap_resource(&pdev->dev, res);
++ if (!eth->base)
++ return -EADDRNOTAVAIL;
++
++ spin_lock_init(&eth->page_lock);
++
++ eth->ethsys = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
++ "mediatek,ethsys");
++ if (IS_ERR(eth->ethsys)) {
++ dev_err(&pdev->dev, "no ethsys regmap found\n");
++ return PTR_ERR(eth->ethsys);
++ }
++
++ eth->pctl = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
++ "mediatek,pctl");
++ if (IS_ERR(eth->pctl)) {
++ dev_err(&pdev->dev, "no pctl regmap found\n");
++ return PTR_ERR(eth->pctl);
++ }
++
++ eth->rstc = devm_reset_control_get(&pdev->dev, "eth");
++ if (IS_ERR(eth->rstc)) {
++ dev_err(&pdev->dev, "no eth reset found\n");
++ return PTR_ERR(eth->rstc);
++ }
++
++ eth->irq = platform_get_irq(pdev, 0);
++ if (eth->irq < 0) {
++ dev_err(&pdev->dev, "no IRQ resource found\n");
++ return -ENXIO;
++ }
++
++ eth->clk_ethif = devm_clk_get(&pdev->dev, "ethif");
++ eth->clk_esw = devm_clk_get(&pdev->dev, "esw");
++ eth->clk_gp1 = devm_clk_get(&pdev->dev, "gp1");
++ eth->clk_gp2 = devm_clk_get(&pdev->dev, "gp2");
++ if (IS_ERR(eth->clk_esw) || IS_ERR(eth->clk_gp1) ||
++ IS_ERR(eth->clk_gp2) || IS_ERR(eth->clk_ethif))
++ return -ENODEV;
++
++ clk_prepare_enable(eth->clk_ethif);
++ clk_prepare_enable(eth->clk_esw);
++ clk_prepare_enable(eth->clk_gp1);
++ clk_prepare_enable(eth->clk_gp2);
++
++ eth->dev = &pdev->dev;
++ eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE);
++
++ err = mtk_hw_init(eth);
++ if (err)
++ return err;
++
++ for_each_child_of_node(pdev->dev.of_node, mac_np) {
++ if (!of_device_is_compatible(mac_np,
++ "mediatek,eth-mac"))
++ continue;
++
++ if (!of_device_is_available(mac_np))
++ continue;
++
++ err = mtk_add_mac(eth, mac_np);
++ if (err)
++ goto err_free_dev;
++ }
++
++ /* we run 2 devices on the same DMA ring so we need a dummy device
++ * for NAPI to work
++ */
++ init_dummy_netdev(&eth->dummy_dev);
++ netif_napi_add(&eth->dummy_dev, &eth->rx_napi, mtk_poll,
++ MTK_NAPI_WEIGHT);
++
++ platform_set_drvdata(pdev, eth);
++
++ return 0;
++
++err_free_dev:
++ mtk_cleanup(eth);
++ return err;
++}
++
++static int mtk_remove(struct platform_device *pdev)
++{
++ struct mtk_eth *eth = platform_get_drvdata(pdev);
++
++ clk_disable_unprepare(eth->clk_ethif);
++ clk_disable_unprepare(eth->clk_esw);
++ clk_disable_unprepare(eth->clk_gp1);
++ clk_disable_unprepare(eth->clk_gp2);
++
++ netif_napi_del(&eth->rx_napi);
++ mtk_cleanup(eth);
++ platform_set_drvdata(pdev, NULL);
++
++ return 0;
++}
++
++const struct of_device_id of_mtk_match[] = {
++ { .compatible = "mediatek,mt7623-eth" },
++ {},
++};
++
++static struct platform_driver mtk_driver = {
++ .probe = mtk_probe,
++ .remove = mtk_remove,
++ .driver = {
++ .name = "mtk_soc_eth",
++ .owner = THIS_MODULE,
++ .of_match_table = of_mtk_match,
++ },
++};
++
++module_platform_driver(mtk_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
++MODULE_DESCRIPTION("Ethernet driver for MediaTek SoC");
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+new file mode 100644
+index 0000000..48a5292
+--- /dev/null
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -0,0 +1,421 @@
++/* This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * Copyright (C) 2009-2016 John Crispin <blogic@openwrt.org>
++ * Copyright (C) 2009-2016 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2013-2016 Michael Lee <igvtee@gmail.com>
++ */
++
++#ifndef MTK_ETH_H
++#define MTK_ETH_H
++
++#define MTK_QDMA_PAGE_SIZE 2048
++#define MTK_MAX_RX_LENGTH 1536
++#define MTK_TX_DMA_BUF_LEN 0x3fff
++#define MTK_DMA_SIZE 256
++#define MTK_NAPI_WEIGHT 64
++#define MTK_MAC_COUNT 2
++#define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)
++#define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
++#define MTK_DMA_DUMMY_DESC 0xffffffff
++#define MTK_DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | \
++ NETIF_MSG_PROBE | \
++ NETIF_MSG_LINK | \
++ NETIF_MSG_TIMER | \
++ NETIF_MSG_IFDOWN | \
++ NETIF_MSG_IFUP | \
++ NETIF_MSG_RX_ERR | \
++ NETIF_MSG_TX_ERR)
++#define MTK_HW_FEATURES (NETIF_F_IP_CSUM | \
++ NETIF_F_RXCSUM | \
++ NETIF_F_HW_VLAN_CTAG_TX | \
++ NETIF_F_HW_VLAN_CTAG_RX | \
++ NETIF_F_SG | NETIF_F_TSO | \
++ NETIF_F_TSO6 | \
++ NETIF_F_IPV6_CSUM)
++#define NEXT_RX_DESP_IDX(X) (((X) + 1) & (MTK_DMA_SIZE - 1))
++
++/* Frame Engine Global Reset Register */
++#define MTK_RST_GL 0x04
++#define RST_GL_PSE BIT(0)
++
++/* Frame Engine Interrupt Status Register */
++#define MTK_INT_STATUS2 0x08
++#define MTK_GDM1_AF BIT(28)
++#define MTK_GDM2_AF BIT(29)
++
++/* Frame Engine Interrupt Grouping Register */
++#define MTK_FE_INT_GRP 0x20
++
++/* CDMP Exgress Control Register */
++#define MTK_CDMP_EG_CTRL 0x404
++
++/* GDM Exgress Control Register */
++#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000))
++#define MTK_GDMA_ICS_EN BIT(22)
++#define MTK_GDMA_TCS_EN BIT(21)
++#define MTK_GDMA_UCS_EN BIT(20)
++
++/* Unicast Filter MAC Address Register - Low */
++#define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000))
++
++/* Unicast Filter MAC Address Register - High */
++#define MTK_GDMA_MAC_ADRH(x) (0x50C + (x * 0x1000))
++
++/* QDMA TX Queue Configuration Registers */
++#define MTK_QTX_CFG(x) (0x1800 + (x * 0x10))
++#define QDMA_RES_THRES 4
++
++/* QDMA TX Queue Scheduler Registers */
++#define MTK_QTX_SCH(x) (0x1804 + (x * 0x10))
++
++/* QDMA RX Base Pointer Register */
++#define MTK_QRX_BASE_PTR0 0x1900
++
++/* QDMA RX Maximum Count Register */
++#define MTK_QRX_MAX_CNT0 0x1904
++
++/* QDMA RX CPU Pointer Register */
++#define MTK_QRX_CRX_IDX0 0x1908
++
++/* QDMA RX DMA Pointer Register */
++#define MTK_QRX_DRX_IDX0 0x190C
++
++/* QDMA Global Configuration Register */
++#define MTK_QDMA_GLO_CFG 0x1A04
++#define MTK_RX_2B_OFFSET BIT(31)
++#define MTK_RX_BT_32DWORDS (3 << 11)
++#define MTK_TX_WB_DDONE BIT(6)
++#define MTK_DMA_SIZE_16DWORDS (2 << 4)
++#define MTK_RX_DMA_BUSY BIT(3)
++#define MTK_TX_DMA_BUSY BIT(1)
++#define MTK_RX_DMA_EN BIT(2)
++#define MTK_TX_DMA_EN BIT(0)
++#define MTK_DMA_BUSY_TIMEOUT HZ
++
++/* QDMA Reset Index Register */
++#define MTK_QDMA_RST_IDX 0x1A08
++#define MTK_PST_DRX_IDX0 BIT(16)
++
++/* QDMA Delay Interrupt Register */
++#define MTK_QDMA_DELAY_INT 0x1A0C
++
++/* QDMA Flow Control Register */
++#define MTK_QDMA_FC_THRES 0x1A10
++#define FC_THRES_DROP_MODE BIT(20)
++#define FC_THRES_DROP_EN (7 << 16)
++#define FC_THRES_MIN 0x4444
++
++/* QDMA Interrupt Status Register */
++#define MTK_QMTK_INT_STATUS 0x1A18
++#define MTK_RX_DONE_INT1 BIT(17)
++#define MTK_RX_DONE_INT0 BIT(16)
++#define MTK_TX_DONE_INT3 BIT(3)
++#define MTK_TX_DONE_INT2 BIT(2)
++#define MTK_TX_DONE_INT1 BIT(1)
++#define MTK_TX_DONE_INT0 BIT(0)
++#define MTK_RX_DONE_INT (MTK_RX_DONE_INT0 | MTK_RX_DONE_INT1)
++#define MTK_TX_DONE_INT (MTK_TX_DONE_INT0 | MTK_TX_DONE_INT1 | \
++ MTK_TX_DONE_INT2 | MTK_TX_DONE_INT3)
++
++/* QDMA Interrupt Status Register */
++#define MTK_QDMA_INT_MASK 0x1A1C
++
++/* QDMA Interrupt Mask Register */
++#define MTK_QDMA_HRED2 0x1A44
++
++/* QDMA TX Forward CPU Pointer Register */
++#define MTK_QTX_CTX_PTR 0x1B00
++
++/* QDMA TX Forward DMA Pointer Register */
++#define MTK_QTX_DTX_PTR 0x1B04
++
++/* QDMA TX Release CPU Pointer Register */
++#define MTK_QTX_CRX_PTR 0x1B10
++
++/* QDMA TX Release DMA Pointer Register */
++#define MTK_QTX_DRX_PTR 0x1B14
++
++/* QDMA FQ Head Pointer Register */
++#define MTK_QDMA_FQ_HEAD 0x1B20
++
++/* QDMA FQ Head Pointer Register */
++#define MTK_QDMA_FQ_TAIL 0x1B24
++
++/* QDMA FQ Free Page Counter Register */
++#define MTK_QDMA_FQ_CNT 0x1B28
++
++/* QDMA FQ Free Page Buffer Length Register */
++#define MTK_QDMA_FQ_BLEN 0x1B2C
++
++/* GMA1 Received Good Byte Count Register */
++#define MTK_GDM1_TX_GBCNT 0x2400
++#define MTK_STAT_OFFSET 0x40
++
++/* QDMA descriptor txd4 */
++#define TX_DMA_CHKSUM (0x7 << 29)
++#define TX_DMA_TSO BIT(28)
++#define TX_DMA_FPORT_SHIFT 25
++#define TX_DMA_FPORT_MASK 0x7
++#define TX_DMA_INS_VLAN BIT(16)
++
++/* QDMA descriptor txd3 */
++#define TX_DMA_OWNER_CPU BIT(31)
++#define TX_DMA_LS0 BIT(30)
++#define TX_DMA_PLEN0(_x) (((_x) & MTK_TX_DMA_BUF_LEN) << 16)
++#define TX_DMA_SWC BIT(14)
++#define TX_DMA_SDL(_x) (((_x) & 0x3fff) << 16)
++
++/* QDMA descriptor rxd2 */
++#define RX_DMA_DONE BIT(31)
++#define RX_DMA_PLEN0(_x) (((_x) & 0x3fff) << 16)
++#define RX_DMA_GET_PLEN0(_x) (((_x) >> 16) & 0x3fff)
++
++/* QDMA descriptor rxd3 */
++#define RX_DMA_VID(_x) ((_x) & 0xfff)
++
++/* QDMA descriptor rxd4 */
++#define RX_DMA_L4_VALID BIT(24)
++#define RX_DMA_FPORT_SHIFT 19
++#define RX_DMA_FPORT_MASK 0x7
++
++/* PHY Indirect Access Control registers */
++#define MTK_PHY_IAC 0x10004
++#define PHY_IAC_ACCESS BIT(31)
++#define PHY_IAC_READ BIT(19)
++#define PHY_IAC_WRITE BIT(18)
++#define PHY_IAC_START BIT(16)
++#define PHY_IAC_ADDR_SHIFT 20
++#define PHY_IAC_REG_SHIFT 25
++#define PHY_IAC_TIMEOUT HZ
++
++/* Mac control registers */
++#define MTK_MAC_MCR(x) (0x10100 + (x * 0x100))
++#define MAC_MCR_MAX_RX_1536 BIT(24)
++#define MAC_MCR_IPG_CFG (BIT(18) | BIT(16))
++#define MAC_MCR_FORCE_MODE BIT(15)
++#define MAC_MCR_TX_EN BIT(14)
++#define MAC_MCR_RX_EN BIT(13)
++#define MAC_MCR_BACKOFF_EN BIT(9)
++#define MAC_MCR_BACKPR_EN BIT(8)
++#define MAC_MCR_FORCE_RX_FC BIT(5)
++#define MAC_MCR_FORCE_TX_FC BIT(4)
++#define MAC_MCR_SPEED_1000 BIT(3)
++#define MAC_MCR_SPEED_100 BIT(2)
++#define MAC_MCR_FORCE_DPX BIT(1)
++#define MAC_MCR_FORCE_LINK BIT(0)
++#define MAC_MCR_FIXED_LINK (MAC_MCR_MAX_RX_1536 | MAC_MCR_IPG_CFG | \
++ MAC_MCR_FORCE_MODE | MAC_MCR_TX_EN | \
++ MAC_MCR_RX_EN | MAC_MCR_BACKOFF_EN | \
++ MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_RX_FC | \
++ MAC_MCR_FORCE_TX_FC | MAC_MCR_SPEED_1000 | \
++ MAC_MCR_FORCE_DPX | MAC_MCR_FORCE_LINK)
++
++/* GPIO port control registers for GMAC 2*/
++#define GPIO_OD33_CTRL8 0x4c0
++#define GPIO_BIAS_CTRL 0xed0
++#define GPIO_DRV_SEL10 0xf00
++
++/* ethernet subsystem config register */
++#define ETHSYS_SYSCFG0 0x14
++#define SYSCFG0_GE_MASK 0x3
++#define SYSCFG0_GE_MODE(x, y) (x << (12 + (y * 2)))
++
++struct mtk_rx_dma {
++ unsigned int rxd1;
++ unsigned int rxd2;
++ unsigned int rxd3;
++ unsigned int rxd4;
++} __packed __aligned(4);
++
++struct mtk_tx_dma {
++ unsigned int txd1;
++ unsigned int txd2;
++ unsigned int txd3;
++ unsigned int txd4;
++} __packed __aligned(4);
++
++struct mtk_eth;
++struct mtk_mac;
++
++/* struct mtk_hw_stats - the structure that holds the traffic statistics.
++ * @stats_lock: make sure that stats operations are atomic
++ * @reg_offset: the status register offset of the SoC
++ * @syncp: the refcount
++ *
++ * All of the supported SoCs have hardware counters for traffic statistics.
++ * Whenever the status IRQ triggers we can read the latest stats from these
++ * counters and store them in this struct.
++ */
++struct mtk_hw_stats {
++ u64 tx_bytes;
++ u64 tx_packets;
++ u64 tx_skip;
++ u64 tx_collisions;
++ u64 rx_bytes;
++ u64 rx_packets;
++ u64 rx_overflow;
++ u64 rx_fcs_errors;
++ u64 rx_short_errors;
++ u64 rx_long_errors;
++ u64 rx_checksum_errors;
++ u64 rx_flow_control_packets;
++
++ spinlock_t stats_lock;
++ u32 reg_offset;
++ struct u64_stats_sync syncp;
++};
++
++/* PDMA descriptor can point at 1-2 segments. This enum allows us to track how
++ * memory was allocated so that it can be freed properly
++ */
++enum mtk_tx_flags {
++ MTK_TX_FLAGS_SINGLE0 = 0x01,
++ MTK_TX_FLAGS_PAGE0 = 0x02,
++};
++
++/* struct mtk_tx_buf - This struct holds the pointers to the memory pointed at
++ * by the TX descriptor s
++ * @skb: The SKB pointer of the packet being sent
++ * @dma_addr0: The base addr of the first segment
++ * @dma_len0: The length of the first segment
++ * @dma_addr1: The base addr of the second segment
++ * @dma_len1: The length of the second segment
++ */
++struct mtk_tx_buf {
++ struct sk_buff *skb;
++ u32 flags;
++ DEFINE_DMA_UNMAP_ADDR(dma_addr0);
++ DEFINE_DMA_UNMAP_LEN(dma_len0);
++ DEFINE_DMA_UNMAP_ADDR(dma_addr1);
++ DEFINE_DMA_UNMAP_LEN(dma_len1);
++};
++
++/* struct mtk_tx_ring - This struct holds info describing a TX ring
++ * @dma: The descriptor ring
++ * @buf: The memory pointed at by the ring
++ * @phys: The physical addr of tx_buf
++ * @next_free: Pointer to the next free descriptor
++ * @last_free: Pointer to the last free descriptor
++ * @thresh: The threshold of minimum amount of free descriptors
++ * @free_count: QDMA uses a linked list. Track how many free descriptors
++ * are present
++ */
++struct mtk_tx_ring {
++ struct mtk_tx_dma *dma;
++ struct mtk_tx_buf *buf;
++ dma_addr_t phys;
++ struct mtk_tx_dma *next_free;
++ struct mtk_tx_dma *last_free;
++ u16 thresh;
++ atomic_t free_count;
++};
++
++/* struct mtk_rx_ring - This struct holds info describing a RX ring
++ * @dma: The descriptor ring
++ * @data: The memory pointed at by the ring
++ * @phys: The physical addr of rx_buf
++ * @frag_size: How big can each fragment be
++ * @buf_size: The size of each packet buffer
++ * @calc_idx: The current head of ring
++ */
++struct mtk_rx_ring {
++ struct mtk_rx_dma *dma;
++ u8 **data;
++ dma_addr_t phys;
++ u16 frag_size;
++ u16 buf_size;
++ u16 calc_idx;
++};
++
++/* currently no SoC has more than 2 macs */
++#define MTK_MAX_DEVS 2
++
++/* struct mtk_eth - This is the main datasructure for holding the state
++ * of the driver
++ * @dev: The device pointer
++ * @base: The mapped register i/o base
++ * @page_lock: Make sure that register operations are atomic
++ * @dummy_dev: we run 2 netdevs on 1 physical DMA ring and need a
++ * dummy for NAPI to work
++ * @netdev: The netdev instances
++ * @mac: Each netdev is linked to a physical MAC
++ * @irq: The IRQ that we are using
++ * @msg_enable: Ethtool msg level
++ * @ethsys: The register map pointing at the range used to setup
++ * MII modes
++ * @pctl: The register map pointing at the range used to setup
++ * GMAC port drive/slew values
++ * @dma_refcnt: track how many netdevs are using the DMA engine
++ * @tx_ring: Pointer to the memore holding info about the TX ring
++ * @rx_ring: Pointer to the memore holding info about the RX ring
++ * @rx_napi: The NAPI struct
++ * @scratch_ring: Newer SoCs need memory for a second HW managed TX ring
++ * @scratch_head: The scratch memory that scratch_ring points to.
++ * @clk_ethif: The ethif clock
++ * @clk_esw: The switch clock
++ * @clk_gp1: The gmac1 clock
++ * @clk_gp2: The gmac2 clock
++ * @mii_bus: If there is a bus we need to create an instance for it
++ */
++
++struct mtk_eth {
++ struct device *dev;
++ void __iomem *base;
++ struct reset_control *rstc;
++ spinlock_t page_lock;
++ struct net_device dummy_dev;
++ struct net_device *netdev[MTK_MAX_DEVS];
++ struct mtk_mac *mac[MTK_MAX_DEVS];
++ int irq;
++ u32 msg_enable;
++ unsigned long sysclk;
++ struct regmap *ethsys;
++ struct regmap *pctl;
++ atomic_t dma_refcnt;
++ struct mtk_tx_ring tx_ring;
++ struct mtk_rx_ring rx_ring;
++ struct napi_struct rx_napi;
++ struct mtk_tx_dma *scratch_ring;
++ void *scratch_head;
++ struct clk *clk_ethif;
++ struct clk *clk_esw;
++ struct clk *clk_gp1;
++ struct clk *clk_gp2;
++ struct mii_bus *mii_bus;
++};
++
++/* struct mtk_mac - the structure that holds the info about the MACs of the
++ * SoC
++ * @id: The number of the MAC
++ * @of_node: Our devicetree node
++ * @hw: Backpointer to our main datastruture
++ * @hw_stats: Packet statistics counter
++ * @phy_dev: The attached PHY if available
++ * @pending_work: The workqueue used to reset the dma ring
++ */
++struct mtk_mac {
++ int id;
++ struct device_node *of_node;
++ struct mtk_eth *hw;
++ struct mtk_hw_stats *hw_stats;
++ struct phy_device *phy_dev;
++ struct work_struct pending_work;
++};
++
++/* the struct describing the SoC. these are declared in the soc_xyz.c files */
++extern const struct of_device_id of_mtk_match[];
++
++/* read the hardware status register */
++void mtk_stats_update_mac(struct mtk_mac *mac);
++
++void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
++u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
++
++#endif /* MTK_ETH_H */
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0050-net-next-mediatek-add-Kconfig-and-Makefile.patch b/target/linux/mediatek/patches-4.4/0050-net-next-mediatek-add-Kconfig-and-Makefile.patch
new file mode 100644
index 0000000000..2358b6a8c0
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0050-net-next-mediatek-add-Kconfig-and-Makefile.patch
@@ -0,0 +1,78 @@
+From 093d38375d35e6fa0f54c2c30b517a73d8448710 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 2 Mar 2016 04:32:43 +0100
+Subject: [PATCH 50/53] net-next: mediatek: add Kconfig and Makefile
+
+This patch adds the Makefile and Kconfig required to make the driver build.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/net/ethernet/Kconfig | 1 +
+ drivers/net/ethernet/Makefile | 1 +
+ drivers/net/ethernet/mediatek/Kconfig | 17 +++++++++++++++++
+ drivers/net/ethernet/mediatek/Makefile | 5 +++++
+ 4 files changed, 24 insertions(+)
+ create mode 100644 drivers/net/ethernet/mediatek/Kconfig
+ create mode 100644 drivers/net/ethernet/mediatek/Makefile
+
+diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
+index 31c5e47..cd28b95 100644
+--- a/drivers/net/ethernet/Kconfig
++++ b/drivers/net/ethernet/Kconfig
+@@ -106,6 +106,7 @@ config LANTIQ_ETOP
+ Support for the MII0 inside the Lantiq SoC
+
+ source "drivers/net/ethernet/marvell/Kconfig"
++source "drivers/net/ethernet/mediatek/Kconfig"
+ source "drivers/net/ethernet/mellanox/Kconfig"
+ source "drivers/net/ethernet/micrel/Kconfig"
+ source "drivers/net/ethernet/microchip/Kconfig"
+diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
+index 071f84e..c62191f 100644
+--- a/drivers/net/ethernet/Makefile
++++ b/drivers/net/ethernet/Makefile
+@@ -46,6 +46,7 @@ obj-$(CONFIG_JME) += jme.o
+ obj-$(CONFIG_KORINA) += korina.o
+ obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o
+ obj-$(CONFIG_NET_VENDOR_MARVELL) += marvell/
++obj-$(CONFIG_NET_VENDOR_MEDIATEK) += mediatek/
+ obj-$(CONFIG_NET_VENDOR_MELLANOX) += mellanox/
+ obj-$(CONFIG_NET_VENDOR_MICREL) += micrel/
+ obj-$(CONFIG_NET_VENDOR_MICROCHIP) += microchip/
+diff --git a/drivers/net/ethernet/mediatek/Kconfig b/drivers/net/ethernet/mediatek/Kconfig
+new file mode 100644
+index 0000000..b0229f4
+--- /dev/null
++++ b/drivers/net/ethernet/mediatek/Kconfig
+@@ -0,0 +1,17 @@
++config NET_VENDOR_MEDIATEK
++ bool "MediaTek ethernet driver"
++ depends on ARCH_MEDIATEK
++ ---help---
++ If you have a Mediatek SoC with ethernet, say Y.
++
++if NET_VENDOR_MEDIATEK
++
++config NET_MEDIATEK_SOC
++ tristate "MediaTek MT7623 Gigabit ethernet support"
++ depends on NET_VENDOR_MEDIATEK #&& (MACH_MT7623 || MACH_MT2701)
++ select PHYLIB
++ ---help---
++ This driver supports the gigabit ethernet MACs in the
++ MediaTek MT2701/MT7623 chipset family.
++
++endif #NET_VENDOR_MEDIATEK
+diff --git a/drivers/net/ethernet/mediatek/Makefile b/drivers/net/ethernet/mediatek/Makefile
+new file mode 100644
+index 0000000..aa3f1c8
+--- /dev/null
++++ b/drivers/net/ethernet/mediatek/Makefile
+@@ -0,0 +1,5 @@
++#
++# Makefile for the Mediatek SoCs built-in ethernet macs
++#
++
++obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth_soc.o
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0051-net-next-mediatek-add-an-entry-to-MAINTAINERS.patch b/target/linux/mediatek/patches-4.4/0051-net-next-mediatek-add-an-entry-to-MAINTAINERS.patch
new file mode 100644
index 0000000000..deb6eff453
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0051-net-next-mediatek-add-an-entry-to-MAINTAINERS.patch
@@ -0,0 +1,34 @@
+From 3180cf4f325411f796468e12d524fe6354ded274 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 2 Mar 2016 04:34:04 +0100
+Subject: [PATCH 51/53] net-next: mediatek: add an entry to MAINTAINERS
+
+Add myself and Felix as the Maintainers for the MediaTek ethernet driver.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ MAINTAINERS | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 156e1d3..7737042 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -6908,6 +6908,13 @@ F: include/uapi/linux/meye.h
+ F: include/uapi/linux/ivtv*
+ F: include/uapi/linux/uvcvideo.h
+
++MEDIATEK ETHERNET DRIVER
++M: Felix Fietkau <nbd@openwrt.org>
++M: John Crispin <blogic@openwrt.org>
++L: netdev@vger.kernel.org
++S: Maintained
++F: drivers/net/ethernet/mediatek/
++
+ MEDIATEK MT7601U WIRELESS LAN DRIVER
+ M: Jakub Kicinski <kubakici@wp.pl>
+ L: linux-wireless@vger.kernel.org
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0052-net-out-of-tree-fixes.patch b/target/linux/mediatek/patches-4.4/0052-net-out-of-tree-fixes.patch
new file mode 100644
index 0000000000..10d9d71e06
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0052-net-out-of-tree-fixes.patch
@@ -0,0 +1,2409 @@
+From 242801fc94db9ceb1e3e2a8b19fb2c57122e53f3 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Mon, 21 Mar 2016 16:36:22 +0100
+Subject: [PATCH] net: out of tree fixes
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/arm/boot/dts/mt7623-evb.dts | 1 -
+ arch/arm/boot/dts/mt7623.dtsi | 40 +-
+ drivers/net/ethernet/mediatek/Makefile | 2 +-
+ drivers/net/ethernet/mediatek/gsw_mt7620.h | 250 +++++++
+ drivers/net/ethernet/mediatek/gsw_mt7623.c | 966 +++++++++++++++++++++++++++
+ drivers/net/ethernet/mediatek/mt7530.c | 808 ++++++++++++++++++++++
+ drivers/net/ethernet/mediatek/mt7530.h | 20 +
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 59 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 5 +
+ lib/dynamic_queue_limits.c | 6 +-
+ 10 files changed, 2110 insertions(+), 47 deletions(-)
+ create mode 100644 drivers/net/ethernet/mediatek/gsw_mt7620.h
+ create mode 100644 drivers/net/ethernet/mediatek/gsw_mt7623.c
+ create mode 100644 drivers/net/ethernet/mediatek/mt7530.c
+ create mode 100644 drivers/net/ethernet/mediatek/mt7530.h
+
+diff --git a/arch/arm/boot/dts/mt7623-evb.dts b/arch/arm/boot/dts/mt7623-evb.dts
+index 5e9381d..bc2b3f1 100644
+--- a/arch/arm/boot/dts/mt7623-evb.dts
++++ b/arch/arm/boot/dts/mt7623-evb.dts
+@@ -425,7 +425,6 @@
+ &usb1 {
+ vusb33-supply = <&mt6323_vusb_reg>;
+ vbus-supply = <&usb_p1_vbus>;
+-// mediatek,wakeup-src = <1>;
+ status = "okay";
+ };
+
+diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
+index 1ba7790..5926e14 100644
+--- a/arch/arm/boot/dts/mt7623.dtsi
++++ b/arch/arm/boot/dts/mt7623.dtsi
+@@ -440,23 +440,30 @@
+ };
+
+ ethsys: syscon@1b000000 {
+- #address-cells = <1>;
+- #size-cells = <1>;
+ compatible = "mediatek,mt2701-ethsys", "syscon";
+ reg = <0 0x1b000000 0 0x1000>;
++ #reset-cells = <1>;
+ #clock-cells = <1>;
+ };
+
+ eth: ethernet@1b100000 {
+ compatible = "mediatek,mt7623-eth";
+- reg = <0 0x1b100000 0 0x10000>;
++ reg = <0 0x1b100000 0 0x20000>;
+
+- clocks = <&topckgen CLK_TOP_ETHIF_SEL>;
+- clock-names = "ethif";
++ clocks = <&topckgen CLK_TOP_ETHIF_SEL>,
++ <&ethsys CLK_ETHSYS_ESW>,
++ <&ethsys CLK_ETHSYS_GP2>,
++ <&ethsys CLK_ETHSYS_GP1>;
++ clock-names = "ethif", "esw", "gp2", "gp1";
+ interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_LOW>;
+ power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
+
++ resets = <&ethsys 6>;
++ reset-names = "eth";
++
+ mediatek,ethsys = <&ethsys>;
++ mediatek,pctl = <&syscfg_pctl_a>;
++
+ mediatek,switch = <&gsw>;
+
+ #address-cells = <1>;
+@@ -468,6 +475,8 @@
+ compatible = "mediatek,eth-mac";
+ reg = <0>;
+
++ phy-handle = <&phy4>;
++
+ status = "disabled";
+ };
+
+@@ -475,6 +484,7 @@
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+
++ phy-handle = <&phy5>;
+ status = "disabled";
+ };
+
+@@ -482,6 +492,16 @@
+ #address-cells = <1>;
+ #size-cells = <0>;
+
++ phy4: ethernet-phy@4 {
++ reg = <4>;
++ phy-mode = "rgmii";
++ };
++
++ phy5: ethernet-phy@5 {
++ reg = <5>;
++ phy-mode = "rgmii";
++ };
++
+ phy1f: ethernet-phy@1f {
+ reg = <0x1f>;
+ phy-mode = "rgmii";
+@@ -491,14 +511,12 @@
+
+ gsw: switch@1b100000 {
+ compatible = "mediatek,mt7623-gsw";
+- reg = <0 0x1b110000 0 0x300000>;
+ interrupt-parent = <&pio>;
+ interrupts = <168 IRQ_TYPE_EDGE_RISING>;
+- clocks = <&apmixedsys CLK_APMIXED_TRGPLL>,
+- <&ethsys CLK_ETHSYS_ESW>,
+- <&ethsys CLK_ETHSYS_GP2>,
+- <&ethsys CLK_ETHSYS_GP1>;
+- clock-names = "trgpll", "esw", "gp2", "gp1";
++ resets = <&ethsys 2>;
++ reset-names = "eth";
++ clocks = <&apmixedsys CLK_APMIXED_TRGPLL>;
++ clock-names = "trgpll";
+ mt7530-supply = <&mt6323_vpa_reg>;
+ mediatek,pctl-regmap = <&syscfg_pctl_a>;
+ mediatek,ethsys = <&ethsys>;
+diff --git a/drivers/net/ethernet/mediatek/Makefile b/drivers/net/ethernet/mediatek/Makefile
+index aa3f1c8..82001c4 100644
+--- a/drivers/net/ethernet/mediatek/Makefile
++++ b/drivers/net/ethernet/mediatek/Makefile
+@@ -2,4 +2,4 @@
+ # Makefile for the Mediatek SoCs built-in ethernet macs
+ #
+
+-obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth_soc.o
++obj-$(CONFIG_NET_MEDIATEK_SOC) += mt7530.o gsw_mt7623.o mtk_eth_soc.o
+diff --git a/drivers/net/ethernet/mediatek/gsw_mt7620.h b/drivers/net/ethernet/mediatek/gsw_mt7620.h
+new file mode 100644
+index 0000000..7013803
+--- /dev/null
++++ b/drivers/net/ethernet/mediatek/gsw_mt7620.h
+@@ -0,0 +1,250 @@
++/* This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * Copyright (C) 2009-2016 John Crispin <blogic@openwrt.org>
++ * Copyright (C) 2009-2016 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2013-2016 Michael Lee <igvtee@gmail.com>
++ */
++
++#ifndef _RALINK_GSW_MT7620_H__
++#define _RALINK_GSW_MT7620_H__
++
++#define GSW_REG_PHY_TIMEOUT (5 * HZ)
++
++#define MT7620_GSW_REG_PIAC 0x0004
++
++#define GSW_NUM_VLANS 16
++#define GSW_NUM_VIDS 4096
++#define GSW_NUM_PORTS 7
++#define GSW_PORT6 6
++
++#define GSW_MDIO_ACCESS BIT(31)
++#define GSW_MDIO_READ BIT(19)
++#define GSW_MDIO_WRITE BIT(18)
++#define GSW_MDIO_START BIT(16)
++#define GSW_MDIO_ADDR_SHIFT 20
++#define GSW_MDIO_REG_SHIFT 25
++
++#define GSW_REG_PORT_PMCR(x) (0x3000 + (x * 0x100))
++#define GSW_REG_PORT_STATUS(x) (0x3008 + (x * 0x100))
++#define GSW_REG_SMACCR0 0x3fE4
++#define GSW_REG_SMACCR1 0x3fE8
++#define GSW_REG_CKGCR 0x3ff0
++
++#define GSW_REG_IMR 0x7008
++#define GSW_REG_ISR 0x700c
++#define GSW_REG_GPC1 0x7014
++
++#define SYSC_REG_CHIP_REV_ID 0x0c
++#define SYSC_REG_CFG 0x10
++#define SYSC_REG_CFG1 0x14
++#define RST_CTRL_MCM BIT(2)
++#define SYSC_PAD_RGMII2_MDIO 0x58
++#define SYSC_GPIO_MODE 0x60
++
++#define PORT_IRQ_ST_CHG 0x7f
++
++#define MT7621_ESW_PHY_POLLING 0x0000
++#define MT7620_ESW_PHY_POLLING 0x7000
++
++#define PMCR_IPG BIT(18)
++#define PMCR_MAC_MODE BIT(16)
++#define PMCR_FORCE BIT(15)
++#define PMCR_TX_EN BIT(14)
++#define PMCR_RX_EN BIT(13)
++#define PMCR_BACKOFF BIT(9)
++#define PMCR_BACKPRES BIT(8)
++#define PMCR_RX_FC BIT(5)
++#define PMCR_TX_FC BIT(4)
++#define PMCR_SPEED(_x) (_x << 2)
++#define PMCR_DUPLEX BIT(1)
++#define PMCR_LINK BIT(0)
++
++#define PHY_AN_EN BIT(31)
++#define PHY_PRE_EN BIT(30)
++#define PMY_MDC_CONF(_x) ((_x & 0x3f) << 24)
++
++/* ethernet subsystem config register */
++#define ETHSYS_SYSCFG0 0x14
++/* ethernet subsystem clock register */
++#define ETHSYS_CLKCFG0 0x2c
++#define ETHSYS_TRGMII_CLK_SEL362_5 BIT(11)
++
++/* p5 RGMII wrapper TX clock control register */
++#define MT7530_P5RGMIITXCR 0x7b04
++/* p5 RGMII wrapper RX clock control register */
++#define MT7530_P5RGMIIRXCR 0x7b00
++/* TRGMII TDX ODT registers */
++#define MT7530_TRGMII_TD0_ODT 0x7a54
++#define MT7530_TRGMII_TD1_ODT 0x7a5c
++#define MT7530_TRGMII_TD2_ODT 0x7a64
++#define MT7530_TRGMII_TD3_ODT 0x7a6c
++#define MT7530_TRGMII_TD4_ODT 0x7a74
++#define MT7530_TRGMII_TD5_ODT 0x7a7c
++/* TRGMII TCK ctrl register */
++#define MT7530_TRGMII_TCK_CTRL 0x7a78
++/* TRGMII Tx ctrl register */
++#define MT7530_TRGMII_TXCTRL 0x7a40
++/* port 6 extended control register */
++#define MT7530_P6ECR 0x7830
++/* IO driver control register */
++#define MT7530_IO_DRV_CR 0x7810
++/* top signal control register */
++#define MT7530_TOP_SIG_CTRL 0x7808
++/* modified hwtrap register */
++#define MT7530_MHWTRAP 0x7804
++/* hwtrap status register */
++#define MT7530_HWTRAP 0x7800
++/* status interrupt register */
++#define MT7530_SYS_INT_STS 0x700c
++/* system nterrupt register */
++#define MT7530_SYS_INT_EN 0x7008
++/* system control register */
++#define MT7530_SYS_CTRL 0x7000
++/* port MAC status register */
++#define MT7530_PMSR_P(x) (0x3008 + (x * 0x100))
++/* port MAC control register */
++#define MT7530_PMCR_P(x) (0x3000 + (x * 0x100))
++
++#define MT7621_XTAL_SHIFT 6
++#define MT7621_XTAL_MASK 0x7
++#define MT7621_XTAL_25 6
++#define MT7621_XTAL_40 3
++#define MT7621_MDIO_DRV_MASK (3 << 4)
++#define MT7621_GE1_MODE_MASK (3 << 12)
++
++#define TRGMII_TXCTRL_TXC_INV BIT(30)
++#define P6ECR_INTF_MODE_RGMII BIT(1)
++#define P5RGMIIRXCR_C_ALIGN BIT(8)
++#define P5RGMIIRXCR_DELAY_2 BIT(1)
++#define P5RGMIITXCR_DELAY_2 (BIT(8) | BIT(2))
++
++/* TOP_SIG_CTRL bits */
++#define TOP_SIG_CTRL_NORMAL (BIT(17) | BIT(16))
++
++/* MHWTRAP bits */
++#define MHWTRAP_MANUAL BIT(16)
++#define MHWTRAP_P5_MAC_SEL BIT(13)
++#define MHWTRAP_P6_DIS BIT(8)
++#define MHWTRAP_P5_RGMII_MODE BIT(7)
++#define MHWTRAP_P5_DIS BIT(6)
++#define MHWTRAP_PHY_ACCESS BIT(5)
++
++/* HWTRAP bits */
++#define HWTRAP_XTAL_SHIFT 9
++#define HWTRAP_XTAL_MASK 0x3
++
++/* SYS_CTRL bits */
++#define SYS_CTRL_SW_RST BIT(1)
++#define SYS_CTRL_REG_RST BIT(0)
++
++/* PMCR bits */
++#define PMCR_IFG_XMIT_96 BIT(18)
++#define PMCR_MAC_MODE BIT(16)
++#define PMCR_FORCE_MODE BIT(15)
++#define PMCR_TX_EN BIT(14)
++#define PMCR_RX_EN BIT(13)
++#define PMCR_BACK_PRES_EN BIT(9)
++#define PMCR_BACKOFF_EN BIT(8)
++#define PMCR_TX_FC_EN BIT(5)
++#define PMCR_RX_FC_EN BIT(4)
++#define PMCR_FORCE_SPEED_1000 BIT(3)
++#define PMCR_FORCE_FDX BIT(1)
++#define PMCR_FORCE_LNK BIT(0)
++#define PMCR_FIXED_LINK (PMCR_IFG_XMIT_96 | PMCR_MAC_MODE | \
++ PMCR_FORCE_MODE | PMCR_TX_EN | PMCR_RX_EN | \
++ PMCR_BACK_PRES_EN | PMCR_BACKOFF_EN | \
++ PMCR_FORCE_SPEED_1000 | PMCR_FORCE_FDX | \
++ PMCR_FORCE_LNK)
++
++#define PMCR_FIXED_LINK_FC (PMCR_FIXED_LINK | \
++ PMCR_TX_FC_EN | PMCR_RX_FC_EN)
++
++/* TRGMII control registers */
++#define GSW_INTF_MODE 0x390
++#define GSW_TRGMII_TD0_ODT 0x354
++#define GSW_TRGMII_TD1_ODT 0x35c
++#define GSW_TRGMII_TD2_ODT 0x364
++#define GSW_TRGMII_TD3_ODT 0x36c
++#define GSW_TRGMII_TXCTL_ODT 0x374
++#define GSW_TRGMII_TCK_ODT 0x37c
++#define GSW_TRGMII_RCK_CTRL 0x300
++
++#define INTF_MODE_TRGMII BIT(1)
++#define TRGMII_RCK_CTRL_RX_RST BIT(31)
++
++
++/* possible XTAL speed */
++#define MT7623_XTAL_40 0
++#define MT7623_XTAL_20 1
++#define MT7623_XTAL_25 3
++
++/* GPIO port control registers */
++#define GPIO_OD33_CTRL8 0x4c0
++#define GPIO_BIAS_CTRL 0xed0
++#define GPIO_DRV_SEL10 0xf00
++
++/* on MT7620 the functio of port 4 can be software configured */
++enum {
++ PORT4_EPHY = 0,
++ PORT4_EXT,
++};
++
++/* struct mt7620_gsw - the structure that holds the SoC specific data
++ * @dev: The Device struct
++ * @base: The base address
++ * @piac_offset: The PIAC base may change depending on SoC
++ * @irq: The IRQ we are using
++ * @port4: The port4 mode on MT7620
++ * @autopoll: Is MDIO autopolling enabled
++ * @ethsys: The ethsys register map
++ * @pctl: The pin control register map
++ * @clk_trgpll: The trgmii pll clock
++ */
++struct mt7620_gsw {
++ struct mtk_eth *eth;
++ struct device *dev;
++ void __iomem *base;
++ u32 piac_offset;
++ int irq;
++ int port4;
++ unsigned long int autopoll;
++
++ struct regmap *ethsys;
++ struct regmap *pctl;
++
++ struct clk *clk_trgpll;
++
++ int trgmii_force;
++};
++
++/* switch register I/O wrappers */
++void mtk_switch_w32(struct mt7620_gsw *gsw, u32 val, unsigned reg);
++u32 mtk_switch_r32(struct mt7620_gsw *gsw, unsigned reg);
++
++/* the callback used by the driver core to bringup the switch */
++int mtk_gsw_init(struct mtk_eth *eth);
++
++/* MDIO access wrappers */
++int mt7620_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val);
++int mt7620_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg);
++void mt7620_mdio_link_adjust(struct mtk_eth *eth, int port);
++int mt7620_has_carrier(struct mtk_eth *eth);
++void mt7620_print_link_state(struct mtk_eth *eth, int port, int link,
++ int speed, int duplex);
++void mt7530_mdio_w32(struct mt7620_gsw *gsw, u32 reg, u32 val);
++u32 mt7530_mdio_r32(struct mt7620_gsw *gsw, u32 reg);
++void mt7530_mdio_m32(struct mt7620_gsw *gsw, u32 mask, u32 set, u32 reg);
++
++u32 _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr,
++ u32 phy_register, u32 write_data);
++u32 _mtk_mdio_read(struct mtk_eth *eth, int phy_addr, int phy_reg);
++void mt7620_handle_carrier(struct mtk_eth *eth);
++
++#endif
+diff --git a/drivers/net/ethernet/mediatek/gsw_mt7623.c b/drivers/net/ethernet/mediatek/gsw_mt7623.c
+new file mode 100644
+index 0000000..78c36c7
+--- /dev/null
++++ b/drivers/net/ethernet/mediatek/gsw_mt7623.c
+@@ -0,0 +1,966 @@
++/* This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; version 2 of the License
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * Copyright (C) 2009-2016 John Crispin <blogic@openwrt.org>
++ * Copyright (C) 2009-2016 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2013-2016 Michael Lee <igvtee@gmail.com>
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/platform_device.h>
++#include <linux/of_device.h>
++#include <linux/of_irq.h>
++#include <linux/of_gpio.h>
++#include <linux/clk.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regulator/consumer.h>
++#include <linux/pm_runtime.h>
++#include <linux/regmap.h>
++#include <linux/reset.h>
++#include <linux/mii.h>
++#include <linux/interrupt.h>
++#include <linux/netdevice.h>
++#include <linux/dma-mapping.h>
++#include <linux/phy.h>
++#include <linux/ethtool.h>
++#include <linux/version.h>
++#include <linux/atomic.h>
++
++#include "mtk_eth_soc.h"
++#include "gsw_mt7620.h"
++#include "mt7530.h"
++
++void mt7530_mdio_w32(struct mt7620_gsw *gsw, u32 reg, u32 val)
++{
++ _mtk_mdio_write(gsw->eth, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
++ _mtk_mdio_write(gsw->eth, 0x1f, (reg >> 2) & 0xf, val & 0xffff);
++ _mtk_mdio_write(gsw->eth, 0x1f, 0x10, val >> 16);
++}
++
++u32 mt7530_mdio_r32(struct mt7620_gsw *gsw, u32 reg)
++{
++ u16 high, low;
++
++ _mtk_mdio_write(gsw->eth, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
++ low = _mtk_mdio_read(gsw->eth, 0x1f, (reg >> 2) & 0xf);
++ high = _mtk_mdio_read(gsw->eth, 0x1f, 0x10);
++
++ return (high << 16) | (low & 0xffff);
++}
++
++void mt7530_mdio_m32(struct mt7620_gsw *gsw, u32 mask, u32 set, u32 reg)
++{
++ u32 val = mt7530_mdio_r32(gsw, reg);
++
++ val &= mask;
++ val |= set;
++ mt7530_mdio_w32(gsw, reg, val);
++}
++
++void mtk_switch_w32(struct mt7620_gsw *gsw, u32 val, unsigned reg)
++{
++ mtk_w32(gsw->eth, val, reg + 0x10000);
++}
++
++u32 mtk_switch_r32(struct mt7620_gsw *gsw, unsigned reg)
++{
++ return mtk_r32(gsw->eth, reg + 0x10000);
++}
++
++void mtk_switch_m32(struct mt7620_gsw *gsw, u32 mask, u32 set, unsigned reg)
++{
++ u32 val = mtk_switch_r32(gsw, reg);
++
++ val &= mask;
++ val |= set;
++
++ mtk_switch_w32(gsw, val, reg);
++}
++
++static irqreturn_t gsw_interrupt_mt7623(int irq, void *_eth)
++{
++ struct mtk_eth *eth = (struct mtk_eth *)_eth;
++ struct mt7620_gsw *gsw = (struct mt7620_gsw *)eth->sw_priv;
++ u32 reg, i;
++
++ reg = mt7530_mdio_r32(gsw, MT7530_SYS_INT_STS);
++
++ for (i = 0; i < 5; i++) {
++ unsigned int link;
++
++ if ((reg & BIT(i)) == 0)
++ continue;
++
++ link = mt7530_mdio_r32(gsw, MT7530_PMSR_P(i)) & 0x1;
++
++ if (link)
++ dev_info(gsw->dev, "port %d link up\n", i);
++ else
++ dev_info(gsw->dev, "port %d link down\n", i);
++ }
++
++ mt7530_mdio_w32(gsw, MT7530_SYS_INT_STS, 0x1f);
++
++ return IRQ_HANDLED;
++}
++
++static void wait_loop(struct mt7620_gsw *gsw)
++{
++ int i;
++ int read_data;
++
++ for (i = 0; i < 320; i = i + 1)
++ read_data = mtk_switch_r32(gsw, 0x610);
++}
++
++int mt7623_gsw_config(struct mtk_eth *eth)
++{
++ if (eth->mii_bus && eth->mii_bus->phy_map[0x1f])
++ mt7530_probe(eth->dev, NULL, eth->mii_bus, 1);
++
++ return 0;
++}
++
++static void trgmii_calibration_7623(struct mt7620_gsw *gsw)
++{
++
++ unsigned int tap_a[5] = { 0, 0, 0, 0, 0 }; /* minumum delay for all correct */
++ unsigned int tap_b[5] = { 0, 0, 0, 0, 0 }; /* maximum delay for all correct */
++ unsigned int final_tap[5];
++ unsigned int rxc_step_size;
++ unsigned int rxd_step_size;
++ unsigned int read_data;
++ unsigned int tmp;
++ unsigned int rd_wd;
++ int i;
++ unsigned int err_cnt[5];
++ unsigned int init_toggle_data;
++ unsigned int err_flag[5];
++ unsigned int err_total_flag;
++ unsigned int training_word;
++ unsigned int rd_tap;
++ u32 val;
++
++ u32 TRGMII_7623_base;
++ u32 TRGMII_7623_RD_0;
++ u32 TRGMII_RCK_CTRL;
++
++ TRGMII_7623_base = 0x300; /* 0xFB110300 */
++ TRGMII_7623_RD_0 = TRGMII_7623_base + 0x10;
++ TRGMII_RCK_CTRL = TRGMII_7623_base;
++ rxd_step_size = 0x1;
++ rxc_step_size = 0x4;
++ init_toggle_data = 0x00000055;
++ training_word = 0x000000AC;
++
++ /* RX clock gating in MT7623 */
++ mtk_switch_m32(gsw, 0x3fffffff, 0, TRGMII_7623_base + 0x04);
++
++ /* Assert RX reset in MT7623 */
++ mtk_switch_m32(gsw, 0, 0x80000000, TRGMII_7623_base + 0x00);
++
++ /* Set TX OE edge in MT7623 */
++ mtk_switch_m32(gsw, 0, 0x00002000, TRGMII_7623_base + 0x78);
++
++ /* Disable RX clock gating in MT7623 */
++ mtk_switch_m32(gsw, 0, 0xC0000000, TRGMII_7623_base + 0x04);
++
++ /* Release RX reset in MT7623 */
++ mtk_switch_m32(gsw, 0x7fffffff, 0, TRGMII_7623_base);
++
++ for (i = 0; i < 5; i++)
++ mtk_switch_m32(gsw, 0, 0x80000000, TRGMII_7623_RD_0 + i * 8);
++
++ /* Enable Training Mode in MT7530 */
++ mt7530_mdio_m32(gsw, 0, 0xC0000000, 0x7A40);
++
++ /* Adjust RXC delay in MT7623 */
++ read_data = 0x0;
++ err_total_flag = 0;
++ while (err_total_flag == 0 && read_data != 0x68) {
++ /* Enable EDGE CHK in MT7623 */
++ for (i = 0; i < 5; i++)
++ mtk_switch_m32(gsw, 0x4fffffff, 0x40000000, TRGMII_7623_RD_0 + i * 8);
++
++ wait_loop(gsw);
++ err_total_flag = 1;
++ for (i = 0; i < 5; i++) {
++ err_cnt[i] =
++ mtk_switch_r32(gsw, TRGMII_7623_RD_0 + i * 8) >> 8;
++ err_cnt[i] &= 0x0000000f;
++ rd_wd = mtk_switch_r32(gsw, TRGMII_7623_RD_0 + i * 8) >> 16;
++ rd_wd &= 0x000000ff;
++ val = mtk_switch_r32(gsw, TRGMII_7623_RD_0 + i * 8);
++ pr_err("ERR_CNT = %d, RD_WD =%x, TRGMII_7623_RD_0=%x\n",
++ err_cnt[i], rd_wd, val);
++ if (err_cnt[i] != 0) {
++ err_flag[i] = 1;
++ } else if (rd_wd != 0x55) {
++ err_flag[i] = 1;
++ } else {
++ err_flag[i] = 0;
++ }
++ err_total_flag = err_flag[i] & err_total_flag;
++ }
++
++ pr_err("2nd Disable EDGE CHK in MT7623\n");
++ /* Disable EDGE CHK in MT7623 */
++ for (i = 0; i < 5; i++)
++ mtk_switch_m32(gsw, 0x4fffffff, 0x40000000, TRGMII_7623_RD_0 + i * 8);
++ wait_loop(gsw);
++ pr_err("2nd Disable EDGE CHK in MT7623\n");
++ /* Adjust RXC delay */
++ /* RX clock gating in MT7623 */
++ mtk_switch_m32(gsw, 0x3fffffff, 0, TRGMII_7623_base + 0x04);
++ read_data = mtk_switch_r32(gsw, TRGMII_7623_base);
++ if (err_total_flag == 0) {
++ tmp = (read_data & 0x0000007f) + rxc_step_size;
++ pr_err(" RXC delay = %d\n", tmp);
++ read_data >>= 8;
++ read_data &= 0xffffff80;
++ read_data |= tmp;
++ read_data <<= 8;
++ read_data &= 0xffffff80;
++ read_data |= tmp;
++ mtk_switch_w32(gsw, read_data, TRGMII_7623_base);
++ } else {
++ tmp = (read_data & 0x0000007f) + 16;
++ pr_err(" RXC delay = %d\n", tmp);
++ read_data >>= 8;
++ read_data &= 0xffffff80;
++ read_data |= tmp;
++ read_data <<= 8;
++ read_data &= 0xffffff80;
++ read_data |= tmp;
++ mtk_switch_w32(gsw, read_data, TRGMII_7623_base);
++ }
++ read_data &= 0x000000ff;
++
++ /* Disable RX clock gating in MT7623 */
++ mtk_switch_m32(gsw, 0, 0xC0000000, TRGMII_7623_base + 0x04);
++ for (i = 0; i < 5; i++)
++ mtk_switch_m32(gsw, 0, 0x80000000, TRGMII_7623_RD_0 + i * 8);
++ }
++
++ /* Read RD_WD MT7623 */
++ for (i = 0; i < 5; i++) {
++ rd_tap = 0;
++ while (err_flag[i] != 0 && rd_tap != 128) {
++ /* Enable EDGE CHK in MT7623 */
++ mtk_switch_m32(gsw, 0x4fffffff, 0x40000000, TRGMII_7623_RD_0 + i * 8);
++ wait_loop(gsw);
++
++ read_data = mtk_switch_r32(gsw, TRGMII_7623_RD_0 + i * 8);
++ err_cnt[i] = (read_data >> 8) & 0x0000000f; /* Read MT7623 Errcnt */
++ rd_wd = (read_data >> 16) & 0x000000ff;
++ if (err_cnt[i] != 0 || rd_wd != 0x55) {
++ err_flag[i] = 1;
++ } else {
++ err_flag[i] = 0;
++ }
++ /* Disable EDGE CHK in MT7623 */
++ mtk_switch_m32(gsw, 0x4fffffff, 0x40000000, TRGMII_7623_RD_0 + i * 8);
++ wait_loop(gsw);
++ if (err_flag[i] != 0) {
++ rd_tap = (read_data & 0x0000007f) + rxd_step_size; /* Add RXD delay in MT7623 */
++ read_data = (read_data & 0xffffff80) | rd_tap;
++ mtk_switch_w32(gsw, read_data,
++ TRGMII_7623_RD_0 + i * 8);
++ tap_a[i] = rd_tap;
++ } else {
++ rd_tap = (read_data & 0x0000007f) + 48;
++ read_data = (read_data & 0xffffff80) | rd_tap;
++ mtk_switch_w32(gsw, read_data,
++ TRGMII_7623_RD_0 + i * 8);
++ }
++
++ }
++ pr_err("MT7623 %dth bit Tap_a = %d\n", i, tap_a[i]);
++ }
++ /* pr_err("Last While Loop\n"); */
++ for (i = 0; i < 5; i++) {
++ while ((err_flag[i] == 0) && (rd_tap != 128)) {
++ read_data = mtk_switch_r32(gsw, TRGMII_7623_RD_0 + i * 8);
++ rd_tap = (read_data & 0x0000007f) + rxd_step_size; /* Add RXD delay in MT7623 */
++ read_data = (read_data & 0xffffff80) | rd_tap;
++ mtk_switch_w32(gsw, read_data, TRGMII_7623_RD_0 + i * 8);
++ /* Enable EDGE CHK in MT7623 */
++ val =
++ mtk_switch_r32(gsw, TRGMII_7623_RD_0 + i * 8) | 0x40000000;
++ val &= 0x4fffffff;
++ mtk_switch_w32(gsw, val, TRGMII_7623_RD_0 + i * 8);
++ wait_loop(gsw);
++ read_data = mtk_switch_r32(gsw, TRGMII_7623_RD_0 + i * 8);
++ err_cnt[i] = (read_data >> 8) & 0x0000000f; /* Read MT7623 Errcnt */
++ rd_wd = (read_data >> 16) & 0x000000ff;
++ if (err_cnt[i] != 0 || rd_wd != 0x55) {
++ err_flag[i] = 1;
++ } else {
++ err_flag[i] = 0;
++ }
++
++ /* Disable EDGE CHK in MT7623 */
++ mtk_switch_m32(gsw, 0x4fffffff, 0x40000000, TRGMII_7623_RD_0 + i * 8);
++ wait_loop(gsw);
++
++ }
++
++ tap_b[i] = rd_tap; /* -rxd_step_size; */
++ pr_err("MT7623 %dth bit Tap_b = %d\n", i, tap_b[i]);
++ final_tap[i] = (tap_a[i] + tap_b[i]) / 2; /* Calculate RXD delay = (TAP_A + TAP_B)/2 */
++ read_data = (read_data & 0xffffff80) | final_tap[i];
++ mtk_switch_w32(gsw, read_data, TRGMII_7623_RD_0 + i * 8);
++ }
++
++ read_data = mt7530_mdio_r32(gsw, 0x7A40);
++ read_data &= 0x3fffffff;
++ mt7530_mdio_w32(gsw, 0x7A40, read_data);
++}
++
++static void trgmii_calibration_7530(struct mt7620_gsw *gsw)
++{
++
++ unsigned int tap_a[5] = { 0, 0, 0, 0, 0 };
++ unsigned int tap_b[5] = { 0, 0, 0, 0, 0 };
++ unsigned int final_tap[5];
++ unsigned int rxc_step_size;
++ unsigned int rxd_step_size;
++ unsigned int read_data;
++ unsigned int tmp = 0;
++ int i;
++ unsigned int err_cnt[5];
++ unsigned int rd_wd;
++ unsigned int init_toggle_data;
++ unsigned int err_flag[5];
++ unsigned int err_total_flag;
++ unsigned int training_word;
++ unsigned int rd_tap;
++
++ u32 TRGMII_7623_base;
++ u32 TRGMII_7530_RD_0;
++ u32 TRGMII_RCK_CTRL;
++ u32 TRGMII_7530_base;
++ u32 TRGMII_7530_TX_base;
++
++ TRGMII_7623_base = 0x300;
++ TRGMII_7530_base = 0x7A00;
++ TRGMII_7530_RD_0 = TRGMII_7530_base + 0x10;
++ TRGMII_RCK_CTRL = TRGMII_7623_base;
++ rxd_step_size = 0x1;
++ rxc_step_size = 0x8;
++ init_toggle_data = 0x00000055;
++ training_word = 0x000000AC;
++
++ TRGMII_7530_TX_base = TRGMII_7530_base + 0x50;
++
++ /* Calibration begin */
++ mtk_switch_m32(gsw, 0, 0x80000000, TRGMII_7623_base + 0x40);
++
++ /* RX clock gating in MT7530 */
++ mt7530_mdio_m32(gsw, 0x3fffffff, 0, TRGMII_7530_base + 0x04);
++
++ /* Set TX OE edge in MT7530 */
++ mt7530_mdio_m32(gsw, 0, 0x2000, TRGMII_7530_base + 0x78);
++
++ /* Assert RX reset in MT7530 */
++ mt7530_mdio_m32(gsw, 0, 0x80000000, TRGMII_7530_base);
++
++ /* Release RX reset in MT7530 */
++ mt7530_mdio_m32(gsw, 0x7fffffff, 0, TRGMII_7530_base);
++
++ /* Disable RX clock gating in MT7530 */
++ mt7530_mdio_m32(gsw, 0, 0xC0000000, TRGMII_7530_base + 0x04);
++
++ /* Enable Training Mode in MT7623 */
++ mtk_switch_m32(gsw, 0, 0x80000000, TRGMII_7623_base + 0x40);
++ if (gsw->trgmii_force == 2000)
++ mtk_switch_m32(gsw, 0, 0xC0000000, TRGMII_7623_base + 0x40);
++ else
++ mtk_switch_m32(gsw, 0, 0x80000000, TRGMII_7623_base + 0x40);
++ mtk_switch_m32(gsw, 0xfffff0ff, 0, TRGMII_7623_base + 0x078);
++ mtk_switch_m32(gsw, 0xfffff0ff, 0, TRGMII_7623_base + 0x50);
++ mtk_switch_m32(gsw, 0xfffff0ff, 0, TRGMII_7623_base + 0x58);
++ mtk_switch_m32(gsw, 0xfffff0ff, 0, TRGMII_7623_base + 0x60);
++ mtk_switch_m32(gsw, 0xfffff0ff, 0, TRGMII_7623_base + 0x68);
++ mtk_switch_m32(gsw, 0xfffff0ff, 0, TRGMII_7623_base + 0x70);
++ mtk_switch_m32(gsw, 0x00000800, 0, TRGMII_7623_base + 0x78);
++
++ /* Adjust RXC delay in MT7530 */
++ err_total_flag = 0;
++ read_data = 0x0;
++ while (err_total_flag == 0 && (read_data != 0x68)) {
++ /* Enable EDGE CHK in MT7530 */
++ for (i = 0; i < 5; i++) {
++ mt7530_mdio_m32(gsw, 0x4fffffff, 0x40000000,
++ TRGMII_7530_RD_0 + i * 8);
++ wait_loop(gsw);
++
++ /* 2nd Disable EDGE CHK in MT7530 */
++ err_cnt[i] = mt7530_mdio_r32(gsw, TRGMII_7530_RD_0 + i * 8);
++ err_cnt[i] >>= 8;
++ err_cnt[i] &= 0x0000ff0f;
++
++ rd_wd = err_cnt[i] >> 8;
++ rd_wd &= 0x000000ff;
++
++ err_cnt[i] &= 0x0000000f;
++ if (err_cnt[i] != 0)
++ err_flag[i] = 1;
++ else if (rd_wd != 0x55)
++ err_flag[i] = 1;
++ else
++ err_flag[i] = 0;
++ if (i == 0)
++ err_total_flag = err_flag[i];
++ else
++ err_total_flag = err_flag[i] & err_total_flag;
++
++ /* Disable EDGE CHK in MT7530 */
++ mt7530_mdio_m32(gsw, 0x4fffffff, 0x40000000,
++ TRGMII_7530_RD_0 + i * 8);
++ wait_loop(gsw);
++ }
++
++ /* Adjust RXC delay */
++ if (err_total_flag == 0) {
++ /* Assert RX reset in MT7530 */
++ mt7530_mdio_m32(gsw, 0, 0x80000000, TRGMII_7530_base);
++
++ /* RX clock gating in MT7530 */
++ mt7530_mdio_m32(gsw, 0x3fffffff, 0, TRGMII_7530_base + 0x04);
++
++ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base);
++ tmp = read_data;
++ tmp &= 0x0000007f;
++ tmp += rxc_step_size;
++ /* pr_err("Current rxc delay = %d\n", tmp); */
++ read_data &= 0xffffff80;
++ read_data |= tmp;
++ mt7530_mdio_w32(gsw, TRGMII_7530_base, read_data);
++ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base);
++ /* pr_err("Current RXC delay = %x\n", read_data); */
++
++ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base);
++ read_data &= 0x7fffffff;
++ mt7530_mdio_w32(gsw, TRGMII_7530_base, read_data); /* Release RX reset in MT7530 */
++
++ read_data =
++ mt7530_mdio_r32(gsw, TRGMII_7530_base + 0x04);
++ read_data |= 0xc0000000;
++ mt7530_mdio_w32(gsw, TRGMII_7530_base + 0x04, read_data); /* Disable RX clock gating in MT7530 */
++ pr_err("####### MT7530 RXC delay is %d\n", tmp);
++ }
++ read_data = tmp;
++ }
++ pr_err("Finish RXC Adjustment while loop\n");
++
++ /* pr_err("Read RD_WD MT7530\n"); */
++ /* Read RD_WD MT7530 */
++ for (i = 0; i < 5; i++) {
++ rd_tap = 0;
++ while (err_flag[i] != 0 && rd_tap != 128) {
++ /* Enable EDGE CHK in MT7530 */
++ read_data =
++ mt7530_mdio_r32(gsw, TRGMII_7530_RD_0 + i * 8);
++ read_data |= 0x40000000;
++ read_data &= 0x4fffffff;
++ mt7530_mdio_w32(gsw, TRGMII_7530_RD_0 + i * 8,
++ read_data);
++ wait_loop(gsw);
++ err_cnt[i] = (read_data >> 8) & 0x0000000f;
++ rd_wd = (read_data >> 16) & 0x000000ff;
++ if (err_cnt[i] != 0 || rd_wd != 0x55) {
++ err_flag[i] = 1;
++ } else {
++ err_flag[i] = 0;
++ }
++ if (err_flag[i] != 0) {
++ rd_tap = (read_data & 0x0000007f) + rxd_step_size; /* Add RXD delay in MT7530 */
++ read_data = (read_data & 0xffffff80) | rd_tap;
++ mt7530_mdio_w32(gsw, TRGMII_7530_RD_0 + i * 8,
++ read_data);
++ tap_a[i] = rd_tap;
++ } else {
++ tap_a[i] = (read_data & 0x0000007f); /* Record the min delay TAP_A */
++ rd_tap = tap_a[i] + 0x4;
++ read_data = (read_data & 0xffffff80) | rd_tap;
++ mt7530_mdio_w32(gsw, TRGMII_7530_RD_0 + i * 8,
++ read_data);
++ }
++
++ /* Disable EDGE CHK in MT7530 */
++ read_data =
++ mt7530_mdio_r32(gsw, TRGMII_7530_RD_0 + i * 8);
++ read_data |= 0x40000000;
++ read_data &= 0x4fffffff;
++ mt7530_mdio_w32(gsw, TRGMII_7530_RD_0 + i * 8,
++ read_data);
++ wait_loop(gsw);
++
++ }
++ pr_err("MT7530 %dth bit Tap_a = %d\n", i, tap_a[i]);
++ }
++
++ /* pr_err("Last While Loop\n"); */
++ for (i = 0; i < 5; i++) {
++ rd_tap = 0;
++ while (err_flag[i] == 0 && (rd_tap != 128)) {
++ /* Enable EDGE CHK in MT7530 */
++ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_RD_0 + i * 8);
++ read_data |= 0x40000000;
++ read_data &= 0x4fffffff;
++ mt7530_mdio_w32(gsw, TRGMII_7530_RD_0 + i * 8,
++ read_data);
++ wait_loop(gsw);
++ err_cnt[i] = (read_data >> 8) & 0x0000000f;
++ rd_wd = (read_data >> 16) & 0x000000ff;
++ if (err_cnt[i] != 0 || rd_wd != 0x55)
++ err_flag[i] = 1;
++ else
++ err_flag[i] = 0;
++
++ if (err_flag[i] == 0 && (rd_tap != 128)) {
++ /* Add RXD delay in MT7530 */
++ rd_tap = (read_data & 0x0000007f) + rxd_step_size;
++ read_data = (read_data & 0xffffff80) | rd_tap;
++ mt7530_mdio_w32(gsw, TRGMII_7530_RD_0 + i * 8,
++ read_data);
++ }
++ /* Disable EDGE CHK in MT7530 */
++ read_data =
++ mt7530_mdio_r32(gsw, TRGMII_7530_RD_0 + i * 8);
++ read_data |= 0x40000000;
++ read_data &= 0x4fffffff;
++ mt7530_mdio_w32(gsw, TRGMII_7530_RD_0 + i * 8,
++ read_data);
++ wait_loop(gsw);
++ }
++ tap_b[i] = rd_tap; /* - rxd_step_size; */
++ pr_err("MT7530 %dth bit Tap_b = %d\n", i, tap_b[i]);
++ final_tap[i] = (tap_a[i] + tap_b[i]) / 2;
++
++ read_data = (read_data & 0xffffff80) | final_tap[i];
++ mt7530_mdio_w32(gsw, TRGMII_7530_RD_0 + i * 8, read_data);
++ }
++
++ if (gsw->trgmii_force == 2000)
++ mtk_switch_m32(gsw, 0x7fffffff, 0, TRGMII_7623_base + 0x40);
++ else
++ mtk_switch_m32(gsw, 0x3fffffff, 0, TRGMII_7623_base + 0x40);
++
++}
++
++static void mt7530_trgmii_clock_setting(struct mt7620_gsw *gsw, u32 xtal_mode)
++{
++ /* TRGMII Clock */
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x410);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x1);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x404);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++
++ if (xtal_mode == 1) {
++ /* 25MHz */
++ if (gsw->trgmii_force == 2600)
++ /* 325MHz */
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x1a00);
++ else if (gsw->trgmii_force == 2000)
++ /* 250MHz */
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x1400);
++ } else if (xtal_mode == 2) {
++ /* 40MHz */
++ if (gsw->trgmii_force == 2600)
++ /* 325MHz */
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x1040);
++ else if (gsw->trgmii_force == 2000)
++ /* 250MHz */
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x0c80);
++ }
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x405);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x0);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x409);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++ if (xtal_mode == 1)
++ /* 25MHz */
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x0057);
++ else
++ /* 40MHz */
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x0087);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x40a);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++ if (xtal_mode == 1)
++ /* 25MHz */
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x0057);
++ else
++ /* 40MHz */
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x0087);
++
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x403);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x1800);
++
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x403);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x1c00);
++
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x401);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0xc020);
++
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x406);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0xa030);
++
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x406);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0xa038);
++
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x410);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x3);
++
++ mt7530_mdio_m32(gsw, 0xfffffffc, 0x1, 0x7830);
++ mt7530_mdio_m32(gsw, 0xcfffffff, 0, 0x7a40);
++ mt7530_mdio_w32(gsw, 0x7a78, 0x55);
++ mtk_switch_m32(gsw, 0x7fffffff, 0, 0x300);
++
++ trgmii_calibration_7623(gsw);
++ trgmii_calibration_7530(gsw);
++
++ mtk_switch_m32(gsw, 0, 0x80000000, 0x300);
++ mtk_switch_m32(gsw, 0, 0x7fffffff, 0x300);
++
++ /* MT7530 RXC reset */
++ mt7530_mdio_m32(gsw, 0, BIT(31), 0x7a00);
++ mdelay(1);
++
++ mt7530_mdio_m32(gsw, ~BIT(31), 0, 0x7a00);
++ mdelay(100);
++}
++
++static void mt7623_hw_init(struct mtk_eth *eth, struct mt7620_gsw *gsw,
++ struct device_node *np)
++{
++ u32 i;
++ u32 val;
++ u32 xtal_mode;
++
++ regmap_update_bits(gsw->ethsys, ETHSYS_CLKCFG0,
++ ETHSYS_TRGMII_CLK_SEL362_5,
++ ETHSYS_TRGMII_CLK_SEL362_5);
++
++ /* reset the TRGMII core */
++ mtk_switch_m32(gsw, 0, INTF_MODE_TRGMII, GSW_INTF_MODE);
++ mtk_switch_m32(gsw, 0, TRGMII_RCK_CTRL_RX_RST, GSW_TRGMII_RCK_CTRL);
++
++ /* Hardware reset Switch */
++ //device_reset(eth->dev);
++ printk("%s:%s[%d]reset_switch\n", __FILE__, __func__, __LINE__);
++
++ /* Wait for Switch Reset Completed*/
++ for (i = 0; i < 100; i++) {
++ mdelay(10);
++ if (mt7530_mdio_r32(gsw, MT7530_HWTRAP))
++ break;
++ }
++
++ /* turn off all PHYs */
++ for (i = 0; i <= 4; i++) {
++ val = _mtk_mdio_read(gsw->eth, i, 0x0);
++ val |= BIT(11);
++ _mtk_mdio_write(gsw->eth, i, 0x0, val);
++ }
++
++ /* reset the switch */
++ mt7530_mdio_w32(gsw, MT7530_SYS_CTRL,
++ SYS_CTRL_SW_RST | SYS_CTRL_REG_RST);
++ udelay(100);
++
++ /* GE1, Force 1000M/FD, FC ON */
++ mt7530_mdio_w32(gsw, MT7530_PMCR_P(6), PMCR_FIXED_LINK_FC);
++
++ /* GE2, Force 1000M/FD, FC ON */
++ mt7530_mdio_w32(gsw, MT7530_PMCR_P(5), PMCR_FIXED_LINK_FC);
++
++ /* Enable Port 6, P5 as GMAC5, P5 disable */
++ val = mt7530_mdio_r32(gsw, MT7530_MHWTRAP);
++ /* Enable Port 6 */
++ val &= ~MHWTRAP_P6_DIS;
++ /* Enable Port 5 */
++ val &= ~MHWTRAP_P5_DIS;
++ /* Port 5 as GMAC */
++ val |= MHWTRAP_P5_MAC_SEL;
++ /* Port 5 Interface mode */
++ val |= MHWTRAP_P5_RGMII_MODE;
++ /* Set MT7530 phy direct access mode**/
++ val &= ~MHWTRAP_PHY_ACCESS;
++ /* manual override of HW-Trap */
++ val |= MHWTRAP_MANUAL;
++ mt7530_mdio_w32(gsw, MT7530_MHWTRAP, val);
++
++ xtal_mode = mt7530_mdio_r32(gsw, MT7530_HWTRAP);
++ xtal_mode >>= HWTRAP_XTAL_SHIFT;
++ xtal_mode &= HWTRAP_XTAL_MASK;
++ if (xtal_mode == MT7623_XTAL_40) {
++ /* disable MT7530 core clock */
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x410);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x0);
++
++ /* disable MT7530 PLL */
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x40d);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x2020);
++
++ /* for MT7530 core clock = 500Mhz */
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x40e);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x119);
++
++ /* enable MT7530 PLL */
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x40d);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x2820);
++
++ udelay(20);
++
++ /* enable MT7530 core clock */
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x1f);
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x410);
++ _mtk_mdio_write(gsw->eth, 0, 13, 0x401f);
++ }
++
++ /* RGMII */
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x1);
++
++ /* set MT7530 central align */
++ mt7530_mdio_m32(gsw, ~BIT(0), BIT(1), MT7530_P6ECR);
++ mt7530_mdio_m32(gsw, ~BIT(30), 0, MT7530_TRGMII_TXCTRL);
++ mt7530_mdio_w32(gsw, MT7530_TRGMII_TCK_CTRL, 0x855);
++
++ /* delay setting for 10/1000M */
++ mt7530_mdio_w32(gsw, MT7530_P5RGMIIRXCR, 0x104);
++ mt7530_mdio_w32(gsw, MT7530_P5RGMIITXCR, 0x10);
++
++ /* lower Tx Driving */
++ mt7530_mdio_w32(gsw, MT7530_TRGMII_TD0_ODT, 0x88);
++ mt7530_mdio_w32(gsw, MT7530_TRGMII_TD1_ODT, 0x88);
++ mt7530_mdio_w32(gsw, MT7530_TRGMII_TD2_ODT, 0x88);
++ mt7530_mdio_w32(gsw, MT7530_TRGMII_TD3_ODT, 0x88);
++ mt7530_mdio_w32(gsw, MT7530_TRGMII_TD4_ODT, 0x88);
++ mt7530_mdio_w32(gsw, MT7530_TRGMII_TD5_ODT, 0x88);
++ mt7530_mdio_w32(gsw, MT7530_IO_DRV_CR, 0x11);
++
++ /* Set MT7623/MT7683 TX Driving */
++ mtk_switch_w32(gsw, 0x88, GSW_TRGMII_TD0_ODT);
++ mtk_switch_w32(gsw, 0x88, GSW_TRGMII_TD0_ODT);
++ mtk_switch_w32(gsw, 0x88, GSW_TRGMII_TD0_ODT);
++ mtk_switch_w32(gsw, 0x88, GSW_TRGMII_TD0_ODT);
++ mtk_switch_w32(gsw, 0x88, GSW_TRGMII_TXCTL_ODT);
++ mtk_switch_w32(gsw, 0x88, GSW_TRGMII_TCK_ODT);
++
++// mt7530_trgmii_clock_setting(gsw, xtal_mode);
++
++ /* disable EEE */
++ for (i = 0; i <= 4; i++) {
++ _mtk_mdio_write(gsw->eth, i, 13, 0x7);
++ _mtk_mdio_write(gsw->eth, i, 14, 0x3C);
++ _mtk_mdio_write(gsw->eth, i, 13, 0x4007);
++ _mtk_mdio_write(gsw->eth, i, 14, 0x0);
++
++ /* Increase SlvDPSready time */
++ _mtk_mdio_write(gsw->eth, i, 31, 0x52b5);
++ _mtk_mdio_write(gsw->eth, i, 16, 0xafae);
++ _mtk_mdio_write(gsw->eth, i, 18, 0x2f);
++ _mtk_mdio_write(gsw->eth, i, 16, 0x8fae);
++
++ /* Incease post_update_timer */
++ _mtk_mdio_write(gsw->eth, i, 31, 0x3);
++ _mtk_mdio_write(gsw->eth, i, 17, 0x4b);
++
++ /* Adjust 100_mse_threshold */
++ _mtk_mdio_write(gsw->eth, i, 13, 0x1e);
++ _mtk_mdio_write(gsw->eth, i, 14, 0x123);
++ _mtk_mdio_write(gsw->eth, i, 13, 0x401e);
++ _mtk_mdio_write(gsw->eth, i, 14, 0xffff);
++
++ /* Disable mcc */
++ _mtk_mdio_write(gsw->eth, i, 13, 0x1e);
++ _mtk_mdio_write(gsw->eth, i, 14, 0xa6);
++ _mtk_mdio_write(gsw->eth, i, 13, 0x401e);
++ _mtk_mdio_write(gsw->eth, i, 14, 0x300);
++
++ /* Disable HW auto downshift*/
++ _mtk_mdio_write(gsw->eth, i, 31, 0x1);
++ val = _mtk_mdio_read(gsw->eth, i, 0x14);
++ val &= ~BIT(4);
++ _mtk_mdio_write(gsw->eth, i, 0x14, val);
++ }
++
++ /* turn on all PHYs */
++ for (i = 0; i <= 4; i++) {
++ val = _mtk_mdio_read(gsw->eth, i, 0);
++ val &= ~BIT(11);
++ _mtk_mdio_write(gsw->eth, i, 0, val);
++ }
++
++ /* enable irq */
++ mt7530_mdio_m32(gsw, 0, TOP_SIG_CTRL_NORMAL, MT7530_TOP_SIG_CTRL);
++}
++
++static const struct of_device_id mediatek_gsw_match[] = {
++ { .compatible = "mediatek,mt7623-gsw" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, mediatek_gsw_match);
++
++int mtk_gsw_init(struct mtk_eth *eth)
++{
++ struct device_node *np = eth->switch_np;
++ struct platform_device *pdev = of_find_device_by_node(np);
++ struct mt7620_gsw *gsw;
++
++ if (!pdev)
++ return -ENODEV;
++
++ if (!of_device_is_compatible(np, mediatek_gsw_match->compatible))
++ return -EINVAL;
++
++ gsw = platform_get_drvdata(pdev);
++ if (!gsw)
++ return -ENODEV;
++ eth->sw_priv = gsw;
++ gsw->eth = eth;
++
++ mt7623_hw_init(eth, gsw, np);
++
++ request_threaded_irq(gsw->irq, gsw_interrupt_mt7623, NULL, 0,
++ "gsw", eth);
++ mt7530_mdio_w32(gsw, MT7530_SYS_INT_EN, 0x1f);
++
++ return 0;
++}
++
++static int mt7623_gsw_probe(struct platform_device *pdev)
++{
++ struct device_node *np = pdev->dev.of_node;
++ struct device_node *pctl;
++ int reset_pin, ret;
++ struct mt7620_gsw *gsw;
++ struct regulator *supply;
++
++ gsw = devm_kzalloc(&pdev->dev, sizeof(struct mt7620_gsw), GFP_KERNEL);
++ if (!gsw)
++ return -ENOMEM;
++
++ gsw->dev = &pdev->dev;
++ gsw->irq = irq_of_parse_and_map(np, 0);
++ if (gsw->irq < 0)
++ return -EINVAL;
++
++ gsw->ethsys = syscon_regmap_lookup_by_phandle(np, "mediatek,ethsys");
++ if (IS_ERR(gsw->ethsys))
++ return PTR_ERR(gsw->ethsys);
++
++ reset_pin = of_get_named_gpio(np, "mediatek,reset-pin", 0);
++ if (reset_pin < 0)
++ return reset_pin;
++
++ pctl = of_parse_phandle(np, "mediatek,pctl-regmap", 0);
++ if (IS_ERR(pctl))
++ return PTR_ERR(pctl);
++
++ gsw->pctl = syscon_node_to_regmap(pctl);
++ if (IS_ERR(pctl))
++ return PTR_ERR(pctl);
++
++ ret = devm_gpio_request(&pdev->dev, reset_pin, "mt7530-reset");
++ if (ret)
++ return ret;
++
++ gsw->clk_trgpll = devm_clk_get(&pdev->dev, "trgpll");
++ if (IS_ERR(gsw->clk_trgpll))
++ return -ENODEV;
++
++ supply = devm_regulator_get(&pdev->dev, "mt7530");
++ if (IS_ERR(supply))
++ return PTR_ERR(supply);
++
++ regulator_set_voltage(supply, 1000000, 1000000);
++ ret = regulator_enable(supply);
++ if (ret) {
++ dev_err(&pdev->dev, "Failed to enable reg-7530: %d\n", ret);
++ return ret;
++ }
++ pm_runtime_enable(&pdev->dev);
++ pm_runtime_get_sync(&pdev->dev);
++
++ ret = clk_set_rate(gsw->clk_trgpll, 500000000);
++ if (ret)
++ return ret;
++
++ clk_prepare_enable(gsw->clk_trgpll);
++
++ gpio_direction_output(reset_pin, 0);
++ udelay(1000);
++ gpio_set_value(reset_pin, 1);
++ mdelay(100);
++
++ platform_set_drvdata(pdev, gsw);
++
++ return 0;
++}
++
++static int mt7623_gsw_remove(struct platform_device *pdev)
++{
++ struct mt7620_gsw *gsw = platform_get_drvdata(pdev);
++
++ clk_disable_unprepare(gsw->clk_trgpll);
++
++ pm_runtime_put_sync(&pdev->dev);
++ pm_runtime_disable(&pdev->dev);
++
++ platform_set_drvdata(pdev, NULL);
++
++ return 0;
++}
++
++static struct platform_driver gsw_driver = {
++ .probe = mt7623_gsw_probe,
++ .remove = mt7623_gsw_remove,
++ .driver = {
++ .name = "mt7623-gsw",
++ .owner = THIS_MODULE,
++ .of_match_table = mediatek_gsw_match,
++ },
++};
++
++module_platform_driver(gsw_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
++MODULE_DESCRIPTION("GBit switch driver for Mediatek MT7623 SoC");
+diff --git a/drivers/net/ethernet/mediatek/mt7530.c b/drivers/net/ethernet/mediatek/mt7530.c
+new file mode 100644
+index 0000000..2e9d280
+--- /dev/null
++++ b/drivers/net/ethernet/mediatek/mt7530.c
+@@ -0,0 +1,808 @@
++/*
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
++ */
++
++#include <linux/if.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/if_ether.h>
++#include <linux/skbuff.h>
++#include <linux/netdevice.h>
++#include <linux/netlink.h>
++#include <linux/bitops.h>
++#include <net/genetlink.h>
++#include <linux/switch.h>
++#include <linux/delay.h>
++#include <linux/phy.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/lockdep.h>
++#include <linux/workqueue.h>
++#include <linux/of_device.h>
++
++#include "mt7530.h"
++
++#define MT7530_CPU_PORT 6
++#define MT7530_NUM_PORTS 8
++#define MT7530_NUM_VLANS 16
++#define MT7530_MAX_VID 4095
++#define MT7530_MIN_VID 0
++
++/* registers */
++#define REG_ESW_VLAN_VTCR 0x90
++#define REG_ESW_VLAN_VAWD1 0x94
++#define REG_ESW_VLAN_VAWD2 0x98
++#define REG_ESW_VLAN_VTIM(x) (0x100 + 4 * ((x) / 2))
++
++#define REG_ESW_VLAN_VAWD1_IVL_MAC BIT(30)
++#define REG_ESW_VLAN_VAWD1_VTAG_EN BIT(28)
++#define REG_ESW_VLAN_VAWD1_VALID BIT(0)
++
++/* vlan egress mode */
++enum {
++ ETAG_CTRL_UNTAG = 0,
++ ETAG_CTRL_TAG = 2,
++ ETAG_CTRL_SWAP = 1,
++ ETAG_CTRL_STACK = 3,
++};
++
++#define REG_ESW_PORT_PCR(x) (0x2004 | ((x) << 8))
++#define REG_ESW_PORT_PVC(x) (0x2010 | ((x) << 8))
++#define REG_ESW_PORT_PPBV1(x) (0x2014 | ((x) << 8))
++
++#define REG_HWTRAP 0x7804
++
++#define MIB_DESC(_s , _o, _n) \
++ { \
++ .size = (_s), \
++ .offset = (_o), \
++ .name = (_n), \
++ }
++
++struct mt7xxx_mib_desc {
++ unsigned int size;
++ unsigned int offset;
++ const char *name;
++};
++
++#define MT7621_MIB_COUNTER_BASE 0x4000
++#define MT7621_MIB_COUNTER_PORT_OFFSET 0x100
++#define MT7621_STATS_TDPC 0x00
++#define MT7621_STATS_TCRC 0x04
++#define MT7621_STATS_TUPC 0x08
++#define MT7621_STATS_TMPC 0x0C
++#define MT7621_STATS_TBPC 0x10
++#define MT7621_STATS_TCEC 0x14
++#define MT7621_STATS_TSCEC 0x18
++#define MT7621_STATS_TMCEC 0x1C
++#define MT7621_STATS_TDEC 0x20
++#define MT7621_STATS_TLCEC 0x24
++#define MT7621_STATS_TXCEC 0x28
++#define MT7621_STATS_TPPC 0x2C
++#define MT7621_STATS_TL64PC 0x30
++#define MT7621_STATS_TL65PC 0x34
++#define MT7621_STATS_TL128PC 0x38
++#define MT7621_STATS_TL256PC 0x3C
++#define MT7621_STATS_TL512PC 0x40
++#define MT7621_STATS_TL1024PC 0x44
++#define MT7621_STATS_TOC 0x48
++#define MT7621_STATS_RDPC 0x60
++#define MT7621_STATS_RFPC 0x64
++#define MT7621_STATS_RUPC 0x68
++#define MT7621_STATS_RMPC 0x6C
++#define MT7621_STATS_RBPC 0x70
++#define MT7621_STATS_RAEPC 0x74
++#define MT7621_STATS_RCEPC 0x78
++#define MT7621_STATS_RUSPC 0x7C
++#define MT7621_STATS_RFEPC 0x80
++#define MT7621_STATS_ROSPC 0x84
++#define MT7621_STATS_RJEPC 0x88
++#define MT7621_STATS_RPPC 0x8C
++#define MT7621_STATS_RL64PC 0x90
++#define MT7621_STATS_RL65PC 0x94
++#define MT7621_STATS_RL128PC 0x98
++#define MT7621_STATS_RL256PC 0x9C
++#define MT7621_STATS_RL512PC 0xA0
++#define MT7621_STATS_RL1024PC 0xA4
++#define MT7621_STATS_ROC 0xA8
++#define MT7621_STATS_RDPC_CTRL 0xB0
++#define MT7621_STATS_RDPC_ING 0xB4
++#define MT7621_STATS_RDPC_ARL 0xB8
++
++static const struct mt7xxx_mib_desc mt7621_mibs[] = {
++ MIB_DESC(1, MT7621_STATS_TDPC, "TxDrop"),
++ MIB_DESC(1, MT7621_STATS_TCRC, "TxCRC"),
++ MIB_DESC(1, MT7621_STATS_TUPC, "TxUni"),
++ MIB_DESC(1, MT7621_STATS_TMPC, "TxMulti"),
++ MIB_DESC(1, MT7621_STATS_TBPC, "TxBroad"),
++ MIB_DESC(1, MT7621_STATS_TCEC, "TxCollision"),
++ MIB_DESC(1, MT7621_STATS_TSCEC, "TxSingleCol"),
++ MIB_DESC(1, MT7621_STATS_TMCEC, "TxMultiCol"),
++ MIB_DESC(1, MT7621_STATS_TDEC, "TxDefer"),
++ MIB_DESC(1, MT7621_STATS_TLCEC, "TxLateCol"),
++ MIB_DESC(1, MT7621_STATS_TXCEC, "TxExcCol"),
++ MIB_DESC(1, MT7621_STATS_TPPC, "TxPause"),
++ MIB_DESC(1, MT7621_STATS_TL64PC, "Tx64Byte"),
++ MIB_DESC(1, MT7621_STATS_TL65PC, "Tx65Byte"),
++ MIB_DESC(1, MT7621_STATS_TL128PC, "Tx128Byte"),
++ MIB_DESC(1, MT7621_STATS_TL256PC, "Tx256Byte"),
++ MIB_DESC(1, MT7621_STATS_TL512PC, "Tx512Byte"),
++ MIB_DESC(1, MT7621_STATS_TL1024PC, "Tx1024Byte"),
++ MIB_DESC(2, MT7621_STATS_TOC, "TxByte"),
++ MIB_DESC(1, MT7621_STATS_RDPC, "RxDrop"),
++ MIB_DESC(1, MT7621_STATS_RFPC, "RxFiltered"),
++ MIB_DESC(1, MT7621_STATS_RUPC, "RxUni"),
++ MIB_DESC(1, MT7621_STATS_RMPC, "RxMulti"),
++ MIB_DESC(1, MT7621_STATS_RBPC, "RxBroad"),
++ MIB_DESC(1, MT7621_STATS_RAEPC, "RxAlignErr"),
++ MIB_DESC(1, MT7621_STATS_RCEPC, "RxCRC"),
++ MIB_DESC(1, MT7621_STATS_RUSPC, "RxUnderSize"),
++ MIB_DESC(1, MT7621_STATS_RFEPC, "RxFragment"),
++ MIB_DESC(1, MT7621_STATS_ROSPC, "RxOverSize"),
++ MIB_DESC(1, MT7621_STATS_RJEPC, "RxJabber"),
++ MIB_DESC(1, MT7621_STATS_RPPC, "RxPause"),
++ MIB_DESC(1, MT7621_STATS_RL64PC, "Rx64Byte"),
++ MIB_DESC(1, MT7621_STATS_RL65PC, "Rx65Byte"),
++ MIB_DESC(1, MT7621_STATS_RL128PC, "Rx128Byte"),
++ MIB_DESC(1, MT7621_STATS_RL256PC, "Rx256Byte"),
++ MIB_DESC(1, MT7621_STATS_RL512PC, "Rx512Byte"),
++ MIB_DESC(1, MT7621_STATS_RL1024PC, "Rx1024Byte"),
++ MIB_DESC(2, MT7621_STATS_ROC, "RxByte"),
++ MIB_DESC(1, MT7621_STATS_RDPC_CTRL, "RxCtrlDrop"),
++ MIB_DESC(1, MT7621_STATS_RDPC_ING, "RxIngDrop"),
++ MIB_DESC(1, MT7621_STATS_RDPC_ARL, "RxARLDrop")
++};
++
++enum {
++ /* Global attributes. */
++ MT7530_ATTR_ENABLE_VLAN,
++};
++
++struct mt7530_port_entry {
++ u16 pvid;
++};
++
++struct mt7530_vlan_entry {
++ u16 vid;
++ u8 member;
++ u8 etags;
++};
++
++struct mt7530_priv {
++ void __iomem *base;
++ struct mii_bus *bus;
++ struct switch_dev swdev;
++
++ bool global_vlan_enable;
++ struct mt7530_vlan_entry vlan_entries[MT7530_NUM_VLANS];
++ struct mt7530_port_entry port_entries[MT7530_NUM_PORTS];
++};
++
++struct mt7530_mapping {
++ char *name;
++ u16 pvids[MT7530_NUM_PORTS];
++ u8 members[MT7530_NUM_VLANS];
++ u8 etags[MT7530_NUM_VLANS];
++ u16 vids[MT7530_NUM_VLANS];
++} mt7530_defaults[] = {
++ {
++ .name = "llllw",
++ .pvids = { 1, 1, 1, 1, 2, 1, 1 },
++ .members = { 0, 0x6f, 0x50 },
++ .etags = { 0, 0x40, 0x40 },
++ .vids = { 0, 1, 2 },
++ }, {
++ .name = "wllll",
++ .pvids = { 2, 1, 1, 1, 1, 1, 1 },
++ .members = { 0, 0x7e, 0x41 },
++ .etags = { 0, 0x40, 0x40 },
++ .vids = { 0, 1, 2 },
++ },
++};
++
++struct mt7530_mapping*
++mt7530_find_mapping(struct device_node *np)
++{
++ const char *map;
++ int i;
++
++ if (of_property_read_string(np, "mediatek,portmap", &map))
++ return NULL;
++
++ for (i = 0; i < ARRAY_SIZE(mt7530_defaults); i++)
++ if (!strcmp(map, mt7530_defaults[i].name))
++ return &mt7530_defaults[i];
++
++ return NULL;
++}
++
++static void
++mt7530_apply_mapping(struct mt7530_priv *mt7530, struct mt7530_mapping *map)
++{
++ int i = 0;
++
++ for (i = 0; i < MT7530_NUM_PORTS; i++)
++ mt7530->port_entries[i].pvid = map->pvids[i];
++
++ for (i = 0; i < MT7530_NUM_VLANS; i++) {
++ mt7530->vlan_entries[i].member = map->members[i];
++ mt7530->vlan_entries[i].etags = map->etags[i];
++ mt7530->vlan_entries[i].vid = map->vids[i];
++ }
++}
++
++static int
++mt7530_reset_switch(struct switch_dev *dev)
++{
++ struct mt7530_priv *eth = container_of(dev, struct mt7530_priv, swdev);
++ int i;
++
++ memset(eth->port_entries, 0, sizeof(eth->port_entries));
++ memset(eth->vlan_entries, 0, sizeof(eth->vlan_entries));
++
++ /* set default vid of each vlan to the same number of vlan, so the vid
++ * won't need be set explicitly.
++ */
++ for (i = 0; i < MT7530_NUM_VLANS; i++) {
++ eth->vlan_entries[i].vid = i;
++ }
++
++ return 0;
++}
++
++static int
++mt7530_get_vlan_enable(struct switch_dev *dev,
++ const struct switch_attr *attr,
++ struct switch_val *val)
++{
++ struct mt7530_priv *eth = container_of(dev, struct mt7530_priv, swdev);
++
++ val->value.i = eth->global_vlan_enable;
++
++ return 0;
++}
++
++static int
++mt7530_set_vlan_enable(struct switch_dev *dev,
++ const struct switch_attr *attr,
++ struct switch_val *val)
++{
++ struct mt7530_priv *eth = container_of(dev, struct mt7530_priv, swdev);
++
++ eth->global_vlan_enable = val->value.i != 0;
++
++ return 0;
++}
++
++static u32
++mt7530_r32(struct mt7530_priv *eth, u32 reg)
++{
++ u32 val;
++ if (eth->bus) {
++ u16 high, low;
++
++ mdiobus_write(eth->bus, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
++ low = mdiobus_read(eth->bus, 0x1f, (reg >> 2) & 0xf);
++ high = mdiobus_read(eth->bus, 0x1f, 0x10);
++
++ return (high << 16) | (low & 0xffff);
++ }
++
++ val = ioread32(eth->base + reg);
++ pr_debug("MT7530 MDIO Read [%04x]=%08x\n", reg, val);
++
++ return val;
++}
++
++static void
++mt7530_w32(struct mt7530_priv *eth, u32 reg, u32 val)
++{
++ if (eth->bus) {
++ mdiobus_write(eth->bus, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
++ mdiobus_write(eth->bus, 0x1f, (reg >> 2) & 0xf, val & 0xffff);
++ mdiobus_write(eth->bus, 0x1f, 0x10, val >> 16);
++ return;
++ }
++
++ pr_debug("MT7530 MDIO Write[%04x]=%08x\n", reg, val);
++ iowrite32(val, eth->base + reg);
++}
++
++static void
++mt7530_vtcr(struct mt7530_priv *eth, u32 cmd, u32 val)
++{
++ int i;
++
++ mt7530_w32(eth, REG_ESW_VLAN_VTCR, BIT(31) | (cmd << 12) | val);
++
++ for (i = 0; i < 20; i++) {
++ u32 val = mt7530_r32(eth, REG_ESW_VLAN_VTCR);
++
++ if ((val & BIT(31)) == 0)
++ break;
++
++ udelay(1000);
++ }
++ if (i == 20)
++ printk("mt7530: vtcr timeout\n");
++}
++
++static int
++mt7530_get_port_pvid(struct switch_dev *dev, int port, int *val)
++{
++ struct mt7530_priv *eth = container_of(dev, struct mt7530_priv, swdev);
++
++ if (port >= MT7530_NUM_PORTS)
++ return -EINVAL;
++
++ *val = mt7530_r32(eth, REG_ESW_PORT_PPBV1(port));
++ *val &= 0xfff;
++
++ return 0;
++}
++
++static int
++mt7530_set_port_pvid(struct switch_dev *dev, int port, int pvid)
++{
++ struct mt7530_priv *eth = container_of(dev, struct mt7530_priv, swdev);
++
++ if (port >= MT7530_NUM_PORTS)
++ return -EINVAL;
++
++ if (pvid < MT7530_MIN_VID || pvid > MT7530_MAX_VID)
++ return -EINVAL;
++
++ eth->port_entries[port].pvid = pvid;
++
++ return 0;
++}
++
++static int
++mt7530_get_vlan_ports(struct switch_dev *dev, struct switch_val *val)
++{
++ struct mt7530_priv *eth = container_of(dev, struct mt7530_priv, swdev);
++ u32 member;
++ u32 etags;
++ int i;
++
++ val->len = 0;
++
++ if (val->port_vlan < 0 || val->port_vlan >= MT7530_NUM_VLANS)
++ return -EINVAL;
++
++ mt7530_vtcr(eth, 0, val->port_vlan);
++
++ member = mt7530_r32(eth, REG_ESW_VLAN_VAWD1);
++ member >>= 16;
++ member &= 0xff;
++
++ etags = mt7530_r32(eth, REG_ESW_VLAN_VAWD2);
++
++ for (i = 0; i < MT7530_NUM_PORTS; i++) {
++ struct switch_port *p;
++ int etag;
++
++ if (!(member & BIT(i)))
++ continue;
++
++ p = &val->value.ports[val->len++];
++ p->id = i;
++
++ etag = (etags >> (i * 2)) & 0x3;
++
++ if (etag == ETAG_CTRL_TAG)
++ p->flags |= BIT(SWITCH_PORT_FLAG_TAGGED);
++ else if (etag != ETAG_CTRL_UNTAG)
++ printk("vlan egress tag control neither untag nor tag.\n");
++ }
++
++ return 0;
++}
++
++static int
++mt7530_set_vlan_ports(struct switch_dev *dev, struct switch_val *val)
++{
++ struct mt7530_priv *eth = container_of(dev, struct mt7530_priv, swdev);
++ u8 member = 0;
++ u8 etags = 0;
++ int i;
++
++ if (val->port_vlan < 0 || val->port_vlan >= MT7530_NUM_VLANS ||
++ val->len > MT7530_NUM_PORTS)
++ return -EINVAL;
++
++ for (i = 0; i < val->len; i++) {
++ struct switch_port *p = &val->value.ports[i];
++
++ if (p->id >= MT7530_NUM_PORTS)
++ return -EINVAL;
++
++ member |= BIT(p->id);
++
++ if (p->flags & BIT(SWITCH_PORT_FLAG_TAGGED))
++ etags |= BIT(p->id);
++ }
++ eth->vlan_entries[val->port_vlan].member = member;
++ eth->vlan_entries[val->port_vlan].etags = etags;
++
++ return 0;
++}
++
++static int
++mt7530_set_vid(struct switch_dev *dev, const struct switch_attr *attr,
++ struct switch_val *val)
++{
++ struct mt7530_priv *eth = container_of(dev, struct mt7530_priv, swdev);
++ int vlan;
++ u16 vid;
++
++ vlan = val->port_vlan;
++ vid = (u16)val->value.i;
++
++ if (vlan < 0 || vlan >= MT7530_NUM_VLANS)
++ return -EINVAL;
++
++ if (vid < MT7530_MIN_VID || vid > MT7530_MAX_VID)
++ return -EINVAL;
++
++ eth->vlan_entries[vlan].vid = vid;
++ return 0;
++}
++
++static int
++mt7530_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
++ struct switch_val *val)
++{
++ struct mt7530_priv *eth = container_of(dev, struct mt7530_priv, swdev);
++ u32 vid;
++ int vlan;
++
++ vlan = val->port_vlan;
++
++ vid = mt7530_r32(eth, REG_ESW_VLAN_VTIM(vlan));
++ if (vlan & 1)
++ vid = vid >> 12;
++ vid &= 0xfff;
++
++ val->value.i = vid;
++ return 0;
++}
++
++static int
++mt7530_apply_config(struct switch_dev *dev)
++{
++ struct mt7530_priv *eth = container_of(dev, struct mt7530_priv, swdev);
++ int i, j;
++ u8 tag_ports;
++ u8 untag_ports;
++
++ if (!eth->global_vlan_enable) {
++ for (i = 0; i < MT7530_NUM_PORTS; i++)
++ mt7530_w32(eth, REG_ESW_PORT_PCR(i), 0x00ff0000);
++
++ for (i = 0; i < MT7530_NUM_PORTS; i++)
++ mt7530_w32(eth, REG_ESW_PORT_PVC(i), 0x810000c0);
++
++ return 0;
++ }
++
++ /* set all ports as security mode */
++ for (i = 0; i < MT7530_NUM_PORTS; i++)
++ mt7530_w32(eth, REG_ESW_PORT_PCR(i), 0x00ff0003);
++
++ /* check if a port is used in tag/untag vlan egress mode */
++ tag_ports = 0;
++ untag_ports = 0;
++
++ for (i = 0; i < MT7530_NUM_VLANS; i++) {
++ u8 member = eth->vlan_entries[i].member;
++ u8 etags = eth->vlan_entries[i].etags;
++
++ if (!member)
++ continue;
++
++ for (j = 0; j < MT7530_NUM_PORTS; j++) {
++ if (!(member & BIT(j)))
++ continue;
++
++ if (etags & BIT(j))
++ tag_ports |= 1u << j;
++ else
++ untag_ports |= 1u << j;
++ }
++ }
++
++ /* set all untag-only ports as transparent and the rest as user port */
++ for (i = 0; i < MT7530_NUM_PORTS; i++) {
++ u32 pvc_mode = 0x81000000;
++
++ if (untag_ports & BIT(i) && !(tag_ports & BIT(i)))
++ pvc_mode = 0x810000c0;
++
++ mt7530_w32(eth, REG_ESW_PORT_PVC(i), pvc_mode);
++ }
++
++ for (i = 0; i < MT7530_NUM_VLANS; i++) {
++ u16 vid = eth->vlan_entries[i].vid;
++ u8 member = eth->vlan_entries[i].member;
++ u8 etags = eth->vlan_entries[i].etags;
++ u32 val;
++
++ /* vid of vlan */
++ val = mt7530_r32(eth, REG_ESW_VLAN_VTIM(i));
++ if (i % 2 == 0) {
++ val &= 0xfff000;
++ val |= vid;
++ } else {
++ val &= 0xfff;
++ val |= (vid << 12);
++ }
++ mt7530_w32(eth, REG_ESW_VLAN_VTIM(i), val);
++
++ /* vlan port membership */
++ if (member)
++ mt7530_w32(eth, REG_ESW_VLAN_VAWD1, REG_ESW_VLAN_VAWD1_IVL_MAC |
++ REG_ESW_VLAN_VAWD1_VTAG_EN | (member << 16) |
++ REG_ESW_VLAN_VAWD1_VALID);
++ else
++ mt7530_w32(eth, REG_ESW_VLAN_VAWD1, 0);
++
++ /* egress mode */
++ val = 0;
++ for (j = 0; j < MT7530_NUM_PORTS; j++) {
++ if (etags & BIT(j))
++ val |= ETAG_CTRL_TAG << (j * 2);
++ else
++ val |= ETAG_CTRL_UNTAG << (j * 2);
++ }
++ mt7530_w32(eth, REG_ESW_VLAN_VAWD2, val);
++
++ /* write to vlan table */
++ mt7530_vtcr(eth, 1, i);
++ }
++
++ /* Port Default PVID */
++ for (i = 0; i < MT7530_NUM_PORTS; i++) {
++ u32 val;
++ val = mt7530_r32(eth, REG_ESW_PORT_PPBV1(i));
++ val &= ~0xfff;
++ val |= eth->port_entries[i].pvid;
++ mt7530_w32(eth, REG_ESW_PORT_PPBV1(i), val);
++ }
++
++ return 0;
++}
++
++static int
++mt7530_get_port_link(struct switch_dev *dev, int port,
++ struct switch_port_link *link)
++{
++ struct mt7530_priv *eth = container_of(dev, struct mt7530_priv, swdev);
++ u32 speed, pmsr;
++
++ if (port < 0 || port >= MT7530_NUM_PORTS)
++ return -EINVAL;
++
++ pmsr = mt7530_r32(eth, 0x3008 + (0x100 * port));
++
++ link->link = pmsr & 1;
++ link->duplex = (pmsr >> 1) & 1;
++ speed = (pmsr >> 2) & 3;
++
++ switch (speed) {
++ case 0:
++ link->speed = SWITCH_PORT_SPEED_10;
++ break;
++ case 1:
++ link->speed = SWITCH_PORT_SPEED_100;
++ break;
++ case 2:
++ case 3: /* forced gige speed can be 2 or 3 */
++ link->speed = SWITCH_PORT_SPEED_1000;
++ break;
++ default:
++ link->speed = SWITCH_PORT_SPEED_UNKNOWN;
++ break;
++ }
++
++ return 0;
++}
++
++static const struct switch_attr mt7530_global[] = {
++ {
++ .type = SWITCH_TYPE_INT,
++ .name = "enable_vlan",
++ .description = "VLAN mode (1:enabled)",
++ .max = 1,
++ .id = MT7530_ATTR_ENABLE_VLAN,
++ .get = mt7530_get_vlan_enable,
++ .set = mt7530_set_vlan_enable,
++ },
++};
++
++static u64 get_mib_counter(struct mt7530_priv *eth, int i, int port)
++{
++ unsigned int port_base;
++ u64 t;
++
++ port_base = MT7621_MIB_COUNTER_BASE +
++ MT7621_MIB_COUNTER_PORT_OFFSET * port;
++
++ t = mt7530_r32(eth, port_base + mt7621_mibs[i].offset);
++ if (mt7621_mibs[i].size == 2) {
++ u64 hi;
++
++ hi = mt7530_r32(eth, port_base + mt7621_mibs[i].offset + 4);
++ t |= hi << 32;
++ }
++
++ return t;
++}
++
++static int mt7621_sw_get_port_mib(struct switch_dev *dev,
++ const struct switch_attr *attr,
++ struct switch_val *val)
++{
++ static char buf[4096];
++ struct mt7530_priv *eth = container_of(dev, struct mt7530_priv, swdev);
++ int i, len = 0;
++
++ if (val->port_vlan >= MT7530_NUM_PORTS)
++ return -EINVAL;
++
++ len += snprintf(buf + len, sizeof(buf) - len,
++ "Port %d MIB counters\n", val->port_vlan);
++
++ for (i = 0; i < sizeof(mt7621_mibs) / sizeof(*mt7621_mibs); ++i) {
++ u64 counter;
++ len += snprintf(buf + len, sizeof(buf) - len,
++ "%-11s: ", mt7621_mibs[i].name);
++ counter = get_mib_counter(eth, i, val->port_vlan);
++ len += snprintf(buf + len, sizeof(buf) - len, "%llu\n",
++ counter);
++ }
++
++ val->value.s = buf;
++ val->len = len;
++ return 0;
++}
++
++static const struct switch_attr mt7621_port[] = {
++ {
++ .type = SWITCH_TYPE_STRING,
++ .name = "mib",
++ .description = "Get MIB counters for port",
++ .get = mt7621_sw_get_port_mib,
++ .set = NULL,
++ },
++};
++
++static const struct switch_attr mt7530_port[] = {
++};
++
++static const struct switch_attr mt7530_vlan[] = {
++ {
++ .type = SWITCH_TYPE_INT,
++ .name = "vid",
++ .description = "VLAN ID (0-4094)",
++ .set = mt7530_set_vid,
++ .get = mt7530_get_vid,
++ .max = 4094,
++ },
++};
++
++static const struct switch_dev_ops mt7621_ops = {
++ .attr_global = {
++ .attr = mt7530_global,
++ .n_attr = ARRAY_SIZE(mt7530_global),
++ },
++/* .attr_port = {
++ .attr = mt7621_port,
++ .n_attr = ARRAY_SIZE(mt7621_port),
++ },*/
++ .attr_vlan = {
++ .attr = mt7530_vlan,
++ .n_attr = ARRAY_SIZE(mt7530_vlan),
++ },
++ .get_vlan_ports = mt7530_get_vlan_ports,
++ .set_vlan_ports = mt7530_set_vlan_ports,
++ .get_port_pvid = mt7530_get_port_pvid,
++ .set_port_pvid = mt7530_set_port_pvid,
++ .get_port_link = mt7530_get_port_link,
++ .apply_config = mt7530_apply_config,
++ .reset_switch = mt7530_reset_switch,
++};
++
++static const struct switch_dev_ops mt7530_ops = {
++ .attr_global = {
++ .attr = mt7530_global,
++ .n_attr = ARRAY_SIZE(mt7530_global),
++ },
++ .attr_port = {
++ .attr = mt7530_port,
++ .n_attr = ARRAY_SIZE(mt7530_port),
++ },
++ .attr_vlan = {
++ .attr = mt7530_vlan,
++ .n_attr = ARRAY_SIZE(mt7530_vlan),
++ },
++ .get_vlan_ports = mt7530_get_vlan_ports,
++ .set_vlan_ports = mt7530_set_vlan_ports,
++ .get_port_pvid = mt7530_get_port_pvid,
++ .set_port_pvid = mt7530_set_port_pvid,
++ .get_port_link = mt7530_get_port_link,
++ .apply_config = mt7530_apply_config,
++ .reset_switch = mt7530_reset_switch,
++};
++
++int
++mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus, int vlan)
++{
++ struct switch_dev *swdev;
++ struct mt7530_priv *mt7530;
++ struct mt7530_mapping *map;
++ int ret;
++
++ mt7530 = devm_kzalloc(dev, sizeof(struct mt7530_priv), GFP_KERNEL);
++ if (!mt7530)
++ return -ENOMEM;
++
++ mt7530->base = base;
++ mt7530->bus = bus;
++ mt7530->global_vlan_enable = vlan;
++
++ swdev = &mt7530->swdev;
++ if (bus) {
++ swdev->alias = "mt7530";
++ swdev->name = "mt7530";
++ } else if (IS_ENABLED(CONFIG_MACH_MT7623)) {
++ swdev->alias = "mt7623";
++ swdev->name = "mt7623";
++ } else if (IS_ENABLED(CONFIG_SOC_MT7621)) {
++ swdev->alias = "mt7621";
++ swdev->name = "mt7621";
++ } else {
++ swdev->alias = "mt7620";
++ swdev->name = "mt7620";
++ }
++ swdev->cpu_port = MT7530_CPU_PORT;
++ swdev->ports = MT7530_NUM_PORTS;
++ swdev->vlans = MT7530_NUM_VLANS;
++ if (IS_ENABLED(CONFIG_SOC_MT7621) || IS_ENABLED(CONFIG_MACH_MT7623))
++ swdev->ops = &mt7621_ops;
++ else
++ swdev->ops = &mt7530_ops;
++
++ ret = register_switch(swdev, NULL);
++ if (ret) {
++ dev_err(dev, "failed to register mt7530\n");
++ return ret;
++ }
++
++ mt7530_reset_switch(swdev);
++
++ map = mt7530_find_mapping(dev->of_node);
++ if (map)
++ mt7530_apply_mapping(mt7530, map);
++ mt7530_apply_config(swdev);
++
++ /* magic vodoo */
++ if (!(IS_ENABLED(CONFIG_SOC_MT7621) || IS_ENABLED(CONFIG_MACH_MT7623)) && bus && mt7530_r32(mt7530, REG_HWTRAP) != 0x1117edf) {
++ dev_info(dev, "fixing up MHWTRAP register - bootloader probably played with it\n");
++ mt7530_w32(mt7530, REG_HWTRAP, 0x1117edf);
++ }
++ dev_info(dev, "loaded %s driver\n", swdev->name);
++
++ return 0;
++}
+diff --git a/drivers/net/ethernet/mediatek/mt7530.h b/drivers/net/ethernet/mediatek/mt7530.h
+new file mode 100644
+index 0000000..1fc8c62
+--- /dev/null
++++ b/drivers/net/ethernet/mediatek/mt7530.h
+@@ -0,0 +1,20 @@
++/*
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
++ */
++
++#ifndef _MT7530_H__
++#define _MT7530_H__
++
++int mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus, int vlan);
++
++#endif
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index ba3afa5..62058a2 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -24,6 +24,9 @@
+
+ #include "mtk_eth_soc.h"
+
++/* the callback used by the driver core to bringup the switch */
++int mtk_gsw_init(struct mtk_eth *eth);
++
+ static int mtk_msg_level = -1;
+ module_param_named(msg_level, mtk_msg_level, int, 0);
+ MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)");
+@@ -69,7 +72,7 @@ static int mtk_mdio_busy_wait(struct mtk_eth *eth)
+ return 0;
+ if (time_after(jiffies, t_start + PHY_IAC_TIMEOUT))
+ break;
+- usleep_range(10, 20);
++// usleep_range(10, 20);
+ }
+
+ dev_err(eth->dev, "mdio: MDIO timeout\n");
+@@ -132,36 +135,20 @@ static int mtk_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
+
+ static void mtk_phy_link_adjust(struct net_device *dev)
+ {
++ return;
++
+ struct mtk_mac *mac = netdev_priv(dev);
+ u32 mcr = MAC_MCR_MAX_RX_1536 | MAC_MCR_IPG_CFG |
+ MAC_MCR_FORCE_MODE | MAC_MCR_TX_EN |
+ MAC_MCR_RX_EN | MAC_MCR_BACKOFF_EN |
+ MAC_MCR_BACKPR_EN;
+
+- switch (mac->phy_dev->speed) {
+- case SPEED_1000:
+- mcr |= MAC_MCR_SPEED_1000;
+- break;
+- case SPEED_100:
+- mcr |= MAC_MCR_SPEED_100;
+- break;
+- };
+-
+- if (mac->phy_dev->link)
+- mcr |= MAC_MCR_FORCE_LINK;
+-
+- if (mac->phy_dev->duplex)
+- mcr |= MAC_MCR_FORCE_DPX;
+-
+- if (mac->phy_dev->pause)
+- mcr |= MAC_MCR_FORCE_RX_FC | MAC_MCR_FORCE_TX_FC;
+-
++ mcr |= MAC_MCR_SPEED_1000;
++ mcr |= MAC_MCR_FORCE_LINK;
++ mcr |= MAC_MCR_FORCE_DPX;
++ mcr |= MAC_MCR_FORCE_RX_FC | MAC_MCR_FORCE_TX_FC;
+ mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
+-
+- if (mac->phy_dev->link)
+- netif_carrier_on(dev);
+- else
+- netif_carrier_off(dev);
++ return;
+ }
+
+ static int mtk_phy_connect_node(struct mtk_eth *eth, struct mtk_mac *mac,
+@@ -193,7 +180,7 @@ static int mtk_phy_connect_node(struct mtk_eth *eth, struct mtk_mac *mac,
+
+ dev_info(eth->dev,
+ "connected mac %d to PHY at %s [uid=%08x, driver=%s]\n",
+- mac->id, phydev_name(phydev), phydev->phy_id,
++ mac->id, dev_name(&phydev->dev), phydev->phy_id,
+ phydev->drv->name);
+
+ mac->phy_dev = phydev;
+@@ -634,7 +621,6 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
+
+ spin_unlock_irqrestore(&eth->page_lock, flags);
+
+- netdev_sent_queue(dev, skb->len);
+ skb_tx_timestamp(skb);
+
+ ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2);
+@@ -882,7 +868,6 @@ static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again)
+ for (i = 0; i < MTK_MAC_COUNT; i++) {
+ if (!eth->netdev[i] || !done[i])
+ continue;
+- netdev_completed_queue(eth->netdev[i], done[i], bytes[i]);
+ total += done[i];
+ }
+
+@@ -1249,6 +1234,8 @@ static int mtk_open(struct net_device *dev)
+ phy_start(mac->phy_dev);
+ netif_start_queue(dev);
+
++ netif_carrier_on(dev);
++
+ return 0;
+ }
+
+@@ -1281,6 +1268,7 @@ static int mtk_stop(struct net_device *dev)
+ struct mtk_mac *mac = netdev_priv(dev);
+ struct mtk_eth *eth = mac->hw;
+
++ netif_carrier_off(dev);
+ netif_tx_disable(dev);
+ phy_stop(mac->phy_dev);
+
+@@ -1326,6 +1314,7 @@ static int __init mtk_hw_init(struct mtk_eth *eth)
+ /* Enable RX VLan Offloading */
+ mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
+
++ mtk_gsw_init(eth);
+ err = devm_request_irq(eth->dev, eth->irq, mtk_handle_irq, 0,
+ dev_name(eth->dev), eth);
+ if (err)
+@@ -1358,6 +1347,8 @@ static int __init mtk_hw_init(struct mtk_eth *eth)
+ mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
+ }
+
++ mt7623_gsw_config(eth);
++
+ return 0;
+ }
+
+@@ -1464,11 +1455,13 @@ static int mtk_set_settings(struct net_device *dev,
+ {
+ struct mtk_mac *mac = netdev_priv(dev);
+
+- if (cmd->phy_address != mac->phy_dev->mdio.addr) {
+- mac->phy_dev = mdiobus_get_phy(mac->hw->mii_bus,
+- cmd->phy_address);
+- if (!mac->phy_dev)
++ if (cmd->phy_address != mac->phy_dev->addr) {
++ if (mac->hw->mii_bus->phy_map[cmd->phy_address]) {
++ mac->phy_dev =
++ mac->hw->mii_bus->phy_map[cmd->phy_address];
++ } else {
+ return -ENODEV;
++ }
+ }
+
+ return phy_ethtool_sset(mac->phy_dev, cmd);
+@@ -1561,7 +1554,6 @@ static void mtk_get_ethtool_stats(struct net_device *dev,
+ data_src = (u64*)hwstats;
+ data_dst = data;
+ start = u64_stats_fetch_begin_irq(&hwstats->syncp);
+-
+ for (i = 0; i < ARRAY_SIZE(mtk_ethtool_stats); i++)
+ *data_dst++ = *(data_src + mtk_ethtool_stats[i].offset);
+ } while (u64_stats_fetch_retry_irq(&hwstats->syncp, start));
+@@ -1733,6 +1725,9 @@ static int mtk_probe(struct platform_device *pdev)
+ clk_prepare_enable(eth->clk_gp1);
+ clk_prepare_enable(eth->clk_gp2);
+
++ eth->switch_np = of_parse_phandle(pdev->dev.of_node,
++ "mediatek,switch", 0);
++
+ eth->dev = &pdev->dev;
+ eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE);
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+index 48a5292..d737d61 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -389,6 +389,9 @@ struct mtk_eth {
+ struct clk *clk_gp1;
+ struct clk *clk_gp2;
+ struct mii_bus *mii_bus;
++
++ struct device_node *switch_np;
++ void *sw_priv;
+ };
+
+ /* struct mtk_mac - the structure that holds the info about the MACs of the
+@@ -418,4 +421,6 @@ void mtk_stats_update_mac(struct mtk_mac *mac);
+ void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
+ u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
+
++int mt7623_gsw_config(struct mtk_eth *eth);
++
+ #endif /* MTK_ETH_H */
+diff --git a/lib/dynamic_queue_limits.c b/lib/dynamic_queue_limits.c
+index f346715..b04f8e6 100644
+--- a/lib/dynamic_queue_limits.c
++++ b/lib/dynamic_queue_limits.c
+@@ -23,8 +23,10 @@ void dql_completed(struct dql *dql, unsigned int count)
+ num_queued = ACCESS_ONCE(dql->num_queued);
+
+ /* Can't complete more than what's in queue */
+- BUG_ON(count > num_queued - dql->num_completed);
+-
++ if (count > num_queued - dql->num_completed) {
++ printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__);
++ count = 0;
++ }
+ completed = dql->num_completed + count;
+ limit = dql->limit;
+ ovlimit = POSDIFF(num_queued - dql->num_completed, limit);
+--
+1.7.10.4
+
diff --git a/target/linux/mediatek/patches-4.4/0053-dont-disable-clocks.patch b/target/linux/mediatek/patches-4.4/0053-dont-disable-clocks.patch
new file mode 100644
index 0000000000..9ec5c89a2f
--- /dev/null
+++ b/target/linux/mediatek/patches-4.4/0053-dont-disable-clocks.patch
@@ -0,0 +1,25 @@
+From 308cdd2b743a5e01b26d79c8fb89e513dea09856 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Tue, 23 Jun 2015 23:46:00 +0200
+Subject: [PATCH 53/53] dont disable clocks
+
+---
+ drivers/clk/clk.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index f13c3f4..5e9ddae 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -233,7 +233,7 @@ unlock_out:
+ clk_enable_unlock(flags);
+ }
+
+-static bool clk_ignore_unused;
++static bool clk_ignore_unused = true;
+ static int __init clk_ignore_unused_setup(char *__unused)
+ {
+ clk_ignore_unused = true;
+--
+1.7.10.4
+