CPU_SUBTYPE:=neon-vfpv4
MAINTAINER:=John Crispin <john@phrozen.org>
-KERNEL_PATCHVER:=4.4
+KERNEL_PATCHVER:=4.9
KERNELNAME:=Image dtbs zImage
+++ /dev/null
-# CONFIG_AIO is not set
-CONFIG_ALIGNMENT_TRAP=y
-# CONFIG_APM_EMULATION is not set
-CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
-CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
-CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
-CONFIG_ARCH_HAS_SG_CHAIN=y
-CONFIG_ARCH_HAS_TICK_BROADCAST=y
-CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_MEDIATEK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-# CONFIG_ARCH_MULTI_CPU_AUTO is not set
-CONFIG_ARCH_MULTI_V6_V7=y
-CONFIG_ARCH_MULTI_V7=y
-CONFIG_ARCH_NR_GPIO=0
-# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
-CONFIG_ARCH_SUPPORTS_UPROBES=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARCH_USE_BUILTIN_BSWAP=y
-CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
-CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
-CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
-CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
-CONFIG_ARM=y
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
-# CONFIG_ARM_ATAG_DTB_COMPAT is not set
-CONFIG_ARM_CPU_SUSPEND=y
-# CONFIG_ARM_CPU_TOPOLOGY is not set
-CONFIG_ARM_GIC=y
-CONFIG_ARM_HAS_SG_CHAIN=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-# CONFIG_ARM_LPAE is not set
-CONFIG_ARM_MT7623_CPUFREQ=y
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-# CONFIG_ARM_SMMU is not set
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_THUMBEE=y
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-CONFIG_ATAGS=y
-CONFIG_AUTO_ZRELADDR=y
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
-CONFIG_BOUNCE=y
-# CONFIG_CACHE_L2X0 is not set
-CONFIG_CC_STACKPROTECTOR=y
-# CONFIG_CC_STACKPROTECTOR_NONE is not set
-CONFIG_CC_STACKPROTECTOR_REGULAR=y
-CONFIG_CLEANCACHE=y
-CONFIG_CLKDEV_LOOKUP=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLKSRC_OF=y
-CONFIG_CLKSRC_PROBE=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 block2mtd.block2mtd=/dev/mmcblk0,65536,eMMC,5 mtdparts=eMMC:256k(mbr)ro,512k(uboot)ro,256k(config)ro,256k(factory)ro,32M(kernel),32M(recovery),1024M(rootfs),2048M(usrdata),-(bmtpool) rootfstype=squashfs,jffs2"
-CONFIG_CMDLINE_FORCE=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_MEDIATEK=y
-CONFIG_COMMON_CLK_MT2701=y
-# CONFIG_COMMON_CLK_MT8135 is not set
-# CONFIG_COMMON_CLK_MT8173 is not set
-CONFIG_COMPACTION=y
-CONFIG_COREDUMP=y
-# CONFIG_CPUFREQ_DT is not set
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-# CONFIG_CPU_BPREDICT_DISABLE is not set
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_COMMON=y
-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
-CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=y
-# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_HAS_ASID=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
-CONFIG_CRC16=y
-# CONFIG_CRC32_SARWATE is not set
-CONFIG_CRC32_SLICEBY8=y
-CONFIG_CROSS_MEMORY_ATTACH=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_WORKQUEUE=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_GPIO=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL=y
-CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
-CONFIG_DEBUG_MT6589_UART0=y
-# CONFIG_DEBUG_MT8127_UART0 is not set
-# CONFIG_DEBUG_MT8135_UART3 is not set
-CONFIG_DEBUG_PREEMPT=y
-CONFIG_DEBUG_UART_8250=y
-# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set
-CONFIG_DEBUG_UART_8250_SHIFT=2
-# CONFIG_DEBUG_UART_8250_WORD is not set
-CONFIG_DEBUG_UART_PHYS=0x11004000
-CONFIG_DEBUG_UART_VIRT=0xf1004000
-CONFIG_DEBUG_UNCOMPRESS=y
-# CONFIG_DEBUG_USER is not set
-CONFIG_DMADEVICES=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DTC=y
-# CONFIG_DW_DMAC_PCI is not set
-CONFIG_EARLY_PRINTK=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_ELF_CORE=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FREEZER=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IO=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_MSI_IRQ=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_DEVRES=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
-CONFIG_HAVE_ARCH_AUDITSYSCALL=y
-CONFIG_HAVE_ARCH_BITREVERSE=y
-CONFIG_HAVE_ARCH_JUMP_LABEL=y
-CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_HAVE_ARCH_PFN_VALID=y
-CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
-CONFIG_HAVE_ARCH_TRACEHOOK=y
-CONFIG_HAVE_ARM_ARCH_TIMER=y
-# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
-CONFIG_HAVE_BPF_JIT=y
-CONFIG_HAVE_CC_STACKPROTECTOR=y
-CONFIG_HAVE_CLK=y
-CONFIG_HAVE_CLK_PREPARE=y
-CONFIG_HAVE_CONTEXT_TRACKING=y
-CONFIG_HAVE_C_RECORDMCOUNT=y
-CONFIG_HAVE_DEBUG_KMEMLEAK=y
-CONFIG_HAVE_DMA_API_DEBUG=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_HAVE_DMA_CONTIGUOUS=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_HAVE_IDE=y
-CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
-CONFIG_HAVE_MEMBLOCK=y
-CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
-CONFIG_HAVE_NET_DSA=y
-CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_OPTPROBES=y
-CONFIG_HAVE_PERF_EVENTS=y
-CONFIG_HAVE_PERF_REGS=y
-CONFIG_HAVE_PERF_USER_STACK_DUMP=y
-CONFIG_HAVE_PROC_CPU=y
-CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
-CONFIG_HAVE_SMP=y
-CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
-CONFIG_HAVE_UID16=y
-CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
-CONFIG_HIGHMEM=y
-# CONFIG_HIGHPTE is not set
-CONFIG_HOTPLUG_CPU=y
-CONFIG_HWMON=y
-CONFIG_HW_RANDOM=y
-CONFIG_HZ_FIXED=0
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_MT65XX=y
-CONFIG_INITRAMFS_ROOT_GID=1000
-CONFIG_INITRAMFS_ROOT_UID=1000
-CONFIG_INITRAMFS_SOURCE="/openwrt/trunk/build_dir/target-arm_cortex-a7_musl-1.1.14_eabi/root-mediatek /openwrt/trunk/target/linux/generic/image/initramfs-base-files.txt"
-CONFIG_IOMMU_HELPER=y
-# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
-CONFIG_IOMMU_SUPPORT=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_KALLSYMS=y
-CONFIG_LIBFDT=y
-CONFIG_LOCKUP_DETECTOR=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MACH_MT2701=y
-# CONFIG_MACH_MT6589 is not set
-# CONFIG_MACH_MT6592 is not set
-CONFIG_MACH_MT7623=y
-CONFIG_MACH_MT8127=y
-# CONFIG_MACH_MT8135 is not set
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_MDIO_BITBANG=y
-CONFIG_MDIO_BOARDINFO=y
-CONFIG_MDIO_GPIO=y
-CONFIG_MEDIATEK_WATCHDOG=y
-CONFIG_MFD_CORE=y
-CONFIG_MFD_MT6397=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGHT_HAVE_PCI=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_MTK=y
-CONFIG_MMC_SDHCI=y
-# CONFIG_MMC_SDHCI_PCI is not set
-CONFIG_MMC_SDHCI_PLTFM=y
-# CONFIG_MMC_TIFM_SD is not set
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_BLOCK2MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_M25P80=y
-CONFIG_MTD_MT81xx_NOR=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_MTK=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-# CONFIG_MTD_UBI_FASTMAP is not set
-# CONFIG_MTD_UBI_GLUEBI is not set
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_MTK_INFRACFG=y
-CONFIG_MTK_PMIC_WRAP=y
-CONFIG_MTK_SCPSYS=y
-CONFIG_MTK_SCPSYS_MT2701=y
-CONFIG_MTK_SCPSYS_MT8173=y
-CONFIG_MTK_TIMER=y
-CONFIG_MULTI_IRQ_HANDLER=y
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-# CONFIG_NEON is not set
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_MEDIATEK_SOC=y
-# CONFIG_NET_VENDOR_AURORA is not set
-CONFIG_NET_VENDOR_MEDIATEK=y
-# CONFIG_NET_VENDOR_WIZNET is not set
-CONFIG_NLS=y
-CONFIG_NO_BOOTMEM=y
-CONFIG_NO_HZ=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NR_CPUS=4
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_ADDRESS_PCI=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_MDIO=y
-CONFIG_OF_MTD=y
-CONFIG_OF_NET=y
-CONFIG_OF_PCI=y
-CONFIG_OF_PCI_IRQ=y
-CONFIG_OF_RESERVED_MEM=y
-CONFIG_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PCI=y
-CONFIG_PCIE_MTK=y
-# CONFIG_PCI_DOMAINS_GENERIC is not set
-CONFIG_PCI_MSI=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHY_MT65XX_USB3=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_MT2701=y
-CONFIG_PINCTRL_MT6397=y
-CONFIG_PINCTRL_MT7623=y
-CONFIG_PINCTRL_MT8127=y
-# CONFIG_PINCTRL_MT8135 is not set
-CONFIG_PINCTRL_MTK_COMMON=y
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-# CONFIG_PM_DEBUG is not set
-CONFIG_PM_GENERIC_DOMAINS=y
-CONFIG_PM_GENERIC_DOMAINS_OF=y
-CONFIG_PM_GENERIC_DOMAINS_SLEEP=y
-CONFIG_PM_OPP=y
-CONFIG_PM_SLEEP=y
-CONFIG_PM_SLEEP_SMP=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PREEMPT=y
-CONFIG_PREEMPT_COUNT=y
-# CONFIG_PREEMPT_NONE is not set
-CONFIG_PREEMPT_RCU=y
-CONFIG_PRINTK_TIME=y
-CONFIG_PWM=y
-CONFIG_PWM_MEDIATEK=y
-# CONFIG_PWM_MTK_DISP is not set
-CONFIG_PWM_SYSFS=y
-CONFIG_RATIONAL=y
-CONFIG_RCU_CPU_STALL_TIMEOUT=21
-# CONFIG_RCU_EXPERT is not set
-CONFIG_RCU_STALL_COMMON=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_GPIO=y
-CONFIG_REGULATOR_MT6323=y
-# CONFIG_REGULATOR_MT6397 is not set
-# CONFIG_REGULATOR_QCOM_SPMI is not set
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_DRV_CMOS is not set
-# CONFIG_RTC_DRV_MT6397 is not set
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_SCHED_HRTICK=y
-# CONFIG_SCHED_INFO is not set
-# CONFIG_SCSI_DMA is not set
-# CONFIG_SERIAL_8250_DMA is not set
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_8250_MT6577=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SMP=y
-# CONFIG_SMP_ON_UP is not set
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MT65XX=y
-CONFIG_SPMI=y
-CONFIG_SRCU=y
-# CONFIG_STRIP_ASM_SYMS is not set
-CONFIG_SUSPEND=y
-CONFIG_SUSPEND_FREEZER=y
-CONFIG_SWCONFIG=y
-CONFIG_SWIOTLB=y
-CONFIG_SWP_EMULATE=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_THUMB2_KERNEL is not set
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_STATS=y
-CONFIG_UBIFS_FS=y
-# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
-CONFIG_UBIFS_FS_LZO=y
-CONFIG_UBIFS_FS_ZLIB=y
-CONFIG_UEVENT_HELPER_PATH=""
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNINLINE_SPIN_UNLOCK=y
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-# CONFIG_USB_EHCI_HCD is not set
-CONFIG_USB_SUPPORT=y
-# CONFIG_USB_UHCI_HCD is not set
-CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_MTK=y
-CONFIG_USB_XHCI_PCI=y
-CONFIG_USB_XHCI_PLATFORM=y
-CONFIG_USE_OF=y
-CONFIG_VECTORS_BASE=0xffff0000
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XPS=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA_FLAG=0
#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/reset/mt2701-resets.h>
#include <dt-bindings/pinctrl/mt7623-pinfunc.h>
#include "skeleton64.dtsi"
+++ /dev/null
-From 1e021917e634b173d466bf0dd3d2ae84e51a77ff Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 27 Jul 2014 09:38:50 +0100
-Subject: [PATCH 001/102] 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(-)
-
---- a/drivers/net/phy/phy.c
-+++ b/drivers/net/phy/phy.c
-@@ -890,7 +890,8 @@ void phy_state_machine(struct work_struc
- /* 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;
- }
-@@ -973,7 +974,8 @@ void phy_state_machine(struct work_struc
- 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);
-@@ -985,7 +987,8 @@ void phy_state_machine(struct work_struc
- 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;
- }
---- 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;
-
+++ /dev/null
-From 1892fcf687116720d07135c83d489a23ec56a166 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 002/102] 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
-
---- 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.
---- 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
---- /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);
---- 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
- 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;
-
-- for (i = 0; i < NUM_DOMAINS; i++) {
-+ pd_data->domains = devm_kzalloc(&pdev->dev,
-+ sizeof(*pd_data->domains) * num, GFP_KERNEL);
-+ if (!pd_data->domains)
-+ return ERR_PTR(-ENOMEM);
-+
-+ 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 pl
- 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 pl
- * 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);
---- /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 */
+++ /dev/null
-From 6f87948c3a58f02f6a64eadda719317016739d5e 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 003/102] 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(-)
-
---- 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);
+++ /dev/null
-From 7c5b29de78f1b15c5bde40a6ca4510fc09588457 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 004/102] 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
-
---- /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 */
+++ /dev/null
-From 8aa49d107d8a22fd6cbf37174614baf32d0976e2 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 005/102] 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
-
---- 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.
---- a/drivers/soc/mediatek/Makefile
-+++ b/drivers/soc/mediatek/Makefile
-@@ -2,3 +2,4 @@ obj-$(CONFIG_MTK_INFRACFG) += mtk-infrac
- 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
---- /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");
+++ /dev/null
-From 69d4e250847f82a5896c41bcb5f1e793c5a8fbac 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 006/102] 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
-
---- 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"
---- /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.
---- 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
+++ /dev/null
-From 7c98b20fa68a2a64bca69822eb7be4fa9b668fab 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 007/102] 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
-
---- 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 provi
- Required Properties:
-
- - compatible: Should be:
-+ - "mediatek,mt2701-apmixedsys"
- - "mediatek,mt8135-apmixedsys"
- - "mediatek,mt8173-apmixedsys"
- - #clock-cells: Must be 1
---- /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>;
-+};
---- /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>;
-+};
---- /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>;
-+};
---- 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
- Required Properties:
-
- - compatible: Should be:
-+ - "mediatek,mt2701-imgsys", "syscon"
- - "mediatek,mt8173-imgsys", "syscon"
- - #clock-cells: Must be 1
-
---- 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
---- 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 v
- Required Properties:
-
- - compatible: Should be:
-+ - "mediatek,mt2701-mmsys", "syscon"
- - "mediatek,mt8173-mmsys", "syscon"
- - #clock-cells: Must be 1
-
---- 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
---- 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 provide
- Required Properties:
-
- - compatible: Should be:
-+ - "mediatek,mt2701-topckgen"
- - "mediatek,mt8135-topckgen"
- - "mediatek,mt8173-topckgen"
- - #clock-cells: Must be 1
---- 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
- Required Properties:
-
- - compatible: Should be:
-+ - "mediatek,mt2701-vdecsys", "syscon"
- - "mediatek,mt8173-vdecsys", "syscon"
- - #clock-cells: Must be 1
-
+++ /dev/null
-From 190696e3995be38fa01490e4ab88ea2c859829c9 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 008/102] 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
-
---- /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 */
+++ /dev/null
-From a4c507d052390b42d7e8c59241e3c336796f730f 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 009/102] 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
-
---- 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
---- 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
---- 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
- 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 cl
- 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_se
- .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,
---- 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_cl
-
- 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,
---- /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 = ð_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);
---- a/drivers/clk/mediatek/clk-mtk.c
-+++ b/drivers/clk/mediatek/clk-mtk.c
-@@ -242,3 +242,28 @@ void __init mtk_clk_register_composites(
- 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;
-+ }
-+}
---- 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);
-
+++ /dev/null
-From 8bf0f2a1e8ff082de3f650211abd985ef68abe1b 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 010/102] 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
-
---- /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 */
+++ /dev/null
-From 3ba0020ea70ffb5503eff1823be7fa5ceda38286 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 011/102] 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(+)
-
---- a/drivers/clk/mediatek/clk-mt2701.c
-+++ b/drivers/clk/mediatek/clk-mt2701.c
-@@ -665,6 +665,8 @@ static void __init mtk_infrasys_init(str
- 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(stru
- 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);
-
+++ /dev/null
-From 32fa899c6ab79953e4f470fb23c38bcc40edc5c8 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 012/102] 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(+)
-
---- 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
+++ /dev/null
-From afcbed6f51e8c3a9195952b27c8aad047c314ed0 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 013/102] 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(-)
-
---- 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
-
- 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.
+++ /dev/null
-From 124894a4d1635915ff95c447767677b60fd27e9c 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 014/102] 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
-
---- /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 */
---- 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
---- 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
---- /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);
---- 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(st
- 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(®_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 p
- 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 p
- 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 pinct
- 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
-
- 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(®_addr, offset);
-+
- regmap_read(pctl->regmap1, reg_addr, &read_val);
- return !(read_val & bit);
- }
---- 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;
---- /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 */
+++ /dev/null
-From 3800e5c33e5becbb56c6694008d1f3435fd78707 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Jan 2016 23:42:06 +0100
-Subject: [PATCH 015/102] 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
-
---- 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.
---- /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 */
-+
+++ /dev/null
-From 641ccb565a934ffaa30b828f2361e6f57325c70a Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sat, 27 Jun 2015 13:13:05 +0200
-Subject: [PATCH 016/102] 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
-
---- 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
---- a/drivers/pinctrl/mediatek/Makefile
-+++ b/drivers/pinctrl/mediatek/Makefile
-@@ -3,6 +3,7 @@ obj-$(CONFIG_PINCTRL_MTK_COMMON) += pinc
-
- # 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
---- /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);
---- /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 */
---- 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)
-
+++ /dev/null
-From f7121d2b19ddad33a09408a2c5923bfd95da8533 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 6 Jan 2016 20:06:49 +0100
-Subject: [PATCH 017/102] 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(+)
-
---- a/drivers/clk/mediatek/clk-mt2701.c
-+++ b/drivers/clk/mediatek/clk-mt2701.c
-@@ -1000,6 +1000,8 @@ static void __init mtk_hifsys_init(struc
- 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);
-
---- 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 */
+++ /dev/null
-From ba126a519da8a036dae0032e9d5a89e47570e5fb 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 018/102] 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
-
---- /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>;
-+};
+++ /dev/null
-From 8b8185586a13ebbd760e80bbe5f22f9417b50fd2 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 019/102] 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
-
---- 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
---- 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
---- /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);
---- /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");
---- /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_ */
---- 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
-@@ -3110,17 +3111,22 @@ static u32 xhci_td_remainder(struct xhci
- {
- 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));
- }
-@@ -3508,7 +3514,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *
- 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);
---- 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"
-@@ -635,7 +636,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 */
-@@ -1691,6 +1696,9 @@ int xhci_drop_endpoint(struct usb_hcd *h
-
- 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,
-@@ -1786,6 +1794,15 @@ int xhci_add_endpoint(struct usb_hcd *hc
- 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);
-
---- a/drivers/usb/host/xhci.h
-+++ b/drivers/usb/host/xhci.h
-@@ -1634,6 +1634,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)
- #define XHCI_MISSING_CAS (1 << 24)
- unsigned int num_active_eps;
- unsigned int limit_active_eps;
+++ /dev/null
-From 645465d4c6dd46c5e6c9ac25cd42608b4201fde0 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 020/102] 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(+)
-
---- 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>;
-+};
---- 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>;
+++ /dev/null
-From e111a35542ac14712026fe1a55236f76c7fc9048 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 5 Jan 2016 12:13:54 +0100
-Subject: [PATCH 021/102] 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(+)
-
---- 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";
---- 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
---- 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
+++ /dev/null
-From f232c3b36355974bf3442de3a4726d2e499ed3fe Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 5 Jan 2016 16:52:31 +0100
-Subject: [PATCH 022/102] 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(+)
-
---- 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_scps
- {
- .compatible = "mediatek,mt2701-scpsys",
- }, {
-+ .compatible = "mediatek,mt7623-scpsys",
-+ }, {
- /* sentinel */
- }
- };
+++ /dev/null
-From 51d5ca9e151eb323bd965e72ad1e1dc93fcf7b13 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 5 Jan 2016 12:16:17 +0100
-Subject: [PATCH 023/102] 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 | 421 ++++++++++++++++++++++++++
- arch/arm/boot/dts/mt7623.dtsi | 601 +++++++++++++++++++++++++++++++++++++
- arch/arm/mach-mediatek/Kconfig | 4 +
- arch/arm/mach-mediatek/mediatek.c | 1 +
- 5 files changed, 1028 insertions(+)
- create mode 100644 arch/arm/boot/dts/mt7623-evb.dts
- create mode 100644 arch/arm/boot/dts/mt7623.dtsi
-
---- 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
---- /dev/null
-+++ b/arch/arm/boot/dts/mt7623-evb.dts
-@@ -0,0 +1,421 @@
-+/*
-+ * 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;
-+ };
-+};
-+
-+&cpu0 {
-+ proc-supply = <&mt6323_vproc_reg>;
-+};
-+
-+&cpu1 {
-+ proc-supply = <&mt6323_vproc_reg>;
-+};
-+
-+&cpu2 {
-+ proc-supply = <&mt6323_vproc_reg>;
-+};
-+
-+&cpu3 {
-+ proc-supply = <&mt6323_vproc_reg>;
-+};
-+
-+&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";
-+};
-+
-+&pio {
-+ nand_pins_default: nanddefault {
-+ pins_dat {
-+ pinmux = <MT7623_PIN_111_MSDC0_DAT7_FUNC_NLD7>,
-+ <MT7623_PIN_112_MSDC0_DAT6_FUNC_NLD6>,
-+ <MT7623_PIN_114_MSDC0_DAT4_FUNC_NLD4>,
-+ <MT7623_PIN_118_MSDC0_DAT3_FUNC_NLD3>,
-+ <MT7623_PIN_121_MSDC0_DAT0_FUNC_NLD0>,
-+ <MT7623_PIN_120_MSDC0_DAT1_FUNC_NLD1>,
-+ <MT7623_PIN_113_MSDC0_DAT5_FUNC_NLD5>,
-+ <MT7623_PIN_115_MSDC0_RSTB_FUNC_NLD8>,
-+ <MT7623_PIN_119_MSDC0_DAT2_FUNC_NLD2>;
-+ input-enable;
-+ drive-strength = <MTK_DRIVE_8mA>;
-+ bias-pull-up;
-+ };
-+
-+ pins_we {
-+ pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_NWEB>;
-+ drive-strength = <MTK_DRIVE_8mA>;
-+ bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
-+ };
-+
-+ pins_ale {
-+ pinmux = <MT7623_PIN_116_MSDC0_CMD_FUNC_NALE>;
-+ drive-strength = <MTK_DRIVE_8mA>;
-+ 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;
-+ };
-+ };
-+};
-+
-+&nandc {
-+ status = "okay";
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&nand_pins_default>;
-+ nand@0 {
-+ reg = <0>;
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@C0000 {
-+ label = "uboot-env";
-+ reg = <0xC0000 0x40000>;
-+ };
-+
-+ partition@100000 {
-+ label = "factory";
-+ reg = <0x100000 0x40000>;
-+ };
-+
-+ partition@140000 {
-+ label = "kernel";
-+ reg = <0x140000 0x2000000>;
-+ };
-+
-+ partition@2140000 {
-+ label = "recovery";
-+ reg = <0x2140000 0x2000000>;
-+ };
-+
-+ partition@4140000 {
-+ label = "rootfs";
-+ reg = <0x4140000 0x1000000>;
-+ };
-+ };
-+ };
-+};
-+&bch {
-+ status = "okay";
-+};
-+
-+&usb1 {
-+ vusb33-supply = <&mt6323_vusb_reg>;
-+ vbus-supply = <&usb_p1_vbus>;
-+ status = "okay";
-+};
-+
-+&u3phy1 {
-+ status = "okay";
-+};
-+
-+&pcie {
-+ status = "okay";
-+};
-+
-+ð {
-+ 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 = <ð_default>;
-+ mediatek,reset-pin = <&pio 15 0>;
-+ status = "okay";
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/mt7623.dtsi
-@@ -0,0 +1,601 @@
-+/*
-+ * 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>;
-+ enable-method = "mediatek,mt6589-smp";
-+
-+ cpu0: cpu@0 {
-+ device_type = "cpu";
-+ compatible = "arm,cortex-a7";
-+ reg = <0x0>;
-+ clocks = <&infracfg CLK_INFRA_CPUSEL>,
-+ <&apmixedsys CLK_APMIXED_MAINPLL>;
-+ clock-names = "cpu", "intermediate";
-+ operating-points = <
-+ 598000 1150000
-+ 747500 1150000
-+ 1040000 1150000
-+ 1196000 1200000
-+ 1300000 1300000
-+ >;
-+ };
-+ cpu1: cpu@1 {
-+ device_type = "cpu";
-+ compatible = "arm,cortex-a7";
-+ reg = <0x1>;
-+ clocks = <&infracfg CLK_INFRA_CPUSEL>,
-+ <&apmixedsys CLK_APMIXED_MAINPLL>;
-+ clock-names = "cpu", "intermediate";
-+ operating-points = <
-+ 598000 1150000
-+ 747500 1150000
-+ 1040000 1150000
-+ 1196000 1200000
-+ 1300000 1300000
-+ >;
-+ };
-+ cpu2: cpu@2 {
-+ device_type = "cpu";
-+ compatible = "arm,cortex-a7";
-+ reg = <0x2>;
-+ clocks = <&infracfg CLK_INFRA_CPUSEL>,
-+ <&apmixedsys CLK_APMIXED_MAINPLL>;
-+ clock-names = "cpu", "intermediate";
-+ operating-points = <
-+ 598000 1150000
-+ 747500 1150000
-+ 1040000 1150000
-+ 1196000 1200000
-+ 1300000 1300000
-+ >;
-+ };
-+ cpu3: cpu@3 {
-+ device_type = "cpu";
-+ compatible = "arm,cortex-a7";
-+ reg = <0x3>;
-+ clocks = <&infracfg CLK_INFRA_CPUSEL>,
-+ <&apmixedsys CLK_APMIXED_MAINPLL>;
-+ clock-names = "cpu", "intermediate";
-+ operating-points = <
-+ 598000 1150000
-+ 747500 1150000
-+ 1040000 1150000
-+ 1196000 1200000
-+ 1300000 1300000
-+ >;
-+ };
-+ };
-+
-+ 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)>;
-+ clock-frequency = <13000000>;
-+ arm,cpu-registers-not-fw-configured;
-+ };
-+
-+ 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";
-+ };
-+
-+ nandc: nfi@1100d000 {
-+ compatible = "mediatek,mt2701-nfc";
-+ reg = <0 0x1100d000 0 0x1000>;
-+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_LOW>;
-+ power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>;
-+ clocks = <&pericfg CLK_PERI_NFI>,
-+ <&pericfg CLK_PERI_NFI_PAD>;
-+ clock-names = "nfi_clk", "pad_clk";
-+ status = "disabled";
-+ ecc-engine = <&bch>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+
-+ bch: ecc@1100e000 {
-+ compatible = "mediatek,mt2701-ecc";
-+ reg = <0 0x1100e000 0 0x1000>;
-+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_LOW>;
-+ clocks = <&pericfg CLK_PERI_NFI_ECC>;
-+ clock-names = "nfiecc_clk";
-+ 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 {
-+ compatible = "mediatek,mt2701-ethsys", "syscon";
-+ reg = <0 0x1b000000 0 0x1000>;
-+ #reset-cells = <1>;
-+ #clock-cells = <1>;
-+ };
-+
-+ eth: ethernet@1b100000 {
-+ compatible = "mediatek,mt2701-eth";
-+ reg = <0 0x1b100000 0 0x20000>;
-+
-+ clocks = <&topckgen CLK_TOP_ETHIF_SEL>,
-+ <ðsys CLK_ETHSYS_ESW>,
-+ <ðsys CLK_ETHSYS_GP2>,
-+ <ðsys CLK_ETHSYS_GP1>;
-+ clock-names = "ethif", "esw", "gp2", "gp1";
-+ interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_LOW
-+ GIC_SPI 199 IRQ_TYPE_LEVEL_LOW
-+ GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
-+ power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
-+
-+ resets = <ðsys 6>;
-+ reset-names = "eth";
-+
-+ mediatek,ethsys = <ðsys>;
-+ mediatek,pctl = <&syscfg_pctl_a>;
-+
-+ mediatek,switch = <&gsw>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ status = "disabled";
-+
-+ gmac1: mac@0 {
-+ compatible = "mediatek,eth-mac";
-+ reg = <0>;
-+
-+ status = "disabled";
-+
-+ phy-mode = "rgmii";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ pause;
-+ };
-+ };
-+
-+ gmac2: mac@1 {
-+ compatible = "mediatek,eth-mac";
-+ reg = <1>;
-+
-+ status = "disabled";
-+
-+ phy-mode = "rgmii";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ pause;
-+ };
-+ };
-+
-+ mdio-bus {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ phy5: ethernet-phy@5 {
-+ reg = <5>;
-+ phy-mode = "rgmii-rxid";
-+ };
-+
-+ phy1f: ethernet-phy@1f {
-+ reg = <0x1f>;
-+ phy-mode = "rgmii";
-+ };
-+ };
-+ };
-+
-+ gsw: switch@1b100000 {
-+ compatible = "mediatek,mt7623-gsw";
-+ interrupt-parent = <&pio>;
-+ interrupts = <168 IRQ_TYPE_EDGE_RISING>;
-+ resets = <ðsys 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 = <ðsys>;
-+ status = "disabled";
-+ };
-+};
---- 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
---- a/arch/arm/mach-mediatek/mediatek.c
-+++ b/arch/arm/mach-mediatek/mediatek.c
-@@ -46,6 +46,7 @@ static void __init mediatek_timer_init(v
- static const char * const mediatek_board_dt_compat[] = {
- "mediatek,mt6589",
- "mediatek,mt6592",
-+ "mediatek,mt7623",
- "mediatek,mt8127",
- "mediatek,mt8135",
- NULL,
+++ /dev/null
-From 05be818061b9f2a0fa5ad0cde6881917ff14a2f2 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 6 Jan 2016 21:55:10 +0100
-Subject: [PATCH 024/102] 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
-
---- /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";
-+ };
-+ };
+++ /dev/null
-From 8ab1d4e0a9a68e03f472dee1c036a01d0198c20c Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 5 Jan 2016 20:20:04 +0100
-Subject: [PATCH 025/102] 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
-
---- 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"
---- a/drivers/pci/host/Kconfig
-+++ b/drivers/pci/host/Kconfig
-@@ -173,4 +173,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
---- a/drivers/pci/host/Makefile
-+++ b/drivers/pci/host/Makefile
-@@ -20,3 +20,4 @@ obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-ip
- 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
---- /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);
+++ /dev/null
-From 59aafd667d2880c90776931b6102b8252214d93c Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 21 Feb 2016 13:52:12 +0100
-Subject: [PATCH 026/102] 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(-)
-
---- a/drivers/clk/mediatek/clk-mt2701.c
-+++ b/drivers/clk/mediatek/clk-mt2701.c
-@@ -1043,6 +1043,8 @@ static void __init mtk_ethsys_init(struc
- 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);
-
---- 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_
- .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,
---- 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 */
+++ /dev/null
-From 55231d8299d3dccde8588ed2e86c2bc0ef2e12ce 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 027/102] 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(-)
-
---- 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 p
- 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_wrapp
- 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_wrappe
- 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);
-
+++ /dev/null
-From d088a94afc768683a881b627b6737442158e7db6 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 5 Jan 2016 17:24:28 +0100
-Subject: [PATCH 028/102] 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(+)
-
---- 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 mt
- { 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_
-
- 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;
+++ /dev/null
-From b92861fbc79b3a7a9bc1c51e2dbfa2c191cc27ea 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 029/102] 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(-)
-
---- 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_t
-
- 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_d
-
- /* 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);
-
+++ /dev/null
-From f88ec31c6ba3a006d0be87ff1d99145f8cc85bee 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 030/102] 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(+)
-
---- 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 mt
- 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 = {
+++ /dev/null
-From 15f4d895578f02cbaed10b0f5f6853b873aba10b Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 20 Jan 2016 13:12:19 +0100
-Subject: [PATCH 031/102] 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(+)
-
---- 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
+++ /dev/null
-From 64e8091be39c3f0a7bf4651bd2045b8c86429d55 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 20 Jan 2016 06:42:01 +0100
-Subject: [PATCH 032/102] 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(-)
-
---- 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_wrappe
-
- 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_wrappe
- 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_d
- 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_d
-
- 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");
+++ /dev/null
-From 756b919b7874cc241a276b4fc5bbec5b3fb4bca8 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 20 Jan 2016 05:27:17 +0100
-Subject: [PATCH 033/102] 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(-)
-
---- 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_
- 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_wrappe
-
- 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_
- .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",
+++ /dev/null
-From a1bbd630710d5da89a9c347c84d7badd30e7e68a Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 20 Jan 2016 10:12:00 +0100
-Subject: [PATCH 034/102] 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(-)
-
---- 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
- 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_wrappe
- 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_mt
- .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_mt
- .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[] = {
+++ /dev/null
-From 274fd9ba57170de88bbdf522cbd6c290c2e51fb8 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 20 Jan 2016 10:14:39 +0100
-Subject: [PATCH 035/102] 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(-)
-
---- 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_mt
- .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_mt
- .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_d
- 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,
+++ /dev/null
-From 511e697282c6425950b95373ac8dc59a42fd2485 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 20 Jan 2016 10:21:42 +0100
-Subject: [PATCH 036/102] 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(-)
-
---- 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 p
- 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_mt
- .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_mt
- .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,
- };
+++ /dev/null
-From 6aecbc79322efd3068c6140f74a68654fbe5b5f6 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 20 Jan 2016 10:48:35 +0100
-Subject: [PATCH 037/102] 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(-)
-
---- 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_mt
- .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_mt
- .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_t
-
- 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_d
- * 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);
-
+++ /dev/null
-From da09b34ad22e8f065a02af114668f7d86357244a Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 20 Jan 2016 10:54:18 +0100
-Subject: [PATCH 038/102] 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(-)
-
---- 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
- 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_wrappe
- 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_wrappe
- 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_wrappe
- 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_mt
- .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_mt
- .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_d
- 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);
+++ /dev/null
-From 21bdcd324f769545b1765fe391d939a1edd07cbb Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 20 Jan 2016 09:55:08 +0100
-Subject: [PATCH 039/102] 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(-)
-
---- 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_
-
- 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(s
- 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
- }
-
- /* 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
- }
-
- /* 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
- 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_specifi
- 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_specifi
- 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_wrappe
- 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_wrappe
- 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_wrappe
- 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_
- .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_d
- 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_d
- 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");
+++ /dev/null
-From 4418ba9a0bb105f00259d10ceb16f9e27199e9b0 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 20 Jan 2016 11:40:43 +0100
-Subject: [PATCH 040/102] 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(+)
-
---- 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
- 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_
- .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_
-
- static const struct of_device_id of_slave_match_tbl[] = {
- {
-+ .compatible = "mediatek,mt6323",
-+ .data = &pmic_mt6323,
-+ }, {
- .compatible = "mediatek,mt6397",
- .data = &pmic_mt6397,
- }, {
+++ /dev/null
-From 7736d97fe2c6c71c9009a1b45a94de06bfc94a37 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 20 Jan 2016 12:09:14 +0100
-Subject: [PATCH 041/102] 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(+)
-
---- 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(s
- 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
- 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_specifi
- 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_slav
- };
- 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_mt
-
- static struct of_device_id of_pwrap_match_tbl[] = {
- {
-+ .compatible = "mediatek,mt2701-pwrap",
-+ .data = &pwrap_mt2701,
-+ }, {
- .compatible = "mediatek,mt8135-pwrap",
- .data = &pwrap_mt8135,
- }, {
+++ /dev/null
-From c14dc2993a272c706650502ec579ceabe5f2355e Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 10 Jan 2016 17:12:37 +0100
-Subject: [PATCH 042/102] 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(-)
-
---- 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 th
- - 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"
+++ /dev/null
-From 8269ed007349714e9ef0e3408a68159d763145dd Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Fri, 8 Jan 2016 08:33:17 +0100
-Subject: [PATCH 043/102] 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(-)
-
---- a/drivers/mfd/mt6397-core.c
-+++ b/drivers/mfd/mt6397-core.c
-@@ -69,8 +69,10 @@ static void mt6397_irq_sync_unlock(struc
- {
- 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
- {
- 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
- 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 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 devi
- {
- 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_
- 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.
---- 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__ */
+++ /dev/null
-From c6c447480e51301faa2254c7316ab075e20c4b0c Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Fri, 8 Jan 2016 08:41:52 +0100
-Subject: [PATCH 044/102] 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(-)
-
---- 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,
- 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;
- }
+++ /dev/null
-From 0ae7153c9f00361c3e6dac9da0c2d994557953f5 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Fri, 8 Jan 2016 04:09:43 +0100
-Subject: [PATCH 045/102] 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
-
---- 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_
- },
- };
-
-+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_
- }
-
- 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
-
- static const struct of_device_id mt6397_of_match[] = {
- { .compatible = "mediatek,mt6397" },
-+ { .compatible = "mediatek,mt6323" },
- { }
- };
- MODULE_DEVICE_TABLE(of, mt6397_of_match);
---- /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__ */
---- /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__ */
+++ /dev/null
-From f536a600e0e20fd57475415ce5b3d909441d53b6 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Sun, 10 Jan 2016 17:31:46 +0100
-Subject: [PATCH 046/102] 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
-
---- /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>;
-+ };
-+ };
-+ };
+++ /dev/null
-From 94c08223cd696d872cda7d9aa4e817956d0a0b84 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 047/102] 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
-
---- a/drivers/regulator/Kconfig
-+++ b/drivers/regulator/Kconfig
-@@ -453,6 +453,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
---- a/drivers/regulator/Makefile
-+++ b/drivers/regulator/Makefile
-@@ -60,6 +60,7 @@ obj-$(CONFIG_REGULATOR_MC13783) += mc137
- 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
---- /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, ®val);
-+ 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,
-+ ®val) < 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, ®_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");
---- /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 */
+++ /dev/null
-From 6efc8d9081b70dcf71d7e8efd7b51d48ee2541be Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 2 Mar 2016 07:18:52 +0100
-Subject: [PATCH 048/102] 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
-
---- /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,mt2701-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,mt2701-eth";
-+ reg = <0 0x1b100000 0 0x20000>;
-+ clocks = <&topckgen CLK_TOP_ETHIF_SEL>,
-+ <ðsys CLK_ETHSYS_ESW>,
-+ <ðsys CLK_ETHSYS_GP2>,
-+ <ðsys 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 = <ðsys MT2701_ETHSYS_ETH_RST>;
-+ reset-names = "eth";
-+ mediatek,ethsys = <ðsys>;
-+ 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";
-+ };
-+ };
-+};
+++ /dev/null
-From 8cc84aa65121135d7b120ce71b4f10f81230c818 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 2 Mar 2016 04:27:10 +0100
-Subject: [PATCH 049/102] 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@nbd.name>
-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
-
---- /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@nbd.name>
-+ * 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(ð->mac[i]->hw_stats->stats_lock)) {
-+ mtk_stats_update_mac(eth->mac[i]);
-+ spin_unlock(ð->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(ð->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(ð->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 = ð->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 = ð->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(ð->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 = ð->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 = ð->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 = ð->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 = ð->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 = ð->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(ð->rx_napi)))
-+ __napi_schedule(ð->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(ð->dma_refcnt)) {
-+ int err = mtk_start_dma(eth);
-+
-+ if (err)
-+ return err;
-+
-+ napi_enable(ð->rx_napi);
-+ mtk_irq_enable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT);
-+ }
-+ atomic_inc(ð->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(ð->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(ð->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(ð->dma_refcnt))
-+ return 0;
-+
-+ mtk_irq_disable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT);
-+ napi_disable(ð->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(ð->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(ð->dummy_dev);
-+ netif_napi_add(ð->dummy_dev, ð->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(ð->rx_napi);
-+ mtk_cleanup(eth);
-+ platform_set_drvdata(pdev, NULL);
-+
-+ return 0;
-+}
-+
-+const struct of_device_id of_mtk_match[] = {
-+ { .compatible = "mediatek,mt2701-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");
---- /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@nbd.name>
-+ * 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 */
+++ /dev/null
-From 31e907e5c3c2fc1c94d005bfccdd4a32b5a05f82 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 2 Mar 2016 04:32:43 +0100
-Subject: [PATCH 050/102] 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
-
---- 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"
---- 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/
---- /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
---- /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
+++ /dev/null
-From 514e4ce65a5f1b5bfa3cbca153f672844f093f0e Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 2 Mar 2016 04:34:04 +0100
-Subject: [PATCH 051/102] 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@nbd.name>
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- MAINTAINERS | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -6902,6 +6902,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@nbd.name>
-+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
+++ /dev/null
-From 5238c5d1d38661955ed3b52f45c46e00bfc9eb6e Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Apr 2016 07:18:35 +0200
-Subject: [PATCH 052/102] clk: dont disable unused clocks
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/clk/clk.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- 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;
+++ /dev/null
-From c8fd103d6c07af5db47f061b70759b7c69169656 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 31 Mar 2016 06:46:51 +0200
-Subject: [PATCH 053/102] clk: mediatek: enable critical clocks
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/clk/mediatek/clk-mt2701.c | 22 ++++++++++++++++++++--
- 1 file changed, 20 insertions(+), 2 deletions(-)
-
---- a/drivers/clk/mediatek/clk-mt2701.c
-+++ b/drivers/clk/mediatek/clk-mt2701.c
-@@ -573,6 +573,20 @@ static const struct mtk_gate top_clks[]
- GATE_TOP_AUD(CLK_TOP_AUD_I2S6_MCLK, "aud_i2s6_mclk", "aud_k6_src_div", 28),
- };
-
-+static struct clk_onecell_data *mt7623_top_clk_data __initdata;
-+static struct clk_onecell_data *mt7623_pll_clk_data __initdata;
-+
-+static void __init mtk_clk_enable_critical(void)
-+{
-+ if (!mt7623_top_clk_data || !mt7623_pll_clk_data)
-+ return;
-+
-+ clk_prepare_enable(mt7623_pll_clk_data->clks[CLK_APMIXED_ARMPLL]);
-+ clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_MEM_SEL]);
-+ clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_DDRPHYCFG_SEL]);
-+ clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_RTC_SEL]);
-+}
-+
- static void __init mtk_topckgen_init(struct device_node *node)
- {
- struct clk_onecell_data *clk_data;
-@@ -585,7 +599,7 @@ static void __init mtk_topckgen_init(str
- return;
- }
-
-- clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
-+ mt7623_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
-
- mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
- clk_data);
-@@ -606,6 +620,8 @@ static void __init mtk_topckgen_init(str
- if (r)
- pr_err("%s(): could not register clock provider: %d\n",
- __func__, r);
-+
-+ mtk_clk_enable_critical();
- }
- CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt2701-topckgen", mtk_topckgen_init);
-
-@@ -1202,7 +1218,7 @@ static void __init mtk_apmixedsys_init(s
- struct clk_onecell_data *clk_data;
- int r;
-
-- clk_data = mtk_alloc_clk_data(ARRAY_SIZE(apmixed_plls));
-+ mt7623_pll_clk_data = clk_data = mtk_alloc_clk_data(ARRAY_SIZE(apmixed_plls));
- if (!clk_data)
- return;
-
-@@ -1213,6 +1229,8 @@ static void __init mtk_apmixedsys_init(s
- if (r)
- pr_err("%s(): could not register clock provider: %d\n",
- __func__, r);
-+
-+ mtk_clk_enable_critical();
- }
- CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt2701-apmixedsys",
- mtk_apmixedsys_init);
+++ /dev/null
-From 1387d4f0ebf4b48c09f2ea0d27a02936c3fa0010 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 31 Mar 2016 02:26:37 +0200
-Subject: [PATCH 054/102] clk: mediatek: Export CPU mux clocks for CPU
- frequency control
-
-This patch adds CPU mux clocks which are used by Mediatek cpufreq driver
-for intermediate clock source switching.
-
-Signed-off-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
----
- drivers/clk/mediatek/Makefile | 2 +-
- drivers/clk/mediatek/clk-cpumux.c | 127 ++++++++++++++++++++++++++++++++
- drivers/clk/mediatek/clk-cpumux.h | 22 ++++++
- drivers/clk/mediatek/clk-mt2701.c | 8 ++
- drivers/clk/mediatek/clk-mt8173.c | 23 ++++++
- include/dt-bindings/clock/mt2701-clk.h | 3 +-
- include/dt-bindings/clock/mt8173-clk.h | 4 +-
- 7 files changed, 186 insertions(+), 3 deletions(-)
- create mode 100644 drivers/clk/mediatek/clk-cpumux.c
- create mode 100644 drivers/clk/mediatek/clk-cpumux.h
-
---- a/drivers/clk/mediatek/Makefile
-+++ b/drivers/clk/mediatek/Makefile
-@@ -1,4 +1,4 @@
--obj-$(CONFIG_COMMON_CLK_MEDIATEK) += 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 clk-cpumux.o
- obj-$(CONFIG_RESET_CONTROLLER) += reset.o
- obj-$(CONFIG_COMMON_CLK_MT2701) += clk-mt2701.o
- obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
---- /dev/null
-+++ b/drivers/clk/mediatek/clk-cpumux.c
-@@ -0,0 +1,127 @@
-+/*
-+ * Copyright (c) 2015 Linaro Ltd.
-+ * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.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 <linux/clk-provider.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/slab.h>
-+
-+#include "clk-mtk.h"
-+#include "clk-cpumux.h"
-+
-+struct mtk_clk_cpumux {
-+ struct clk_hw hw;
-+ struct regmap *regmap;
-+ u32 reg;
-+ u32 mask;
-+ u8 shift;
-+};
-+
-+static inline struct mtk_clk_cpumux *to_clk_mux(struct clk_hw *_hw)
-+{
-+ return container_of(_hw, struct mtk_clk_cpumux, hw);
-+}
-+
-+static u8 clk_cpumux_get_parent(struct clk_hw *hw)
-+{
-+ struct mtk_clk_cpumux *mux = to_clk_mux(hw);
-+ int num_parents = clk_hw_get_num_parents(hw);
-+ unsigned int val;
-+
-+ regmap_read(mux->regmap, mux->reg, &val);
-+
-+ val >>= mux->shift;
-+ val &= mux->mask;
-+
-+ if (val >= num_parents)
-+ return -EINVAL;
-+
-+ return val;
-+}
-+
-+static int clk_cpumux_set_parent(struct clk_hw *hw, u8 index)
-+{
-+ struct mtk_clk_cpumux *mux = to_clk_mux(hw);
-+ u32 mask, val;
-+
-+ val = index << mux->shift;
-+ mask = mux->mask << mux->shift;
-+
-+ return regmap_update_bits(mux->regmap, mux->reg, mask, val);
-+}
-+
-+static const struct clk_ops clk_cpumux_ops = {
-+ .get_parent = clk_cpumux_get_parent,
-+ .set_parent = clk_cpumux_set_parent,
-+};
-+
-+static struct clk __init *mtk_clk_register_cpumux(const struct mtk_composite *mux,
-+ struct regmap *regmap)
-+{
-+ struct mtk_clk_cpumux *cpumux;
-+ struct clk *clk;
-+ struct clk_init_data init;
-+
-+ cpumux = kzalloc(sizeof(*cpumux), GFP_KERNEL);
-+ if (!cpumux)
-+ return ERR_PTR(-ENOMEM);
-+
-+ init.name = mux->name;
-+ init.ops = &clk_cpumux_ops;
-+ init.parent_names = mux->parent_names;
-+ init.num_parents = mux->num_parents;
-+ init.flags = mux->flags;
-+
-+ cpumux->reg = mux->mux_reg;
-+ cpumux->shift = mux->mux_shift;
-+ cpumux->mask = BIT(mux->mux_width) - 1;
-+ cpumux->regmap = regmap;
-+ cpumux->hw.init = &init;
-+
-+ clk = clk_register(NULL, &cpumux->hw);
-+ if (IS_ERR(clk))
-+ kfree(cpumux);
-+
-+ return clk;
-+}
-+
-+int __init mtk_clk_register_cpumuxes(struct device_node *node,
-+ const struct mtk_composite *clks, int num,
-+ struct clk_onecell_data *clk_data)
-+{
-+ int i;
-+ struct clk *clk;
-+ struct regmap *regmap;
-+
-+ regmap = syscon_node_to_regmap(node);
-+ if (IS_ERR(regmap)) {
-+ pr_err("Cannot find regmap for %s: %ld\n", node->full_name,
-+ PTR_ERR(regmap));
-+ return PTR_ERR(regmap);
-+ }
-+
-+ for (i = 0; i < num; i++) {
-+ const struct mtk_composite *mux = &clks[i];
-+
-+ clk = mtk_clk_register_cpumux(mux, regmap);
-+ if (IS_ERR(clk)) {
-+ pr_err("Failed to register clk %s: %ld\n",
-+ mux->name, PTR_ERR(clk));
-+ continue;
-+ }
-+
-+ clk_data->clks[mux->id] = clk;
-+ }
-+
-+ return 0;
-+}
---- /dev/null
-+++ b/drivers/clk/mediatek/clk-cpumux.h
-@@ -0,0 +1,22 @@
-+/*
-+ * Copyright (c) 2015 Linaro Ltd.
-+ * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.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 __DRV_CLK_CPUMUX_H
-+#define __DRV_CLK_CPUMUX_H
-+
-+int mtk_clk_register_cpumuxes(struct device_node *node,
-+ const struct mtk_composite *clks, int num,
-+ struct clk_onecell_data *clk_data);
-+
-+#endif /* __DRV_CLK_CPUMUX_H */
---- a/drivers/clk/mediatek/clk-mt2701.c
-+++ b/drivers/clk/mediatek/clk-mt2701.c
-@@ -18,6 +18,7 @@
-
- #include "clk-mtk.h"
- #include "clk-gate.h"
-+#include "clk-cpumux.h"
-
- #include <dt-bindings/clock/mt2701-clk.h>
-
-@@ -465,6 +466,10 @@ static const char * const cpu_parents[]
- "mmpll"
- };
-
-+static const struct mtk_composite cpu_muxes[] __initconst = {
-+ MUX(CLK_INFRA_CPUSEL, "infra_cpu_sel", cpu_parents, 0x0000, 2, 2),
-+};
-+
- 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),
-@@ -677,6 +682,9 @@ static void __init mtk_infrasys_init(str
- mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
- clk_data);
-
-+ mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
-+ 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",
---- a/drivers/clk/mediatek/clk-mt8173.c
-+++ b/drivers/clk/mediatek/clk-mt8173.c
-@@ -18,6 +18,7 @@
-
- #include "clk-mtk.h"
- #include "clk-gate.h"
-+#include "clk-cpumux.h"
-
- #include <dt-bindings/clock/mt8173-clk.h>
-
-@@ -526,6 +527,25 @@ static const char * const i2s3_b_ck_pare
- "apll2_div5"
- };
-
-+static const char * const ca53_parents[] __initconst = {
-+ "clk26m",
-+ "armca7pll",
-+ "mainpll",
-+ "univpll"
-+};
-+
-+static const char * const ca57_parents[] __initconst = {
-+ "clk26m",
-+ "armca15pll",
-+ "mainpll",
-+ "univpll"
-+};
-+
-+static const struct mtk_composite cpu_muxes[] __initconst = {
-+ MUX(CLK_INFRA_CA53SEL, "infra_ca53_sel", ca53_parents, 0x0000, 0, 2),
-+ MUX(CLK_INFRA_CA57SEL, "infra_ca57_sel", ca57_parents, 0x0000, 2, 2),
-+};
-+
- static const struct mtk_composite top_muxes[] __initconst = {
- /* CLK_CFG_0 */
- MUX(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, 0x0040, 0, 3),
-@@ -945,6 +965,9 @@ static void __init mtk_infrasys_init(str
- clk_data);
- mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
-
-+ mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
-+ 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",
---- a/include/dt-bindings/clock/mt2701-clk.h
-+++ b/include/dt-bindings/clock/mt2701-clk.h
-@@ -217,7 +217,8 @@
- #define CLK_INFRA_PMICWRAP 17
- #define CLK_INFRA_DDCCI 18
- #define CLK_INFRA_CLK_13M 19
--#define CLK_INFRA_NR 20
-+#define CLK_INFRA_CPUSEL 20
-+#define CLK_INFRA_NR 21
-
- /* PERICFG */
-
---- a/include/dt-bindings/clock/mt8173-clk.h
-+++ b/include/dt-bindings/clock/mt8173-clk.h
-@@ -192,7 +192,9 @@
- #define CLK_INFRA_PMICSPI 10
- #define CLK_INFRA_PMICWRAP 11
- #define CLK_INFRA_CLK_13M 12
--#define CLK_INFRA_NR_CLK 13
-+#define CLK_INFRA_CA53SEL 13
-+#define CLK_INFRA_CA57SEL 14
-+#define CLK_INFRA_NR_CLK 15
-
- /* PERI_SYS */
-
+++ /dev/null
-From 60f4e41b367bdb29530468c91c1e613b17a37755 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 30 Mar 2016 23:48:53 +0200
-Subject: [PATCH 055/102] cpufreq: mediatek: add driver
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/cpufreq/Kconfig.arm | 9 +
- drivers/cpufreq/Makefile | 1 +
- drivers/cpufreq/mt7623-cpufreq.c | 389 ++++++++++++++++++++++++++++++++++++++
- 3 files changed, 399 insertions(+)
- create mode 100644 drivers/cpufreq/mt7623-cpufreq.c
-
---- a/drivers/cpufreq/Kconfig.arm
-+++ b/drivers/cpufreq/Kconfig.arm
-@@ -81,6 +81,15 @@ config ARM_KIRKWOOD_CPUFREQ
- This adds the CPUFreq driver for Marvell Kirkwood
- SoCs.
-
-+config ARM_MT7623_CPUFREQ
-+ bool "Mediatek MT7623 CPUFreq support"
-+ depends on ARCH_MEDIATEK && REGULATOR
-+ depends on ARM || (ARM_CPU_TOPOLOGY && COMPILE_TEST)
-+ depends on !CPU_THERMAL || THERMAL=y
-+ select PM_OPP
-+ help
-+ This adds the CPUFreq driver support for Mediatek MT7623 SoC.
-+
- config ARM_MT8173_CPUFREQ
- bool "Mediatek MT8173 CPUFreq support"
- depends on ARCH_MEDIATEK && REGULATOR
---- a/drivers/cpufreq/Makefile
-+++ b/drivers/cpufreq/Makefile
-@@ -57,6 +57,7 @@ obj-$(CONFIG_ARM_HISI_ACPU_CPUFREQ) += h
- obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
- obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o
- obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
-+obj-$(CONFIG_ARM_MT7623_CPUFREQ) += mt7623-cpufreq.o
- obj-$(CONFIG_ARM_MT8173_CPUFREQ) += mt8173-cpufreq.o
- obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
- obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o
---- /dev/null
-+++ b/drivers/cpufreq/mt7623-cpufreq.c
-@@ -0,0 +1,389 @@
-+/*
-+ * Copyright (c) 2015 Linaro Ltd.
-+ * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.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 <linux/clk.h>
-+#include <linux/cpu.h>
-+#include <linux/cpu_cooling.h>
-+#include <linux/cpufreq.h>
-+#include <linux/cpumask.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_opp.h>
-+#include <linux/regulator/consumer.h>
-+#include <linux/slab.h>
-+#include <linux/thermal.h>
-+
-+#define VOLT_TOL (10000)
-+
-+/*
-+ * When scaling the clock frequency of a CPU clock domain, the clock source
-+ * needs to be switched to another stable PLL clock temporarily until
-+ * the original PLL becomes stable at target frequency.
-+ */
-+struct mtk_cpu_dvfs_info {
-+ struct device *cpu_dev;
-+ struct regulator *proc_reg;
-+ struct clk *cpu_clk;
-+ struct clk *inter_clk;
-+ struct thermal_cooling_device *cdev;
-+ int intermediate_voltage;
-+};
-+
-+static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc)
-+{
-+ return regulator_set_voltage(info->proc_reg, vproc,
-+ vproc + VOLT_TOL);
-+}
-+
-+static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
-+ unsigned int index)
-+{
-+ struct cpufreq_frequency_table *freq_table = policy->freq_table;
-+ struct clk *cpu_clk = policy->clk;
-+ struct clk *armpll = clk_get_parent(cpu_clk);
-+ struct mtk_cpu_dvfs_info *info = policy->driver_data;
-+ struct device *cpu_dev = info->cpu_dev;
-+ struct dev_pm_opp *opp;
-+ long freq_hz, old_freq_hz;
-+ int vproc, old_vproc, inter_vproc, target_vproc, ret;
-+
-+ inter_vproc = info->intermediate_voltage;
-+
-+ old_freq_hz = clk_get_rate(cpu_clk);
-+ old_vproc = regulator_get_voltage(info->proc_reg);
-+
-+ freq_hz = freq_table[index].frequency * 1000;
-+
-+ rcu_read_lock();
-+ opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
-+ if (IS_ERR(opp)) {
-+ rcu_read_unlock();
-+ pr_err("cpu%d: failed to find OPP for %ld\n",
-+ policy->cpu, freq_hz);
-+ return PTR_ERR(opp);
-+ }
-+ vproc = dev_pm_opp_get_voltage(opp);
-+ rcu_read_unlock();
-+
-+ /*
-+ * If the new voltage or the intermediate voltage is higher than the
-+ * current voltage, scale up voltage first.
-+ */
-+ target_vproc = (inter_vproc > vproc) ? inter_vproc : vproc;
-+ if (old_vproc < target_vproc) {
-+ ret = mtk_cpufreq_set_voltage(info, target_vproc);
-+ if (ret) {
-+ pr_err("cpu%d: failed to scale up voltage!\n",
-+ policy->cpu);
-+ mtk_cpufreq_set_voltage(info, old_vproc);
-+ return ret;
-+ }
-+ }
-+
-+ /* Reparent the CPU clock to intermediate clock. */
-+ ret = clk_set_parent(cpu_clk, info->inter_clk);
-+ if (ret) {
-+ pr_err("cpu%d: failed to re-parent cpu clock!\n",
-+ policy->cpu);
-+ mtk_cpufreq_set_voltage(info, old_vproc);
-+ WARN_ON(1);
-+ return ret;
-+ }
-+
-+ /* Set the original PLL to target rate. */
-+ ret = clk_set_rate(armpll, freq_hz);
-+ if (ret) {
-+ pr_err("cpu%d: failed to scale cpu clock rate!\n",
-+ policy->cpu);
-+ clk_set_parent(cpu_clk, armpll);
-+ mtk_cpufreq_set_voltage(info, old_vproc);
-+ return ret;
-+ }
-+
-+ /* Set parent of CPU clock back to the original PLL. */
-+ ret = clk_set_parent(cpu_clk, armpll);
-+ if (ret) {
-+ pr_err("cpu%d: failed to re-parent cpu clock!\n",
-+ policy->cpu);
-+ mtk_cpufreq_set_voltage(info, inter_vproc);
-+ WARN_ON(1);
-+ return ret;
-+ }
-+
-+ /*
-+ * If the new voltage is lower than the intermediate voltage or the
-+ * original voltage, scale down to the new voltage.
-+ */
-+ if (vproc < inter_vproc || vproc < old_vproc) {
-+ ret = mtk_cpufreq_set_voltage(info, vproc);
-+ if (ret) {
-+ pr_err("cpu%d: failed to scale down voltage!\n",
-+ policy->cpu);
-+ clk_set_parent(cpu_clk, info->inter_clk);
-+ clk_set_rate(armpll, old_freq_hz);
-+ clk_set_parent(cpu_clk, armpll);
-+ return ret;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static void mtk_cpufreq_ready(struct cpufreq_policy *policy)
-+{
-+ struct mtk_cpu_dvfs_info *info = policy->driver_data;
-+ struct device_node *np = of_node_get(info->cpu_dev->of_node);
-+
-+ if (WARN_ON(!np))
-+ return;
-+
-+ if (of_find_property(np, "#cooling-cells", NULL)) {
-+ info->cdev = of_cpufreq_cooling_register(np,
-+ policy->related_cpus);
-+
-+ if (IS_ERR(info->cdev)) {
-+ dev_err(info->cpu_dev,
-+ "running cpufreq without cooling device: %ld\n",
-+ PTR_ERR(info->cdev));
-+
-+ info->cdev = NULL;
-+ }
-+ }
-+
-+ of_node_put(np);
-+}
-+
-+static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
-+{
-+ struct device *cpu_dev;
-+ struct regulator *proc_reg = ERR_PTR(-ENODEV);
-+ struct clk *cpu_clk = ERR_PTR(-ENODEV);
-+ struct clk *inter_clk = ERR_PTR(-ENODEV);
-+ struct dev_pm_opp *opp;
-+ unsigned long rate;
-+ int ret;
-+
-+ cpu_dev = get_cpu_device(cpu);
-+ if (!cpu_dev) {
-+ pr_err("failed to get cpu%d device\n", cpu);
-+ return -ENODEV;
-+ }
-+
-+ cpu_clk = clk_get(cpu_dev, "cpu");
-+ if (IS_ERR(cpu_clk)) {
-+ if (PTR_ERR(cpu_clk) == -EPROBE_DEFER)
-+ pr_warn("cpu clk for cpu%d not ready, retry.\n", cpu);
-+ else
-+ pr_err("failed to get cpu clk for cpu%d\n", cpu);
-+
-+ ret = PTR_ERR(cpu_clk);
-+ return ret;
-+ }
-+
-+ inter_clk = clk_get(cpu_dev, "intermediate");
-+ if (IS_ERR(inter_clk)) {
-+ if (PTR_ERR(inter_clk) == -EPROBE_DEFER)
-+ pr_warn("intermediate clk for cpu%d not ready, retry.\n",
-+ cpu);
-+ else
-+ pr_err("failed to get intermediate clk for cpu%d\n",
-+ cpu);
-+
-+ ret = PTR_ERR(inter_clk);
-+ goto out_free_resources;
-+ }
-+
-+ proc_reg = regulator_get_exclusive(cpu_dev, "proc");
-+ if (IS_ERR(proc_reg)) {
-+ if (PTR_ERR(proc_reg) == -EPROBE_DEFER)
-+ pr_warn("proc regulator for cpu%d not ready, retry.\n",
-+ cpu);
-+ else
-+ pr_err("failed to get proc regulator for cpu%d\n",
-+ cpu);
-+
-+ ret = PTR_ERR(proc_reg);
-+ goto out_free_resources;
-+ }
-+
-+ ret = dev_pm_opp_of_add_table(cpu_dev);
-+ if (ret) {
-+ pr_warn("no OPP table for cpu%d\n", cpu);
-+ goto out_free_resources;
-+ }
-+
-+ /* Search a safe voltage for intermediate frequency. */
-+ rate = clk_get_rate(inter_clk);
-+ rcu_read_lock();
-+ opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate);
-+ if (IS_ERR(opp)) {
-+ rcu_read_unlock();
-+ pr_err("failed to get intermediate opp for cpu%d\n", cpu);
-+ ret = PTR_ERR(opp);
-+ goto out_free_opp_table;
-+ }
-+ info->intermediate_voltage = dev_pm_opp_get_voltage(opp);
-+ rcu_read_unlock();
-+
-+ info->cpu_dev = cpu_dev;
-+ info->proc_reg = proc_reg;
-+ info->cpu_clk = cpu_clk;
-+ info->inter_clk = inter_clk;
-+
-+ return 0;
-+
-+out_free_opp_table:
-+ dev_pm_opp_of_remove_table(cpu_dev);
-+
-+out_free_resources:
-+ if (!IS_ERR(proc_reg))
-+ regulator_put(proc_reg);
-+ if (!IS_ERR(cpu_clk))
-+ clk_put(cpu_clk);
-+ if (!IS_ERR(inter_clk))
-+ clk_put(inter_clk);
-+
-+ return ret;
-+}
-+
-+static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info)
-+{
-+ if (!IS_ERR(info->proc_reg))
-+ regulator_put(info->proc_reg);
-+ if (!IS_ERR(info->cpu_clk))
-+ clk_put(info->cpu_clk);
-+ if (!IS_ERR(info->inter_clk))
-+ clk_put(info->inter_clk);
-+
-+ dev_pm_opp_of_remove_table(info->cpu_dev);
-+}
-+
-+static int mtk_cpufreq_init(struct cpufreq_policy *policy)
-+{
-+ struct mtk_cpu_dvfs_info *info;
-+ struct cpufreq_frequency_table *freq_table;
-+ int ret;
-+
-+ info = kzalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return -ENOMEM;
-+
-+ ret = mtk_cpu_dvfs_info_init(info, policy->cpu);
-+ if (ret) {
-+ pr_err("%s failed to initialize dvfs info for cpu%d\n",
-+ __func__, policy->cpu);
-+ goto out_free_dvfs_info;
-+ }
-+
-+ ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table);
-+ if (ret) {
-+ pr_err("failed to init cpufreq table for cpu%d: %d\n",
-+ policy->cpu, ret);
-+ goto out_release_dvfs_info;
-+ }
-+
-+ ret = cpufreq_table_validate_and_show(policy, freq_table);
-+ if (ret) {
-+ pr_err("%s: invalid frequency table: %d\n", __func__, ret);
-+ goto out_free_cpufreq_table;
-+ }
-+
-+ /* CPUs in the same cluster share a clock and power domain. */
-+ cpumask_setall(policy->cpus);
-+ policy->driver_data = info;
-+ policy->clk = info->cpu_clk;
-+
-+ return 0;
-+
-+out_free_cpufreq_table:
-+ dev_pm_opp_free_cpufreq_table(info->cpu_dev, &freq_table);
-+
-+out_release_dvfs_info:
-+ mtk_cpu_dvfs_info_release(info);
-+
-+out_free_dvfs_info:
-+ kfree(info);
-+
-+ return ret;
-+}
-+
-+static int mtk_cpufreq_exit(struct cpufreq_policy *policy)
-+{
-+ struct mtk_cpu_dvfs_info *info = policy->driver_data;
-+
-+ cpufreq_cooling_unregister(info->cdev);
-+ dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table);
-+ mtk_cpu_dvfs_info_release(info);
-+ kfree(info);
-+
-+ return 0;
-+}
-+
-+static struct cpufreq_driver mt7623_cpufreq_driver = {
-+ .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
-+ .verify = cpufreq_generic_frequency_table_verify,
-+ .target_index = mtk_cpufreq_set_target,
-+ .get = cpufreq_generic_get,
-+ .init = mtk_cpufreq_init,
-+ .exit = mtk_cpufreq_exit,
-+ .ready = mtk_cpufreq_ready,
-+ .name = "mtk-cpufreq",
-+ .attr = cpufreq_generic_attr,
-+};
-+
-+static int mt7623_cpufreq_probe(struct platform_device *pdev)
-+{
-+ int ret;
-+
-+ ret = cpufreq_register_driver(&mt7623_cpufreq_driver);
-+ if (ret)
-+ pr_err("failed to register mtk cpufreq driver\n");
-+
-+ return ret;
-+}
-+
-+static struct platform_driver mt7623_cpufreq_platdrv = {
-+ .driver = {
-+ .name = "mt7623-cpufreq",
-+ },
-+ .probe = mt7623_cpufreq_probe,
-+};
-+
-+static int mt7623_cpufreq_driver_init(void)
-+{
-+ struct platform_device *pdev;
-+ int err;
-+
-+ if (!of_machine_is_compatible("mediatek,mt7623"))
-+ return -ENODEV;
-+
-+ err = platform_driver_register(&mt7623_cpufreq_platdrv);
-+ if (err)
-+ return err;
-+
-+ /*
-+ * Since there's no place to hold device registration code and no
-+ * device tree based way to match cpufreq driver yet, both the driver
-+ * and the device registration codes are put here to handle defer
-+ * probing.
-+ */
-+ pdev = platform_device_register_simple("mt7623-cpufreq", -1, NULL, 0);
-+ if (IS_ERR(pdev)) {
-+ pr_err("failed to register mtk-cpufreq platform device\n");
-+ return PTR_ERR(pdev);
-+ }
-+
-+ return 0;
-+}
-+device_initcall(mt7623_cpufreq_driver_init);
+++ /dev/null
-From f8cda0bc698706413b5dd6fde827f9a2601ac61b Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 31 Mar 2016 06:07:01 +0200
-Subject: [PATCH 056/102] arm: mediatek: make a7 timer work Signed-off-by:
- John Crispin <blogic@openwrt.org>
-
----
- arch/arm/mach-mediatek/Kconfig | 1 +
- arch/arm/mach-mediatek/mediatek.c | 1 +
- 2 files changed, 2 insertions(+)
-
---- 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 HAVE_ARM_ARCH_TIMER
- select MIGHT_HAVE_PCI
-
- config MACH_MT8127
---- a/arch/arm/mach-mediatek/mediatek.c
-+++ b/arch/arm/mach-mediatek/mediatek.c
-@@ -29,6 +29,7 @@ static void __init mediatek_timer_init(v
- void __iomem *gpt_base;
-
- if (of_machine_is_compatible("mediatek,mt6589") ||
-+ of_machine_is_compatible("mediatek,mt7623") ||
- of_machine_is_compatible("mediatek,mt8135") ||
- of_machine_is_compatible("mediatek,mt8127")) {
- /* turn on GPT6 which ungates arch timer clocks */
+++ /dev/null
-From b9f9b937dd12dc57bd54a6c89b18eb40d4508424 Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <dan.carpenter@oracle.com>
-Date: Tue, 15 Mar 2016 10:18:49 +0300
-Subject: [PATCH 057/102] net: mediatek: checking for IS_ERR() instead of NULL
-
-of_phy_connect() returns NULL on error, it never returns error pointers.
-
-Fixes: 656e705243fd ('net-next: mediatek: add support for MT7623 ethernet')
-Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -186,9 +186,9 @@ static int mtk_phy_connect_node(struct m
-
- phydev = of_phy_connect(eth->netdev[mac->id], phy_node,
- mtk_phy_link_adjust, 0, phy_mode);
-- if (IS_ERR(phydev)) {
-+ if (!phydev) {
- dev_err(eth->dev, "could not connect to PHY\n");
-- return PTR_ERR(phydev);
-+ return -ENODEV;
- }
-
- dev_info(eth->dev,
+++ /dev/null
-From 6c12340c0c307d18b8d6120f64a8275b6d4d3e67 Mon Sep 17 00:00:00 2001
-From: Dan Carpenter <dan.carpenter@oracle.com>
-Date: Tue, 15 Mar 2016 10:19:04 +0300
-Subject: [PATCH 058/102] net: mediatek: unlock on error in mtk_tx_map()
-
-There was a missing unlock on the error path.
-
-Fixes: 656e705243fd ('net-next: mediatek: add support for MT7623 ethernet')
-Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -661,6 +661,8 @@ err_dma:
- itxd = mtk_qdma_phys_to_virt(ring, itxd->txd2);
- } while (itxd != txd);
-
-+ spin_unlock_irqrestore(ð->page_lock, flags);
-+
- return -ENOMEM;
- }
-
+++ /dev/null
-From a572747434b6153e75812c5466c0557e5ed69284 Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Mon, 14 Mar 2016 15:07:10 +0100
-Subject: [PATCH 059/102] net: mediatek: use dma_addr_t correctly
-
-dma_alloc_coherent() expects a dma_addr_t pointer as its argument,
-not an 'unsigned int', and gcc correctly warns about broken
-code in the mtk_init_fq_dma function:
-
-drivers/net/ethernet/mediatek/mtk_eth_soc.c: In function 'mtk_init_fq_dma':
-drivers/net/ethernet/mediatek/mtk_eth_soc.c:463:13: error: passing argument 3 of 'dma_alloc_coherent' from incompatible pointer type [-Werror=incompatible-pointer-types]
-
-This changes the type of the local variable to dma_addr_t.
-
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -453,7 +453,7 @@ static inline void mtk_rx_get_desc(struc
- /* 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;
-+ dma_addr_t phy_ring_head, phy_ring_tail;
- int cnt = MTK_DMA_SIZE;
- dma_addr_t dma_addr;
- int i;
+++ /dev/null
-From 8473af12d5aa34613070447d6fd8f785f31301de Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Mon, 14 Mar 2016 15:07:11 +0100
-Subject: [PATCH 060/102] net: mediatek: remove incorrect dma_mask assignment
-
-Device drivers should not mess with the DMA mask directly,
-but instead call dma_set_mask() etc if needed.
-
-In case of the mtk_eth_soc driver, the mask already gets set
-correctly when the device is created, and setting it again
-is against the documented API.
-
-This removes the incorrect setting.
-
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 ---
- 1 file changed, 3 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1678,9 +1678,6 @@ static int mtk_probe(struct platform_dev
- 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);
+++ /dev/null
-From 99159791184752ece724b741f9fa6334fdc67123 Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Mon, 14 Mar 2016 15:07:12 +0100
-Subject: [PATCH 061/102] net: mediatek: check device_reset return code
-
-The device_reset() function may fail, so we have to check
-its return value, e.g. to make deferred probing work correctly.
-gcc warns about it because of the warn_unused_result attribute:
-
-drivers/net/ethernet/mediatek/mtk_eth_soc.c: In function 'mtk_probe':
-drivers/net/ethernet/mediatek/mtk_eth_soc.c:1679:2: error: ignoring return value of 'device_reset', declared with attribute warn_unused_result [-Werror=unused-result]
-
-This adds the trivial error check to propagate the return value
-to the generic platform device probe code.
-
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1678,7 +1678,9 @@ static int mtk_probe(struct platform_dev
- struct mtk_eth *eth;
- int err;
-
-- device_reset(&pdev->dev);
-+ err = device_reset(&pdev->dev);
-+ if (err)
-+ return err;
-
- match = of_match_device(of_mtk_match, &pdev->dev);
- soc = (struct mtk_soc_data *)match->data;
+++ /dev/null
-From 387257cbd6f3f92de71e2f578d3a9414d0dada27 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 30 Mar 2016 03:18:17 +0200
-Subject: [PATCH 062/102] net: mediatek: watchdog_timeo was not set
-
-The original commit failed to set watchdog_timeo. This patch sets
-watchdog_timeo to HZ.
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1645,6 +1645,7 @@ static int mtk_add_mac(struct mtk_eth *e
- mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
-
- SET_NETDEV_DEV(eth->netdev[id], eth->dev);
-+ eth->netdev[id]->watchdog_timeo = HZ;
- 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 &
+++ /dev/null
-From d8f3e96943334c91ecc0827ed0d3232068c389e6 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 22 Mar 2016 04:42:27 +0100
-Subject: [PATCH 063/102] net: mediatek: mtk_cal_txd_req() returns bad value
-
-The code used to also support the PDMA engine, which had 2 packet pointers
-per descriptor. Because of this we have to divide the result by 2 and round
-it up. This is no longer needed as the code only supports QDMA.
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -681,7 +681,7 @@ static inline int mtk_cal_txd_req(struct
- nfrags += skb_shinfo(skb)->nr_frags;
- }
-
-- return DIV_ROUND_UP(nfrags, 2);
-+ return nfrags;
- }
-
- static int mtk_start_xmit(struct sk_buff *skb, struct net_device *dev)
+++ /dev/null
-From 2597d2cedba62b2a3fdca9c044187705f98a0372 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Fri, 25 Mar 2016 04:24:27 +0100
-Subject: [PATCH 064/102] net: mediatek: remove superflous reset call
-
-HW reset is triggered int he mtk_hw_init() function. There is no need to
-reset the core during probe.
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ----
- 1 file changed, 4 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1679,10 +1679,6 @@ static int mtk_probe(struct platform_dev
- struct mtk_eth *eth;
- int err;
-
-- err = device_reset(&pdev->dev);
-- if (err)
-- return err;
--
- match = of_match_device(of_mtk_match, &pdev->dev);
- soc = (struct mtk_soc_data *)match->data;
-
+++ /dev/null
-From afc838dde560ab584d3fb0e4b011e4a6770dab3d Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 29 Mar 2016 16:41:07 +0200
-Subject: [PATCH 065/102] net: mediatek: fix stop and wakeup of queue
-
-The driver supports 2 MACs. Both run on the same DMA ring. If we go
-above/below the TX rings thershold value, we always need to wake/stop
-the queu of both devices. Not doing to can cause TX stalls and packet
-drops on one of the devices.
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 37 +++++++++++++++++++--------
- 1 file changed, 27 insertions(+), 10 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -684,6 +684,28 @@ static inline int mtk_cal_txd_req(struct
- return nfrags;
- }
-
-+static void mtk_wake_queue(struct mtk_eth *eth)
-+{
-+ int i;
-+
-+ for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ if (!eth->netdev[i])
-+ continue;
-+ netif_wake_queue(eth->netdev[i]);
-+ }
-+}
-+
-+static void mtk_stop_queue(struct mtk_eth *eth)
-+{
-+ int i;
-+
-+ for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ if (!eth->netdev[i])
-+ continue;
-+ netif_stop_queue(eth->netdev[i]);
-+ }
-+}
-+
- static int mtk_start_xmit(struct sk_buff *skb, struct net_device *dev)
- {
- struct mtk_mac *mac = netdev_priv(dev);
-@@ -695,7 +717,7 @@ static int mtk_start_xmit(struct sk_buff
-
- tx_num = mtk_cal_txd_req(skb);
- if (unlikely(atomic_read(&ring->free_count) <= tx_num)) {
-- netif_stop_queue(dev);
-+ mtk_stop_queue(eth);
- netif_err(eth, tx_queued, dev,
- "Tx Ring full when queue awake!\n");
- return NETDEV_TX_BUSY;
-@@ -720,10 +742,10 @@ static int mtk_start_xmit(struct sk_buff
- goto drop;
-
- if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) {
-- netif_stop_queue(dev);
-+ mtk_stop_queue(eth);
- if (unlikely(atomic_read(&ring->free_count) >
- ring->thresh))
-- netif_wake_queue(dev);
-+ mtk_wake_queue(eth);
- }
-
- return NETDEV_TX_OK;
-@@ -897,13 +919,8 @@ static int mtk_poll_tx(struct mtk_eth *e
- 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]);
-- }
-+ if (atomic_read(&ring->free_count) > ring->thresh)
-+ mtk_wake_queue(eth);
-
- return total;
- }
+++ /dev/null
-From e2cc73e6ddb0cc39b8f58654a449651a621916a9 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 29 Mar 2016 17:00:47 +0200
-Subject: [PATCH 066/102] net: mediatek: fix mtk_pending_work
-
-The driver supports 2 MACs. Both run on the same DMA ring. If we hit a TX
-timeout we need to stop both netdevs before retarting them again. If we
-dont do thsi, mtk_stop() wont shutdown DMA and the consecutive call to
-mtk_open() wont restart DMA and enable IRQs.
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++++++++++++++--------
- 1 file changed, 21 insertions(+), 9 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1430,19 +1430,31 @@ static int mtk_do_ioctl(struct net_devic
-
- 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;
-+ struct mtk_eth *eth = container_of(work, struct mtk_eth, pending_work);
-+ int err, i;
-+ unsigned long restart = 0;
-
- rtnl_lock();
-- mtk_stop(dev);
-
-- err = mtk_open(dev);
-- if (err) {
-- netif_alert(eth, ifup, dev,
-+ /* stop all devices to make sure that dma is properly shut down */
-+ for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ if (!netif_oper_up(eth->netdev[i]))
-+ continue;
-+ mtk_stop(eth->netdev[i]);
-+ __set_bit(i, &restart);
-+ }
-+
-+
-+ /* restart DMA and enable IRQs */
-+ for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ if (!test_bit(i, &restart))
-+ continue;
-+ err = mtk_open(eth->netdev[i]);
-+ if (err) {
-+ netif_alert(eth, ifup, eth->netdev[i],
- "Driver up/down cycle failed, closing device.\n");
-- dev_close(dev);
-+ dev_close(eth->netdev[i]);
-+ }
- }
- rtnl_unlock();
- }
+++ /dev/null
-From 6f152b2bdb295d86beb746494ef6fddf17986f8e Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 29 Mar 2016 17:20:01 +0200
-Subject: [PATCH 067/102] net: mediatek: fix TX locking
-
-Inside the TX path there is a lock inside the tx_map function. This is
-however too late. The patch moves the lock to the start of the xmit
-function right before the free count check of the DMA ring happens.
-If we do not do this, the code becomes racy leading to TX stalls and
-dropped packets. This happens as there are 2 netdevs running on the
-same physical DMA ring.
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 20 ++++++++++----------
- 1 file changed, 10 insertions(+), 10 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -536,7 +536,6 @@ static int mtk_tx_map(struct sk_buff *sk
- 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;
-@@ -568,11 +567,6 @@ static int mtk_tx_map(struct sk_buff *sk
- 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(ð->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);
-@@ -632,8 +626,6 @@ static int mtk_tx_map(struct sk_buff *sk
- WRITE_ONCE(itxd->txd3, (TX_DMA_SWC | TX_DMA_PLEN0(skb_headlen(skb)) |
- (!nr_frags * TX_DMA_LS0)));
-
-- spin_unlock_irqrestore(ð->page_lock, flags);
--
- netdev_sent_queue(dev, skb->len);
- skb_tx_timestamp(skb);
-
-@@ -661,8 +653,6 @@ err_dma:
- itxd = mtk_qdma_phys_to_virt(ring, itxd->txd2);
- } while (itxd != txd);
-
-- spin_unlock_irqrestore(ð->page_lock, flags);
--
- return -ENOMEM;
- }
-
-@@ -712,14 +702,22 @@ static int mtk_start_xmit(struct sk_buff
- struct mtk_eth *eth = mac->hw;
- struct mtk_tx_ring *ring = ð->tx_ring;
- struct net_device_stats *stats = &dev->stats;
-+ unsigned long flags;
- bool gso = false;
- int tx_num;
-
-+ /* 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(ð->page_lock, flags);
-+
- tx_num = mtk_cal_txd_req(skb);
- if (unlikely(atomic_read(&ring->free_count) <= tx_num)) {
- mtk_stop_queue(eth);
- netif_err(eth, tx_queued, dev,
- "Tx Ring full when queue awake!\n");
-+ spin_unlock_irqrestore(ð->page_lock, flags);
- return NETDEV_TX_BUSY;
- }
-
-@@ -747,10 +745,12 @@ static int mtk_start_xmit(struct sk_buff
- ring->thresh))
- mtk_wake_queue(eth);
- }
-+ spin_unlock_irqrestore(ð->page_lock, flags);
-
- return NETDEV_TX_OK;
-
- drop:
-+ spin_unlock_irqrestore(ð->page_lock, flags);
- stats->tx_dropped++;
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
+++ /dev/null
-From 29bc7a1e374425937b5dd2f316dbeef343d4c68a Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 29 Mar 2016 17:24:24 +0200
-Subject: [PATCH 068/102] net: mediatek: move the pending_work struct to the
- device generic struct
-
-The worker always touches both netdevs. It is ethernet core and not MAC
-specific. We only need one worker, which belongs into the ethernets core struct.
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 10 ++++------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++--
- 2 files changed, 6 insertions(+), 8 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1193,7 +1193,7 @@ static void mtk_tx_timeout(struct net_de
- eth->netdev[mac->id]->stats.tx_errors++;
- netif_err(eth, tx_err, dev,
- "transmit timed out\n");
-- schedule_work(&mac->pending_work);
-+ schedule_work(ð->pending_work);
- }
-
- static irqreturn_t mtk_handle_irq(int irq, void *_eth)
-@@ -1438,7 +1438,7 @@ static void mtk_pending_work(struct work
-
- /* stop all devices to make sure that dma is properly shut down */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
-- if (!netif_oper_up(eth->netdev[i]))
-+ if (!eth->netdev[i])
- continue;
- mtk_stop(eth->netdev[i]);
- __set_bit(i, &restart);
-@@ -1464,15 +1464,13 @@ static int mtk_cleanup(struct mtk_eth *e
- 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);
- }
-+ cancel_work_sync(ð->pending_work);
-
- return 0;
- }
-@@ -1660,7 +1658,6 @@ static int mtk_add_mac(struct mtk_eth *e
- 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),
-@@ -1762,6 +1759,7 @@ static int mtk_probe(struct platform_dev
-
- eth->dev = &pdev->dev;
- eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE);
-+ INIT_WORK(ð->pending_work, mtk_pending_work);
-
- err = mtk_hw_init(eth);
- if (err)
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -363,6 +363,7 @@ struct mtk_rx_ring {
- * @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
-+ * @pending_work: The workqueue used to reset the dma ring
- */
-
- struct mtk_eth {
-@@ -389,6 +390,7 @@ struct mtk_eth {
- struct clk *clk_gp1;
- struct clk *clk_gp2;
- struct mii_bus *mii_bus;
-+ struct work_struct pending_work;
- };
-
- /* struct mtk_mac - the structure that holds the info about the MACs of the
-@@ -398,7 +400,6 @@ struct mtk_eth {
- * @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;
-@@ -406,7 +407,6 @@ struct mtk_mac {
- 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 */
+++ /dev/null
-From 4742349c1595d38b3e3b463e66cf21af4217c869 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Apr 2016 17:36:23 +0200
-Subject: [PATCH 069/102] net: mediatek: do not set the QID field in the TX
- DMA descriptors
-
-The QID field gets set to the mac id. This made the DMA linked list queue
-the traffic of each MAC on a different internal queue. However during long
-term testing we found that this will cause traffic stalls as the multi
-queue setup requires a more complete initialisation which is not part of
-the upstream driver yet.
-
-This patch removes the code setting the QID field, resulting in all
-traffic ending up in queue 0 which works without any special setup.
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -603,8 +603,7 @@ static int mtk_tx_map(struct sk_buff *sk
- 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);
-+ last_frag * TX_DMA_LS0));
- WRITE_ONCE(txd->txd4, 0);
-
- tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC;
+++ /dev/null
-From 297ef52cd21e28da671996d7b4f39f268d2d0ec1 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 29 Mar 2016 14:32:07 +0200
-Subject: [PATCH 070/102] net: mediatek: update the IRQ part of the binding
- document
-
-The current binding document only describes a single interrupt. Update the
-document by adding the 2 other interrupts.
-
-The driver currently only uses a single interrupt. The HW is however able
-to using IRQ grouping to split TX and RX onto separate GIC irqs.
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
- Acked-by: Rob Herring <robh@kernel.org>
----
- Documentation/devicetree/bindings/net/mediatek-net.txt | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
---- a/Documentation/devicetree/bindings/net/mediatek-net.txt
-+++ b/Documentation/devicetree/bindings/net/mediatek-net.txt
-@@ -9,7 +9,8 @@ have dual GMAC each represented by a chi
- Required properties:
- - compatible: Should be "mediatek,mt2701-eth"
- - reg: Address and length of the register set for the device
--- interrupts: Should contain the frame engines interrupt
-+- interrupts: Should contain the three frame engines interrupts in numeric
-+ order. These are fe_int0, fe_int1 and fe_int2.
- - 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"
-@@ -42,7 +43,9 @@ eth: ethernet@1b100000 {
- <ðsys CLK_ETHSYS_GP2>,
- <ðsys CLK_ETHSYS_GP1>;
- clock-names = "ethif", "esw", "gp2", "gp1";
-- interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_LOW>;
-+ interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_LOW
-+ GIC_SPI 199 IRQ_TYPE_LEVEL_LOW
-+ GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
- power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
- resets = <ðsys MT2701_ETHSYS_ETH_RST>;
- reset-names = "eth";
+++ /dev/null
-From 6f5941c93bdf7649f392f1263b9068d360ceab4d Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 6 May 2016 02:55:48 +0200
-Subject: [PATCH 071/102] pwm: add pwm-mediatek
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- arch/arm/boot/dts/mt7623-evb.dts | 17 +++
- arch/arm/boot/dts/mt7623.dtsi | 22 ++++
- drivers/pwm/Kconfig | 9 ++
- drivers/pwm/Makefile | 1 +
- drivers/pwm/pwm-mediatek.c | 230 ++++++++++++++++++++++++++++++++++++++
- 5 files changed, 279 insertions(+)
- create mode 100644 drivers/pwm/pwm-mediatek.c
-
---- a/arch/arm/boot/dts/mt7623-evb.dts
-+++ b/arch/arm/boot/dts/mt7623-evb.dts
-@@ -341,6 +341,17 @@
- output-low;
- };
- };
-+
-+ pwm_pins: pwm {
-+ pins_pwm1 {
-+ pinmux = <MT7623_PIN_204_PWM1_FUNC_PWM1>;
-+ };
-+
-+ pins_pwm2 {
-+ pinmux = <MT7623_PIN_205_PWM2_FUNC_PWM2>;
-+ };
-+ };
-+
- };
-
- &nandc {
-@@ -419,3 +430,9 @@
- mediatek,reset-pin = <&pio 15 0>;
- status = "okay";
- };
-+
-+&pwm {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pwm_pins>;
-+ status = "okay";
-+};
---- a/arch/arm/boot/dts/mt7623.dtsi
-+++ b/arch/arm/boot/dts/mt7623.dtsi
-@@ -324,6 +324,28 @@
- status = "disabled";
- };
-
-+ pwm: pwm@11006000 {
-+ compatible = "mediatek,mt7623-pwm";
-+
-+ reg = <0 0x11006000 0 0x1000>;
-+
-+ resets = <&pericfg MT2701_PERI_PWM_SW_RST>;
-+ reset-names = "pwm";
-+
-+ #pwm-cells = <2>;
-+ clocks = <&topckgen CLK_TOP_PWM_SEL>,
-+ <&pericfg CLK_PERI_PWM>,
-+ <&pericfg CLK_PERI_PWM1>,
-+ <&pericfg CLK_PERI_PWM2>,
-+ <&pericfg CLK_PERI_PWM3>,
-+ <&pericfg CLK_PERI_PWM4>,
-+ <&pericfg CLK_PERI_PWM5>;
-+ clock-names = "top", "main", "pwm1", "pwm2",
-+ "pwm3", "pwm4", "pwm5";
-+
-+ status = "disabled";
-+ };
-+
- spi: spi@1100a000 {
- compatible = "mediatek,mt7623-spi", "mediatek,mt6589-spi";
- reg = <0 0x1100a000 0 0x1000>;
---- a/drivers/pwm/Kconfig
-+++ b/drivers/pwm/Kconfig
-@@ -260,6 +260,15 @@ config PWM_MTK_DISP
- To compile this driver as a module, choose M here: the module
- will be called pwm-mtk-disp.
-
-+config PWM_MEDIATEK
-+ tristate "MediaTek PWM support"
-+ depends on ARCH_MEDIATEK || COMPILE_TEST
-+ help
-+ Generic PWM framework driver for Mediatek ARM SoC.
-+
-+ To compile this driver as a module, choose M here: the module
-+ will be called pwm-mxs.
-+
- config PWM_MXS
- tristate "Freescale MXS PWM support"
- depends on ARCH_MXS && OF
---- a/drivers/pwm/Makefile
-+++ b/drivers/pwm/Makefile
-@@ -22,6 +22,7 @@ obj-$(CONFIG_PWM_LPC32XX) += pwm-lpc32xx
- obj-$(CONFIG_PWM_LPSS) += pwm-lpss.o
- obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-pci.o
- obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o
-+obj-$(CONFIG_PWM_MEDIATEK) += pwm-mediatek.o
- obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o
- obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
- obj-$(CONFIG_PWM_PCA9685) += pwm-pca9685.o
---- /dev/null
-+++ b/drivers/pwm/pwm-mediatek.c
-@@ -0,0 +1,230 @@
-+/*
-+ * Mediatek Pulse Width Modulator driver
-+ *
-+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
-+ *
-+ * This file is licensed under the terms of the GNU General Public
-+ * License version 2. This program is licensed "as is" without any
-+ * warranty of any kind, whether express or implied.
-+ */
-+
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/ioport.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/clk.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pwm.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+
-+#define NUM_PWM 5
-+
-+/* PWM registers and bits definitions */
-+#define PWMCON 0x00
-+#define PWMHDUR 0x04
-+#define PWMLDUR 0x08
-+#define PWMGDUR 0x0c
-+#define PWMWAVENUM 0x28
-+#define PWMDWIDTH 0x2c
-+#define PWMTHRES 0x30
-+
-+/**
-+ * struct mtk_pwm_chip - struct representing pwm chip
-+ *
-+ * @mmio_base: base address of pwm chip
-+ * @chip: linux pwm chip representation
-+ */
-+struct mtk_pwm_chip {
-+ void __iomem *mmio_base;
-+ struct pwm_chip chip;
-+ struct clk *clk_top;
-+ struct clk *clk_main;
-+ struct clk *clk_pwm[NUM_PWM];
-+};
-+
-+static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
-+{
-+ return container_of(chip, struct mtk_pwm_chip, chip);
-+}
-+
-+static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
-+ unsigned long offset)
-+{
-+ return ioread32(chip->mmio_base + 0x10 + (num * 0x40) + offset);
-+}
-+
-+static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
-+ unsigned int num, unsigned long offset,
-+ unsigned long val)
-+{
-+ iowrite32(val, chip->mmio_base + 0x10 + (num * 0x40) + offset);
-+}
-+
-+static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
-+ int duty_ns, int period_ns)
-+{
-+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
-+ u32 resolution = 100 / 4;
-+ u32 clkdiv = 0;
-+
-+ resolution = 1000000000 / (clk_get_rate(pc->clk_pwm[pwm->hwpwm]));
-+
-+ while (period_ns / resolution > 8191) {
-+ clkdiv++;
-+ resolution *= 2;
-+ }
-+
-+ if (clkdiv > 7)
-+ return -1;
-+
-+ mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | BIT(3) | clkdiv);
-+ mtk_pwm_writel(pc, pwm->hwpwm, PWMDWIDTH, period_ns / resolution);
-+ mtk_pwm_writel(pc, pwm->hwpwm, PWMTHRES, duty_ns / resolution);
-+ return 0;
-+}
-+
-+static int mtk_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
-+{
-+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
-+ u32 val;
-+ int ret;
-+
-+ ret = clk_prepare(pc->clk_pwm[pwm->hwpwm]);
-+ if (ret < 0)
-+ return ret;
-+
-+ val = ioread32(pc->mmio_base);
-+ val |= BIT(pwm->hwpwm);
-+ iowrite32(val, pc->mmio_base);
-+
-+ return 0;
-+}
-+
-+static void mtk_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
-+{
-+ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
-+ u32 val;
-+
-+ val = ioread32(pc->mmio_base);
-+ val &= ~BIT(pwm->hwpwm);
-+ iowrite32(val, pc->mmio_base);
-+ clk_unprepare(pc->clk_pwm[pwm->hwpwm]);
-+}
-+
-+static const struct pwm_ops mtk_pwm_ops = {
-+ .config = mtk_pwm_config,
-+ .enable = mtk_pwm_enable,
-+ .disable = mtk_pwm_disable,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int mtk_pwm_probe(struct platform_device *pdev)
-+{
-+ struct mtk_pwm_chip *pc;
-+ struct resource *r;
-+ int ret;
-+
-+ pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
-+ if (!pc)
-+ return -ENOMEM;
-+
-+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ pc->mmio_base = devm_ioremap_resource(&pdev->dev, r);
-+ if (IS_ERR(pc->mmio_base))
-+ return PTR_ERR(pc->mmio_base);
-+
-+ pc->clk_main = devm_clk_get(&pdev->dev, "main");
-+ if (IS_ERR(pc->clk_main))
-+ return PTR_ERR(pc->clk_main);
-+
-+ pc->clk_top = devm_clk_get(&pdev->dev, "top");
-+ if (IS_ERR(pc->clk_top))
-+ return PTR_ERR(pc->clk_top);
-+
-+ pc->clk_pwm[0] = devm_clk_get(&pdev->dev, "pwm1");
-+ if (IS_ERR(pc->clk_pwm[0]))
-+ return PTR_ERR(pc->clk_pwm[0]);
-+
-+ pc->clk_pwm[1] = devm_clk_get(&pdev->dev, "pwm2");
-+ if (IS_ERR(pc->clk_pwm[1]))
-+ return PTR_ERR(pc->clk_pwm[1]);
-+
-+ pc->clk_pwm[2] = devm_clk_get(&pdev->dev, "pwm3");
-+ if (IS_ERR(pc->clk_pwm[2]))
-+ return PTR_ERR(pc->clk_pwm[2]);
-+
-+ pc->clk_pwm[3] = devm_clk_get(&pdev->dev, "pwm4");
-+ if (IS_ERR(pc->clk_pwm[3]))
-+ return PTR_ERR(pc->clk_pwm[3]);
-+
-+ pc->clk_pwm[4] = devm_clk_get(&pdev->dev, "pwm5");
-+ if (IS_ERR(pc->clk_pwm[4]))
-+ return PTR_ERR(pc->clk_pwm[4]);
-+
-+ ret = clk_prepare(pc->clk_top);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = clk_prepare(pc->clk_main);
-+ if (ret < 0)
-+ goto disable_clk_top;
-+
-+ platform_set_drvdata(pdev, pc);
-+
-+ pc->chip.dev = &pdev->dev;
-+ pc->chip.ops = &mtk_pwm_ops;
-+ pc->chip.base = -1;
-+ pc->chip.npwm = NUM_PWM;
-+
-+ ret = pwmchip_add(&pc->chip);
-+ if (ret < 0) {
-+ dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
-+ goto disable_clk_main;
-+ }
-+
-+ return 0;
-+
-+disable_clk_main:
-+ clk_unprepare(pc->clk_main);
-+disable_clk_top:
-+ clk_unprepare(pc->clk_top);
-+
-+ return ret;
-+}
-+
-+static int mtk_pwm_remove(struct platform_device *pdev)
-+{
-+ struct mtk_pwm_chip *pc = platform_get_drvdata(pdev);
-+ int i;
-+
-+ for (i = 0; i < NUM_PWM; i++)
-+ pwm_disable(&pc->chip.pwms[i]);
-+
-+ return pwmchip_remove(&pc->chip);
-+}
-+
-+static const struct of_device_id mtk_pwm_of_match[] = {
-+ { .compatible = "mediatek,mt7623-pwm" },
-+ { }
-+};
-+
-+MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
-+
-+static struct platform_driver mtk_pwm_driver = {
-+ .driver = {
-+ .name = "mtk-pwm",
-+ .owner = THIS_MODULE,
-+ .of_match_table = mtk_pwm_of_match,
-+ },
-+ .probe = mtk_pwm_probe,
-+ .remove = mtk_pwm_remove,
-+};
-+
-+module_platform_driver(mtk_pwm_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
-+MODULE_ALIAS("platform:mtk-pwm");
+++ /dev/null
-From a369af5149e6eb442b22ce89b564dd7a76e03638 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 26 Apr 2016 19:05:01 +0200
-Subject: [PATCH 072/102] mtd: backport v4.7-0day patches from Boris
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/mtd/Kconfig | 4 +-
- drivers/mtd/cmdlinepart.c | 3 +-
- drivers/mtd/devices/m25p80.c | 44 +--
- drivers/mtd/maps/physmap_of.c | 6 +-
- drivers/mtd/mtdchar.c | 123 ++++++--
- drivers/mtd/mtdconcat.c | 2 +-
- drivers/mtd/mtdcore.c | 428 ++++++++++++++++++++++++--
- drivers/mtd/mtdcore.h | 7 +-
- drivers/mtd/mtdpart.c | 161 ++++++----
- drivers/mtd/mtdswap.c | 24 +-
- drivers/mtd/nand/Kconfig | 21 +-
- drivers/mtd/nand/Makefile | 2 +
- drivers/mtd/nand/nand_base.c | 571 +++++++++++++++++++----------------
- drivers/mtd/nand/nand_bbt.c | 34 +--
- drivers/mtd/nand/nand_bch.c | 52 ++--
- drivers/mtd/nand/nand_ecc.c | 6 +-
- drivers/mtd/nand/nand_ids.c | 4 +-
- drivers/mtd/nand/nandsim.c | 43 +--
- drivers/mtd/ofpart.c | 53 ++--
- drivers/mtd/spi-nor/Kconfig | 10 +-
- drivers/mtd/spi-nor/Makefile | 1 +
- drivers/mtd/spi-nor/mtk-quadspi.c | 485 +++++++++++++++++++++++++++++
- drivers/mtd/spi-nor/spi-nor.c | 321 +++++++++++++-------
- drivers/mtd/tests/mtd_nandecctest.c | 2 +-
- drivers/mtd/tests/oobtest.c | 49 ++-
- drivers/mtd/tests/pagetest.c | 3 +-
- include/linux/mtd/bbm.h | 1 -
- include/linux/mtd/fsmc.h | 18 --
- include/linux/mtd/inftl.h | 1 -
- include/linux/mtd/map.h | 9 +-
- include/linux/mtd/mtd.h | 80 ++++-
- include/linux/mtd/nand.h | 94 ++++--
- include/linux/mtd/nand_bch.h | 10 +-
- include/linux/mtd/nftl.h | 1 -
- include/linux/mtd/onenand.h | 2 -
- include/linux/mtd/partitions.h | 27 +-
- include/linux/mtd/sh_flctl.h | 4 +-
- include/linux/mtd/sharpsl.h | 2 +-
- include/linux/mtd/spi-nor.h | 23 +-
- include/uapi/mtd/mtd-abi.h | 2 +-
- 45 files changed, 2077 insertions(+), 748 deletions(-)
- create mode 100644 drivers/mtd/spi-nor/mtk-quadspi.c
-
---- a/drivers/mtd/Kconfig
-+++ b/drivers/mtd/Kconfig
-@@ -131,7 +131,7 @@ config MTD_CMDLINE_PARTS
-
- config MTD_AFS_PARTS
- tristate "ARM Firmware Suite partition parsing"
-- depends on ARM
-+ depends on (ARM || ARM64)
- ---help---
- The ARM Firmware Suite allows the user to divide flash devices into
- multiple 'images'. Each such image has a header containing its name
-@@ -161,7 +161,7 @@ config MTD_AR7_PARTS
-
- config MTD_BCM63XX_PARTS
- tristate "BCM63XX CFE partitioning support"
-- depends on BCM63XX
-+ depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST
- select CRC32
- help
- This provides partions parsing for BCM63xx devices with CFE
---- a/drivers/mtd/cmdlinepart.c
-+++ b/drivers/mtd/cmdlinepart.c
-@@ -304,7 +304,7 @@ static int mtdpart_setup_real(char *s)
- * the first one in the chain if a NULL mtd_id is passed in.
- */
- static int parse_cmdline_partitions(struct mtd_info *master,
-- struct mtd_partition **pparts,
-+ const struct mtd_partition **pparts,
- struct mtd_part_parser_data *data)
- {
- unsigned long long offset;
-@@ -382,7 +382,6 @@ static int __init mtdpart_setup(char *s)
- __setup("mtdparts=", mtdpart_setup);
-
- static struct mtd_part_parser cmdline_parser = {
-- .owner = THIS_MODULE,
- .parse_fn = parse_cmdline_partitions,
- .name = "cmdlinepart",
- };
---- a/drivers/mtd/devices/m25p80.c
-+++ b/drivers/mtd/devices/m25p80.c
-@@ -174,22 +174,6 @@ static int m25p80_read(struct spi_nor *n
- return 0;
- }
-
--static int m25p80_erase(struct spi_nor *nor, loff_t offset)
--{
-- struct m25p *flash = nor->priv;
--
-- dev_dbg(nor->dev, "%dKiB at 0x%08x\n",
-- flash->spi_nor.mtd.erasesize / 1024, (u32)offset);
--
-- /* Set up command buffer. */
-- flash->command[0] = nor->erase_opcode;
-- m25p_addr2cmd(nor, offset, flash->command);
--
-- spi_write(flash->spi, flash->command, m25p_cmdsz(nor));
--
-- return 0;
--}
--
- /*
- * board specific setup should have ensured the SPI clock used here
- * matches what the READ command supports, at least until this driver
-@@ -197,12 +181,11 @@ static int m25p80_erase(struct spi_nor *
- */
- static int m25p_probe(struct spi_device *spi)
- {
-- struct mtd_part_parser_data ppdata;
- struct flash_platform_data *data;
- struct m25p *flash;
- struct spi_nor *nor;
- enum read_mode mode = SPI_NOR_NORMAL;
-- char *flash_name = NULL;
-+ char *flash_name;
- int ret;
-
- data = dev_get_platdata(&spi->dev);
-@@ -216,12 +199,11 @@ static int m25p_probe(struct spi_device
- /* install the hooks */
- nor->read = m25p80_read;
- nor->write = m25p80_write;
-- nor->erase = m25p80_erase;
- nor->write_reg = m25p80_write_reg;
- nor->read_reg = m25p80_read_reg;
-
- nor->dev = &spi->dev;
-- nor->flash_node = spi->dev.of_node;
-+ spi_nor_set_flash_node(nor, spi->dev.of_node);
- nor->priv = flash;
-
- spi_set_drvdata(spi, flash);
-@@ -242,6 +224,8 @@ static int m25p_probe(struct spi_device
- */
- if (data && data->type)
- flash_name = data->type;
-+ else if (!strcmp(spi->modalias, "spi-nor"))
-+ flash_name = NULL; /* auto-detect */
- else
- flash_name = spi->modalias;
-
-@@ -249,11 +233,8 @@ static int m25p_probe(struct spi_device
- if (ret)
- return ret;
-
-- ppdata.of_node = spi->dev.of_node;
--
-- return mtd_device_parse_register(&nor->mtd, NULL, &ppdata,
-- data ? data->parts : NULL,
-- data ? data->nr_parts : 0);
-+ return mtd_device_register(&nor->mtd, data ? data->parts : NULL,
-+ data ? data->nr_parts : 0);
- }
-
-
-@@ -279,14 +260,21 @@ static int m25p_remove(struct spi_device
- */
- static const struct spi_device_id m25p_ids[] = {
- /*
-+ * Allow non-DT platform devices to bind to the "spi-nor" modalias, and
-+ * hack around the fact that the SPI core does not provide uevent
-+ * matching for .of_match_table
-+ */
-+ {"spi-nor"},
-+
-+ /*
- * Entries not used in DTs that should be safe to drop after replacing
-- * them with "nor-jedec" in platform data.
-+ * them with "spi-nor" in platform data.
- */
- {"s25sl064a"}, {"w25x16"}, {"m25p10"}, {"m25px64"},
-
- /*
-- * Entries that were used in DTs without "nor-jedec" fallback and should
-- * be kept for backward compatibility.
-+ * Entries that were used in DTs without "jedec,spi-nor" fallback and
-+ * should be kept for backward compatibility.
- */
- {"at25df321a"}, {"at25df641"}, {"at26df081a"},
- {"mr25h256"},
---- a/drivers/mtd/maps/physmap_of.c
-+++ b/drivers/mtd/maps/physmap_of.c
-@@ -128,7 +128,6 @@ static int of_flash_probe(struct platfor
- int reg_tuple_size;
- struct mtd_info **mtd_list = NULL;
- resource_size_t res_size;
-- struct mtd_part_parser_data ppdata;
- bool map_indirect;
- const char *mtd_name = NULL;
-
-@@ -272,8 +271,9 @@ static int of_flash_probe(struct platfor
- if (err)
- goto err_out;
-
-- ppdata.of_node = dp;
-- mtd_device_parse_register(info->cmtd, part_probe_types_def, &ppdata,
-+ info->cmtd->dev.parent = &dev->dev;
-+ mtd_set_of_node(info->cmtd, dp);
-+ mtd_device_parse_register(info->cmtd, part_probe_types_def, NULL,
- NULL, 0);
-
- kfree(mtd_list);
---- a/drivers/mtd/mtdchar.c
-+++ b/drivers/mtd/mtdchar.c
-@@ -465,38 +465,111 @@ static int mtdchar_readoob(struct file *
- }
-
- /*
-- * Copies (and truncates, if necessary) data from the larger struct,
-- * nand_ecclayout, to the smaller, deprecated layout struct,
-- * nand_ecclayout_user. This is necessary only to support the deprecated
-- * API ioctl ECCGETLAYOUT while allowing all new functionality to use
-- * nand_ecclayout flexibly (i.e. the struct may change size in new
-- * releases without requiring major rewrites).
-+ * Copies (and truncates, if necessary) OOB layout information to the
-+ * deprecated layout struct, nand_ecclayout_user. This is necessary only to
-+ * support the deprecated API ioctl ECCGETLAYOUT while allowing all new
-+ * functionality to use mtd_ooblayout_ops flexibly (i.e. mtd_ooblayout_ops
-+ * can describe any kind of OOB layout with almost zero overhead from a
-+ * memory usage point of view).
- */
--static int shrink_ecclayout(const struct nand_ecclayout *from,
-- struct nand_ecclayout_user *to)
-+static int shrink_ecclayout(struct mtd_info *mtd,
-+ struct nand_ecclayout_user *to)
- {
-- int i;
-+ struct mtd_oob_region oobregion;
-+ int i, section = 0, ret;
-
-- if (!from || !to)
-+ if (!mtd || !to)
- return -EINVAL;
-
- memset(to, 0, sizeof(*to));
-
-- to->eccbytes = min((int)from->eccbytes, MTD_MAX_ECCPOS_ENTRIES);
-- for (i = 0; i < to->eccbytes; i++)
-- to->eccpos[i] = from->eccpos[i];
-+ to->eccbytes = 0;
-+ for (i = 0; i < MTD_MAX_ECCPOS_ENTRIES;) {
-+ u32 eccpos;
-+
-+ ret = mtd_ooblayout_ecc(mtd, section, &oobregion);
-+ if (ret < 0) {
-+ if (ret != -ERANGE)
-+ return ret;
-+
-+ break;
-+ }
-+
-+ eccpos = oobregion.offset;
-+ for (; i < MTD_MAX_ECCPOS_ENTRIES &&
-+ eccpos < oobregion.offset + oobregion.length; i++) {
-+ to->eccpos[i] = eccpos++;
-+ to->eccbytes++;
-+ }
-+ }
-
- for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++) {
-- if (from->oobfree[i].length == 0 &&
-- from->oobfree[i].offset == 0)
-+ ret = mtd_ooblayout_free(mtd, i, &oobregion);
-+ if (ret < 0) {
-+ if (ret != -ERANGE)
-+ return ret;
-+
- break;
-- to->oobavail += from->oobfree[i].length;
-- to->oobfree[i] = from->oobfree[i];
-+ }
-+
-+ to->oobfree[i].offset = oobregion.offset;
-+ to->oobfree[i].length = oobregion.length;
-+ to->oobavail += to->oobfree[i].length;
- }
-
- return 0;
- }
-
-+static int get_oobinfo(struct mtd_info *mtd, struct nand_oobinfo *to)
-+{
-+ struct mtd_oob_region oobregion;
-+ int i, section = 0, ret;
-+
-+ if (!mtd || !to)
-+ return -EINVAL;
-+
-+ memset(to, 0, sizeof(*to));
-+
-+ to->eccbytes = 0;
-+ for (i = 0; i < ARRAY_SIZE(to->eccpos);) {
-+ u32 eccpos;
-+
-+ ret = mtd_ooblayout_ecc(mtd, section, &oobregion);
-+ if (ret < 0) {
-+ if (ret != -ERANGE)
-+ return ret;
-+
-+ break;
-+ }
-+
-+ if (oobregion.length + i > ARRAY_SIZE(to->eccpos))
-+ return -EINVAL;
-+
-+ eccpos = oobregion.offset;
-+ for (; eccpos < oobregion.offset + oobregion.length; i++) {
-+ to->eccpos[i] = eccpos++;
-+ to->eccbytes++;
-+ }
-+ }
-+
-+ for (i = 0; i < 8; i++) {
-+ ret = mtd_ooblayout_free(mtd, i, &oobregion);
-+ if (ret < 0) {
-+ if (ret != -ERANGE)
-+ return ret;
-+
-+ break;
-+ }
-+
-+ to->oobfree[i][0] = oobregion.offset;
-+ to->oobfree[i][1] = oobregion.length;
-+ }
-+
-+ to->useecc = MTD_NANDECC_AUTOPLACE;
-+
-+ return 0;
-+}
-+
- static int mtdchar_blkpg_ioctl(struct mtd_info *mtd,
- struct blkpg_ioctl_arg *arg)
- {
-@@ -815,16 +888,12 @@ static int mtdchar_ioctl(struct file *fi
- {
- struct nand_oobinfo oi;
-
-- if (!mtd->ecclayout)
-+ if (!mtd->ooblayout)
- return -EOPNOTSUPP;
-- if (mtd->ecclayout->eccbytes > ARRAY_SIZE(oi.eccpos))
-- return -EINVAL;
-
-- oi.useecc = MTD_NANDECC_AUTOPLACE;
-- memcpy(&oi.eccpos, mtd->ecclayout->eccpos, sizeof(oi.eccpos));
-- memcpy(&oi.oobfree, mtd->ecclayout->oobfree,
-- sizeof(oi.oobfree));
-- oi.eccbytes = mtd->ecclayout->eccbytes;
-+ ret = get_oobinfo(mtd, &oi);
-+ if (ret)
-+ return ret;
-
- if (copy_to_user(argp, &oi, sizeof(struct nand_oobinfo)))
- return -EFAULT;
-@@ -913,14 +982,14 @@ static int mtdchar_ioctl(struct file *fi
- {
- struct nand_ecclayout_user *usrlay;
-
-- if (!mtd->ecclayout)
-+ if (!mtd->ooblayout)
- return -EOPNOTSUPP;
-
- usrlay = kmalloc(sizeof(*usrlay), GFP_KERNEL);
- if (!usrlay)
- return -ENOMEM;
-
-- shrink_ecclayout(mtd->ecclayout, usrlay);
-+ shrink_ecclayout(mtd, usrlay);
-
- if (copy_to_user(argp, usrlay, sizeof(*usrlay)))
- ret = -EFAULT;
---- a/drivers/mtd/mtdconcat.c
-+++ b/drivers/mtd/mtdconcat.c
-@@ -777,7 +777,7 @@ struct mtd_info *mtd_concat_create(struc
-
- }
-
-- concat->mtd.ecclayout = subdev[0]->ecclayout;
-+ mtd_set_ooblayout(&concat->mtd, subdev[0]->ooblayout);
-
- concat->num_subdev = num_devs;
- concat->mtd.name = name;
---- a/drivers/mtd/mtdcore.c
-+++ b/drivers/mtd/mtdcore.c
-@@ -32,6 +32,7 @@
- #include <linux/err.h>
- #include <linux/ioctl.h>
- #include <linux/init.h>
-+#include <linux/of.h>
- #include <linux/proc_fs.h>
- #include <linux/idr.h>
- #include <linux/backing-dev.h>
-@@ -446,6 +447,7 @@ int add_mtd_device(struct mtd_info *mtd)
- mtd->dev.devt = MTD_DEVT(i);
- dev_set_name(&mtd->dev, "mtd%d", i);
- dev_set_drvdata(&mtd->dev, mtd);
-+ of_node_get(mtd_get_of_node(mtd));
- error = device_register(&mtd->dev);
- if (error)
- goto fail_added;
-@@ -477,6 +479,7 @@ int add_mtd_device(struct mtd_info *mtd)
- return 0;
-
- fail_added:
-+ of_node_put(mtd_get_of_node(mtd));
- idr_remove(&mtd_idr, i);
- fail_locked:
- mutex_unlock(&mtd_table_mutex);
-@@ -518,6 +521,7 @@ int del_mtd_device(struct mtd_info *mtd)
- device_unregister(&mtd->dev);
-
- idr_remove(&mtd_idr, mtd->index);
-+ of_node_put(mtd_get_of_node(mtd));
-
- module_put(THIS_MODULE);
- ret = 0;
-@@ -529,9 +533,10 @@ out_error:
- }
-
- static int mtd_add_device_partitions(struct mtd_info *mtd,
-- struct mtd_partition *real_parts,
-- int nbparts)
-+ struct mtd_partitions *parts)
- {
-+ const struct mtd_partition *real_parts = parts->parts;
-+ int nbparts = parts->nr_parts;
- int ret;
-
- if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
-@@ -600,29 +605,29 @@ int mtd_device_parse_register(struct mtd
- const struct mtd_partition *parts,
- int nr_parts)
- {
-+ struct mtd_partitions parsed;
- int ret;
-- struct mtd_partition *real_parts = NULL;
-
- mtd_set_dev_defaults(mtd);
-
-- ret = parse_mtd_partitions(mtd, types, &real_parts, parser_data);
-- if (ret <= 0 && nr_parts && parts) {
-- real_parts = kmemdup(parts, sizeof(*parts) * nr_parts,
-- GFP_KERNEL);
-- if (!real_parts)
-- ret = -ENOMEM;
-- else
-- ret = nr_parts;
-- }
-- /* Didn't come up with either parsed OR fallback partitions */
-- if (ret < 0) {
-- pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n",
-+ memset(&parsed, 0, sizeof(parsed));
-+
-+ ret = parse_mtd_partitions(mtd, types, &parsed, parser_data);
-+ if ((ret < 0 || parsed.nr_parts == 0) && parts && nr_parts) {
-+ /* Fall back to driver-provided partitions */
-+ parsed = (struct mtd_partitions){
-+ .parts = parts,
-+ .nr_parts = nr_parts,
-+ };
-+ } else if (ret < 0) {
-+ /* Didn't come up with parsed OR fallback partitions */
-+ pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n",
- ret);
- /* Don't abort on errors; we can still use unpartitioned MTD */
-- ret = 0;
-+ memset(&parsed, 0, sizeof(parsed));
- }
-
-- ret = mtd_add_device_partitions(mtd, real_parts, ret);
-+ ret = mtd_add_device_partitions(mtd, &parsed);
- if (ret)
- goto out;
-
-@@ -642,7 +647,8 @@ int mtd_device_parse_register(struct mtd
- }
-
- out:
-- kfree(real_parts);
-+ /* Cleanup any parsed partitions */
-+ mtd_part_parser_cleanup(&parsed);
- return ret;
- }
- EXPORT_SYMBOL_GPL(mtd_device_parse_register);
-@@ -767,7 +773,6 @@ out:
- }
- EXPORT_SYMBOL_GPL(get_mtd_device);
-
--
- int __get_mtd_device(struct mtd_info *mtd)
- {
- int err;
-@@ -1001,6 +1006,366 @@ int mtd_read_oob(struct mtd_info *mtd, l
- }
- EXPORT_SYMBOL_GPL(mtd_read_oob);
-
-+/**
-+ * mtd_ooblayout_ecc - Get the OOB region definition of a specific ECC section
-+ * @mtd: MTD device structure
-+ * @section: ECC section. Depending on the layout you may have all the ECC
-+ * bytes stored in a single contiguous section, or one section
-+ * per ECC chunk (and sometime several sections for a single ECC
-+ * ECC chunk)
-+ * @oobecc: OOB region struct filled with the appropriate ECC position
-+ * information
-+ *
-+ * This functions return ECC section information in the OOB area. I you want
-+ * to get all the ECC bytes information, then you should call
-+ * mtd_ooblayout_ecc(mtd, section++, oobecc) until it returns -ERANGE.
-+ *
-+ * Returns zero on success, a negative error code otherwise.
-+ */
-+int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oobecc)
-+{
-+ memset(oobecc, 0, sizeof(*oobecc));
-+
-+ if (!mtd || section < 0)
-+ return -EINVAL;
-+
-+ if (!mtd->ooblayout || !mtd->ooblayout->ecc)
-+ return -ENOTSUPP;
-+
-+ return mtd->ooblayout->ecc(mtd, section, oobecc);
-+}
-+EXPORT_SYMBOL_GPL(mtd_ooblayout_ecc);
-+
-+/**
-+ * mtd_ooblayout_free - Get the OOB region definition of a specific free
-+ * section
-+ * @mtd: MTD device structure
-+ * @section: Free section you are interested in. Depending on the layout
-+ * you may have all the free bytes stored in a single contiguous
-+ * section, or one section per ECC chunk plus an extra section
-+ * for the remaining bytes (or other funky layout).
-+ * @oobfree: OOB region struct filled with the appropriate free position
-+ * information
-+ *
-+ * This functions return free bytes position in the OOB area. I you want
-+ * to get all the free bytes information, then you should call
-+ * mtd_ooblayout_free(mtd, section++, oobfree) until it returns -ERANGE.
-+ *
-+ * Returns zero on success, a negative error code otherwise.
-+ */
-+int mtd_ooblayout_free(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oobfree)
-+{
-+ memset(oobfree, 0, sizeof(*oobfree));
-+
-+ if (!mtd || section < 0)
-+ return -EINVAL;
-+
-+ if (!mtd->ooblayout || !mtd->ooblayout->free)
-+ return -ENOTSUPP;
-+
-+ return mtd->ooblayout->free(mtd, section, oobfree);
-+}
-+EXPORT_SYMBOL_GPL(mtd_ooblayout_free);
-+
-+/**
-+ * mtd_ooblayout_find_region - Find the region attached to a specific byte
-+ * @mtd: mtd info structure
-+ * @byte: the byte we are searching for
-+ * @sectionp: pointer where the section id will be stored
-+ * @oobregion: used to retrieve the ECC position
-+ * @iter: iterator function. Should be either mtd_ooblayout_free or
-+ * mtd_ooblayout_ecc depending on the region type you're searching for
-+ *
-+ * This functions returns the section id and oobregion information of a
-+ * specific byte. For example, say you want to know where the 4th ECC byte is
-+ * stored, you'll use:
-+ *
-+ * mtd_ooblayout_find_region(mtd, 3, §ion, &oobregion, mtd_ooblayout_ecc);
-+ *
-+ * Returns zero on success, a negative error code otherwise.
-+ */
-+static int mtd_ooblayout_find_region(struct mtd_info *mtd, int byte,
-+ int *sectionp, struct mtd_oob_region *oobregion,
-+ int (*iter)(struct mtd_info *,
-+ int section,
-+ struct mtd_oob_region *oobregion))
-+{
-+ int pos = 0, ret, section = 0;
-+
-+ memset(oobregion, 0, sizeof(*oobregion));
-+
-+ while (1) {
-+ ret = iter(mtd, section, oobregion);
-+ if (ret)
-+ return ret;
-+
-+ if (pos + oobregion->length > byte)
-+ break;
-+
-+ pos += oobregion->length;
-+ section++;
-+ }
-+
-+ /*
-+ * Adjust region info to make it start at the beginning at the
-+ * 'start' ECC byte.
-+ */
-+ oobregion->offset += byte - pos;
-+ oobregion->length -= byte - pos;
-+ *sectionp = section;
-+
-+ return 0;
-+}
-+
-+/**
-+ * mtd_ooblayout_find_eccregion - Find the ECC region attached to a specific
-+ * ECC byte
-+ * @mtd: mtd info structure
-+ * @eccbyte: the byte we are searching for
-+ * @sectionp: pointer where the section id will be stored
-+ * @oobregion: OOB region information
-+ *
-+ * Works like mtd_ooblayout_find_region() except it searches for a specific ECC
-+ * byte.
-+ *
-+ * Returns zero on success, a negative error code otherwise.
-+ */
-+int mtd_ooblayout_find_eccregion(struct mtd_info *mtd, int eccbyte,
-+ int *section,
-+ struct mtd_oob_region *oobregion)
-+{
-+ return mtd_ooblayout_find_region(mtd, eccbyte, section, oobregion,
-+ mtd_ooblayout_ecc);
-+}
-+EXPORT_SYMBOL_GPL(mtd_ooblayout_find_eccregion);
-+
-+/**
-+ * mtd_ooblayout_get_bytes - Extract OOB bytes from the oob buffer
-+ * @mtd: mtd info structure
-+ * @buf: destination buffer to store OOB bytes
-+ * @oobbuf: OOB buffer
-+ * @start: first byte to retrieve
-+ * @nbytes: number of bytes to retrieve
-+ * @iter: section iterator
-+ *
-+ * Extract bytes attached to a specific category (ECC or free)
-+ * from the OOB buffer and copy them into buf.
-+ *
-+ * Returns zero on success, a negative error code otherwise.
-+ */
-+static int mtd_ooblayout_get_bytes(struct mtd_info *mtd, u8 *buf,
-+ const u8 *oobbuf, int start, int nbytes,
-+ int (*iter)(struct mtd_info *,
-+ int section,
-+ struct mtd_oob_region *oobregion))
-+{
-+ struct mtd_oob_region oobregion = { };
-+ int section = 0, ret;
-+
-+ ret = mtd_ooblayout_find_region(mtd, start, §ion,
-+ &oobregion, iter);
-+
-+ while (!ret) {
-+ int cnt;
-+
-+ cnt = oobregion.length > nbytes ? nbytes : oobregion.length;
-+ memcpy(buf, oobbuf + oobregion.offset, cnt);
-+ buf += cnt;
-+ nbytes -= cnt;
-+
-+ if (!nbytes)
-+ break;
-+
-+ ret = iter(mtd, ++section, &oobregion);
-+ }
-+
-+ return ret;
-+}
-+
-+/**
-+ * mtd_ooblayout_set_bytes - put OOB bytes into the oob buffer
-+ * @mtd: mtd info structure
-+ * @buf: source buffer to get OOB bytes from
-+ * @oobbuf: OOB buffer
-+ * @start: first OOB byte to set
-+ * @nbytes: number of OOB bytes to set
-+ * @iter: section iterator
-+ *
-+ * Fill the OOB buffer with data provided in buf. The category (ECC or free)
-+ * is selected by passing the appropriate iterator.
-+ *
-+ * Returns zero on success, a negative error code otherwise.
-+ */
-+static int mtd_ooblayout_set_bytes(struct mtd_info *mtd, const u8 *buf,
-+ u8 *oobbuf, int start, int nbytes,
-+ int (*iter)(struct mtd_info *,
-+ int section,
-+ struct mtd_oob_region *oobregion))
-+{
-+ struct mtd_oob_region oobregion = { };
-+ int section = 0, ret;
-+
-+ ret = mtd_ooblayout_find_region(mtd, start, §ion,
-+ &oobregion, iter);
-+
-+ while (!ret) {
-+ int cnt;
-+
-+ cnt = oobregion.length > nbytes ? nbytes : oobregion.length;
-+ memcpy(oobbuf + oobregion.offset, buf, cnt);
-+ buf += cnt;
-+ nbytes -= cnt;
-+
-+ if (!nbytes)
-+ break;
-+
-+ ret = iter(mtd, ++section, &oobregion);
-+ }
-+
-+ return ret;
-+}
-+
-+/**
-+ * mtd_ooblayout_count_bytes - count the number of bytes in a OOB category
-+ * @mtd: mtd info structure
-+ * @iter: category iterator
-+ *
-+ * Count the number of bytes in a given category.
-+ *
-+ * Returns a positive value on success, a negative error code otherwise.
-+ */
-+static int mtd_ooblayout_count_bytes(struct mtd_info *mtd,
-+ int (*iter)(struct mtd_info *,
-+ int section,
-+ struct mtd_oob_region *oobregion))
-+{
-+ struct mtd_oob_region oobregion = { };
-+ int section = 0, ret, nbytes = 0;
-+
-+ while (1) {
-+ ret = iter(mtd, section++, &oobregion);
-+ if (ret) {
-+ if (ret == -ERANGE)
-+ ret = nbytes;
-+ break;
-+ }
-+
-+ nbytes += oobregion.length;
-+ }
-+
-+ return ret;
-+}
-+
-+/**
-+ * mtd_ooblayout_get_eccbytes - extract ECC bytes from the oob buffer
-+ * @mtd: mtd info structure
-+ * @eccbuf: destination buffer to store ECC bytes
-+ * @oobbuf: OOB buffer
-+ * @start: first ECC byte to retrieve
-+ * @nbytes: number of ECC bytes to retrieve
-+ *
-+ * Works like mtd_ooblayout_get_bytes(), except it acts on ECC bytes.
-+ *
-+ * Returns zero on success, a negative error code otherwise.
-+ */
-+int mtd_ooblayout_get_eccbytes(struct mtd_info *mtd, u8 *eccbuf,
-+ const u8 *oobbuf, int start, int nbytes)
-+{
-+ return mtd_ooblayout_get_bytes(mtd, eccbuf, oobbuf, start, nbytes,
-+ mtd_ooblayout_ecc);
-+}
-+EXPORT_SYMBOL_GPL(mtd_ooblayout_get_eccbytes);
-+
-+/**
-+ * mtd_ooblayout_set_eccbytes - set ECC bytes into the oob buffer
-+ * @mtd: mtd info structure
-+ * @eccbuf: source buffer to get ECC bytes from
-+ * @oobbuf: OOB buffer
-+ * @start: first ECC byte to set
-+ * @nbytes: number of ECC bytes to set
-+ *
-+ * Works like mtd_ooblayout_set_bytes(), except it acts on ECC bytes.
-+ *
-+ * Returns zero on success, a negative error code otherwise.
-+ */
-+int mtd_ooblayout_set_eccbytes(struct mtd_info *mtd, const u8 *eccbuf,
-+ u8 *oobbuf, int start, int nbytes)
-+{
-+ return mtd_ooblayout_set_bytes(mtd, eccbuf, oobbuf, start, nbytes,
-+ mtd_ooblayout_ecc);
-+}
-+EXPORT_SYMBOL_GPL(mtd_ooblayout_set_eccbytes);
-+
-+/**
-+ * mtd_ooblayout_get_databytes - extract data bytes from the oob buffer
-+ * @mtd: mtd info structure
-+ * @databuf: destination buffer to store ECC bytes
-+ * @oobbuf: OOB buffer
-+ * @start: first ECC byte to retrieve
-+ * @nbytes: number of ECC bytes to retrieve
-+ *
-+ * Works like mtd_ooblayout_get_bytes(), except it acts on free bytes.
-+ *
-+ * Returns zero on success, a negative error code otherwise.
-+ */
-+int mtd_ooblayout_get_databytes(struct mtd_info *mtd, u8 *databuf,
-+ const u8 *oobbuf, int start, int nbytes)
-+{
-+ return mtd_ooblayout_get_bytes(mtd, databuf, oobbuf, start, nbytes,
-+ mtd_ooblayout_free);
-+}
-+EXPORT_SYMBOL_GPL(mtd_ooblayout_get_databytes);
-+
-+/**
-+ * mtd_ooblayout_get_eccbytes - set data bytes into the oob buffer
-+ * @mtd: mtd info structure
-+ * @eccbuf: source buffer to get data bytes from
-+ * @oobbuf: OOB buffer
-+ * @start: first ECC byte to set
-+ * @nbytes: number of ECC bytes to set
-+ *
-+ * Works like mtd_ooblayout_get_bytes(), except it acts on free bytes.
-+ *
-+ * Returns zero on success, a negative error code otherwise.
-+ */
-+int mtd_ooblayout_set_databytes(struct mtd_info *mtd, const u8 *databuf,
-+ u8 *oobbuf, int start, int nbytes)
-+{
-+ return mtd_ooblayout_set_bytes(mtd, databuf, oobbuf, start, nbytes,
-+ mtd_ooblayout_free);
-+}
-+EXPORT_SYMBOL_GPL(mtd_ooblayout_set_databytes);
-+
-+/**
-+ * mtd_ooblayout_count_freebytes - count the number of free bytes in OOB
-+ * @mtd: mtd info structure
-+ *
-+ * Works like mtd_ooblayout_count_bytes(), except it count free bytes.
-+ *
-+ * Returns zero on success, a negative error code otherwise.
-+ */
-+int mtd_ooblayout_count_freebytes(struct mtd_info *mtd)
-+{
-+ return mtd_ooblayout_count_bytes(mtd, mtd_ooblayout_free);
-+}
-+EXPORT_SYMBOL_GPL(mtd_ooblayout_count_freebytes);
-+
-+/**
-+ * mtd_ooblayout_count_freebytes - count the number of ECC bytes in OOB
-+ * @mtd: mtd info structure
-+ *
-+ * Works like mtd_ooblayout_count_bytes(), except it count ECC bytes.
-+ *
-+ * Returns zero on success, a negative error code otherwise.
-+ */
-+int mtd_ooblayout_count_eccbytes(struct mtd_info *mtd)
-+{
-+ return mtd_ooblayout_count_bytes(mtd, mtd_ooblayout_ecc);
-+}
-+EXPORT_SYMBOL_GPL(mtd_ooblayout_count_eccbytes);
-+
- /*
- * Method to access the protection register area, present in some flash
- * devices. The user data is one time programmable but the factory data is read
---- a/drivers/mtd/mtdcore.h
-+++ b/drivers/mtd/mtdcore.h
-@@ -10,10 +10,15 @@ int add_mtd_device(struct mtd_info *mtd)
- int del_mtd_device(struct mtd_info *mtd);
- int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
- int del_mtd_partitions(struct mtd_info *);
-+
-+struct mtd_partitions;
-+
- int parse_mtd_partitions(struct mtd_info *master, const char * const *types,
-- struct mtd_partition **pparts,
-+ struct mtd_partitions *pparts,
- struct mtd_part_parser_data *data);
-
-+void mtd_part_parser_cleanup(struct mtd_partitions *parts);
-+
- int __init init_mtdchar(void);
- void __exit cleanup_mtdchar(void);
-
---- a/drivers/mtd/mtdpart.c
-+++ b/drivers/mtd/mtdpart.c
-@@ -55,9 +55,12 @@ static void mtd_partition_split(struct m
-
- /*
- * Given a pointer to the MTD object in the mtd_part structure, we can retrieve
-- * the pointer to that structure with this macro.
-+ * the pointer to that structure.
- */
--#define PART(x) ((struct mtd_part *)(x))
-+static inline struct mtd_part *mtd_to_part(const struct mtd_info *mtd)
-+{
-+ return container_of(mtd, struct mtd_part, mtd);
-+}
-
-
- /*
-@@ -68,7 +71,7 @@ static void mtd_partition_split(struct m
- static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
- size_t *retlen, u_char *buf)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- struct mtd_ecc_stats stats;
- int res;
-
-@@ -87,7 +90,7 @@ static int part_read(struct mtd_info *mt
- static int part_point(struct mtd_info *mtd, loff_t from, size_t len,
- size_t *retlen, void **virt, resource_size_t *phys)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
-
- return part->master->_point(part->master, from + part->offset, len,
- retlen, virt, phys);
-@@ -95,7 +98,7 @@ static int part_point(struct mtd_info *m
-
- static int part_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
-
- return part->master->_unpoint(part->master, from + part->offset, len);
- }
-@@ -105,7 +108,7 @@ static unsigned long part_get_unmapped_a
- unsigned long offset,
- unsigned long flags)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
-
- offset += part->offset;
- return part->master->_get_unmapped_area(part->master, len, offset,
-@@ -115,7 +118,7 @@ static unsigned long part_get_unmapped_a
- static int part_read_oob(struct mtd_info *mtd, loff_t from,
- struct mtd_oob_ops *ops)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- int res;
-
- if (from >= mtd->size)
-@@ -130,10 +133,7 @@ static int part_read_oob(struct mtd_info
- if (ops->oobbuf) {
- size_t len, pages;
-
-- if (ops->mode == MTD_OPS_AUTO_OOB)
-- len = mtd->oobavail;
-- else
-- len = mtd->oobsize;
-+ len = mtd_oobavail(mtd, ops);
- pages = mtd_div_by_ws(mtd->size, mtd);
- pages -= mtd_div_by_ws(from, mtd);
- if (ops->ooboffs + ops->ooblen > pages * len)
-@@ -153,7 +153,7 @@ static int part_read_oob(struct mtd_info
- static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
- size_t len, size_t *retlen, u_char *buf)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- return part->master->_read_user_prot_reg(part->master, from, len,
- retlen, buf);
- }
-@@ -161,7 +161,7 @@ static int part_read_user_prot_reg(struc
- static int part_get_user_prot_info(struct mtd_info *mtd, size_t len,
- size_t *retlen, struct otp_info *buf)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- return part->master->_get_user_prot_info(part->master, len, retlen,
- buf);
- }
-@@ -169,7 +169,7 @@ static int part_get_user_prot_info(struc
- static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
- size_t len, size_t *retlen, u_char *buf)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- return part->master->_read_fact_prot_reg(part->master, from, len,
- retlen, buf);
- }
-@@ -177,7 +177,7 @@ static int part_read_fact_prot_reg(struc
- static int part_get_fact_prot_info(struct mtd_info *mtd, size_t len,
- size_t *retlen, struct otp_info *buf)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- return part->master->_get_fact_prot_info(part->master, len, retlen,
- buf);
- }
-@@ -185,7 +185,7 @@ static int part_get_fact_prot_info(struc
- static int part_write(struct mtd_info *mtd, loff_t to, size_t len,
- size_t *retlen, const u_char *buf)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- return part->master->_write(part->master, to + part->offset, len,
- retlen, buf);
- }
-@@ -193,7 +193,7 @@ static int part_write(struct mtd_info *m
- static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
- size_t *retlen, const u_char *buf)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- return part->master->_panic_write(part->master, to + part->offset, len,
- retlen, buf);
- }
-@@ -201,7 +201,7 @@ static int part_panic_write(struct mtd_i
- static int part_write_oob(struct mtd_info *mtd, loff_t to,
- struct mtd_oob_ops *ops)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
-
- if (to >= mtd->size)
- return -EINVAL;
-@@ -213,7 +213,7 @@ static int part_write_oob(struct mtd_inf
- static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
- size_t len, size_t *retlen, u_char *buf)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- return part->master->_write_user_prot_reg(part->master, from, len,
- retlen, buf);
- }
-@@ -221,21 +221,21 @@ static int part_write_user_prot_reg(stru
- static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
- size_t len)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- return part->master->_lock_user_prot_reg(part->master, from, len);
- }
-
- static int part_writev(struct mtd_info *mtd, const struct kvec *vecs,
- unsigned long count, loff_t to, size_t *retlen)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- return part->master->_writev(part->master, vecs, count,
- to + part->offset, retlen);
- }
-
- static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- int ret;
-
-
-@@ -299,7 +299,7 @@ static int part_erase(struct mtd_info *m
- void mtd_erase_callback(struct erase_info *instr)
- {
- if (instr->mtd->_erase == part_erase) {
-- struct mtd_part *part = PART(instr->mtd);
-+ struct mtd_part *part = mtd_to_part(instr->mtd);
- size_t wrlen = 0;
-
- if (instr->mtd->flags & MTD_ERASE_PARTIAL) {
-@@ -330,13 +330,13 @@ EXPORT_SYMBOL_GPL(mtd_erase_callback);
-
- static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- return part->master->_lock(part->master, ofs + part->offset, len);
- }
-
- static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
-
- ofs += part->offset;
- if (mtd->flags & MTD_ERASE_PARTIAL) {
-@@ -349,45 +349,45 @@ static int part_unlock(struct mtd_info *
-
- static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- return part->master->_is_locked(part->master, ofs + part->offset, len);
- }
-
- static void part_sync(struct mtd_info *mtd)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- part->master->_sync(part->master);
- }
-
- static int part_suspend(struct mtd_info *mtd)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- return part->master->_suspend(part->master);
- }
-
- static void part_resume(struct mtd_info *mtd)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- part->master->_resume(part->master);
- }
-
- static int part_block_isreserved(struct mtd_info *mtd, loff_t ofs)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- ofs += part->offset;
- return part->master->_block_isreserved(part->master, ofs);
- }
-
- static int part_block_isbad(struct mtd_info *mtd, loff_t ofs)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- ofs += part->offset;
- return part->master->_block_isbad(part->master, ofs);
- }
-
- static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
- {
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- int res;
-
- ofs += part->offset;
-@@ -397,6 +397,27 @@ static int part_block_markbad(struct mtd
- return res;
- }
-
-+static int part_ooblayout_ecc(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oobregion)
-+{
-+ struct mtd_part *part = mtd_to_part(mtd);
-+
-+ return mtd_ooblayout_ecc(part->master, section, oobregion);
-+}
-+
-+static int part_ooblayout_free(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oobregion)
-+{
-+ struct mtd_part *part = mtd_to_part(mtd);
-+
-+ return mtd_ooblayout_free(part->master, section, oobregion);
-+}
-+
-+static const struct mtd_ooblayout_ops part_ooblayout_ops = {
-+ .ecc = part_ooblayout_ecc,
-+ .free = part_ooblayout_free,
-+};
-+
- static inline void free_partition(struct mtd_part *p)
- {
- kfree(p->mtd.name);
-@@ -614,7 +635,7 @@ static struct mtd_part *allocate_partiti
- slave->mtd.erasesize = slave->mtd.size;
- }
-
-- slave->mtd.ecclayout = master->ecclayout;
-+ mtd_set_ooblayout(&slave->mtd, &part_ooblayout_ops);
- slave->mtd.ecc_step_size = master->ecc_step_size;
- slave->mtd.ecc_strength = master->ecc_strength;
- slave->mtd.bitflip_threshold = master->bitflip_threshold;
-@@ -639,7 +660,7 @@ static ssize_t mtd_partition_offset_show
- struct device_attribute *attr, char *buf)
- {
- struct mtd_info *mtd = dev_get_drvdata(dev);
-- struct mtd_part *part = PART(mtd);
-+ struct mtd_part *part = mtd_to_part(mtd);
- return snprintf(buf, PAGE_SIZE, "%lld\n", part->offset);
- }
-
-@@ -677,11 +698,10 @@ int mtd_add_partition(struct mtd_info *m
- if (length <= 0)
- return -EINVAL;
-
-+ memset(&part, 0, sizeof(part));
- part.name = name;
- part.size = length;
- part.offset = offset;
-- part.mask_flags = 0;
-- part.ecclayout = NULL;
-
- new = allocate_partition(master, &part, -1, offset);
- if (IS_ERR(new))
-@@ -845,7 +865,7 @@ int add_mtd_partitions(struct mtd_info *
- static DEFINE_SPINLOCK(part_parser_lock);
- static LIST_HEAD(part_parsers);
-
--static struct mtd_part_parser *get_partition_parser(const char *name)
-+static struct mtd_part_parser *mtd_part_parser_get(const char *name)
- {
- struct mtd_part_parser *p, *ret = NULL;
-
-@@ -862,7 +882,20 @@ static struct mtd_part_parser *get_parti
- return ret;
- }
-
--#define put_partition_parser(p) do { module_put((p)->owner); } while (0)
-+static inline void mtd_part_parser_put(const struct mtd_part_parser *p)
-+{
-+ module_put(p->owner);
-+}
-+
-+/*
-+ * Many partition parsers just expected the core to kfree() all their data in
-+ * one chunk. Do that by default.
-+ */
-+static void mtd_part_parser_cleanup_default(const struct mtd_partition *pparts,
-+ int nr_parts)
-+{
-+ kfree(pparts);
-+}
-
- static struct mtd_part_parser *
- get_partition_parser_by_type(enum mtd_parser_type type,
-@@ -874,7 +907,7 @@ get_partition_parser_by_type(enum mtd_pa
-
- p = list_prepare_entry(start, &part_parsers, list);
- if (start)
-- put_partition_parser(start);
-+ mtd_part_parser_put(start);
-
- list_for_each_entry_continue(p, &part_parsers, list) {
- if (p->type == type && try_module_get(p->owner)) {
-@@ -888,13 +921,19 @@ get_partition_parser_by_type(enum mtd_pa
- return ret;
- }
-
--void register_mtd_parser(struct mtd_part_parser *p)
--{
-+int __register_mtd_parser(struct mtd_part_parser *p, struct module *owner)
-+ {
-+ p->owner = owner;
-+
-+ if (!p->cleanup)
-+ p->cleanup = &mtd_part_parser_cleanup_default;
-+
- spin_lock(&part_parser_lock);
- list_add(&p->list, &part_parsers);
- spin_unlock(&part_parser_lock);
-+ return 0;
- }
--EXPORT_SYMBOL_GPL(register_mtd_parser);
-+EXPORT_SYMBOL_GPL(__register_mtd_parser);
-
- void deregister_mtd_parser(struct mtd_part_parser *p)
- {
-@@ -954,7 +993,7 @@ static const char * const default_mtd_pa
- * parse_mtd_partitions - parse MTD partitions
- * @master: the master partition (describes whole MTD device)
- * @types: names of partition parsers to try or %NULL
-- * @pparts: array of partitions found is returned here
-+ * @pparts: info about partitions found is returned here
- * @data: MTD partition parser-specific data
- *
- * This function tries to find partition on MTD device @master. It uses MTD
-@@ -966,45 +1005,42 @@ static const char * const default_mtd_pa
- *
- * This function may return:
- * o a negative error code in case of failure
-- * o zero if no partitions were found
-- * o a positive number of found partitions, in which case on exit @pparts will
-- * point to an array containing this number of &struct mtd_info objects.
-+ * o zero otherwise, and @pparts will describe the partitions, number of
-+ * partitions, and the parser which parsed them. Caller must release
-+ * resources with mtd_part_parser_cleanup() when finished with the returned
-+ * data.
- */
- int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
-- struct mtd_partition **pparts,
-+ struct mtd_partitions *pparts,
- struct mtd_part_parser_data *data)
- {
- struct mtd_part_parser *parser;
- int ret, err = 0;
- const char *const *types_of = NULL;
-
-- if (data && data->of_node) {
-- types_of = of_get_probes(data->of_node);
-- if (types_of != NULL)
-- types = types_of;
-- }
--
- if (!types)
- types = default_mtd_part_types;
-
- for ( ; *types; types++) {
- pr_debug("%s: parsing partitions %s\n", master->name, *types);
-- parser = get_partition_parser(*types);
-+ parser = mtd_part_parser_get(*types);
- if (!parser && !request_module("%s", *types))
-- parser = get_partition_parser(*types);
-+ parser = mtd_part_parser_get(*types);
- pr_debug("%s: got parser %s\n", master->name,
- parser ? parser->name : NULL);
- if (!parser)
- continue;
-- ret = (*parser->parse_fn)(master, pparts, data);
-+ ret = (*parser->parse_fn)(master, &pparts->parts, data);
- pr_debug("%s: parser %s: %i\n",
- master->name, parser->name, ret);
-- put_partition_parser(parser);
- if (ret > 0) {
- printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
- ret, parser->name, master->name);
-- return ret;
-+ pparts->nr_parts = ret;
-+ pparts->parser = parser;
-+ return 0;
- }
-+ mtd_part_parser_put(parser);
- /*
- * Stash the first error we see; only report it if no parser
- * succeeds
-@@ -1034,7 +1070,7 @@ int parse_mtd_partitions_by_type(struct
- ret = (*parser->parse_fn)(master, pparts, data);
-
- if (ret > 0) {
-- put_partition_parser(parser);
-+ mtd_part_parser_put(parser);
- printk(KERN_NOTICE
- "%d %s partitions found on MTD device %s\n",
- ret, parser->name, master->name);
-@@ -1048,6 +1084,22 @@ int parse_mtd_partitions_by_type(struct
- }
- EXPORT_SYMBOL_GPL(parse_mtd_partitions_by_type);
-
-+void mtd_part_parser_cleanup(struct mtd_partitions *parts)
-+{
-+ const struct mtd_part_parser *parser;
-+
-+ if (!parts)
-+ return;
-+
-+ parser = parts->parser;
-+ if (parser) {
-+ if (parser->cleanup)
-+ parser->cleanup(parts->parts, parts->nr_parts);
-+
-+ mtd_part_parser_put(parser);
-+ }
-+}
-+
- int mtd_is_partition(const struct mtd_info *mtd)
- {
- struct mtd_part *part;
-@@ -1070,7 +1122,7 @@ struct mtd_info *mtdpart_get_master(cons
- if (!mtd_is_partition(mtd))
- return (struct mtd_info *)mtd;
-
-- return PART(mtd)->master;
-+ return mtd_to_part(mtd)->master;
- }
- EXPORT_SYMBOL_GPL(mtdpart_get_master);
-
-@@ -1079,7 +1131,7 @@ uint64_t mtdpart_get_offset(const struct
- if (!mtd_is_partition(mtd))
- return 0;
-
-- return PART(mtd)->offset;
-+ return mtd_to_part(mtd)->offset;
- }
- EXPORT_SYMBOL_GPL(mtdpart_get_offset);
-
-@@ -1089,6 +1141,6 @@ uint64_t mtd_get_device_size(const struc
- if (!mtd_is_partition(mtd))
- return mtd->size;
-
-- return PART(mtd)->master->size;
-+ return mtd_to_part(mtd)->master->size;
- }
- EXPORT_SYMBOL_GPL(mtd_get_device_size);
---- a/drivers/mtd/mtdswap.c
-+++ b/drivers/mtd/mtdswap.c
-@@ -346,7 +346,7 @@ static int mtdswap_read_markers(struct m
- if (mtd_can_have_bb(d->mtd) && mtd_block_isbad(d->mtd, offset))
- return MTDSWAP_SCANNED_BAD;
-
-- ops.ooblen = 2 * d->mtd->ecclayout->oobavail;
-+ ops.ooblen = 2 * d->mtd->oobavail;
- ops.oobbuf = d->oob_buf;
- ops.ooboffs = 0;
- ops.datbuf = NULL;
-@@ -359,7 +359,7 @@ static int mtdswap_read_markers(struct m
-
- data = (struct mtdswap_oobdata *)d->oob_buf;
- data2 = (struct mtdswap_oobdata *)
-- (d->oob_buf + d->mtd->ecclayout->oobavail);
-+ (d->oob_buf + d->mtd->oobavail);
-
- if (le16_to_cpu(data->magic) == MTDSWAP_MAGIC_CLEAN) {
- eb->erase_count = le32_to_cpu(data->count);
-@@ -933,7 +933,7 @@ static unsigned int mtdswap_eblk_passes(
-
- ops.mode = MTD_OPS_AUTO_OOB;
- ops.len = mtd->writesize;
-- ops.ooblen = mtd->ecclayout->oobavail;
-+ ops.ooblen = mtd->oobavail;
- ops.ooboffs = 0;
- ops.datbuf = d->page_buf;
- ops.oobbuf = d->oob_buf;
-@@ -945,7 +945,7 @@ static unsigned int mtdswap_eblk_passes(
- for (i = 0; i < mtd_pages; i++) {
- patt = mtdswap_test_patt(test + i);
- memset(d->page_buf, patt, mtd->writesize);
-- memset(d->oob_buf, patt, mtd->ecclayout->oobavail);
-+ memset(d->oob_buf, patt, mtd->oobavail);
- ret = mtd_write_oob(mtd, pos, &ops);
- if (ret)
- goto error;
-@@ -964,7 +964,7 @@ static unsigned int mtdswap_eblk_passes(
- if (p1[j] != patt)
- goto error;
-
-- for (j = 0; j < mtd->ecclayout->oobavail; j++)
-+ for (j = 0; j < mtd->oobavail; j++)
- if (p2[j] != (unsigned char)patt)
- goto error;
-
-@@ -1387,7 +1387,7 @@ static int mtdswap_init(struct mtdswap_d
- if (!d->page_buf)
- goto page_buf_fail;
-
-- d->oob_buf = kmalloc(2 * mtd->ecclayout->oobavail, GFP_KERNEL);
-+ d->oob_buf = kmalloc(2 * mtd->oobavail, GFP_KERNEL);
- if (!d->oob_buf)
- goto oob_buf_fail;
-
-@@ -1417,7 +1417,6 @@ static void mtdswap_add_mtd(struct mtd_b
- unsigned long part;
- unsigned int eblocks, eavailable, bad_blocks, spare_cnt;
- uint64_t swap_size, use_size, size_limit;
-- struct nand_ecclayout *oinfo;
- int ret;
-
- parts = &partitions[0];
-@@ -1447,17 +1446,10 @@ static void mtdswap_add_mtd(struct mtd_b
- return;
- }
-
-- oinfo = mtd->ecclayout;
-- if (!oinfo) {
-- printk(KERN_ERR "%s: mtd%d does not have OOB\n",
-- MTDSWAP_PREFIX, mtd->index);
-- return;
-- }
--
-- if (!mtd->oobsize || oinfo->oobavail < MTDSWAP_OOBSIZE) {
-+ if (!mtd->oobsize || mtd->oobavail < MTDSWAP_OOBSIZE) {
- printk(KERN_ERR "%s: Not enough free bytes in OOB, "
- "%d available, %zu needed.\n",
-- MTDSWAP_PREFIX, oinfo->oobavail, MTDSWAP_OOBSIZE);
-+ MTDSWAP_PREFIX, mtd->oobavail, MTDSWAP_OOBSIZE);
- return;
- }
-
---- a/drivers/mtd/nand/Kconfig
-+++ b/drivers/mtd/nand/Kconfig
-@@ -55,7 +55,7 @@ config MTD_NAND_DENALI_PCI
- config MTD_NAND_DENALI_DT
- tristate "Support Denali NAND controller as a DT device"
- select MTD_NAND_DENALI
-- depends on HAS_DMA && HAVE_CLK
-+ depends on HAS_DMA && HAVE_CLK && OF
- help
- Enable the driver for NAND flash on platforms using a Denali NAND
- controller as a DT device.
-@@ -74,6 +74,7 @@ config MTD_NAND_DENALI_SCRATCH_REG_ADDR
- config MTD_NAND_GPIO
- tristate "GPIO assisted NAND Flash driver"
- depends on GPIOLIB || COMPILE_TEST
-+ depends on HAS_IOMEM
- help
- This enables a NAND flash driver where control signals are
- connected to GPIO pins, and commands and data are communicated
-@@ -310,6 +311,7 @@ config MTD_NAND_CAFE
- config MTD_NAND_CS553X
- tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)"
- depends on X86_32
-+ depends on !UML && HAS_IOMEM
- help
- The CS553x companion chips for the AMD Geode processor
- include NAND flash controllers with built-in hardware ECC
-@@ -463,6 +465,7 @@ config MTD_NAND_MPC5121_NFC
- config MTD_NAND_VF610_NFC
- tristate "Support for Freescale NFC for VF610/MPC5125"
- depends on (SOC_VF610 || COMPILE_TEST)
-+ depends on HAS_IOMEM
- help
- Enables support for NAND Flash Controller on some Freescale
- processors like the VF610, MPC5125, MCF54418 or Kinetis K70.
-@@ -480,7 +483,7 @@ config MTD_NAND_MXC
-
- config MTD_NAND_SH_FLCTL
- tristate "Support for NAND on Renesas SuperH FLCTL"
-- depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST
-+ depends on SUPERH || COMPILE_TEST
- depends on HAS_IOMEM
- depends on HAS_DMA
- help
-@@ -519,6 +522,13 @@ config MTD_NAND_JZ4740
- help
- Enables support for NAND Flash on JZ4740 SoC based boards.
-
-+config MTD_NAND_JZ4780
-+ tristate "Support for NAND on JZ4780 SoC"
-+ depends on MACH_JZ4780 && JZ4780_NEMC
-+ help
-+ Enables support for NAND Flash connected to the NEMC on JZ4780 SoC
-+ based boards, using the BCH controller for hardware error correction.
-+
- config MTD_NAND_FSMC
- tristate "Support for NAND on ST Micros FSMC"
- depends on PLAT_SPEAR || ARCH_NOMADIK || ARCH_U8500 || MACH_U300
-@@ -546,4 +556,11 @@ config MTD_NAND_HISI504
- help
- Enables support for NAND controller on Hisilicon SoC Hip04.
-
-+config MTD_NAND_QCOM
-+ tristate "Support for NAND on QCOM SoCs"
-+ depends on ARCH_QCOM
-+ help
-+ Enables support for NAND flash chips on SoCs containing the EBI2 NAND
-+ controller. This controller is found on IPQ806x SoC.
-+
- endif # MTD_NAND
---- a/drivers/mtd/nand/Makefile
-+++ b/drivers/mtd/nand/Makefile
-@@ -49,11 +49,13 @@ obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mp
- obj-$(CONFIG_MTD_NAND_VF610_NFC) += vf610_nfc.o
- obj-$(CONFIG_MTD_NAND_RICOH) += r852.o
- obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o
-+obj-$(CONFIG_MTD_NAND_JZ4780) += jz4780_nand.o jz4780_bch.o
- obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/
- obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o
- obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/
- obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_nand.o
- obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o
- obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/
-+obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o
-
- nand-objs := nand_base.o nand_bbt.o nand_timings.o
---- a/drivers/mtd/nand/nand_base.c
-+++ b/drivers/mtd/nand/nand_base.c
-@@ -48,50 +48,6 @@
- #include <linux/mtd/partitions.h>
- #include <linux/of_mtd.h>
-
--/* Define default oob placement schemes for large and small page devices */
--static struct nand_ecclayout nand_oob_8 = {
-- .eccbytes = 3,
-- .eccpos = {0, 1, 2},
-- .oobfree = {
-- {.offset = 3,
-- .length = 2},
-- {.offset = 6,
-- .length = 2} }
--};
--
--static struct nand_ecclayout nand_oob_16 = {
-- .eccbytes = 6,
-- .eccpos = {0, 1, 2, 3, 6, 7},
-- .oobfree = {
-- {.offset = 8,
-- . length = 8} }
--};
--
--static struct nand_ecclayout nand_oob_64 = {
-- .eccbytes = 24,
-- .eccpos = {
-- 40, 41, 42, 43, 44, 45, 46, 47,
-- 48, 49, 50, 51, 52, 53, 54, 55,
-- 56, 57, 58, 59, 60, 61, 62, 63},
-- .oobfree = {
-- {.offset = 2,
-- .length = 38} }
--};
--
--static struct nand_ecclayout nand_oob_128 = {
-- .eccbytes = 48,
-- .eccpos = {
-- 80, 81, 82, 83, 84, 85, 86, 87,
-- 88, 89, 90, 91, 92, 93, 94, 95,
-- 96, 97, 98, 99, 100, 101, 102, 103,
-- 104, 105, 106, 107, 108, 109, 110, 111,
-- 112, 113, 114, 115, 116, 117, 118, 119,
-- 120, 121, 122, 123, 124, 125, 126, 127},
-- .oobfree = {
-- {.offset = 2,
-- .length = 78} }
--};
--
- static int nand_get_device(struct mtd_info *mtd, int new_state);
-
- static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
-@@ -103,10 +59,96 @@ static int nand_do_write_oob(struct mtd_
- */
- DEFINE_LED_TRIGGER(nand_led_trigger);
-
-+/* Define default oob placement schemes for large and small page devices */
-+static int nand_ooblayout_ecc_sp(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oobregion)
-+{
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct nand_ecc_ctrl *ecc = &chip->ecc;
-+
-+ if (section > 1)
-+ return -ERANGE;
-+
-+ if (!section) {
-+ oobregion->offset = 0;
-+ oobregion->length = 4;
-+ } else {
-+ oobregion->offset = 6;
-+ oobregion->length = ecc->total - 4;
-+ }
-+
-+ return 0;
-+}
-+
-+static int nand_ooblayout_free_sp(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oobregion)
-+{
-+ if (section > 1)
-+ return -ERANGE;
-+
-+ if (mtd->oobsize == 16) {
-+ if (section)
-+ return -ERANGE;
-+
-+ oobregion->length = 8;
-+ oobregion->offset = 8;
-+ } else {
-+ oobregion->length = 2;
-+ if (!section)
-+ oobregion->offset = 3;
-+ else
-+ oobregion->offset = 6;
-+ }
-+
-+ return 0;
-+}
-+
-+const struct mtd_ooblayout_ops nand_ooblayout_sp_ops = {
-+ .ecc = nand_ooblayout_ecc_sp,
-+ .free = nand_ooblayout_free_sp,
-+};
-+EXPORT_SYMBOL_GPL(nand_ooblayout_sp_ops);
-+
-+static int nand_ooblayout_ecc_lp(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oobregion)
-+{
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct nand_ecc_ctrl *ecc = &chip->ecc;
-+
-+ if (section)
-+ return -ERANGE;
-+
-+ oobregion->length = ecc->total;
-+ oobregion->offset = mtd->oobsize - oobregion->length;
-+
-+ return 0;
-+}
-+
-+static int nand_ooblayout_free_lp(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oobregion)
-+{
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct nand_ecc_ctrl *ecc = &chip->ecc;
-+
-+ if (section)
-+ return -ERANGE;
-+
-+ oobregion->length = mtd->oobsize - ecc->total - 2;
-+ oobregion->offset = 2;
-+
-+ return 0;
-+}
-+
-+const struct mtd_ooblayout_ops nand_ooblayout_lp_ops = {
-+ .ecc = nand_ooblayout_ecc_lp,
-+ .free = nand_ooblayout_free_lp,
-+};
-+EXPORT_SYMBOL_GPL(nand_ooblayout_lp_ops);
-+
- static int check_offs_len(struct mtd_info *mtd,
- loff_t ofs, uint64_t len)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- int ret = 0;
-
- /* Start address must align on block boundary */
-@@ -132,7 +174,7 @@ static int check_offs_len(struct mtd_inf
- */
- static void nand_release_device(struct mtd_info *mtd)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-
- /* Release the controller and the chip */
- spin_lock(&chip->controller->lock);
-@@ -150,7 +192,7 @@ static void nand_release_device(struct m
- */
- static uint8_t nand_read_byte(struct mtd_info *mtd)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- return readb(chip->IO_ADDR_R);
- }
-
-@@ -163,7 +205,7 @@ static uint8_t nand_read_byte(struct mtd
- */
- static uint8_t nand_read_byte16(struct mtd_info *mtd)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R));
- }
-
-@@ -175,7 +217,7 @@ static uint8_t nand_read_byte16(struct m
- */
- static u16 nand_read_word(struct mtd_info *mtd)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- return readw(chip->IO_ADDR_R);
- }
-
-@@ -188,7 +230,7 @@ static u16 nand_read_word(struct mtd_inf
- */
- static void nand_select_chip(struct mtd_info *mtd, int chipnr)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-
- switch (chipnr) {
- case -1:
-@@ -211,7 +253,7 @@ static void nand_select_chip(struct mtd_
- */
- static void nand_write_byte(struct mtd_info *mtd, uint8_t byte)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-
- chip->write_buf(mtd, &byte, 1);
- }
-@@ -225,7 +267,7 @@ static void nand_write_byte(struct mtd_i
- */
- static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- uint16_t word = byte;
-
- /*
-@@ -257,7 +299,7 @@ static void nand_write_byte16(struct mtd
- */
- static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-
- iowrite8_rep(chip->IO_ADDR_W, buf, len);
- }
-@@ -272,7 +314,7 @@ static void nand_write_buf(struct mtd_in
- */
- static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-
- ioread8_rep(chip->IO_ADDR_R, buf, len);
- }
-@@ -287,7 +329,7 @@ static void nand_read_buf(struct mtd_inf
- */
- static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- u16 *p = (u16 *) buf;
-
- iowrite16_rep(chip->IO_ADDR_W, p, len >> 1);
-@@ -303,7 +345,7 @@ static void nand_write_buf16(struct mtd_
- */
- static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- u16 *p = (u16 *) buf;
-
- ioread16_rep(chip->IO_ADDR_R, p, len >> 1);
-@@ -313,14 +355,13 @@ static void nand_read_buf16(struct mtd_i
- * nand_block_bad - [DEFAULT] Read bad block marker from the chip
- * @mtd: MTD device structure
- * @ofs: offset from device start
-- * @getchip: 0, if the chip is already selected
- *
- * Check, if the block is bad.
- */
--static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
-+static int nand_block_bad(struct mtd_info *mtd, loff_t ofs)
- {
-- int page, chipnr, res = 0, i = 0;
-- struct nand_chip *chip = mtd->priv;
-+ int page, res = 0, i = 0;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- u16 bad;
-
- if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
-@@ -328,15 +369,6 @@ static int nand_block_bad(struct mtd_inf
-
- page = (int)(ofs >> chip->page_shift) & chip->pagemask;
-
-- if (getchip) {
-- chipnr = (int)(ofs >> chip->chip_shift);
--
-- nand_get_device(mtd, FL_READING);
--
-- /* Select the NAND device */
-- chip->select_chip(mtd, chipnr);
-- }
--
- do {
- if (chip->options & NAND_BUSWIDTH_16) {
- chip->cmdfunc(mtd, NAND_CMD_READOOB,
-@@ -361,11 +393,6 @@ static int nand_block_bad(struct mtd_inf
- i++;
- } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE));
-
-- if (getchip) {
-- chip->select_chip(mtd, -1);
-- nand_release_device(mtd);
-- }
--
- return res;
- }
-
-@@ -380,7 +407,7 @@ static int nand_block_bad(struct mtd_inf
- */
- static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- struct mtd_oob_ops ops;
- uint8_t buf[2] = { 0, 0 };
- int ret = 0, res, i = 0;
-@@ -430,7 +457,7 @@ static int nand_default_block_markbad(st
- */
- static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- int res, ret = 0;
-
- if (!(chip->bbt_options & NAND_BBT_NO_OOB_BBM)) {
-@@ -471,7 +498,7 @@ static int nand_block_markbad_lowlevel(s
- */
- static int nand_check_wp(struct mtd_info *mtd)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-
- /* Broken xD cards report WP despite being writable */
- if (chip->options & NAND_BROKEN_XD)
-@@ -491,7 +518,7 @@ static int nand_check_wp(struct mtd_info
- */
- static int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-
- if (!chip->bbt)
- return 0;
-@@ -503,19 +530,17 @@ static int nand_block_isreserved(struct
- * nand_block_checkbad - [GENERIC] Check if a block is marked bad
- * @mtd: MTD device structure
- * @ofs: offset from device start
-- * @getchip: 0, if the chip is already selected
- * @allowbbt: 1, if its allowed to access the bbt area
- *
- * Check, if the block is bad. Either by reading the bad block table or
- * calling of the scan function.
- */
--static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
-- int allowbbt)
-+static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int allowbbt)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-
- if (!chip->bbt)
-- return chip->block_bad(mtd, ofs, getchip);
-+ return chip->block_bad(mtd, ofs);
-
- /* Return info from the table */
- return nand_isbad_bbt(mtd, ofs, allowbbt);
-@@ -531,7 +556,7 @@ static int nand_block_checkbad(struct mt
- */
- static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- int i;
-
- /* Wait for the device to get ready */
-@@ -551,7 +576,7 @@ static void panic_nand_wait_ready(struct
- */
- void nand_wait_ready(struct mtd_info *mtd)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- unsigned long timeo = 400;
-
- if (in_interrupt() || oops_in_progress)
-@@ -566,8 +591,8 @@ void nand_wait_ready(struct mtd_info *mt
- cond_resched();
- } while (time_before(jiffies, timeo));
-
-- pr_warn_ratelimited(
-- "timeout while waiting for chip to become ready\n");
-+ if (!chip->dev_ready(mtd))
-+ pr_warn_ratelimited("timeout while waiting for chip to become ready\n");
- out:
- led_trigger_event(nand_led_trigger, LED_OFF);
- }
-@@ -582,7 +607,7 @@ EXPORT_SYMBOL_GPL(nand_wait_ready);
- */
- static void nand_wait_status_ready(struct mtd_info *mtd, unsigned long timeo)
- {
-- register struct nand_chip *chip = mtd->priv;
-+ register struct nand_chip *chip = mtd_to_nand(mtd);
-
- timeo = jiffies + msecs_to_jiffies(timeo);
- do {
-@@ -605,7 +630,7 @@ static void nand_wait_status_ready(struc
- static void nand_command(struct mtd_info *mtd, unsigned int command,
- int column, int page_addr)
- {
-- register struct nand_chip *chip = mtd->priv;
-+ register struct nand_chip *chip = mtd_to_nand(mtd);
- int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE;
-
- /* Write out the command to the device */
-@@ -708,7 +733,7 @@ static void nand_command(struct mtd_info
- static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
- int column, int page_addr)
- {
-- register struct nand_chip *chip = mtd->priv;
-+ register struct nand_chip *chip = mtd_to_nand(mtd);
-
- /* Emulate NAND_CMD_READOOB */
- if (command == NAND_CMD_READOOB) {
-@@ -832,7 +857,7 @@ static void panic_nand_get_device(struct
- static int
- nand_get_device(struct mtd_info *mtd, int new_state)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- spinlock_t *lock = &chip->controller->lock;
- wait_queue_head_t *wq = &chip->controller->wq;
- DECLARE_WAITQUEUE(wait, current);
-@@ -952,7 +977,7 @@ static int __nand_unlock(struct mtd_info
- {
- int ret = 0;
- int status, page;
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-
- /* Submit address of first page to unlock */
- page = ofs >> chip->page_shift;
-@@ -987,7 +1012,7 @@ int nand_unlock(struct mtd_info *mtd, lo
- {
- int ret = 0;
- int chipnr;
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-
- pr_debug("%s: start = 0x%012llx, len = %llu\n",
- __func__, (unsigned long long)ofs, len);
-@@ -1050,7 +1075,7 @@ int nand_lock(struct mtd_info *mtd, loff
- {
- int ret = 0;
- int chipnr, status, page;
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-
- pr_debug("%s: start = 0x%012llx, len = %llu\n",
- __func__, (unsigned long long)ofs, len);
-@@ -1309,13 +1334,12 @@ static int nand_read_page_raw_syndrome(s
- static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
- uint8_t *buf, int oob_required, int page)
- {
-- int i, eccsize = chip->ecc.size;
-+ int i, eccsize = chip->ecc.size, ret;
- int eccbytes = chip->ecc.bytes;
- int eccsteps = chip->ecc.steps;
- uint8_t *p = buf;
- uint8_t *ecc_calc = chip->buffers->ecccalc;
- uint8_t *ecc_code = chip->buffers->ecccode;
-- uint32_t *eccpos = chip->ecc.layout->eccpos;
- unsigned int max_bitflips = 0;
-
- chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
-@@ -1323,8 +1347,10 @@ static int nand_read_page_swecc(struct m
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
- chip->ecc.calculate(mtd, p, &ecc_calc[i]);
-
-- for (i = 0; i < chip->ecc.total; i++)
-- ecc_code[i] = chip->oob_poi[eccpos[i]];
-+ ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
-+ chip->ecc.total);
-+ if (ret)
-+ return ret;
-
- eccsteps = chip->ecc.steps;
- p = buf;
-@@ -1356,14 +1382,14 @@ static int nand_read_subpage(struct mtd_
- uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi,
- int page)
- {
-- int start_step, end_step, num_steps;
-- uint32_t *eccpos = chip->ecc.layout->eccpos;
-+ int start_step, end_step, num_steps, ret;
- uint8_t *p;
- int data_col_addr, i, gaps = 0;
- int datafrag_len, eccfrag_len, aligned_len, aligned_pos;
- int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1;
-- int index;
-+ int index, section = 0;
- unsigned int max_bitflips = 0;
-+ struct mtd_oob_region oobregion = { };
-
- /* Column address within the page aligned to ECC size (256bytes) */
- start_step = data_offs / chip->ecc.size;
-@@ -1391,12 +1417,13 @@ static int nand_read_subpage(struct mtd_
- * The performance is faster if we position offsets according to
- * ecc.pos. Let's make sure that there are no gaps in ECC positions.
- */
-- for (i = 0; i < eccfrag_len - 1; i++) {
-- if (eccpos[i + index] + 1 != eccpos[i + index + 1]) {
-- gaps = 1;
-- break;
-- }
-- }
-+ ret = mtd_ooblayout_find_eccregion(mtd, index, §ion, &oobregion);
-+ if (ret)
-+ return ret;
-+
-+ if (oobregion.length < eccfrag_len)
-+ gaps = 1;
-+
- if (gaps) {
- chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1);
- chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
-@@ -1405,20 +1432,23 @@ static int nand_read_subpage(struct mtd_
- * Send the command to read the particular ECC bytes take care
- * about buswidth alignment in read_buf.
- */
-- aligned_pos = eccpos[index] & ~(busw - 1);
-+ aligned_pos = oobregion.offset & ~(busw - 1);
- aligned_len = eccfrag_len;
-- if (eccpos[index] & (busw - 1))
-+ if (oobregion.offset & (busw - 1))
- aligned_len++;
-- if (eccpos[index + (num_steps * chip->ecc.bytes)] & (busw - 1))
-+ if ((oobregion.offset + (num_steps * chip->ecc.bytes)) &
-+ (busw - 1))
- aligned_len++;
-
- chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
-- mtd->writesize + aligned_pos, -1);
-+ mtd->writesize + aligned_pos, -1);
- chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len);
- }
-
-- for (i = 0; i < eccfrag_len; i++)
-- chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + index]];
-+ ret = mtd_ooblayout_get_eccbytes(mtd, chip->buffers->ecccode,
-+ chip->oob_poi, index, eccfrag_len);
-+ if (ret)
-+ return ret;
-
- p = bufpoi + data_col_addr;
- for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) {
-@@ -1426,6 +1456,16 @@ static int nand_read_subpage(struct mtd_
-
- stat = chip->ecc.correct(mtd, p,
- &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
-+ if (stat == -EBADMSG &&
-+ (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
-+ /* check for empty pages with bitflips */
-+ stat = nand_check_erased_ecc_chunk(p, chip->ecc.size,
-+ &chip->buffers->ecccode[i],
-+ chip->ecc.bytes,
-+ NULL, 0,
-+ chip->ecc.strength);
-+ }
-+
- if (stat < 0) {
- mtd->ecc_stats.failed++;
- } else {
-@@ -1449,13 +1489,12 @@ static int nand_read_subpage(struct mtd_
- static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
- uint8_t *buf, int oob_required, int page)
- {
-- int i, eccsize = chip->ecc.size;
-+ int i, eccsize = chip->ecc.size, ret;
- int eccbytes = chip->ecc.bytes;
- int eccsteps = chip->ecc.steps;
- uint8_t *p = buf;
- uint8_t *ecc_calc = chip->buffers->ecccalc;
- uint8_t *ecc_code = chip->buffers->ecccode;
-- uint32_t *eccpos = chip->ecc.layout->eccpos;
- unsigned int max_bitflips = 0;
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
-@@ -1465,8 +1504,10 @@ static int nand_read_page_hwecc(struct m
- }
- chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
-
-- for (i = 0; i < chip->ecc.total; i++)
-- ecc_code[i] = chip->oob_poi[eccpos[i]];
-+ ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
-+ chip->ecc.total);
-+ if (ret)
-+ return ret;
-
- eccsteps = chip->ecc.steps;
- p = buf;
-@@ -1475,6 +1516,15 @@ static int nand_read_page_hwecc(struct m
- int stat;
-
- stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
-+ if (stat == -EBADMSG &&
-+ (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
-+ /* check for empty pages with bitflips */
-+ stat = nand_check_erased_ecc_chunk(p, eccsize,
-+ &ecc_code[i], eccbytes,
-+ NULL, 0,
-+ chip->ecc.strength);
-+ }
-+
- if (stat < 0) {
- mtd->ecc_stats.failed++;
- } else {
-@@ -1502,12 +1552,11 @@ static int nand_read_page_hwecc(struct m
- static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
- struct nand_chip *chip, uint8_t *buf, int oob_required, int page)
- {
-- int i, eccsize = chip->ecc.size;
-+ int i, eccsize = chip->ecc.size, ret;
- int eccbytes = chip->ecc.bytes;
- int eccsteps = chip->ecc.steps;
- uint8_t *p = buf;
- uint8_t *ecc_code = chip->buffers->ecccode;
-- uint32_t *eccpos = chip->ecc.layout->eccpos;
- uint8_t *ecc_calc = chip->buffers->ecccalc;
- unsigned int max_bitflips = 0;
-
-@@ -1516,8 +1565,10 @@ static int nand_read_page_hwecc_oob_firs
- chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
- chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
-
-- for (i = 0; i < chip->ecc.total; i++)
-- ecc_code[i] = chip->oob_poi[eccpos[i]];
-+ ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
-+ chip->ecc.total);
-+ if (ret)
-+ return ret;
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
- int stat;
-@@ -1527,6 +1578,15 @@ static int nand_read_page_hwecc_oob_firs
- chip->ecc.calculate(mtd, p, &ecc_calc[i]);
-
- stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL);
-+ if (stat == -EBADMSG &&
-+ (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
-+ /* check for empty pages with bitflips */
-+ stat = nand_check_erased_ecc_chunk(p, eccsize,
-+ &ecc_code[i], eccbytes,
-+ NULL, 0,
-+ chip->ecc.strength);
-+ }
-+
- if (stat < 0) {
- mtd->ecc_stats.failed++;
- } else {
-@@ -1554,6 +1614,7 @@ static int nand_read_page_syndrome(struc
- int i, eccsize = chip->ecc.size;
- int eccbytes = chip->ecc.bytes;
- int eccsteps = chip->ecc.steps;
-+ int eccpadbytes = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
- uint8_t *p = buf;
- uint8_t *oob = chip->oob_poi;
- unsigned int max_bitflips = 0;
-@@ -1573,19 +1634,29 @@ static int nand_read_page_syndrome(struc
- chip->read_buf(mtd, oob, eccbytes);
- stat = chip->ecc.correct(mtd, p, oob, NULL);
-
-- if (stat < 0) {
-- mtd->ecc_stats.failed++;
-- } else {
-- mtd->ecc_stats.corrected += stat;
-- max_bitflips = max_t(unsigned int, max_bitflips, stat);
-- }
--
- oob += eccbytes;
-
- if (chip->ecc.postpad) {
- chip->read_buf(mtd, oob, chip->ecc.postpad);
- oob += chip->ecc.postpad;
- }
-+
-+ if (stat == -EBADMSG &&
-+ (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
-+ /* check for empty pages with bitflips */
-+ stat = nand_check_erased_ecc_chunk(p, chip->ecc.size,
-+ oob - eccpadbytes,
-+ eccpadbytes,
-+ NULL, 0,
-+ chip->ecc.strength);
-+ }
-+
-+ if (stat < 0) {
-+ mtd->ecc_stats.failed++;
-+ } else {
-+ mtd->ecc_stats.corrected += stat;
-+ max_bitflips = max_t(unsigned int, max_bitflips, stat);
-+ }
- }
-
- /* Calculate remaining oob bytes */
-@@ -1598,14 +1669,17 @@ static int nand_read_page_syndrome(struc
-
- /**
- * nand_transfer_oob - [INTERN] Transfer oob to client buffer
-- * @chip: nand chip structure
-+ * @mtd: mtd info structure
- * @oob: oob destination address
- * @ops: oob ops structure
- * @len: size of oob to transfer
- */
--static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
-+static uint8_t *nand_transfer_oob(struct mtd_info *mtd, uint8_t *oob,
- struct mtd_oob_ops *ops, size_t len)
- {
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ int ret;
-+
- switch (ops->mode) {
-
- case MTD_OPS_PLACE_OOB:
-@@ -1613,31 +1687,12 @@ static uint8_t *nand_transfer_oob(struct
- memcpy(oob, chip->oob_poi + ops->ooboffs, len);
- return oob + len;
-
-- case MTD_OPS_AUTO_OOB: {
-- struct nand_oobfree *free = chip->ecc.layout->oobfree;
-- uint32_t boffs = 0, roffs = ops->ooboffs;
-- size_t bytes = 0;
--
-- for (; free->length && len; free++, len -= bytes) {
-- /* Read request not from offset 0? */
-- if (unlikely(roffs)) {
-- if (roffs >= free->length) {
-- roffs -= free->length;
-- continue;
-- }
-- boffs = free->offset + roffs;
-- bytes = min_t(size_t, len,
-- (free->length - roffs));
-- roffs = 0;
-- } else {
-- bytes = min_t(size_t, len, free->length);
-- boffs = free->offset;
-- }
-- memcpy(oob, chip->oob_poi + boffs, bytes);
-- oob += bytes;
-- }
-- return oob;
-- }
-+ case MTD_OPS_AUTO_OOB:
-+ ret = mtd_ooblayout_get_databytes(mtd, oob, chip->oob_poi,
-+ ops->ooboffs, len);
-+ BUG_ON(ret);
-+ return oob + len;
-+
- default:
- BUG();
- }
-@@ -1655,7 +1710,7 @@ static uint8_t *nand_transfer_oob(struct
- */
- static int nand_setup_read_retry(struct mtd_info *mtd, int retry_mode)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-
- pr_debug("setting READ RETRY mode %d\n", retry_mode);
-
-@@ -1680,12 +1735,11 @@ static int nand_do_read_ops(struct mtd_i
- struct mtd_oob_ops *ops)
- {
- int chipnr, page, realpage, col, bytes, aligned, oob_required;
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- int ret = 0;
- uint32_t readlen = ops->len;
- uint32_t oobreadlen = ops->ooblen;
-- uint32_t max_oobsize = ops->mode == MTD_OPS_AUTO_OOB ?
-- mtd->oobavail : mtd->oobsize;
-+ uint32_t max_oobsize = mtd_oobavail(mtd, ops);
-
- uint8_t *bufpoi, *oob, *buf;
- int use_bufpoi;
-@@ -1772,7 +1826,7 @@ read_retry:
- int toread = min(oobreadlen, max_oobsize);
-
- if (toread) {
-- oob = nand_transfer_oob(chip,
-+ oob = nand_transfer_oob(mtd,
- oob, ops, toread);
- oobreadlen -= toread;
- }
-@@ -2024,7 +2078,7 @@ static int nand_do_read_oob(struct mtd_i
- struct mtd_oob_ops *ops)
- {
- int page, realpage, chipnr;
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- struct mtd_ecc_stats stats;
- int readlen = ops->ooblen;
- int len;
-@@ -2036,10 +2090,7 @@ static int nand_do_read_oob(struct mtd_i
-
- stats = mtd->ecc_stats;
-
-- if (ops->mode == MTD_OPS_AUTO_OOB)
-- len = chip->ecc.layout->oobavail;
-- else
-- len = mtd->oobsize;
-+ len = mtd_oobavail(mtd, ops);
-
- if (unlikely(ops->ooboffs >= len)) {
- pr_debug("%s: attempt to start read outside oob\n",
-@@ -2073,7 +2124,7 @@ static int nand_do_read_oob(struct mtd_i
- break;
-
- len = min(len, readlen);
-- buf = nand_transfer_oob(chip, buf, ops, len);
-+ buf = nand_transfer_oob(mtd, buf, ops, len);
-
- if (chip->options & NAND_NEED_READRDY) {
- /* Apply delay or wait for ready/busy pin */
-@@ -2232,19 +2283,20 @@ static int nand_write_page_swecc(struct
- const uint8_t *buf, int oob_required,
- int page)
- {
-- int i, eccsize = chip->ecc.size;
-+ int i, eccsize = chip->ecc.size, ret;
- int eccbytes = chip->ecc.bytes;
- int eccsteps = chip->ecc.steps;
- uint8_t *ecc_calc = chip->buffers->ecccalc;
- const uint8_t *p = buf;
-- uint32_t *eccpos = chip->ecc.layout->eccpos;
-
- /* Software ECC calculation */
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
- chip->ecc.calculate(mtd, p, &ecc_calc[i]);
-
-- for (i = 0; i < chip->ecc.total; i++)
-- chip->oob_poi[eccpos[i]] = ecc_calc[i];
-+ ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0,
-+ chip->ecc.total);
-+ if (ret)
-+ return ret;
-
- return chip->ecc.write_page_raw(mtd, chip, buf, 1, page);
- }
-@@ -2261,12 +2313,11 @@ static int nand_write_page_hwecc(struct
- const uint8_t *buf, int oob_required,
- int page)
- {
-- int i, eccsize = chip->ecc.size;
-+ int i, eccsize = chip->ecc.size, ret;
- int eccbytes = chip->ecc.bytes;
- int eccsteps = chip->ecc.steps;
- uint8_t *ecc_calc = chip->buffers->ecccalc;
- const uint8_t *p = buf;
-- uint32_t *eccpos = chip->ecc.layout->eccpos;
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
- chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
-@@ -2274,8 +2325,10 @@ static int nand_write_page_hwecc(struct
- chip->ecc.calculate(mtd, p, &ecc_calc[i]);
- }
-
-- for (i = 0; i < chip->ecc.total; i++)
-- chip->oob_poi[eccpos[i]] = ecc_calc[i];
-+ ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0,
-+ chip->ecc.total);
-+ if (ret)
-+ return ret;
-
- chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
-
-@@ -2303,11 +2356,10 @@ static int nand_write_subpage_hwecc(stru
- int ecc_size = chip->ecc.size;
- int ecc_bytes = chip->ecc.bytes;
- int ecc_steps = chip->ecc.steps;
-- uint32_t *eccpos = chip->ecc.layout->eccpos;
- uint32_t start_step = offset / ecc_size;
- uint32_t end_step = (offset + data_len - 1) / ecc_size;
- int oob_bytes = mtd->oobsize / ecc_steps;
-- int step, i;
-+ int step, ret;
-
- for (step = 0; step < ecc_steps; step++) {
- /* configure controller for WRITE access */
-@@ -2335,8 +2387,10 @@ static int nand_write_subpage_hwecc(stru
- /* copy calculated ECC for whole page to chip->buffer->oob */
- /* this include masked-value(0xFF) for unwritten subpages */
- ecc_calc = chip->buffers->ecccalc;
-- for (i = 0; i < chip->ecc.total; i++)
-- chip->oob_poi[eccpos[i]] = ecc_calc[i];
-+ ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0,
-+ chip->ecc.total);
-+ if (ret)
-+ return ret;
-
- /* write OOB buffer to NAND device */
- chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
-@@ -2472,7 +2526,8 @@ static int nand_write_page(struct mtd_in
- static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,
- struct mtd_oob_ops *ops)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ int ret;
-
- /*
- * Initialise to all 0xFF, to avoid the possibility of left over OOB
-@@ -2487,31 +2542,12 @@ static uint8_t *nand_fill_oob(struct mtd
- memcpy(chip->oob_poi + ops->ooboffs, oob, len);
- return oob + len;
-
-- case MTD_OPS_AUTO_OOB: {
-- struct nand_oobfree *free = chip->ecc.layout->oobfree;
-- uint32_t boffs = 0, woffs = ops->ooboffs;
-- size_t bytes = 0;
--
-- for (; free->length && len; free++, len -= bytes) {
-- /* Write request not from offset 0? */
-- if (unlikely(woffs)) {
-- if (woffs >= free->length) {
-- woffs -= free->length;
-- continue;
-- }
-- boffs = free->offset + woffs;
-- bytes = min_t(size_t, len,
-- (free->length - woffs));
-- woffs = 0;
-- } else {
-- bytes = min_t(size_t, len, free->length);
-- boffs = free->offset;
-- }
-- memcpy(chip->oob_poi + boffs, oob, bytes);
-- oob += bytes;
-- }
-- return oob;
-- }
-+ case MTD_OPS_AUTO_OOB:
-+ ret = mtd_ooblayout_set_databytes(mtd, oob, chip->oob_poi,
-+ ops->ooboffs, len);
-+ BUG_ON(ret);
-+ return oob + len;
-+
- default:
- BUG();
- }
-@@ -2532,12 +2568,11 @@ static int nand_do_write_ops(struct mtd_
- struct mtd_oob_ops *ops)
- {
- int chipnr, realpage, page, blockmask, column;
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- uint32_t writelen = ops->len;
-
- uint32_t oobwritelen = ops->ooblen;
-- uint32_t oobmaxlen = ops->mode == MTD_OPS_AUTO_OOB ?
-- mtd->oobavail : mtd->oobsize;
-+ uint32_t oobmaxlen = mtd_oobavail(mtd, ops);
-
- uint8_t *oob = ops->oobbuf;
- uint8_t *buf = ops->datbuf;
-@@ -2662,7 +2697,7 @@ err_out:
- static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
- size_t *retlen, const uint8_t *buf)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- struct mtd_oob_ops ops;
- int ret;
-
-@@ -2722,15 +2757,12 @@ static int nand_do_write_oob(struct mtd_
- struct mtd_oob_ops *ops)
- {
- int chipnr, page, status, len;
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-
- pr_debug("%s: to = 0x%08x, len = %i\n",
- __func__, (unsigned int)to, (int)ops->ooblen);
-
-- if (ops->mode == MTD_OPS_AUTO_OOB)
-- len = chip->ecc.layout->oobavail;
-- else
-- len = mtd->oobsize;
-+ len = mtd_oobavail(mtd, ops);
-
- /* Do not allow write past end of page */
- if ((ops->ooboffs + ops->ooblen) > len) {
-@@ -2847,7 +2879,7 @@ out:
- */
- static int single_erase(struct mtd_info *mtd, int page)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- /* Send commands to erase a block */
- chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
- chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
-@@ -2879,7 +2911,7 @@ int nand_erase_nand(struct mtd_info *mtd
- int allowbbt)
- {
- int page, status, pages_per_block, ret, chipnr;
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- loff_t len;
-
- pr_debug("%s: start = 0x%012llx, len = %llu\n",
-@@ -2918,7 +2950,7 @@ int nand_erase_nand(struct mtd_info *mtd
- while (len) {
- /* Check if we have a bad block, we do not erase bad blocks! */
- if (nand_block_checkbad(mtd, ((loff_t) page) <<
-- chip->page_shift, 0, allowbbt)) {
-+ chip->page_shift, allowbbt)) {
- pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
- __func__, page);
- instr->state = MTD_ERASE_FAILED;
-@@ -3005,7 +3037,20 @@ static void nand_sync(struct mtd_info *m
- */
- static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
- {
-- return nand_block_checkbad(mtd, offs, 1, 0);
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ int chipnr = (int)(offs >> chip->chip_shift);
-+ int ret;
-+
-+ /* Select the NAND device */
-+ nand_get_device(mtd, FL_READING);
-+ chip->select_chip(mtd, chipnr);
-+
-+ ret = nand_block_checkbad(mtd, offs, 0);
-+
-+ chip->select_chip(mtd, -1);
-+ nand_release_device(mtd);
-+
-+ return ret;
- }
-
- /**
-@@ -3094,7 +3139,7 @@ static int nand_suspend(struct mtd_info
- */
- static void nand_resume(struct mtd_info *mtd)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-
- if (chip->state == FL_PM_SUSPENDED)
- nand_release_device(mtd);
-@@ -3266,7 +3311,7 @@ ext_out:
-
- static int nand_setup_read_retry_micron(struct mtd_info *mtd, int retry_mode)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {retry_mode};
-
- return chip->onfi_set_features(mtd, chip, ONFI_FEATURE_ADDR_READ_RETRY,
-@@ -3937,10 +3982,13 @@ ident_done:
- return type;
- }
-
--static int nand_dt_init(struct mtd_info *mtd, struct nand_chip *chip,
-- struct device_node *dn)
-+static int nand_dt_init(struct nand_chip *chip)
- {
-- int ecc_mode, ecc_strength, ecc_step;
-+ struct device_node *dn = nand_get_flash_node(chip);
-+ int ecc_mode, ecc_algo, ecc_strength, ecc_step;
-+
-+ if (!dn)
-+ return 0;
-
- if (of_get_nand_bus_width(dn) == 16)
- chip->options |= NAND_BUSWIDTH_16;
-@@ -3949,6 +3997,7 @@ static int nand_dt_init(struct mtd_info
- chip->bbt_options |= NAND_BBT_USE_FLASH;
-
- ecc_mode = of_get_nand_ecc_mode(dn);
-+ ecc_algo = of_get_nand_ecc_algo(dn);
- ecc_strength = of_get_nand_ecc_strength(dn);
- ecc_step = of_get_nand_ecc_step_size(dn);
-
-@@ -3961,6 +4010,9 @@ static int nand_dt_init(struct mtd_info
- if (ecc_mode >= 0)
- chip->ecc.mode = ecc_mode;
-
-+ if (ecc_algo >= 0)
-+ chip->ecc.algo = ecc_algo;
-+
- if (ecc_strength >= 0)
- chip->ecc.strength = ecc_strength;
-
-@@ -3984,15 +4036,16 @@ int nand_scan_ident(struct mtd_info *mtd
- struct nand_flash_dev *table)
- {
- int i, nand_maf_id, nand_dev_id;
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- struct nand_flash_dev *type;
- int ret;
-
-- if (chip->flash_node) {
-- ret = nand_dt_init(mtd, chip, chip->flash_node);
-- if (ret)
-- return ret;
-- }
-+ ret = nand_dt_init(chip);
-+ if (ret)
-+ return ret;
-+
-+ if (!mtd->name && mtd->dev.parent)
-+ mtd->name = dev_name(mtd->dev.parent);
-
- if (!mtd->name && mtd->dev.parent)
- mtd->name = dev_name(mtd->dev.parent);
-@@ -4055,7 +4108,7 @@ EXPORT_SYMBOL(nand_scan_ident);
- */
- static bool nand_ecc_strength_good(struct mtd_info *mtd)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- struct nand_ecc_ctrl *ecc = &chip->ecc;
- int corr, ds_corr;
-
-@@ -4083,10 +4136,10 @@ static bool nand_ecc_strength_good(struc
- */
- int nand_scan_tail(struct mtd_info *mtd)
- {
-- int i;
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
- struct nand_ecc_ctrl *ecc = &chip->ecc;
- struct nand_buffers *nbuf;
-+ int ret;
-
- /* New bad blocks should be marked in OOB, flash-based BBT, or both */
- BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) &&
-@@ -4113,19 +4166,15 @@ int nand_scan_tail(struct mtd_info *mtd)
- /*
- * If no default placement scheme is given, select an appropriate one.
- */
-- if (!ecc->layout && (ecc->mode != NAND_ECC_SOFT_BCH)) {
-+ if (!mtd->ooblayout && (ecc->mode != NAND_ECC_SOFT_BCH)) {
- switch (mtd->oobsize) {
- case 8:
-- ecc->layout = &nand_oob_8;
-- break;
- case 16:
-- ecc->layout = &nand_oob_16;
-+ mtd_set_ooblayout(mtd, &nand_ooblayout_sp_ops);
- break;
- case 64:
-- ecc->layout = &nand_oob_64;
-- break;
- case 128:
-- ecc->layout = &nand_oob_128;
-+ mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops);
- break;
- default:
- pr_warn("No oob scheme defined for oobsize %d\n",
-@@ -4168,7 +4217,7 @@ int nand_scan_tail(struct mtd_info *mtd)
- ecc->write_oob = nand_write_oob_std;
- if (!ecc->read_subpage)
- ecc->read_subpage = nand_read_subpage;
-- if (!ecc->write_subpage)
-+ if (!ecc->write_subpage && ecc->hwctl && ecc->calculate)
- ecc->write_subpage = nand_write_subpage_hwecc;
-
- case NAND_ECC_HW_SYNDROME:
-@@ -4246,10 +4295,8 @@ int nand_scan_tail(struct mtd_info *mtd)
- }
-
- /* See nand_bch_init() for details. */
-- ecc->bytes = DIV_ROUND_UP(
-- ecc->strength * fls(8 * ecc->size), 8);
-- ecc->priv = nand_bch_init(mtd, ecc->size, ecc->bytes,
-- &ecc->layout);
-+ ecc->bytes = 0;
-+ ecc->priv = nand_bch_init(mtd);
- if (!ecc->priv) {
- pr_warn("BCH ECC initialization failed!\n");
- BUG();
-@@ -4280,20 +4327,9 @@ int nand_scan_tail(struct mtd_info *mtd)
- if (!ecc->write_oob_raw)
- ecc->write_oob_raw = ecc->write_oob;
-
-- /*
-- * The number of bytes available for a client to place data into
-- * the out of band area.
-- */
-- ecc->layout->oobavail = 0;
-- for (i = 0; ecc->layout->oobfree[i].length
-- && i < ARRAY_SIZE(ecc->layout->oobfree); i++)
-- ecc->layout->oobavail += ecc->layout->oobfree[i].length;
-- mtd->oobavail = ecc->layout->oobavail;
--
-- /* ECC sanity check: warn if it's too weak */
-- if (!nand_ecc_strength_good(mtd))
-- pr_warn("WARNING: %s: the ECC used on your system is too weak compared to the one required by the NAND chip\n",
-- mtd->name);
-+ /* propagate ecc info to mtd_info */
-+ mtd->ecc_strength = ecc->strength;
-+ mtd->ecc_step_size = ecc->size;
-
- /*
- * Set the number of read / write steps for one page depending on ECC
-@@ -4306,6 +4342,21 @@ int nand_scan_tail(struct mtd_info *mtd)
- }
- ecc->total = ecc->steps * ecc->bytes;
-
-+ /*
-+ * The number of bytes available for a client to place data into
-+ * the out of band area.
-+ */
-+ ret = mtd_ooblayout_count_freebytes(mtd);
-+ if (ret < 0)
-+ ret = 0;
-+
-+ mtd->oobavail = ret;
-+
-+ /* ECC sanity check: warn if it's too weak */
-+ if (!nand_ecc_strength_good(mtd))
-+ pr_warn("WARNING: %s: the ECC used on your system is too weak compared to the one required by the NAND chip\n",
-+ mtd->name);
-+
- /* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
- if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && nand_is_slc(chip)) {
- switch (ecc->steps) {
-@@ -4362,10 +4413,6 @@ int nand_scan_tail(struct mtd_info *mtd)
- mtd->_block_markbad = nand_block_markbad;
- mtd->writebufsize = mtd->writesize;
-
-- /* propagate ecc info to mtd_info */
-- mtd->ecclayout = ecc->layout;
-- mtd->ecc_strength = ecc->strength;
-- mtd->ecc_step_size = ecc->size;
- /*
- * Initialize bitflip_threshold to its default prior scan_bbt() call.
- * scan_bbt() might invoke mtd_read(), thus bitflip_threshold must be
-@@ -4421,7 +4468,7 @@ EXPORT_SYMBOL(nand_scan);
- */
- void nand_release(struct mtd_info *mtd)
- {
-- struct nand_chip *chip = mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-
- if (chip->ecc.mode == NAND_ECC_SOFT_BCH)
- nand_bch_free((struct nand_bch_control *)chip->ecc.priv);
---- a/drivers/mtd/nand/nand_bbt.c
-+++ b/drivers/mtd/nand/nand_bbt.c
-@@ -172,7 +172,7 @@ static int read_bbt(struct mtd_info *mtd
- struct nand_bbt_descr *td, int offs)
- {
- int res, ret = 0, i, j, act = 0;
-- struct nand_chip *this = mtd->priv;
-+ struct nand_chip *this = mtd_to_nand(mtd);
- size_t retlen, len, totlen;
- loff_t from;
- int bits = td->options & NAND_BBT_NRBITS_MSK;
-@@ -263,7 +263,7 @@ static int read_bbt(struct mtd_info *mtd
- */
- static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip)
- {
-- struct nand_chip *this = mtd->priv;
-+ struct nand_chip *this = mtd_to_nand(mtd);
- int res = 0, i;
-
- if (td->options & NAND_BBT_PERCHIP) {
-@@ -388,7 +388,7 @@ static u32 bbt_get_ver_offs(struct mtd_i
- static void read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
- struct nand_bbt_descr *td, struct nand_bbt_descr *md)
- {
-- struct nand_chip *this = mtd->priv;
-+ struct nand_chip *this = mtd_to_nand(mtd);
-
- /* Read the primary version, if available */
- if (td->options & NAND_BBT_VERSION) {
-@@ -454,7 +454,7 @@ static int scan_block_fast(struct mtd_in
- static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
- struct nand_bbt_descr *bd, int chip)
- {
-- struct nand_chip *this = mtd->priv;
-+ struct nand_chip *this = mtd_to_nand(mtd);
- int i, numblocks, numpages;
- int startblock;
- loff_t from;
-@@ -523,7 +523,7 @@ static int create_bbt(struct mtd_info *m
- */
- static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
- {
-- struct nand_chip *this = mtd->priv;
-+ struct nand_chip *this = mtd_to_nand(mtd);
- int i, chips;
- int startblock, block, dir;
- int scanlen = mtd->writesize + mtd->oobsize;
-@@ -618,7 +618,7 @@ static int write_bbt(struct mtd_info *mt
- struct nand_bbt_descr *td, struct nand_bbt_descr *md,
- int chipsel)
- {
-- struct nand_chip *this = mtd->priv;
-+ struct nand_chip *this = mtd_to_nand(mtd);
- struct erase_info einfo;
- int i, res, chip = 0;
- int bits, startblock, dir, page, offs, numblocks, sft, sftmsk;
-@@ -819,7 +819,7 @@ static int write_bbt(struct mtd_info *mt
- */
- static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
- {
-- struct nand_chip *this = mtd->priv;
-+ struct nand_chip *this = mtd_to_nand(mtd);
-
- return create_bbt(mtd, this->buffers->databuf, bd, -1);
- }
-@@ -838,7 +838,7 @@ static inline int nand_memory_bbt(struct
- static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd)
- {
- int i, chips, writeops, create, chipsel, res, res2;
-- struct nand_chip *this = mtd->priv;
-+ struct nand_chip *this = mtd_to_nand(mtd);
- struct nand_bbt_descr *td = this->bbt_td;
- struct nand_bbt_descr *md = this->bbt_md;
- struct nand_bbt_descr *rd, *rd2;
-@@ -962,7 +962,7 @@ static int check_create(struct mtd_info
- */
- static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td)
- {
-- struct nand_chip *this = mtd->priv;
-+ struct nand_chip *this = mtd_to_nand(mtd);
- int i, j, chips, block, nrblocks, update;
- uint8_t oldval;
-
-@@ -1022,7 +1022,7 @@ static void mark_bbt_region(struct mtd_i
- */
- static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
- {
-- struct nand_chip *this = mtd->priv;
-+ struct nand_chip *this = mtd_to_nand(mtd);
- u32 pattern_len;
- u32 bits;
- u32 table_size;
-@@ -1074,7 +1074,7 @@ static void verify_bbt_descr(struct mtd_
- */
- static int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
- {
-- struct nand_chip *this = mtd->priv;
-+ struct nand_chip *this = mtd_to_nand(mtd);
- int len, res;
- uint8_t *buf;
- struct nand_bbt_descr *td = this->bbt_td;
-@@ -1147,7 +1147,7 @@ err:
- */
- static int nand_update_bbt(struct mtd_info *mtd, loff_t offs)
- {
-- struct nand_chip *this = mtd->priv;
-+ struct nand_chip *this = mtd_to_nand(mtd);
- int len, res = 0;
- int chip, chipsel;
- uint8_t *buf;
-@@ -1281,7 +1281,7 @@ static int nand_create_badblock_pattern(
- */
- int nand_default_bbt(struct mtd_info *mtd)
- {
-- struct nand_chip *this = mtd->priv;
-+ struct nand_chip *this = mtd_to_nand(mtd);
- int ret;
-
- /* Is a flash based bad block table requested? */
-@@ -1317,7 +1317,7 @@ int nand_default_bbt(struct mtd_info *mt
- */
- int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs)
- {
-- struct nand_chip *this = mtd->priv;
-+ struct nand_chip *this = mtd_to_nand(mtd);
- int block;
-
- block = (int)(offs >> this->bbt_erase_shift);
-@@ -1332,7 +1332,7 @@ int nand_isreserved_bbt(struct mtd_info
- */
- int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
- {
-- struct nand_chip *this = mtd->priv;
-+ struct nand_chip *this = mtd_to_nand(mtd);
- int block, res;
-
- block = (int)(offs >> this->bbt_erase_shift);
-@@ -1359,7 +1359,7 @@ int nand_isbad_bbt(struct mtd_info *mtd,
- */
- int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs)
- {
-- struct nand_chip *this = mtd->priv;
-+ struct nand_chip *this = mtd_to_nand(mtd);
- int block, ret = 0;
-
- block = (int)(offs >> this->bbt_erase_shift);
-@@ -1373,5 +1373,3 @@ int nand_markbad_bbt(struct mtd_info *mt
-
- return ret;
- }
--
--EXPORT_SYMBOL(nand_scan_bbt);
---- a/drivers/mtd/nand/nand_bch.c
-+++ b/drivers/mtd/nand/nand_bch.c
-@@ -32,13 +32,11 @@
- /**
- * struct nand_bch_control - private NAND BCH control structure
- * @bch: BCH control structure
-- * @ecclayout: private ecc layout for this BCH configuration
- * @errloc: error location array
- * @eccmask: XOR ecc mask, allows erased pages to be decoded as valid
- */
- struct nand_bch_control {
- struct bch_control *bch;
-- struct nand_ecclayout ecclayout;
- unsigned int *errloc;
- unsigned char *eccmask;
- };
-@@ -52,7 +50,7 @@ struct nand_bch_control {
- int nand_bch_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf,
- unsigned char *code)
- {
-- const struct nand_chip *chip = mtd->priv;
-+ const struct nand_chip *chip = mtd_to_nand(mtd);
- struct nand_bch_control *nbc = chip->ecc.priv;
- unsigned int i;
-
-@@ -79,7 +77,7 @@ EXPORT_SYMBOL(nand_bch_calculate_ecc);
- int nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf,
- unsigned char *read_ecc, unsigned char *calc_ecc)
- {
-- const struct nand_chip *chip = mtd->priv;
-+ const struct nand_chip *chip = mtd_to_nand(mtd);
- struct nand_bch_control *nbc = chip->ecc.priv;
- unsigned int *errloc = nbc->errloc;
- int i, count;
-@@ -98,7 +96,7 @@ int nand_bch_correct_data(struct mtd_inf
- }
- } else if (count < 0) {
- printk(KERN_ERR "ecc unrecoverable error\n");
-- count = -1;
-+ count = -EBADMSG;
- }
- return count;
- }
-@@ -107,9 +105,6 @@ EXPORT_SYMBOL(nand_bch_correct_data);
- /**
- * nand_bch_init - [NAND Interface] Initialize NAND BCH error correction
- * @mtd: MTD block structure
-- * @eccsize: ecc block size in bytes
-- * @eccbytes: ecc length in bytes
-- * @ecclayout: output default layout
- *
- * Returns:
- * a pointer to a new NAND BCH control structure, or NULL upon failure
-@@ -123,14 +118,20 @@ EXPORT_SYMBOL(nand_bch_correct_data);
- * @eccsize = 512 (thus, m=13 is the smallest integer such that 2^m-1 > 512*8)
- * @eccbytes = 7 (7 bytes are required to store m*t = 13*4 = 52 bits)
- */
--struct nand_bch_control *
--nand_bch_init(struct mtd_info *mtd, unsigned int eccsize, unsigned int eccbytes,
-- struct nand_ecclayout **ecclayout)
-+struct nand_bch_control *nand_bch_init(struct mtd_info *mtd)
- {
-+ struct nand_chip *nand = mtd_to_nand(mtd);
- unsigned int m, t, eccsteps, i;
-- struct nand_ecclayout *layout;
- struct nand_bch_control *nbc = NULL;
- unsigned char *erased_page;
-+ unsigned int eccsize = nand->ecc.size;
-+ unsigned int eccbytes = nand->ecc.bytes;
-+ unsigned int eccstrength = nand->ecc.strength;
-+
-+ if (!eccbytes && eccstrength) {
-+ eccbytes = DIV_ROUND_UP(eccstrength * fls(8 * eccsize), 8);
-+ nand->ecc.bytes = eccbytes;
-+ }
-
- if (!eccsize || !eccbytes) {
- printk(KERN_WARNING "ecc parameters not supplied\n");
-@@ -158,7 +159,7 @@ nand_bch_init(struct mtd_info *mtd, unsi
- eccsteps = mtd->writesize/eccsize;
-
- /* if no ecc placement scheme was provided, build one */
-- if (!*ecclayout) {
-+ if (!mtd->ooblayout) {
-
- /* handle large page devices only */
- if (mtd->oobsize < 64) {
-@@ -167,24 +168,7 @@ nand_bch_init(struct mtd_info *mtd, unsi
- goto fail;
- }
-
-- layout = &nbc->ecclayout;
-- layout->eccbytes = eccsteps*eccbytes;
--
-- /* reserve 2 bytes for bad block marker */
-- if (layout->eccbytes+2 > mtd->oobsize) {
-- printk(KERN_WARNING "no suitable oob scheme available "
-- "for oobsize %d eccbytes %u\n", mtd->oobsize,
-- eccbytes);
-- goto fail;
-- }
-- /* put ecc bytes at oob tail */
-- for (i = 0; i < layout->eccbytes; i++)
-- layout->eccpos[i] = mtd->oobsize-layout->eccbytes+i;
--
-- layout->oobfree[0].offset = 2;
-- layout->oobfree[0].length = mtd->oobsize-2-layout->eccbytes;
--
-- *ecclayout = layout;
-+ mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops);
- }
-
- /* sanity checks */
-@@ -192,7 +176,8 @@ nand_bch_init(struct mtd_info *mtd, unsi
- printk(KERN_WARNING "eccsize %u is too large\n", eccsize);
- goto fail;
- }
-- if ((*ecclayout)->eccbytes != (eccsteps*eccbytes)) {
-+
-+ if (mtd_ooblayout_count_eccbytes(mtd) != (eccsteps*eccbytes)) {
- printk(KERN_WARNING "invalid ecc layout\n");
- goto fail;
- }
-@@ -216,6 +201,9 @@ nand_bch_init(struct mtd_info *mtd, unsi
- for (i = 0; i < eccbytes; i++)
- nbc->eccmask[i] ^= 0xff;
-
-+ if (!eccstrength)
-+ nand->ecc.strength = (eccbytes * 8) / fls(8 * eccsize);
-+
- return nbc;
- fail:
- nand_bch_free(nbc);
---- a/drivers/mtd/nand/nand_ecc.c
-+++ b/drivers/mtd/nand/nand_ecc.c
-@@ -424,7 +424,7 @@ int nand_calculate_ecc(struct mtd_info *
- unsigned char *code)
- {
- __nand_calculate_ecc(buf,
-- ((struct nand_chip *)mtd->priv)->ecc.size, code);
-+ mtd_to_nand(mtd)->ecc.size, code);
-
- return 0;
- }
-@@ -524,7 +524,7 @@ int nand_correct_data(struct mtd_info *m
- unsigned char *read_ecc, unsigned char *calc_ecc)
- {
- return __nand_correct_data(buf, read_ecc, calc_ecc,
-- ((struct nand_chip *)mtd->priv)->ecc.size);
-+ mtd_to_nand(mtd)->ecc.size);
- }
- EXPORT_SYMBOL(nand_correct_data);
-
---- a/drivers/mtd/nand/nand_ids.c
-+++ b/drivers/mtd/nand/nand_ids.c
-@@ -50,8 +50,8 @@ struct nand_flash_dev nand_flash_ids[] =
- SZ_16K, SZ_8K, SZ_4M, 0, 6, 1280, NAND_ECC_INFO(40, SZ_1K) },
- {"H27UCG8T2ATR-BC 64G 3.3V 8-bit",
- { .id = {0xad, 0xde, 0x94, 0xda, 0x74, 0xc4} },
-- SZ_8K, SZ_8K, SZ_2M, 0, 6, 640, NAND_ECC_INFO(40, SZ_1K),
-- 4 },
-+ SZ_8K, SZ_8K, SZ_2M, NAND_NEED_SCRAMBLING, 6, 640,
-+ NAND_ECC_INFO(40, SZ_1K), 4 },
-
- LEGACY_ID_NAND("NAND 4MiB 5V 8-bit", 0x6B, 4, SZ_8K, SP_OPTIONS),
- LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE3, 4, SZ_8K, SP_OPTIONS),
---- a/drivers/mtd/nand/nandsim.c
-+++ b/drivers/mtd/nand/nandsim.c
-@@ -666,8 +666,8 @@ static char *get_partition_name(int i)
- */
- static int init_nandsim(struct mtd_info *mtd)
- {
-- struct nand_chip *chip = mtd->priv;
-- struct nandsim *ns = chip->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct nandsim *ns = nand_get_controller_data(chip);
- int i, ret = 0;
- uint64_t remains;
- uint64_t next_offset;
-@@ -1908,7 +1908,8 @@ static void switch_state(struct nandsim
-
- static u_char ns_nand_read_byte(struct mtd_info *mtd)
- {
-- struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct nandsim *ns = nand_get_controller_data(chip);
- u_char outb = 0x00;
-
- /* Sanity and correctness checks */
-@@ -1969,7 +1970,8 @@ static u_char ns_nand_read_byte(struct m
-
- static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
- {
-- struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct nandsim *ns = nand_get_controller_data(chip);
-
- /* Sanity and correctness checks */
- if (!ns->lines.ce) {
-@@ -2123,7 +2125,8 @@ static void ns_nand_write_byte(struct mt
-
- static void ns_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int bitmask)
- {
-- struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct nandsim *ns = nand_get_controller_data(chip);
-
- ns->lines.cle = bitmask & NAND_CLE ? 1 : 0;
- ns->lines.ale = bitmask & NAND_ALE ? 1 : 0;
-@@ -2141,7 +2144,7 @@ static int ns_device_ready(struct mtd_in
-
- static uint16_t ns_nand_read_word(struct mtd_info *mtd)
- {
-- struct nand_chip *chip = (struct nand_chip *)mtd->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-
- NS_DBG("read_word\n");
-
-@@ -2150,7 +2153,8 @@ static uint16_t ns_nand_read_word(struct
-
- static void ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
- {
-- struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct nandsim *ns = nand_get_controller_data(chip);
-
- /* Check that chip is expecting data input */
- if (!(ns->state & STATE_DATAIN_MASK)) {
-@@ -2177,7 +2181,8 @@ static void ns_nand_write_buf(struct mtd
-
- static void ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
- {
-- struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv;
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct nandsim *ns = nand_get_controller_data(chip);
-
- /* Sanity and correctness checks */
- if (!ns->lines.ce) {
-@@ -2198,7 +2203,7 @@ static void ns_nand_read_buf(struct mtd_
- int i;
-
- for (i = 0; i < len; i++)
-- buf[i] = ((struct nand_chip *)mtd->priv)->read_byte(mtd);
-+ buf[i] = mtd_to_nand(mtd)->read_byte(mtd);
-
- return;
- }
-@@ -2236,16 +2241,15 @@ static int __init ns_init_module(void)
- }
-
- /* Allocate and initialize mtd_info, nand_chip and nandsim structures */
-- nsmtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip)
-- + sizeof(struct nandsim), GFP_KERNEL);
-- if (!nsmtd) {
-+ chip = kzalloc(sizeof(struct nand_chip) + sizeof(struct nandsim),
-+ GFP_KERNEL);
-+ if (!chip) {
- NS_ERR("unable to allocate core structures.\n");
- return -ENOMEM;
- }
-- chip = (struct nand_chip *)(nsmtd + 1);
-- nsmtd->priv = (void *)chip;
-+ nsmtd = nand_to_mtd(chip);
- nand = (struct nandsim *)(chip + 1);
-- chip->priv = (void *)nand;
-+ nand_set_controller_data(chip, (void *)nand);
-
- /*
- * Register simulator's callbacks.
-@@ -2257,6 +2261,7 @@ static int __init ns_init_module(void)
- chip->read_buf = ns_nand_read_buf;
- chip->read_word = ns_nand_read_word;
- chip->ecc.mode = NAND_ECC_SOFT;
-+ chip->ecc.algo = NAND_ECC_HAMMING;
- /* The NAND_SKIP_BBTSCAN option is necessary for 'overridesize' */
- /* and 'badblocks' parameters to work */
- chip->options |= NAND_SKIP_BBTSCAN;
-@@ -2335,6 +2340,7 @@ static int __init ns_init_module(void)
- goto error;
- }
- chip->ecc.mode = NAND_ECC_SOFT_BCH;
-+ chip->ecc.algo = NAND_ECC_BCH;
- chip->ecc.size = 512;
- chip->ecc.strength = bch;
- chip->ecc.bytes = eccbytes;
-@@ -2392,7 +2398,7 @@ err_exit:
- for (i = 0;i < ARRAY_SIZE(nand->partitions); ++i)
- kfree(nand->partitions[i].name);
- error:
-- kfree(nsmtd);
-+ kfree(chip);
- free_lists();
-
- return retval;
-@@ -2405,7 +2411,8 @@ module_init(ns_init_module);
- */
- static void __exit ns_cleanup_module(void)
- {
-- struct nandsim *ns = ((struct nand_chip *)nsmtd->priv)->priv;
-+ struct nand_chip *chip = mtd_to_nand(nsmtd);
-+ struct nandsim *ns = nand_get_controller_data(chip);
- int i;
-
- nandsim_debugfs_remove(ns);
-@@ -2413,7 +2420,7 @@ static void __exit ns_cleanup_module(voi
- nand_release(nsmtd); /* Unregister driver */
- for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i)
- kfree(ns->partitions[i].name);
-- kfree(nsmtd); /* Free other structures */
-+ kfree(mtd_to_nand(nsmtd)); /* Free other structures */
- free_lists();
- }
-
---- a/drivers/mtd/ofpart.c
-+++ b/drivers/mtd/ofpart.c
-@@ -26,9 +26,10 @@ static bool node_has_compatible(struct d
- }
-
- static int parse_ofpart_partitions(struct mtd_info *master,
-- struct mtd_partition **pparts,
-+ const struct mtd_partition **pparts,
- struct mtd_part_parser_data *data)
- {
-+ struct mtd_partition *parts;
- struct device_node *mtd_node;
- struct device_node *ofpart_node;
- const char *partname;
-@@ -37,10 +38,8 @@ static int parse_ofpart_partitions(struc
- bool dedicated = true;
-
-
-- if (!data)
-- return 0;
--
-- mtd_node = data->of_node;
-+ /* Pull of_node from the master device node */
-+ mtd_node = mtd_get_of_node(master);
- if (!mtd_node)
- return 0;
-
-@@ -72,8 +71,8 @@ static int parse_ofpart_partitions(struc
- if (nr_parts == 0)
- return 0;
-
-- *pparts = kzalloc(nr_parts * sizeof(**pparts), GFP_KERNEL);
-- if (!*pparts)
-+ parts = kzalloc(nr_parts * sizeof(*parts), GFP_KERNEL);
-+ if (!parts)
- return -ENOMEM;
-
- i = 0;
-@@ -107,19 +106,19 @@ static int parse_ofpart_partitions(struc
- goto ofpart_fail;
- }
-
-- (*pparts)[i].offset = of_read_number(reg, a_cells);
-- (*pparts)[i].size = of_read_number(reg + a_cells, s_cells);
-+ parts[i].offset = of_read_number(reg, a_cells);
-+ parts[i].size = of_read_number(reg + a_cells, s_cells);
-
- partname = of_get_property(pp, "label", &len);
- if (!partname)
- partname = of_get_property(pp, "name", &len);
-- (*pparts)[i].name = partname;
-+ parts[i].name = partname;
-
- if (of_get_property(pp, "read-only", &len))
-- (*pparts)[i].mask_flags |= MTD_WRITEABLE;
-+ parts[i].mask_flags |= MTD_WRITEABLE;
-
- if (of_get_property(pp, "lock", &len))
-- (*pparts)[i].mask_flags |= MTD_POWERUP_LOCK;
-+ parts[i].mask_flags |= MTD_POWERUP_LOCK;
-
- i++;
- }
-@@ -127,6 +126,7 @@ static int parse_ofpart_partitions(struc
- if (!nr_parts)
- goto ofpart_none;
-
-+ *pparts = parts;
- return nr_parts;
-
- ofpart_fail:
-@@ -135,21 +135,20 @@ ofpart_fail:
- ret = -EINVAL;
- ofpart_none:
- of_node_put(pp);
-- kfree(*pparts);
-- *pparts = NULL;
-+ kfree(parts);
- return ret;
- }
-
- static struct mtd_part_parser ofpart_parser = {
-- .owner = THIS_MODULE,
- .parse_fn = parse_ofpart_partitions,
- .name = "ofpart",
- };
-
- static int parse_ofoldpart_partitions(struct mtd_info *master,
-- struct mtd_partition **pparts,
-+ const struct mtd_partition **pparts,
- struct mtd_part_parser_data *data)
- {
-+ struct mtd_partition *parts;
- struct device_node *dp;
- int i, plen, nr_parts;
- const struct {
-@@ -157,10 +156,8 @@ static int parse_ofoldpart_partitions(st
- } *part;
- const char *names;
-
-- if (!data)
-- return 0;
--
-- dp = data->of_node;
-+ /* Pull of_node from the master device node */
-+ dp = mtd_get_of_node(master);
- if (!dp)
- return 0;
-
-@@ -173,37 +170,37 @@ static int parse_ofoldpart_partitions(st
-
- nr_parts = plen / sizeof(part[0]);
-
-- *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL);
-- if (!*pparts)
-+ parts = kzalloc(nr_parts * sizeof(*parts), GFP_KERNEL);
-+ if (!parts)
- return -ENOMEM;
-
- names = of_get_property(dp, "partition-names", &plen);
-
- for (i = 0; i < nr_parts; i++) {
-- (*pparts)[i].offset = be32_to_cpu(part->offset);
-- (*pparts)[i].size = be32_to_cpu(part->len) & ~1;
-+ parts[i].offset = be32_to_cpu(part->offset);
-+ parts[i].size = be32_to_cpu(part->len) & ~1;
- /* bit 0 set signifies read only partition */
- if (be32_to_cpu(part->len) & 1)
-- (*pparts)[i].mask_flags = MTD_WRITEABLE;
-+ parts[i].mask_flags = MTD_WRITEABLE;
-
- if (names && (plen > 0)) {
- int len = strlen(names) + 1;
-
-- (*pparts)[i].name = names;
-+ parts[i].name = names;
- plen -= len;
- names += len;
- } else {
-- (*pparts)[i].name = "unnamed";
-+ parts[i].name = "unnamed";
- }
-
- part++;
- }
-
-+ *pparts = parts;
- return nr_parts;
- }
-
- static struct mtd_part_parser ofoldpart_parser = {
-- .owner = THIS_MODULE,
- .parse_fn = parse_ofoldpart_partitions,
- .name = "ofoldpart",
- };
---- a/drivers/mtd/spi-nor/Kconfig
-+++ b/drivers/mtd/spi-nor/Kconfig
-@@ -7,6 +7,14 @@ menuconfig MTD_SPI_NOR
-
- if MTD_SPI_NOR
-
-+config MTD_MT81xx_NOR
-+ tristate "Mediatek MT81xx SPI NOR flash controller"
-+ depends on HAS_IOMEM
-+ help
-+ This enables access to SPI NOR flash, using MT81xx SPI NOR flash
-+ controller. This controller does not support generic SPI BUS, it only
-+ supports SPI NOR Flash.
-+
- config MTD_SPI_NOR_USE_4K_SECTORS
- bool "Use small 4096 B erase sectors"
- default y
-@@ -23,7 +31,7 @@ config MTD_SPI_NOR_USE_4K_SECTORS
-
- config SPI_FSL_QUADSPI
- tristate "Freescale Quad SPI controller"
-- depends on ARCH_MXC || COMPILE_TEST
-+ depends on ARCH_MXC || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST
- depends on HAS_IOMEM
- help
- This enables support for the Quad SPI controller in master mode.
---- a/drivers/mtd/spi-nor/Makefile
-+++ b/drivers/mtd/spi-nor/Makefile
-@@ -1,3 +1,4 @@
- obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o
- obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o
-+obj-$(CONFIG_MTD_MT81xx_NOR) += mtk-quadspi.o
- obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o
---- /dev/null
-+++ b/drivers/mtd/spi-nor/mtk-quadspi.c
-@@ -0,0 +1,485 @@
-+/*
-+ * Copyright (c) 2015 MediaTek Inc.
-+ * Author: Bayi Cheng <bayi.cheng@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/delay.h>
-+#include <linux/device.h>
-+#include <linux/init.h>
-+#include <linux/io.h>
-+#include <linux/iopoll.h>
-+#include <linux/ioport.h>
-+#include <linux/math64.h>
-+#include <linux/module.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mutex.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/pinctrl/consumer.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/mtd/spi-nor.h>
-+
-+#define MTK_NOR_CMD_REG 0x00
-+#define MTK_NOR_CNT_REG 0x04
-+#define MTK_NOR_RDSR_REG 0x08
-+#define MTK_NOR_RDATA_REG 0x0c
-+#define MTK_NOR_RADR0_REG 0x10
-+#define MTK_NOR_RADR1_REG 0x14
-+#define MTK_NOR_RADR2_REG 0x18
-+#define MTK_NOR_WDATA_REG 0x1c
-+#define MTK_NOR_PRGDATA0_REG 0x20
-+#define MTK_NOR_PRGDATA1_REG 0x24
-+#define MTK_NOR_PRGDATA2_REG 0x28
-+#define MTK_NOR_PRGDATA3_REG 0x2c
-+#define MTK_NOR_PRGDATA4_REG 0x30
-+#define MTK_NOR_PRGDATA5_REG 0x34
-+#define MTK_NOR_SHREG0_REG 0x38
-+#define MTK_NOR_SHREG1_REG 0x3c
-+#define MTK_NOR_SHREG2_REG 0x40
-+#define MTK_NOR_SHREG3_REG 0x44
-+#define MTK_NOR_SHREG4_REG 0x48
-+#define MTK_NOR_SHREG5_REG 0x4c
-+#define MTK_NOR_SHREG6_REG 0x50
-+#define MTK_NOR_SHREG7_REG 0x54
-+#define MTK_NOR_SHREG8_REG 0x58
-+#define MTK_NOR_SHREG9_REG 0x5c
-+#define MTK_NOR_CFG1_REG 0x60
-+#define MTK_NOR_CFG2_REG 0x64
-+#define MTK_NOR_CFG3_REG 0x68
-+#define MTK_NOR_STATUS0_REG 0x70
-+#define MTK_NOR_STATUS1_REG 0x74
-+#define MTK_NOR_STATUS2_REG 0x78
-+#define MTK_NOR_STATUS3_REG 0x7c
-+#define MTK_NOR_FLHCFG_REG 0x84
-+#define MTK_NOR_TIME_REG 0x94
-+#define MTK_NOR_PP_DATA_REG 0x98
-+#define MTK_NOR_PREBUF_STUS_REG 0x9c
-+#define MTK_NOR_DELSEL0_REG 0xa0
-+#define MTK_NOR_DELSEL1_REG 0xa4
-+#define MTK_NOR_INTRSTUS_REG 0xa8
-+#define MTK_NOR_INTREN_REG 0xac
-+#define MTK_NOR_CHKSUM_CTL_REG 0xb8
-+#define MTK_NOR_CHKSUM_REG 0xbc
-+#define MTK_NOR_CMD2_REG 0xc0
-+#define MTK_NOR_WRPROT_REG 0xc4
-+#define MTK_NOR_RADR3_REG 0xc8
-+#define MTK_NOR_DUAL_REG 0xcc
-+#define MTK_NOR_DELSEL2_REG 0xd0
-+#define MTK_NOR_DELSEL3_REG 0xd4
-+#define MTK_NOR_DELSEL4_REG 0xd8
-+
-+/* commands for mtk nor controller */
-+#define MTK_NOR_READ_CMD 0x0
-+#define MTK_NOR_RDSR_CMD 0x2
-+#define MTK_NOR_PRG_CMD 0x4
-+#define MTK_NOR_WR_CMD 0x10
-+#define MTK_NOR_PIO_WR_CMD 0x90
-+#define MTK_NOR_WRSR_CMD 0x20
-+#define MTK_NOR_PIO_READ_CMD 0x81
-+#define MTK_NOR_WR_BUF_ENABLE 0x1
-+#define MTK_NOR_WR_BUF_DISABLE 0x0
-+#define MTK_NOR_ENABLE_SF_CMD 0x30
-+#define MTK_NOR_DUAD_ADDR_EN 0x8
-+#define MTK_NOR_QUAD_READ_EN 0x4
-+#define MTK_NOR_DUAL_ADDR_EN 0x2
-+#define MTK_NOR_DUAL_READ_EN 0x1
-+#define MTK_NOR_DUAL_DISABLE 0x0
-+#define MTK_NOR_FAST_READ 0x1
-+
-+#define SFLASH_WRBUF_SIZE 128
-+
-+/* Can shift up to 48 bits (6 bytes) of TX/RX */
-+#define MTK_NOR_MAX_RX_TX_SHIFT 6
-+/* can shift up to 56 bits (7 bytes) transfer by MTK_NOR_PRG_CMD */
-+#define MTK_NOR_MAX_SHIFT 7
-+
-+/* Helpers for accessing the program data / shift data registers */
-+#define MTK_NOR_PRG_REG(n) (MTK_NOR_PRGDATA0_REG + 4 * (n))
-+#define MTK_NOR_SHREG(n) (MTK_NOR_SHREG0_REG + 4 * (n))
-+
-+struct mt8173_nor {
-+ struct spi_nor nor;
-+ struct device *dev;
-+ void __iomem *base; /* nor flash base address */
-+ struct clk *spi_clk;
-+ struct clk *nor_clk;
-+};
-+
-+static void mt8173_nor_set_read_mode(struct mt8173_nor *mt8173_nor)
-+{
-+ struct spi_nor *nor = &mt8173_nor->nor;
-+
-+ switch (nor->flash_read) {
-+ case SPI_NOR_FAST:
-+ writeb(nor->read_opcode, mt8173_nor->base +
-+ MTK_NOR_PRGDATA3_REG);
-+ writeb(MTK_NOR_FAST_READ, mt8173_nor->base +
-+ MTK_NOR_CFG1_REG);
-+ break;
-+ case SPI_NOR_DUAL:
-+ writeb(nor->read_opcode, mt8173_nor->base +
-+ MTK_NOR_PRGDATA3_REG);
-+ writeb(MTK_NOR_DUAL_READ_EN, mt8173_nor->base +
-+ MTK_NOR_DUAL_REG);
-+ break;
-+ case SPI_NOR_QUAD:
-+ writeb(nor->read_opcode, mt8173_nor->base +
-+ MTK_NOR_PRGDATA4_REG);
-+ writeb(MTK_NOR_QUAD_READ_EN, mt8173_nor->base +
-+ MTK_NOR_DUAL_REG);
-+ break;
-+ default:
-+ writeb(MTK_NOR_DUAL_DISABLE, mt8173_nor->base +
-+ MTK_NOR_DUAL_REG);
-+ break;
-+ }
-+}
-+
-+static int mt8173_nor_execute_cmd(struct mt8173_nor *mt8173_nor, u8 cmdval)
-+{
-+ int reg;
-+ u8 val = cmdval & 0x1f;
-+
-+ writeb(cmdval, mt8173_nor->base + MTK_NOR_CMD_REG);
-+ return readl_poll_timeout(mt8173_nor->base + MTK_NOR_CMD_REG, reg,
-+ !(reg & val), 100, 10000);
-+}
-+
-+static int mt8173_nor_do_tx_rx(struct mt8173_nor *mt8173_nor, u8 op,
-+ u8 *tx, int txlen, u8 *rx, int rxlen)
-+{
-+ int len = 1 + txlen + rxlen;
-+ int i, ret, idx;
-+
-+ if (len > MTK_NOR_MAX_SHIFT)
-+ return -EINVAL;
-+
-+ writeb(len * 8, mt8173_nor->base + MTK_NOR_CNT_REG);
-+
-+ /* start at PRGDATA5, go down to PRGDATA0 */
-+ idx = MTK_NOR_MAX_RX_TX_SHIFT - 1;
-+
-+ /* opcode */
-+ writeb(op, mt8173_nor->base + MTK_NOR_PRG_REG(idx));
-+ idx--;
-+
-+ /* program TX data */
-+ for (i = 0; i < txlen; i++, idx--)
-+ writeb(tx[i], mt8173_nor->base + MTK_NOR_PRG_REG(idx));
-+
-+ /* clear out rest of TX registers */
-+ while (idx >= 0) {
-+ writeb(0, mt8173_nor->base + MTK_NOR_PRG_REG(idx));
-+ idx--;
-+ }
-+
-+ ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PRG_CMD);
-+ if (ret)
-+ return ret;
-+
-+ /* restart at first RX byte */
-+ idx = rxlen - 1;
-+
-+ /* read out RX data */
-+ for (i = 0; i < rxlen; i++, idx--)
-+ rx[i] = readb(mt8173_nor->base + MTK_NOR_SHREG(idx));
-+
-+ return 0;
-+}
-+
-+/* Do a WRSR (Write Status Register) command */
-+static int mt8173_nor_wr_sr(struct mt8173_nor *mt8173_nor, u8 sr)
-+{
-+ writeb(sr, mt8173_nor->base + MTK_NOR_PRGDATA5_REG);
-+ writeb(8, mt8173_nor->base + MTK_NOR_CNT_REG);
-+ return mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_WRSR_CMD);
-+}
-+
-+static int mt8173_nor_write_buffer_enable(struct mt8173_nor *mt8173_nor)
-+{
-+ u8 reg;
-+
-+ /* the bit0 of MTK_NOR_CFG2_REG is pre-fetch buffer
-+ * 0: pre-fetch buffer use for read
-+ * 1: pre-fetch buffer use for page program
-+ */
-+ writel(MTK_NOR_WR_BUF_ENABLE, mt8173_nor->base + MTK_NOR_CFG2_REG);
-+ return readb_poll_timeout(mt8173_nor->base + MTK_NOR_CFG2_REG, reg,
-+ 0x01 == (reg & 0x01), 100, 10000);
-+}
-+
-+static int mt8173_nor_write_buffer_disable(struct mt8173_nor *mt8173_nor)
-+{
-+ u8 reg;
-+
-+ writel(MTK_NOR_WR_BUF_DISABLE, mt8173_nor->base + MTK_NOR_CFG2_REG);
-+ return readb_poll_timeout(mt8173_nor->base + MTK_NOR_CFG2_REG, reg,
-+ MTK_NOR_WR_BUF_DISABLE == (reg & 0x1), 100,
-+ 10000);
-+}
-+
-+static void mt8173_nor_set_addr(struct mt8173_nor *mt8173_nor, u32 addr)
-+{
-+ int i;
-+
-+ for (i = 0; i < 3; i++) {
-+ writeb(addr & 0xff, mt8173_nor->base + MTK_NOR_RADR0_REG + i * 4);
-+ addr >>= 8;
-+ }
-+ /* Last register is non-contiguous */
-+ writeb(addr & 0xff, mt8173_nor->base + MTK_NOR_RADR3_REG);
-+}
-+
-+static int mt8173_nor_read(struct spi_nor *nor, loff_t from, size_t length,
-+ size_t *retlen, u_char *buffer)
-+{
-+ int i, ret;
-+ int addr = (int)from;
-+ u8 *buf = (u8 *)buffer;
-+ struct mt8173_nor *mt8173_nor = nor->priv;
-+
-+ /* set mode for fast read mode ,dual mode or quad mode */
-+ mt8173_nor_set_read_mode(mt8173_nor);
-+ mt8173_nor_set_addr(mt8173_nor, addr);
-+
-+ for (i = 0; i < length; i++, (*retlen)++) {
-+ ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PIO_READ_CMD);
-+ if (ret < 0)
-+ return ret;
-+ buf[i] = readb(mt8173_nor->base + MTK_NOR_RDATA_REG);
-+ }
-+ return 0;
-+}
-+
-+static int mt8173_nor_write_single_byte(struct mt8173_nor *mt8173_nor,
-+ int addr, int length, u8 *data)
-+{
-+ int i, ret;
-+
-+ mt8173_nor_set_addr(mt8173_nor, addr);
-+
-+ for (i = 0; i < length; i++) {
-+ writeb(*data++, mt8173_nor->base + MTK_NOR_WDATA_REG);
-+ ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PIO_WR_CMD);
-+ if (ret < 0)
-+ return ret;
-+ }
-+ return 0;
-+}
-+
-+static int mt8173_nor_write_buffer(struct mt8173_nor *mt8173_nor, int addr,
-+ const u8 *buf)
-+{
-+ int i, bufidx, data;
-+
-+ mt8173_nor_set_addr(mt8173_nor, addr);
-+
-+ bufidx = 0;
-+ for (i = 0; i < SFLASH_WRBUF_SIZE; i += 4) {
-+ data = buf[bufidx + 3]<<24 | buf[bufidx + 2]<<16 |
-+ buf[bufidx + 1]<<8 | buf[bufidx];
-+ bufidx += 4;
-+ writel(data, mt8173_nor->base + MTK_NOR_PP_DATA_REG);
-+ }
-+ return mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_WR_CMD);
-+}
-+
-+static void mt8173_nor_write(struct spi_nor *nor, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf)
-+{
-+ int ret;
-+ struct mt8173_nor *mt8173_nor = nor->priv;
-+
-+ ret = mt8173_nor_write_buffer_enable(mt8173_nor);
-+ if (ret < 0)
-+ dev_warn(mt8173_nor->dev, "write buffer enable failed!\n");
-+
-+ while (len >= SFLASH_WRBUF_SIZE) {
-+ ret = mt8173_nor_write_buffer(mt8173_nor, to, buf);
-+ if (ret < 0)
-+ dev_err(mt8173_nor->dev, "write buffer failed!\n");
-+ len -= SFLASH_WRBUF_SIZE;
-+ to += SFLASH_WRBUF_SIZE;
-+ buf += SFLASH_WRBUF_SIZE;
-+ (*retlen) += SFLASH_WRBUF_SIZE;
-+ }
-+ ret = mt8173_nor_write_buffer_disable(mt8173_nor);
-+ if (ret < 0)
-+ dev_warn(mt8173_nor->dev, "write buffer disable failed!\n");
-+
-+ if (len) {
-+ ret = mt8173_nor_write_single_byte(mt8173_nor, to, (int)len,
-+ (u8 *)buf);
-+ if (ret < 0)
-+ dev_err(mt8173_nor->dev, "write single byte failed!\n");
-+ (*retlen) += len;
-+ }
-+}
-+
-+static int mt8173_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
-+{
-+ int ret;
-+ struct mt8173_nor *mt8173_nor = nor->priv;
-+
-+ switch (opcode) {
-+ case SPINOR_OP_RDSR:
-+ ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_RDSR_CMD);
-+ if (ret < 0)
-+ return ret;
-+ if (len == 1)
-+ *buf = readb(mt8173_nor->base + MTK_NOR_RDSR_REG);
-+ else
-+ dev_err(mt8173_nor->dev, "len should be 1 for read status!\n");
-+ break;
-+ default:
-+ ret = mt8173_nor_do_tx_rx(mt8173_nor, opcode, NULL, 0, buf, len);
-+ break;
-+ }
-+ return ret;
-+}
-+
-+static int mt8173_nor_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
-+ int len)
-+{
-+ int ret;
-+ struct mt8173_nor *mt8173_nor = nor->priv;
-+
-+ switch (opcode) {
-+ case SPINOR_OP_WRSR:
-+ /* We only handle 1 byte */
-+ ret = mt8173_nor_wr_sr(mt8173_nor, *buf);
-+ break;
-+ default:
-+ ret = mt8173_nor_do_tx_rx(mt8173_nor, opcode, buf, len, NULL, 0);
-+ if (ret)
-+ dev_warn(mt8173_nor->dev, "write reg failure!\n");
-+ break;
-+ }
-+ return ret;
-+}
-+
-+static int mtk_nor_init(struct mt8173_nor *mt8173_nor,
-+ struct device_node *flash_node)
-+{
-+ int ret;
-+ struct spi_nor *nor;
-+
-+ /* initialize controller to accept commands */
-+ writel(MTK_NOR_ENABLE_SF_CMD, mt8173_nor->base + MTK_NOR_WRPROT_REG);
-+
-+ nor = &mt8173_nor->nor;
-+ nor->dev = mt8173_nor->dev;
-+ nor->priv = mt8173_nor;
-+ spi_nor_set_flash_node(nor, flash_node);
-+
-+ /* fill the hooks to spi nor */
-+ nor->read = mt8173_nor_read;
-+ nor->read_reg = mt8173_nor_read_reg;
-+ nor->write = mt8173_nor_write;
-+ nor->write_reg = mt8173_nor_write_reg;
-+ nor->mtd.name = "mtk_nor";
-+ /* initialized with NULL */
-+ ret = spi_nor_scan(nor, NULL, SPI_NOR_DUAL);
-+ if (ret)
-+ return ret;
-+
-+ return mtd_device_register(&nor->mtd, NULL, 0);
-+}
-+
-+static int mtk_nor_drv_probe(struct platform_device *pdev)
-+{
-+ struct device_node *flash_np;
-+ struct resource *res;
-+ int ret;
-+ struct mt8173_nor *mt8173_nor;
-+
-+ if (!pdev->dev.of_node) {
-+ dev_err(&pdev->dev, "No DT found\n");
-+ return -EINVAL;
-+ }
-+
-+ mt8173_nor = devm_kzalloc(&pdev->dev, sizeof(*mt8173_nor), GFP_KERNEL);
-+ if (!mt8173_nor)
-+ return -ENOMEM;
-+ platform_set_drvdata(pdev, mt8173_nor);
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ mt8173_nor->base = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(mt8173_nor->base))
-+ return PTR_ERR(mt8173_nor->base);
-+
-+ mt8173_nor->spi_clk = devm_clk_get(&pdev->dev, "spi");
-+ if (IS_ERR(mt8173_nor->spi_clk))
-+ return PTR_ERR(mt8173_nor->spi_clk);
-+
-+ mt8173_nor->nor_clk = devm_clk_get(&pdev->dev, "sf");
-+ if (IS_ERR(mt8173_nor->nor_clk))
-+ return PTR_ERR(mt8173_nor->nor_clk);
-+
-+ mt8173_nor->dev = &pdev->dev;
-+ ret = clk_prepare_enable(mt8173_nor->spi_clk);
-+ if (ret)
-+ return ret;
-+
-+ ret = clk_prepare_enable(mt8173_nor->nor_clk);
-+ if (ret) {
-+ clk_disable_unprepare(mt8173_nor->spi_clk);
-+ return ret;
-+ }
-+ /* only support one attached flash */
-+ flash_np = of_get_next_available_child(pdev->dev.of_node, NULL);
-+ if (!flash_np) {
-+ dev_err(&pdev->dev, "no SPI flash device to configure\n");
-+ ret = -ENODEV;
-+ goto nor_free;
-+ }
-+ ret = mtk_nor_init(mt8173_nor, flash_np);
-+
-+nor_free:
-+ if (ret) {
-+ clk_disable_unprepare(mt8173_nor->spi_clk);
-+ clk_disable_unprepare(mt8173_nor->nor_clk);
-+ }
-+ return ret;
-+}
-+
-+static int mtk_nor_drv_remove(struct platform_device *pdev)
-+{
-+ struct mt8173_nor *mt8173_nor = platform_get_drvdata(pdev);
-+
-+ clk_disable_unprepare(mt8173_nor->spi_clk);
-+ clk_disable_unprepare(mt8173_nor->nor_clk);
-+ return 0;
-+}
-+
-+static const struct of_device_id mtk_nor_of_ids[] = {
-+ { .compatible = "mediatek,mt8173-nor"},
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, mtk_nor_of_ids);
-+
-+static struct platform_driver mtk_nor_driver = {
-+ .probe = mtk_nor_drv_probe,
-+ .remove = mtk_nor_drv_remove,
-+ .driver = {
-+ .name = "mtk-nor",
-+ .of_match_table = mtk_nor_of_ids,
-+ },
-+};
-+
-+module_platform_driver(mtk_nor_driver);
-+MODULE_LICENSE("GPL v2");
-+MODULE_DESCRIPTION("MediaTek SPI NOR Flash Driver");
---- a/drivers/mtd/spi-nor/spi-nor.c
-+++ b/drivers/mtd/spi-nor/spi-nor.c
-@@ -38,6 +38,7 @@
- #define CHIP_ERASE_2MB_READY_WAIT_JIFFIES (40UL * HZ)
-
- #define SPI_NOR_MAX_ID_LEN 6
-+#define SPI_NOR_MAX_ADDR_WIDTH 4
-
- struct flash_info {
- char *name;
-@@ -60,15 +61,20 @@ struct flash_info {
- u16 addr_width;
-
- u16 flags;
--#define SECT_4K 0x01 /* SPINOR_OP_BE_4K works uniformly */
--#define SPI_NOR_NO_ERASE 0x02 /* No erase command needed */
--#define SST_WRITE 0x04 /* use SST byte programming */
--#define SPI_NOR_NO_FR 0x08 /* Can't do fastread */
--#define SECT_4K_PMC 0x10 /* SPINOR_OP_BE_4K_PMC works uniformly */
--#define SPI_NOR_DUAL_READ 0x20 /* Flash supports Dual Read */
--#define SPI_NOR_QUAD_READ 0x40 /* Flash supports Quad Read */
--#define USE_FSR 0x80 /* use flag status register */
--#define SPI_NOR_HAS_LOCK 0x100 /* Flash supports lock/unlock via SR */
-+#define SECT_4K BIT(0) /* SPINOR_OP_BE_4K works uniformly */
-+#define SPI_NOR_NO_ERASE BIT(1) /* No erase command needed */
-+#define SST_WRITE BIT(2) /* use SST byte programming */
-+#define SPI_NOR_NO_FR BIT(3) /* Can't do fastread */
-+#define SECT_4K_PMC BIT(4) /* SPINOR_OP_BE_4K_PMC works uniformly */
-+#define SPI_NOR_DUAL_READ BIT(5) /* Flash supports Dual Read */
-+#define SPI_NOR_QUAD_READ BIT(6) /* Flash supports Quad Read */
-+#define USE_FSR BIT(7) /* use flag status register */
-+#define SPI_NOR_HAS_LOCK BIT(8) /* Flash supports lock/unlock via SR */
-+#define SPI_NOR_HAS_TB BIT(9) /*
-+ * Flash SR has Top/Bottom (TB) protect
-+ * bit. Must be used with
-+ * SPI_NOR_HAS_LOCK.
-+ */
- };
-
- #define JEDEC_MFR(info) ((info)->id[0])
-@@ -314,6 +320,29 @@ static void spi_nor_unlock_and_unprep(st
- }
-
- /*
-+ * Initiate the erasure of a single sector
-+ */
-+static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
-+{
-+ u8 buf[SPI_NOR_MAX_ADDR_WIDTH];
-+ int i;
-+
-+ if (nor->erase)
-+ return nor->erase(nor, addr);
-+
-+ /*
-+ * Default implementation, if driver doesn't have a specialized HW
-+ * control
-+ */
-+ for (i = nor->addr_width - 1; i >= 0; i--) {
-+ buf[i] = addr & 0xff;
-+ addr >>= 8;
-+ }
-+
-+ return nor->write_reg(nor, nor->erase_opcode, buf, nor->addr_width);
-+}
-+
-+/*
- * Erase an address range on the nor chip. The address range may extend
- * one or more erase sectors. Return an error is there is a problem erasing.
- */
-@@ -372,10 +401,9 @@ static int spi_nor_erase(struct mtd_info
- while (len) {
- write_enable(nor);
-
-- if (nor->erase(nor, addr)) {
-- ret = -EIO;
-+ ret = spi_nor_erase_sector(nor, addr);
-+ if (ret)
- goto erase_err;
-- }
-
- addr += mtd->erasesize;
- len -= mtd->erasesize;
-@@ -388,17 +416,13 @@ static int spi_nor_erase(struct mtd_info
-
- write_disable(nor);
-
-+erase_err:
- spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
-
-- instr->state = MTD_ERASE_DONE;
-+ instr->state = ret ? MTD_ERASE_FAILED : MTD_ERASE_DONE;
- mtd_erase_callback(instr);
-
- return ret;
--
--erase_err:
-- spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
-- instr->state = MTD_ERASE_FAILED;
-- return ret;
- }
-
- static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs,
-@@ -416,32 +440,58 @@ static void stm_get_locked_range(struct
- } else {
- pow = ((sr & mask) ^ mask) >> shift;
- *len = mtd->size >> pow;
-- *ofs = mtd->size - *len;
-+ if (nor->flags & SNOR_F_HAS_SR_TB && sr & SR_TB)
-+ *ofs = 0;
-+ else
-+ *ofs = mtd->size - *len;
- }
- }
-
- /*
-- * Return 1 if the entire region is locked, 0 otherwise
-+ * Return 1 if the entire region is locked (if @locked is true) or unlocked (if
-+ * @locked is false); 0 otherwise
- */
--static int stm_is_locked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len,
-- u8 sr)
-+static int stm_check_lock_status_sr(struct spi_nor *nor, loff_t ofs, uint64_t len,
-+ u8 sr, bool locked)
- {
- loff_t lock_offs;
- uint64_t lock_len;
-
-+ if (!len)
-+ return 1;
-+
- stm_get_locked_range(nor, sr, &lock_offs, &lock_len);
-
-- return (ofs + len <= lock_offs + lock_len) && (ofs >= lock_offs);
-+ if (locked)
-+ /* Requested range is a sub-range of locked range */
-+ return (ofs + len <= lock_offs + lock_len) && (ofs >= lock_offs);
-+ else
-+ /* Requested range does not overlap with locked range */
-+ return (ofs >= lock_offs + lock_len) || (ofs + len <= lock_offs);
-+}
-+
-+static int stm_is_locked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len,
-+ u8 sr)
-+{
-+ return stm_check_lock_status_sr(nor, ofs, len, sr, true);
-+}
-+
-+static int stm_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len,
-+ u8 sr)
-+{
-+ return stm_check_lock_status_sr(nor, ofs, len, sr, false);
- }
-
- /*
- * Lock a region of the flash. Compatible with ST Micro and similar flash.
-- * Supports only the block protection bits BP{0,1,2} in the status register
-+ * Supports the block protection bits BP{0,1,2} in the status register
- * (SR). Does not support these features found in newer SR bitfields:
-- * - TB: top/bottom protect - only handle TB=0 (top protect)
- * - SEC: sector/block protect - only handle SEC=0 (block protect)
- * - CMP: complement protect - only support CMP=0 (range is not complemented)
- *
-+ * Support for the following is provided conditionally for some flash:
-+ * - TB: top/bottom protect
-+ *
- * Sample table portion for 8MB flash (Winbond w25q64fw):
- *
- * SEC | TB | BP2 | BP1 | BP0 | Prot Length | Protected Portion
-@@ -454,26 +504,55 @@ static int stm_is_locked_sr(struct spi_n
- * 0 | 0 | 1 | 0 | 1 | 2 MB | Upper 1/4
- * 0 | 0 | 1 | 1 | 0 | 4 MB | Upper 1/2
- * X | X | 1 | 1 | 1 | 8 MB | ALL
-+ * ------|-------|-------|-------|-------|---------------|-------------------
-+ * 0 | 1 | 0 | 0 | 1 | 128 KB | Lower 1/64
-+ * 0 | 1 | 0 | 1 | 0 | 256 KB | Lower 1/32
-+ * 0 | 1 | 0 | 1 | 1 | 512 KB | Lower 1/16
-+ * 0 | 1 | 1 | 0 | 0 | 1 MB | Lower 1/8
-+ * 0 | 1 | 1 | 0 | 1 | 2 MB | Lower 1/4
-+ * 0 | 1 | 1 | 1 | 0 | 4 MB | Lower 1/2
- *
- * Returns negative on errors, 0 on success.
- */
- static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
- {
- struct mtd_info *mtd = &nor->mtd;
-- u8 status_old, status_new;
-+ int status_old, status_new;
- u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
- u8 shift = ffs(mask) - 1, pow, val;
-+ loff_t lock_len;
-+ bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
-+ bool use_top;
-+ int ret;
-
- status_old = read_sr(nor);
-+ if (status_old < 0)
-+ return status_old;
-
-- /* SPI NOR always locks to the end */
-- if (ofs + len != mtd->size) {
-- /* Does combined region extend to end? */
-- if (!stm_is_locked_sr(nor, ofs + len, mtd->size - ofs - len,
-- status_old))
-- return -EINVAL;
-- len = mtd->size - ofs;
-- }
-+ /* If nothing in our range is unlocked, we don't need to do anything */
-+ if (stm_is_locked_sr(nor, ofs, len, status_old))
-+ return 0;
-+
-+ /* If anything below us is unlocked, we can't use 'bottom' protection */
-+ if (!stm_is_locked_sr(nor, 0, ofs, status_old))
-+ can_be_bottom = false;
-+
-+ /* If anything above us is unlocked, we can't use 'top' protection */
-+ if (!stm_is_locked_sr(nor, ofs + len, mtd->size - (ofs + len),
-+ status_old))
-+ can_be_top = false;
-+
-+ if (!can_be_bottom && !can_be_top)
-+ return -EINVAL;
-+
-+ /* Prefer top, if both are valid */
-+ use_top = can_be_top;
-+
-+ /* lock_len: length of region that should end up locked */
-+ if (use_top)
-+ lock_len = mtd->size - ofs;
-+ else
-+ lock_len = ofs + len;
-
- /*
- * Need smallest pow such that:
-@@ -484,7 +563,7 @@ static int stm_lock(struct spi_nor *nor,
- *
- * pow = ceil(log2(size / len)) = log2(size) - floor(log2(len))
- */
-- pow = ilog2(mtd->size) - ilog2(len);
-+ pow = ilog2(mtd->size) - ilog2(lock_len);
- val = mask - (pow << shift);
- if (val & ~mask)
- return -EINVAL;
-@@ -492,14 +571,27 @@ static int stm_lock(struct spi_nor *nor,
- if (!(val & mask))
- return -EINVAL;
-
-- status_new = (status_old & ~mask) | val;
-+ status_new = (status_old & ~mask & ~SR_TB) | val;
-+
-+ /* Disallow further writes if WP pin is asserted */
-+ status_new |= SR_SRWD;
-+
-+ if (!use_top)
-+ status_new |= SR_TB;
-+
-+ /* Don't bother if they're the same */
-+ if (status_new == status_old)
-+ return 0;
-
- /* Only modify protection if it will not unlock other areas */
-- if ((status_new & mask) <= (status_old & mask))
-+ if ((status_new & mask) < (status_old & mask))
- return -EINVAL;
-
- write_enable(nor);
-- return write_sr(nor, status_new);
-+ ret = write_sr(nor, status_new);
-+ if (ret)
-+ return ret;
-+ return spi_nor_wait_till_ready(nor);
- }
-
- /*
-@@ -510,17 +602,43 @@ static int stm_lock(struct spi_nor *nor,
- static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
- {
- struct mtd_info *mtd = &nor->mtd;
-- uint8_t status_old, status_new;
-+ int status_old, status_new;
- u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
- u8 shift = ffs(mask) - 1, pow, val;
-+ loff_t lock_len;
-+ bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
-+ bool use_top;
-+ int ret;
-
- status_old = read_sr(nor);
-+ if (status_old < 0)
-+ return status_old;
-+
-+ /* If nothing in our range is locked, we don't need to do anything */
-+ if (stm_is_unlocked_sr(nor, ofs, len, status_old))
-+ return 0;
-+
-+ /* If anything below us is locked, we can't use 'top' protection */
-+ if (!stm_is_unlocked_sr(nor, 0, ofs, status_old))
-+ can_be_top = false;
-+
-+ /* If anything above us is locked, we can't use 'bottom' protection */
-+ if (!stm_is_unlocked_sr(nor, ofs + len, mtd->size - (ofs + len),
-+ status_old))
-+ can_be_bottom = false;
-
-- /* Cannot unlock; would unlock larger region than requested */
-- if (stm_is_locked_sr(nor, ofs - mtd->erasesize, mtd->erasesize,
-- status_old))
-+ if (!can_be_bottom && !can_be_top)
- return -EINVAL;
-
-+ /* Prefer top, if both are valid */
-+ use_top = can_be_top;
-+
-+ /* lock_len: length of region that should remain locked */
-+ if (use_top)
-+ lock_len = mtd->size - (ofs + len);
-+ else
-+ lock_len = ofs;
-+
- /*
- * Need largest pow such that:
- *
-@@ -530,8 +648,8 @@ static int stm_unlock(struct spi_nor *no
- *
- * pow = floor(log2(size / len)) = log2(size) - ceil(log2(len))
- */
-- pow = ilog2(mtd->size) - order_base_2(mtd->size - (ofs + len));
-- if (ofs + len == mtd->size) {
-+ pow = ilog2(mtd->size) - order_base_2(lock_len);
-+ if (lock_len == 0) {
- val = 0; /* fully unlocked */
- } else {
- val = mask - (pow << shift);
-@@ -540,14 +658,28 @@ static int stm_unlock(struct spi_nor *no
- return -EINVAL;
- }
-
-- status_new = (status_old & ~mask) | val;
-+ status_new = (status_old & ~mask & ~SR_TB) | val;
-+
-+ /* Don't protect status register if we're fully unlocked */
-+ if (lock_len == mtd->size)
-+ status_new &= ~SR_SRWD;
-+
-+ if (!use_top)
-+ status_new |= SR_TB;
-+
-+ /* Don't bother if they're the same */
-+ if (status_new == status_old)
-+ return 0;
-
- /* Only modify protection if it will not lock other areas */
-- if ((status_new & mask) >= (status_old & mask))
-+ if ((status_new & mask) > (status_old & mask))
- return -EINVAL;
-
- write_enable(nor);
-- return write_sr(nor, status_new);
-+ ret = write_sr(nor, status_new);
-+ if (ret)
-+ return ret;
-+ return spi_nor_wait_till_ready(nor);
- }
-
- /*
-@@ -737,8 +869,8 @@ static const struct flash_info spi_nor_i
- { "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) },
- { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) },
- { "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) },
-- { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ) },
-- { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SPI_NOR_QUAD_READ) },
-+ { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
-+ { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
- { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) },
- { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
- { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
-@@ -772,6 +904,7 @@ static const struct flash_info spi_nor_i
- { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
- { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
- { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
-+ { "s25fl116k", INFO(0x014015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
- { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) },
- { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128, SECT_4K) },
- { "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ) },
-@@ -835,11 +968,23 @@ static const struct flash_info spi_nor_i
- { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) },
- { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) },
- { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) },
-- { "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-+ {
-+ "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64,
-+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
-+ },
- { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
- { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
-- { "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-- { "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-+ {
-+ "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128,
-+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
-+ },
-+ {
-+ "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256,
-+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
-+ },
- { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) },
- { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) },
- { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
-@@ -862,7 +1007,7 @@ static const struct flash_info *spi_nor_
-
- tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
- if (tmp < 0) {
-- dev_dbg(nor->dev, " error %d reading JEDEC ID\n", tmp);
-+ dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp);
- return ERR_PTR(tmp);
- }
-
-@@ -873,7 +1018,7 @@ static const struct flash_info *spi_nor_
- return &spi_nor_ids[tmp];
- }
- }
-- dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %2x, %2x\n",
-+ dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n",
- id[0], id[1], id[2]);
- return ERR_PTR(-ENODEV);
- }
-@@ -1019,6 +1164,8 @@ static int macronix_quad_enable(struct s
- int ret, val;
-
- val = read_sr(nor);
-+ if (val < 0)
-+ return val;
- write_enable(nor);
-
- write_sr(nor, val | SR_QUAD_EN_MX);
-@@ -1100,7 +1247,7 @@ static int set_quad_mode(struct spi_nor
- static int spi_nor_check(struct spi_nor *nor)
- {
- if (!nor->dev || !nor->read || !nor->write ||
-- !nor->read_reg || !nor->write_reg || !nor->erase) {
-+ !nor->read_reg || !nor->write_reg) {
- pr_err("spi-nor: please fill all the necessary fields!\n");
- return -EINVAL;
- }
-@@ -1113,7 +1260,7 @@ int spi_nor_scan(struct spi_nor *nor, co
- const struct flash_info *info = NULL;
- struct device *dev = nor->dev;
- struct mtd_info *mtd = &nor->mtd;
-- struct device_node *np = nor->flash_node;
-+ struct device_node *np = spi_nor_get_flash_node(nor);
- int ret;
- int i;
-
-@@ -1167,6 +1314,7 @@ int spi_nor_scan(struct spi_nor *nor, co
- info->flags & SPI_NOR_HAS_LOCK) {
- write_enable(nor);
- write_sr(nor, 0);
-+ spi_nor_wait_till_ready(nor);
- }
-
- if (!mtd->name)
-@@ -1201,6 +1349,8 @@ int spi_nor_scan(struct spi_nor *nor, co
-
- if (info->flags & USE_FSR)
- nor->flags |= SNOR_F_USE_FSR;
-+ if (info->flags & SPI_NOR_HAS_TB)
-+ nor->flags |= SNOR_F_HAS_SR_TB;
-
- #ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
- /* prefer "small sector" erase if possible */
-@@ -1303,6 +1453,12 @@ int spi_nor_scan(struct spi_nor *nor, co
- nor->addr_width = 3;
- }
-
-+ if (nor->addr_width > SPI_NOR_MAX_ADDR_WIDTH) {
-+ dev_err(dev, "address width is too large: %u\n",
-+ nor->addr_width);
-+ return -EINVAL;
-+ }
-+
- nor->read_dummy = spi_nor_read_dummy_cycles(nor);
-
- dev_info(dev, "%s (%lld Kbytes)\n", info->name,
---- a/drivers/mtd/tests/mtd_nandecctest.c
-+++ b/drivers/mtd/tests/mtd_nandecctest.c
-@@ -187,7 +187,7 @@ static int double_bit_error_detect(void
- __nand_calculate_ecc(error_data, size, calc_ecc);
- ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size);
-
-- return (ret == -1) ? 0 : -EINVAL;
-+ return (ret == -EBADMSG) ? 0 : -EINVAL;
- }
-
- static const struct nand_ecc_test nand_ecc_test[] = {
---- a/drivers/mtd/tests/oobtest.c
-+++ b/drivers/mtd/tests/oobtest.c
-@@ -215,19 +215,19 @@ static int verify_eraseblock(int ebnum)
- pr_info("ignoring error as within bitflip_limit\n");
- }
-
-- if (use_offset != 0 || use_len < mtd->ecclayout->oobavail) {
-+ if (use_offset != 0 || use_len < mtd->oobavail) {
- int k;
-
- ops.mode = MTD_OPS_AUTO_OOB;
- ops.len = 0;
- ops.retlen = 0;
-- ops.ooblen = mtd->ecclayout->oobavail;
-+ ops.ooblen = mtd->oobavail;
- ops.oobretlen = 0;
- ops.ooboffs = 0;
- ops.datbuf = NULL;
- ops.oobbuf = readbuf;
- err = mtd_read_oob(mtd, addr, &ops);
-- if (err || ops.oobretlen != mtd->ecclayout->oobavail) {
-+ if (err || ops.oobretlen != mtd->oobavail) {
- pr_err("error: readoob failed at %#llx\n",
- (long long)addr);
- errcnt += 1;
-@@ -244,7 +244,7 @@ static int verify_eraseblock(int ebnum)
- /* verify post-(use_offset + use_len) area for 0xff */
- k = use_offset + use_len;
- bitflips += memffshow(addr, k, readbuf + k,
-- mtd->ecclayout->oobavail - k);
-+ mtd->oobavail - k);
-
- if (bitflips > bitflip_limit) {
- pr_err("error: verify failed at %#llx\n",
-@@ -269,8 +269,8 @@ static int verify_eraseblock_in_one_go(i
- struct mtd_oob_ops ops;
- int err = 0;
- loff_t addr = (loff_t)ebnum * mtd->erasesize;
-- size_t len = mtd->ecclayout->oobavail * pgcnt;
-- size_t oobavail = mtd->ecclayout->oobavail;
-+ size_t len = mtd->oobavail * pgcnt;
-+ size_t oobavail = mtd->oobavail;
- size_t bitflips;
- int i;
-
-@@ -394,8 +394,8 @@ static int __init mtd_oobtest_init(void)
- goto out;
-
- use_offset = 0;
-- use_len = mtd->ecclayout->oobavail;
-- use_len_max = mtd->ecclayout->oobavail;
-+ use_len = mtd->oobavail;
-+ use_len_max = mtd->oobavail;
- vary_offset = 0;
-
- /* First test: write all OOB, read it back and verify */
-@@ -460,8 +460,8 @@ static int __init mtd_oobtest_init(void)
-
- /* Write all eraseblocks */
- use_offset = 0;
-- use_len = mtd->ecclayout->oobavail;
-- use_len_max = mtd->ecclayout->oobavail;
-+ use_len = mtd->oobavail;
-+ use_len_max = mtd->oobavail;
- vary_offset = 1;
- prandom_seed_state(&rnd_state, 5);
-
-@@ -471,8 +471,8 @@ static int __init mtd_oobtest_init(void)
-
- /* Check all eraseblocks */
- use_offset = 0;
-- use_len = mtd->ecclayout->oobavail;
-- use_len_max = mtd->ecclayout->oobavail;
-+ use_len = mtd->oobavail;
-+ use_len_max = mtd->oobavail;
- vary_offset = 1;
- prandom_seed_state(&rnd_state, 5);
- err = verify_all_eraseblocks();
-@@ -480,8 +480,8 @@ static int __init mtd_oobtest_init(void)
- goto out;
-
- use_offset = 0;
-- use_len = mtd->ecclayout->oobavail;
-- use_len_max = mtd->ecclayout->oobavail;
-+ use_len = mtd->oobavail;
-+ use_len_max = mtd->oobavail;
- vary_offset = 0;
-
- /* Fourth test: try to write off end of device */
-@@ -501,7 +501,7 @@ static int __init mtd_oobtest_init(void)
- ops.retlen = 0;
- ops.ooblen = 1;
- ops.oobretlen = 0;
-- ops.ooboffs = mtd->ecclayout->oobavail;
-+ ops.ooboffs = mtd->oobavail;
- ops.datbuf = NULL;
- ops.oobbuf = writebuf;
- pr_info("attempting to start write past end of OOB\n");
-@@ -521,7 +521,7 @@ static int __init mtd_oobtest_init(void)
- ops.retlen = 0;
- ops.ooblen = 1;
- ops.oobretlen = 0;
-- ops.ooboffs = mtd->ecclayout->oobavail;
-+ ops.ooboffs = mtd->oobavail;
- ops.datbuf = NULL;
- ops.oobbuf = readbuf;
- pr_info("attempting to start read past end of OOB\n");
-@@ -543,7 +543,7 @@ static int __init mtd_oobtest_init(void)
- ops.mode = MTD_OPS_AUTO_OOB;
- ops.len = 0;
- ops.retlen = 0;
-- ops.ooblen = mtd->ecclayout->oobavail + 1;
-+ ops.ooblen = mtd->oobavail + 1;
- ops.oobretlen = 0;
- ops.ooboffs = 0;
- ops.datbuf = NULL;
-@@ -563,7 +563,7 @@ static int __init mtd_oobtest_init(void)
- ops.mode = MTD_OPS_AUTO_OOB;
- ops.len = 0;
- ops.retlen = 0;
-- ops.ooblen = mtd->ecclayout->oobavail + 1;
-+ ops.ooblen = mtd->oobavail + 1;
- ops.oobretlen = 0;
- ops.ooboffs = 0;
- ops.datbuf = NULL;
-@@ -587,7 +587,7 @@ static int __init mtd_oobtest_init(void)
- ops.mode = MTD_OPS_AUTO_OOB;
- ops.len = 0;
- ops.retlen = 0;
-- ops.ooblen = mtd->ecclayout->oobavail;
-+ ops.ooblen = mtd->oobavail;
- ops.oobretlen = 0;
- ops.ooboffs = 1;
- ops.datbuf = NULL;
-@@ -607,7 +607,7 @@ static int __init mtd_oobtest_init(void)
- ops.mode = MTD_OPS_AUTO_OOB;
- ops.len = 0;
- ops.retlen = 0;
-- ops.ooblen = mtd->ecclayout->oobavail;
-+ ops.ooblen = mtd->oobavail;
- ops.oobretlen = 0;
- ops.ooboffs = 1;
- ops.datbuf = NULL;
-@@ -638,7 +638,7 @@ static int __init mtd_oobtest_init(void)
- for (i = 0; i < ebcnt - 1; ++i) {
- int cnt = 2;
- int pg;
-- size_t sz = mtd->ecclayout->oobavail;
-+ size_t sz = mtd->oobavail;
- if (bbt[i] || bbt[i + 1])
- continue;
- addr = (loff_t)(i + 1) * mtd->erasesize - mtd->writesize;
-@@ -673,13 +673,12 @@ static int __init mtd_oobtest_init(void)
- for (i = 0; i < ebcnt - 1; ++i) {
- if (bbt[i] || bbt[i + 1])
- continue;
-- prandom_bytes_state(&rnd_state, writebuf,
-- mtd->ecclayout->oobavail * 2);
-+ prandom_bytes_state(&rnd_state, writebuf, mtd->oobavail * 2);
- addr = (loff_t)(i + 1) * mtd->erasesize - mtd->writesize;
- ops.mode = MTD_OPS_AUTO_OOB;
- ops.len = 0;
- ops.retlen = 0;
-- ops.ooblen = mtd->ecclayout->oobavail * 2;
-+ ops.ooblen = mtd->oobavail * 2;
- ops.oobretlen = 0;
- ops.ooboffs = 0;
- ops.datbuf = NULL;
-@@ -688,7 +687,7 @@ static int __init mtd_oobtest_init(void)
- if (err)
- goto out;
- if (memcmpshow(addr, readbuf, writebuf,
-- mtd->ecclayout->oobavail * 2)) {
-+ mtd->oobavail * 2)) {
- pr_err("error: verify failed at %#llx\n",
- (long long)addr);
- errcnt += 1;
---- a/drivers/mtd/tests/pagetest.c
-+++ b/drivers/mtd/tests/pagetest.c
-@@ -127,13 +127,12 @@ static int crosstest(void)
- unsigned char *pp1, *pp2, *pp3, *pp4;
-
- pr_info("crosstest\n");
-- pp1 = kmalloc(pgsize * 4, GFP_KERNEL);
-+ pp1 = kzalloc(pgsize * 4, GFP_KERNEL);
- if (!pp1)
- return -ENOMEM;
- pp2 = pp1 + pgsize;
- pp3 = pp2 + pgsize;
- pp4 = pp3 + pgsize;
-- memset(pp1, 0, pgsize * 4);
-
- addr0 = 0;
- for (i = 0; i < ebcnt && bbt[i]; ++i)
---- a/include/linux/mtd/bbm.h
-+++ b/include/linux/mtd/bbm.h
-@@ -166,7 +166,6 @@ struct bbm_info {
- };
-
- /* OneNAND BBT interface */
--extern int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd);
- extern int onenand_default_bbt(struct mtd_info *mtd);
-
- #endif /* __LINUX_MTD_BBM_H */
---- a/include/linux/mtd/fsmc.h
-+++ b/include/linux/mtd/fsmc.h
-@@ -103,24 +103,6 @@
-
- #define FSMC_BUSY_WAIT_TIMEOUT (1 * HZ)
-
--/*
-- * There are 13 bytes of ecc for every 512 byte block in FSMC version 8
-- * and it has to be read consecutively and immediately after the 512
-- * byte data block for hardware to generate the error bit offsets
-- * Managing the ecc bytes in the following way is easier. This way is
-- * similar to oobfree structure maintained already in u-boot nand driver
-- */
--#define MAX_ECCPLACE_ENTRIES 32
--
--struct fsmc_nand_eccplace {
-- uint8_t offset;
-- uint8_t length;
--};
--
--struct fsmc_eccplace {
-- struct fsmc_nand_eccplace eccplace[MAX_ECCPLACE_ENTRIES];
--};
--
- struct fsmc_nand_timings {
- uint8_t tclr;
- uint8_t tar;
---- a/include/linux/mtd/inftl.h
-+++ b/include/linux/mtd/inftl.h
-@@ -44,7 +44,6 @@ struct INFTLrecord {
- unsigned int nb_blocks; /* number of physical blocks */
- unsigned int nb_boot_blocks; /* number of blocks used by the bios */
- struct erase_info instr;
-- struct nand_ecclayout oobinfo;
- };
-
- int INFTL_mount(struct INFTLrecord *s);
---- a/include/linux/mtd/map.h
-+++ b/include/linux/mtd/map.h
-@@ -142,7 +142,9 @@
- #endif
-
- #ifndef map_bankwidth
-+#ifdef CONFIG_MTD
- #warning "No CONFIG_MTD_MAP_BANK_WIDTH_xx selected. No NOR chip support can work"
-+#endif
- static inline int map_bankwidth(void *map)
- {
- BUG();
-@@ -238,8 +240,11 @@ struct map_info {
- If there is no cache to care about this can be set to NULL. */
- void (*inval_cache)(struct map_info *, unsigned long, ssize_t);
-
-- /* set_vpp() must handle being reentered -- enable, enable, disable
-- must leave it enabled. */
-+ /* This will be called with 1 as parameter when the first map user
-+ * needs VPP, and called with 0 when the last user exits. The map
-+ * core maintains a reference counter, and assumes that VPP is a
-+ * global resource applying to all mapped flash chips on the system.
-+ */
- void (*set_vpp)(struct map_info *, int);
-
- unsigned long pfow_base;
---- a/include/linux/mtd/mtd.h
-+++ b/include/linux/mtd/mtd.h
-@@ -100,17 +100,35 @@ struct mtd_oob_ops {
-
- #define MTD_MAX_OOBFREE_ENTRIES_LARGE 32
- #define MTD_MAX_ECCPOS_ENTRIES_LARGE 640
-+/**
-+ * struct mtd_oob_region - oob region definition
-+ * @offset: region offset
-+ * @length: region length
-+ *
-+ * This structure describes a region of the OOB area, and is used
-+ * to retrieve ECC or free bytes sections.
-+ * Each section is defined by an offset within the OOB area and a
-+ * length.
-+ */
-+struct mtd_oob_region {
-+ u32 offset;
-+ u32 length;
-+};
-+
- /*
-- * Internal ECC layout control structure. For historical reasons, there is a
-- * similar, smaller struct nand_ecclayout_user (in mtd-abi.h) that is retained
-- * for export to user-space via the ECCGETLAYOUT ioctl.
-- * nand_ecclayout should be expandable in the future simply by the above macros.
-+ * struct mtd_ooblayout_ops - NAND OOB layout operations
-+ * @ecc: function returning an ECC region in the OOB area.
-+ * Should return -ERANGE if %section exceeds the total number of
-+ * ECC sections.
-+ * @free: function returning a free region in the OOB area.
-+ * Should return -ERANGE if %section exceeds the total number of
-+ * free sections.
- */
--struct nand_ecclayout {
-- __u32 eccbytes;
-- __u32 eccpos[MTD_MAX_ECCPOS_ENTRIES_LARGE];
-- __u32 oobavail;
-- struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES_LARGE];
-+struct mtd_ooblayout_ops {
-+ int (*ecc)(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oobecc);
-+ int (*free)(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oobfree);
- };
-
- struct module; /* only needed for owner field in mtd_info */
-@@ -171,8 +189,8 @@ struct mtd_info {
- const char *name;
- int index;
-
-- /* ECC layout structure pointer - read only! */
-- struct nand_ecclayout *ecclayout;
-+ /* OOB layout description */
-+ const struct mtd_ooblayout_ops *ooblayout;
-
- /* the ecc step size. */
- unsigned int ecc_step_size;
-@@ -258,6 +276,46 @@ struct mtd_info {
- int usecount;
- };
-
-+int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oobecc);
-+int mtd_ooblayout_find_eccregion(struct mtd_info *mtd, int eccbyte,
-+ int *section,
-+ struct mtd_oob_region *oobregion);
-+int mtd_ooblayout_get_eccbytes(struct mtd_info *mtd, u8 *eccbuf,
-+ const u8 *oobbuf, int start, int nbytes);
-+int mtd_ooblayout_set_eccbytes(struct mtd_info *mtd, const u8 *eccbuf,
-+ u8 *oobbuf, int start, int nbytes);
-+int mtd_ooblayout_free(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oobfree);
-+int mtd_ooblayout_get_databytes(struct mtd_info *mtd, u8 *databuf,
-+ const u8 *oobbuf, int start, int nbytes);
-+int mtd_ooblayout_set_databytes(struct mtd_info *mtd, const u8 *databuf,
-+ u8 *oobbuf, int start, int nbytes);
-+int mtd_ooblayout_count_freebytes(struct mtd_info *mtd);
-+int mtd_ooblayout_count_eccbytes(struct mtd_info *mtd);
-+
-+static inline void mtd_set_ooblayout(struct mtd_info *mtd,
-+ const struct mtd_ooblayout_ops *ooblayout)
-+{
-+ mtd->ooblayout = ooblayout;
-+}
-+
-+static inline void mtd_set_of_node(struct mtd_info *mtd,
-+ struct device_node *np)
-+{
-+ mtd->dev.of_node = np;
-+}
-+
-+static inline struct device_node *mtd_get_of_node(struct mtd_info *mtd)
-+{
-+ return mtd->dev.of_node;
-+}
-+
-+static inline int mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops)
-+{
-+ return ops->mode == MTD_OPS_AUTO_OOB ? mtd->oobavail : mtd->oobsize;
-+}
-+
- int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
- int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
- void **virt, resource_size_t *phys);
---- a/include/linux/mtd/nand.h
-+++ b/include/linux/mtd/nand.h
-@@ -119,6 +119,12 @@ typedef enum {
- NAND_ECC_SOFT_BCH,
- } nand_ecc_modes_t;
-
-+enum nand_ecc_algo {
-+ NAND_ECC_UNKNOWN,
-+ NAND_ECC_HAMMING,
-+ NAND_ECC_BCH,
-+};
-+
- /*
- * Constants for Hardware ECC
- */
-@@ -129,6 +135,14 @@ typedef enum {
- /* Enable Hardware ECC before syndrome is read back from flash */
- #define NAND_ECC_READSYN 2
-
-+/*
-+ * Enable generic NAND 'page erased' check. This check is only done when
-+ * ecc.correct() returns -EBADMSG.
-+ * Set this flag if your implementation does not fix bitflips in erased
-+ * pages and you want to rely on the default implementation.
-+ */
-+#define NAND_ECC_GENERIC_ERASED_CHECK BIT(0)
-+
- /* Bit mask for flags passed to do_nand_read_ecc */
- #define NAND_GET_DEVICE 0x80
-
-@@ -160,6 +174,12 @@ typedef enum {
- /* Device supports subpage reads */
- #define NAND_SUBPAGE_READ 0x00001000
-
-+/*
-+ * Some MLC NANDs need data scrambling to limit bitflips caused by repeated
-+ * patterns.
-+ */
-+#define NAND_NEED_SCRAMBLING 0x00002000
-+
- /* Options valid for Samsung large page devices */
- #define NAND_SAMSUNG_LP_OPTIONS NAND_CACHEPRG
-
-@@ -276,15 +296,15 @@ struct nand_onfi_params {
- __le16 t_r;
- __le16 t_ccs;
- __le16 src_sync_timing_mode;
-- __le16 src_ssync_features;
-+ u8 src_ssync_features;
- __le16 clk_pin_capacitance_typ;
- __le16 io_pin_capacitance_typ;
- __le16 input_pin_capacitance_typ;
- u8 input_pin_capacitance_max;
- u8 driver_strength_support;
- __le16 t_int_r;
-- __le16 t_ald;
-- u8 reserved4[7];
-+ __le16 t_adl;
-+ u8 reserved4[8];
-
- /* vendor */
- __le16 vendor_revision;
-@@ -407,7 +427,7 @@ struct nand_jedec_params {
- __le16 input_pin_capacitance_typ;
- __le16 clk_pin_capacitance_typ;
- u8 driver_strength_support;
-- __le16 t_ald;
-+ __le16 t_adl;
- u8 reserved4[36];
-
- /* ECC and endurance block */
-@@ -444,6 +464,7 @@ struct nand_hw_control {
- /**
- * struct nand_ecc_ctrl - Control structure for ECC
- * @mode: ECC mode
-+ * @algo: ECC algorithm
- * @steps: number of ECC steps per page
- * @size: data bytes per ECC step
- * @bytes: ECC bytes per step
-@@ -451,12 +472,18 @@ struct nand_hw_control {
- * @total: total number of ECC bytes per page
- * @prepad: padding information for syndrome based ECC generators
- * @postpad: padding information for syndrome based ECC generators
-- * @layout: ECC layout control struct pointer
-+ * @options: ECC specific options (see NAND_ECC_XXX flags defined above)
- * @priv: pointer to private ECC control data
- * @hwctl: function to control hardware ECC generator. Must only
- * be provided if an hardware ECC is available
- * @calculate: function for ECC calculation or readback from ECC hardware
-- * @correct: function for ECC correction, matching to ECC generator (sw/hw)
-+ * @correct: function for ECC correction, matching to ECC generator (sw/hw).
-+ * Should return a positive number representing the number of
-+ * corrected bitflips, -EBADMSG if the number of bitflips exceed
-+ * ECC strength, or any other error code if the error is not
-+ * directly related to correction.
-+ * If -EBADMSG is returned the input buffers should be left
-+ * untouched.
- * @read_page_raw: function to read a raw page without ECC. This function
- * should hide the specific layout used by the ECC
- * controller and always return contiguous in-band and
-@@ -487,6 +514,7 @@ struct nand_hw_control {
- */
- struct nand_ecc_ctrl {
- nand_ecc_modes_t mode;
-+ enum nand_ecc_algo algo;
- int steps;
- int size;
- int bytes;
-@@ -494,7 +522,7 @@ struct nand_ecc_ctrl {
- int strength;
- int prepad;
- int postpad;
-- struct nand_ecclayout *layout;
-+ unsigned int options;
- void *priv;
- void (*hwctl)(struct mtd_info *mtd, int mode);
- int (*calculate)(struct mtd_info *mtd, const uint8_t *dat,
-@@ -540,11 +568,11 @@ struct nand_buffers {
-
- /**
- * struct nand_chip - NAND Private Flash Chip Data
-+ * @mtd: MTD device registered to the MTD framework
- * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the
- * flash device
- * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the
- * flash device.
-- * @flash_node: [BOARDSPECIFIC] device node describing this instance
- * @read_byte: [REPLACEABLE] read one byte from the chip
- * @read_word: [REPLACEABLE] read one word from the chip
- * @write_byte: [REPLACEABLE] write a single byte to the chip on the
-@@ -640,18 +668,17 @@ struct nand_buffers {
- */
-
- struct nand_chip {
-+ struct mtd_info mtd;
- void __iomem *IO_ADDR_R;
- void __iomem *IO_ADDR_W;
-
-- struct device_node *flash_node;
--
- uint8_t (*read_byte)(struct mtd_info *mtd);
- u16 (*read_word)(struct mtd_info *mtd);
- void (*write_byte)(struct mtd_info *mtd, uint8_t byte);
- void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
- void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
- void (*select_chip)(struct mtd_info *mtd, int chip);
-- int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
-+ int (*block_bad)(struct mtd_info *mtd, loff_t ofs);
- int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
- void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl);
- int (*dev_ready)(struct mtd_info *mtd);
-@@ -719,6 +746,40 @@ struct nand_chip {
- void *priv;
- };
-
-+extern const struct mtd_ooblayout_ops nand_ooblayout_sp_ops;
-+extern const struct mtd_ooblayout_ops nand_ooblayout_lp_ops;
-+
-+static inline void nand_set_flash_node(struct nand_chip *chip,
-+ struct device_node *np)
-+{
-+ mtd_set_of_node(&chip->mtd, np);
-+}
-+
-+static inline struct device_node *nand_get_flash_node(struct nand_chip *chip)
-+{
-+ return mtd_get_of_node(&chip->mtd);
-+}
-+
-+static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd)
-+{
-+ return container_of(mtd, struct nand_chip, mtd);
-+}
-+
-+static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip)
-+{
-+ return &chip->mtd;
-+}
-+
-+static inline void *nand_get_controller_data(struct nand_chip *chip)
-+{
-+ return chip->priv;
-+}
-+
-+static inline void nand_set_controller_data(struct nand_chip *chip, void *priv)
-+{
-+ chip->priv = priv;
-+}
-+
- /*
- * NAND Flash Manufacturer ID Codes
- */
-@@ -850,7 +911,6 @@ extern int nand_do_read(struct mtd_info
- * @chip_delay: R/B delay value in us
- * @options: Option flags, e.g. 16bit buswidth
- * @bbt_options: BBT option flags, e.g. NAND_BBT_USE_FLASH
-- * @ecclayout: ECC layout info structure
- * @part_probe_types: NULL-terminated array of probe types
- */
- struct platform_nand_chip {
-@@ -858,7 +918,6 @@ struct platform_nand_chip {
- int chip_offset;
- int nr_partitions;
- struct mtd_partition *partitions;
-- struct nand_ecclayout *ecclayout;
- int chip_delay;
- unsigned int options;
- unsigned int bbt_options;
-@@ -908,15 +967,6 @@ struct platform_nand_data {
- struct platform_nand_ctrl ctrl;
- };
-
--/* Some helpers to access the data structures */
--static inline
--struct platform_nand_chip *get_platform_nandchip(struct mtd_info *mtd)
--{
-- struct nand_chip *chip = mtd->priv;
--
-- return chip->priv;
--}
--
- /* return the supported features. */
- static inline int onfi_feature(struct nand_chip *chip)
- {
---- a/include/linux/mtd/nand_bch.h
-+++ b/include/linux/mtd/nand_bch.h
-@@ -32,9 +32,7 @@ int nand_bch_correct_data(struct mtd_inf
- /*
- * Initialize BCH encoder/decoder
- */
--struct nand_bch_control *
--nand_bch_init(struct mtd_info *mtd, unsigned int eccsize,
-- unsigned int eccbytes, struct nand_ecclayout **ecclayout);
-+struct nand_bch_control *nand_bch_init(struct mtd_info *mtd);
- /*
- * Release BCH encoder/decoder resources
- */
-@@ -55,12 +53,10 @@ static inline int
- nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf,
- unsigned char *read_ecc, unsigned char *calc_ecc)
- {
-- return -1;
-+ return -ENOTSUPP;
- }
-
--static inline struct nand_bch_control *
--nand_bch_init(struct mtd_info *mtd, unsigned int eccsize,
-- unsigned int eccbytes, struct nand_ecclayout **ecclayout)
-+static inline struct nand_bch_control *nand_bch_init(struct mtd_info *mtd)
- {
- return NULL;
- }
---- a/include/linux/mtd/nftl.h
-+++ b/include/linux/mtd/nftl.h
-@@ -50,7 +50,6 @@ struct NFTLrecord {
- unsigned int nb_blocks; /* number of physical blocks */
- unsigned int nb_boot_blocks; /* number of blocks used by the bios */
- struct erase_info instr;
-- struct nand_ecclayout oobinfo;
- };
-
- int NFTL_mount(struct NFTLrecord *s);
---- a/include/linux/mtd/onenand.h
-+++ b/include/linux/mtd/onenand.h
-@@ -80,7 +80,6 @@ struct onenand_bufferram {
- * @page_buf: [INTERN] page main data buffer
- * @oob_buf: [INTERN] page oob data buffer
- * @subpagesize: [INTERN] holds the subpagesize
-- * @ecclayout: [REPLACEABLE] the default ecc placement scheme
- * @bbm: [REPLACEABLE] pointer to Bad Block Management
- * @priv: [OPTIONAL] pointer to private chip date
- */
-@@ -134,7 +133,6 @@ struct onenand_chip {
- #endif
-
- int subpagesize;
-- struct nand_ecclayout *ecclayout;
-
- void *bbm;
-
---- a/include/linux/mtd/partitions.h
-+++ b/include/linux/mtd/partitions.h
-@@ -42,7 +42,6 @@ struct mtd_partition {
- uint64_t size; /* partition size */
- uint64_t offset; /* offset within the master MTD space */
- uint32_t mask_flags; /* master MTD flags to mask out for this partition */
-- struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only) */
- };
-
- #define MTDPART_OFS_RETAIN (-3)
-@@ -56,11 +55,9 @@ struct device_node;
- /**
- * struct mtd_part_parser_data - used to pass data to MTD partition parsers.
- * @origin: for RedBoot, start address of MTD device
-- * @of_node: for OF parsers, device node containing partitioning information
- */
- struct mtd_part_parser_data {
- unsigned long origin;
-- struct device_node *of_node;
- };
-
-
-@@ -78,14 +75,34 @@ struct mtd_part_parser {
- struct list_head list;
- struct module *owner;
- const char *name;
-- int (*parse_fn)(struct mtd_info *, struct mtd_partition **,
-+ int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
- struct mtd_part_parser_data *);
-+ void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
- enum mtd_parser_type type;
- };
-
--extern void register_mtd_parser(struct mtd_part_parser *parser);
-+/* Container for passing around a set of parsed partitions */
-+struct mtd_partitions {
-+ const struct mtd_partition *parts;
-+ int nr_parts;
-+ const struct mtd_part_parser *parser;
-+};
-+
-+extern int __register_mtd_parser(struct mtd_part_parser *parser,
-+ struct module *owner);
-+#define register_mtd_parser(parser) __register_mtd_parser(parser, THIS_MODULE)
-+
- extern void deregister_mtd_parser(struct mtd_part_parser *parser);
-
-+/*
-+ * module_mtd_part_parser() - Helper macro for MTD partition parsers that don't
-+ * do anything special in module init/exit. Each driver may only use this macro
-+ * once, and calling it replaces module_init() and module_exit().
-+ */
-+#define module_mtd_part_parser(__mtd_part_parser) \
-+ module_driver(__mtd_part_parser, register_mtd_parser, \
-+ deregister_mtd_parser)
-+
- int mtd_is_partition(const struct mtd_info *mtd);
- int mtd_add_partition(struct mtd_info *master, const char *name,
- long long offset, long long length);
---- a/include/linux/mtd/sh_flctl.h
-+++ b/include/linux/mtd/sh_flctl.h
-@@ -143,11 +143,11 @@ enum flctl_ecc_res_t {
- struct dma_chan;
-
- struct sh_flctl {
-- struct mtd_info mtd;
- struct nand_chip chip;
- struct platform_device *pdev;
- struct dev_pm_qos_request pm_qos;
- void __iomem *reg;
-+ resource_size_t fifo;
-
- uint8_t done_buff[2048 + 64]; /* max size 2048 + 64 */
- int read_bytes;
-@@ -186,7 +186,7 @@ struct sh_flctl_platform_data {
-
- static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo)
- {
-- return container_of(mtdinfo, struct sh_flctl, mtd);
-+ return container_of(mtd_to_nand(mtdinfo), struct sh_flctl, chip);
- }
-
- #endif /* __SH_FLCTL_H__ */
---- a/include/linux/mtd/sharpsl.h
-+++ b/include/linux/mtd/sharpsl.h
-@@ -14,7 +14,7 @@
-
- struct sharpsl_nand_platform_data {
- struct nand_bbt_descr *badblock_pattern;
-- struct nand_ecclayout *ecc_layout;
-+ const struct mtd_ooblayout_ops *ecc_layout;
- struct mtd_partition *partitions;
- unsigned int nr_partitions;
- };
---- a/include/uapi/mtd/mtd-abi.h
-+++ b/include/uapi/mtd/mtd-abi.h
-@@ -228,7 +228,7 @@ struct nand_oobfree {
- * complete set of ECC information. The ioctl truncates the larger internal
- * structure to retain binary compatibility with the static declaration of the
- * ioctl. Note that the "MTD_MAX_..._ENTRIES" macros represent the max size of
-- * the user struct, not the MAX size of the internal struct nand_ecclayout.
-+ * the user struct, not the MAX size of the internal OOB layout representation.
- */
- struct nand_ecclayout_user {
- __u32 eccbytes;
---- a/fs/jffs2/wbuf.c
-+++ b/fs/jffs2/wbuf.c
-@@ -1153,7 +1153,7 @@ static struct jffs2_sb_info *work_to_sb(
- {
- struct delayed_work *dwork;
-
-- dwork = container_of(work, struct delayed_work, work);
-+ dwork = to_delayed_work(work);
- return container_of(dwork, struct jffs2_sb_info, wbuf_dwork);
- }
-
-@@ -1183,22 +1183,20 @@ void jffs2_dirty_trigger(struct jffs2_sb
-
- int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
- {
-- struct nand_ecclayout *oinfo = c->mtd->ecclayout;
--
- if (!c->mtd->oobsize)
- return 0;
-
- /* Cleanmarker is out-of-band, so inline size zero */
- c->cleanmarker_size = 0;
-
-- if (!oinfo || oinfo->oobavail == 0) {
-+ if (c->mtd->oobavail == 0) {
- pr_err("inconsistent device description\n");
- return -EINVAL;
- }
-
- jffs2_dbg(1, "using OOB on NAND\n");
-
-- c->oobavail = oinfo->oobavail;
-+ c->oobavail = c->mtd->oobavail;
-
- /* Initialise write buffer */
- init_rwsem(&c->wbuf_sem);
---- a/include/linux/mtd/spi-nor.h
-+++ b/include/linux/mtd/spi-nor.h
-@@ -85,6 +85,7 @@
- #define SR_BP0 BIT(2) /* Block protect 0 */
- #define SR_BP1 BIT(3) /* Block protect 1 */
- #define SR_BP2 BIT(4) /* Block protect 2 */
-+#define SR_TB BIT(5) /* Top/Bottom protect */
- #define SR_SRWD BIT(7) /* SR write protect */
-
- #define SR_QUAD_EN_MX BIT(6) /* Macronix Quad I/O */
-@@ -116,6 +117,7 @@ enum spi_nor_ops {
-
- enum spi_nor_option_flags {
- SNOR_F_USE_FSR = BIT(0),
-+ SNOR_F_HAS_SR_TB = BIT(1),
- };
-
- /**
-@@ -123,7 +125,6 @@ enum spi_nor_option_flags {
- * @mtd: point to a mtd_info structure
- * @lock: the lock for the read/write/erase/lock/unlock operations
- * @dev: point to a spi device, or a spi nor controller device.
-- * @flash_node: point to a device node describing this flash instance.
- * @page_size: the page size of the SPI NOR
- * @addr_width: number of address bytes
- * @erase_opcode: the opcode for erasing a sector
-@@ -143,7 +144,8 @@ enum spi_nor_option_flags {
- * @read: [DRIVER-SPECIFIC] read data from the SPI NOR
- * @write: [DRIVER-SPECIFIC] write data to the SPI NOR
- * @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR
-- * at the offset @offs
-+ * at the offset @offs; if not provided by the driver,
-+ * spi-nor will send the erase opcode via write_reg()
- * @flash_lock: [FLASH-SPECIFIC] lock a region of the SPI NOR
- * @flash_unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR
- * @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is
-@@ -154,7 +156,6 @@ struct spi_nor {
- struct mtd_info mtd;
- struct mutex lock;
- struct device *dev;
-- struct device_node *flash_node;
- u32 page_size;
- u8 addr_width;
- u8 erase_opcode;
-@@ -184,6 +185,17 @@ struct spi_nor {
- void *priv;
- };
-
-+static inline void spi_nor_set_flash_node(struct spi_nor *nor,
-+ struct device_node *np)
-+{
-+ mtd_set_of_node(&nor->mtd, np);
-+}
-+
-+static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor)
-+{
-+ return mtd_get_of_node(&nor->mtd);
-+}
-+
- /**
- * spi_nor_scan() - scan the SPI NOR
- * @nor: the spi_nor structure
+++ /dev/null
-From 410a91f6efa1c4c3c4369d1dd2c31286749dff33 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Wed, 23 Mar 2016 11:19:01 +0100
-Subject: [PATCH 073/102] of: mtd: prepare helper reading NAND ECC algo from
- DT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-NAND subsystem is being slightly reworked to store ECC details in
-separated fields. In future we'll want to add support for more DT
-properties as specifying every possible setup with a single
-"nand-ecc-mode" is a pretty bad idea.
-To allow this let's add a helper that will support something like
-"nand-ecc-algo" in future. Right now we use it for keeping backward
-compatibility.
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
----
- drivers/of/of_mtd.c | 36 ++++++++++++++++++++++++++++++++++++
- include/linux/of_mtd.h | 6 ++++++
- 2 files changed, 42 insertions(+)
-
---- a/drivers/of/of_mtd.c
-+++ b/drivers/of/of_mtd.c
-@@ -50,6 +50,42 @@ int of_get_nand_ecc_mode(struct device_n
- EXPORT_SYMBOL_GPL(of_get_nand_ecc_mode);
-
- /**
-+ * of_get_nand_ecc_algo - Get nand ecc algorithm for given device_node
-+ * @np: Pointer to the given device_node
-+ *
-+ * The function gets ecc algorithm and returns its enum value, or errno in error
-+ * case.
-+ */
-+int of_get_nand_ecc_algo(struct device_node *np)
-+{
-+ const char *pm;
-+ int err;
-+
-+ /*
-+ * TODO: Read ECC algo OF property and map it to enum nand_ecc_algo.
-+ * It's not implemented yet as currently NAND subsystem ignores
-+ * algorithm explicitly set this way. Once it's handled we should
-+ * document & support new property.
-+ */
-+
-+ /*
-+ * For backward compatibility we also read "nand-ecc-mode" checking
-+ * for some obsoleted values that were specifying ECC algorithm.
-+ */
-+ err = of_property_read_string(np, "nand-ecc-mode", &pm);
-+ if (err < 0)
-+ return err;
-+
-+ if (!strcasecmp(pm, "soft"))
-+ return NAND_ECC_HAMMING;
-+ else if (!strcasecmp(pm, "soft_bch"))
-+ return NAND_ECC_BCH;
-+
-+ return -ENODEV;
-+}
-+EXPORT_SYMBOL_GPL(of_get_nand_ecc_algo);
-+
-+/**
- * of_get_nand_ecc_step_size - Get ECC step size associated to
- * the required ECC strength (see below).
- * @np: Pointer to the given device_node
---- a/include/linux/of_mtd.h
-+++ b/include/linux/of_mtd.h
-@@ -13,6 +13,7 @@
-
- #include <linux/of.h>
- int of_get_nand_ecc_mode(struct device_node *np);
-+int of_get_nand_ecc_algo(struct device_node *np);
- int of_get_nand_ecc_step_size(struct device_node *np);
- int of_get_nand_ecc_strength(struct device_node *np);
- int of_get_nand_bus_width(struct device_node *np);
-@@ -24,6 +25,11 @@ static inline int of_get_nand_ecc_mode(s
- {
- return -ENOSYS;
- }
-+
-+static inline int of_get_nand_ecc_algo(struct device_node *np)
-+{
-+ return -ENOSYS;
-+}
-
- static inline int of_get_nand_ecc_step_size(struct device_node *np)
- {
+++ /dev/null
-From 5e1c00983efeca4522ac2e8574e3e3997d26a203 Mon Sep 17 00:00:00 2001
-From: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
-Date: Fri, 29 Apr 2016 12:17:21 -0400
-Subject: [PATCH 074/102] mtd: mediatek: device tree docs for MTK Smart Device
- Gen1 NAND
-
-This patch adds documentation support for Smart Device Gen1 type of
-NAND controllers.
-
-Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
----
- Documentation/devicetree/bindings/mtd/mtk-nand.txt | 161 ++++++++++++++++++++
- 1 file changed, 161 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/mtd/mtk-nand.txt
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mtd/mtk-nand.txt
-@@ -0,0 +1,161 @@
-+MTK SoCs NAND FLASH controller (NFC) DT binding
-+
-+This file documents the device tree bindings for MTK SoCs NAND controllers.
-+The functional split of the controller requires two drivers to operate:
-+the nand controller interface driver and the ECC engine driver.
-+
-+The hardware description for both devices must be captured as device
-+tree nodes.
-+
-+1) NFC NAND Controller Interface (NFI):
-+=======================================
-+
-+The first part of NFC is NAND Controller Interface (NFI) HW.
-+Required NFI properties:
-+- compatible: Should be "mediatek,mtxxxx-nfc".
-+- reg: Base physical address and size of NFI.
-+- interrupts: Interrupts of NFI.
-+- clocks: NFI required clocks.
-+- clock-names: NFI clocks internal name.
-+- status: Disabled default. Then set "okay" by platform.
-+- ecc-engine: Required ECC Engine node.
-+- #address-cells: NAND chip index, should be 1.
-+- #size-cells: Should be 0.
-+
-+Example:
-+
-+ nandc: nfi@1100d000 {
-+ compatible = "mediatek,mt2701-nfc";
-+ reg = <0 0x1100d000 0 0x1000>;
-+ interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_LOW>;
-+ clocks = <&pericfg CLK_PERI_NFI>,
-+ <&pericfg CLK_PERI_NFI_PAD>;
-+ clock-names = "nfi_clk", "pad_clk";
-+ status = "disabled";
-+ ecc-engine = <&bch>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+
-+Platform related properties, should be set in {platform_name}.dts:
-+- children nodes: NAND chips.
-+
-+Children nodes properties:
-+- reg: Chip Select Signal, default 0.
-+ Set as reg = <0>, <1> when need 2 CS.
-+Optional:
-+- nand-on-flash-bbt: Store BBT on NAND Flash.
-+- nand-ecc-mode: the NAND ecc mode (check driver for supported modes)
-+- nand-ecc-step-size: Number of data bytes covered by a single ECC step.
-+ The controller only supports 512 and 1024.
-+ For large page NANDs ther recommended value is 1024.
-+- nand-ecc-strength: Number of bits to correct per ECC step.
-+ The valid values that the controller supports are: 4, 6,
-+ 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 40, 44,
-+ 48, 52, 56, 60.
-+ The strength should be calculated as follows:
-+ E = (S - F) * 8 / 14
-+ S = O / (P / Q)
-+ E :nand-ecc-strength;
-+ S :spare size per sector;
-+ F : FDM size, should be in the range [1,8].
-+ It is used to store free oob data.
-+ O : oob size;
-+ P : page size;
-+ Q :nand-ecc-step-size
-+ If the result does not match any one of the listed
-+ choices above, please select the smaller valid value from
-+ the list.
-+ (otherwise the driver will do the clamping at runtime).
-+- vmch-supply: NAND power supply.
-+- pinctrl-names: Default NAND pin GPIO setting name.
-+- pinctrl-0: GPIO setting node.
-+
-+Example:
-+ &pio {
-+ nand_pins_default: nanddefault {
-+ pins_dat {
-+ pinmux = <MT2701_PIN_111_MSDC0_DAT7__FUNC_NLD7>,
-+ <MT2701_PIN_112_MSDC0_DAT6__FUNC_NLD6>,
-+ <MT2701_PIN_114_MSDC0_DAT4__FUNC_NLD4>,
-+ <MT2701_PIN_118_MSDC0_DAT3__FUNC_NLD3>,
-+ <MT2701_PIN_121_MSDC0_DAT0__FUNC_NLD0>,
-+ <MT2701_PIN_120_MSDC0_DAT1__FUNC_NLD1>,
-+ <MT2701_PIN_113_MSDC0_DAT5__FUNC_NLD5>,
-+ <MT2701_PIN_115_MSDC0_RSTB__FUNC_NLD8>,
-+ <MT2701_PIN_119_MSDC0_DAT2__FUNC_NLD2>;
-+ input-enable;
-+ drive-strength = <MTK_DRIVE_8mA>;
-+ bias-pull-up;
-+ };
-+
-+ pins_we {
-+ pinmux = <MT2701_PIN_117_MSDC0_CLK__FUNC_NWEB>;
-+ drive-strength = <MTK_DRIVE_8mA>;
-+ bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
-+ };
-+
-+ pins_ale {
-+ pinmux = <MT2701_PIN_116_MSDC0_CMD__FUNC_NALE>;
-+ drive-strength = <MTK_DRIVE_8mA>;
-+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
-+ };
-+ };
-+ };
-+
-+ &nandc {
-+ status = "okay";
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&nand_pins_default>;
-+ nand@0 {
-+ reg = <0>;
-+ nand-on-flash-bbt;
-+ nand-ecc-mode = "hw";
-+ nand-ecc-strength = <24>;
-+ nand-ecc-step-size = <1024>;
-+ };
-+ };
-+
-+NAND chip optional subnodes:
-+- Partitions, see Documentation/devicetree/bindings/mtd/partition.txt
-+
-+Example:
-+ nand@0 {
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ preloader@0 {
-+ label = "pl";
-+ read-only;
-+ reg = <0x00000000 0x00400000>;
-+ };
-+ android@0x00400000 {
-+ label = "android";
-+ reg = <0x00400000 0x12c00000>;
-+ };
-+ };
-+ };
-+
-+2) ECC Engine:
-+==============
-+
-+Required BCH properties:
-+- compatible: Should be "mediatek,mtxxxx-ecc".
-+- reg: Base physical address and size of ECC.
-+- interrupts: Interrupts of ECC.
-+- clocks: ECC required clocks.
-+- clock-names: ECC clocks internal name.
-+- status: Disabled default. Then set "okay" by platform.
-+
-+Example:
-+
-+ bch: ecc@1100e000 {
-+ compatible = "mediatek,mt2701-ecc";
-+ reg = <0 0x1100e000 0 0x1000>;
-+ interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_LOW>;
-+ clocks = <&pericfg CLK_PERI_NFI_ECC>;
-+ clock-names = "nfiecc_clk";
-+ status = "disabled";
-+ };
+++ /dev/null
-From de18239fc971cfc17c53320c66ae64dd5ade032d Mon Sep 17 00:00:00 2001
-From: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
-Date: Fri, 29 Apr 2016 12:17:22 -0400
-Subject: [PATCH 075/102] mtd: mediatek: driver for MTK Smart Device Gen1 NAND
-
-This patch adds support for mediatek's SDG1 NFC nand controller
-embedded in SoC 2701
-
-Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
----
- drivers/mtd/nand/Kconfig | 7 +
- drivers/mtd/nand/Makefile | 1 +
- drivers/mtd/nand/mtk_ecc.c | 527 ++++++++++++++++
- drivers/mtd/nand/mtk_ecc.h | 53 ++
- drivers/mtd/nand/mtk_nand.c | 1432 +++++++++++++++++++++++++++++++++++++++++++
- 5 files changed, 2020 insertions(+)
- create mode 100644 drivers/mtd/nand/mtk_ecc.c
- create mode 100644 drivers/mtd/nand/mtk_ecc.h
- create mode 100644 drivers/mtd/nand/mtk_nand.c
-
---- a/drivers/mtd/nand/Kconfig
-+++ b/drivers/mtd/nand/Kconfig
-@@ -563,4 +563,11 @@ config MTD_NAND_QCOM
- Enables support for NAND flash chips on SoCs containing the EBI2 NAND
- controller. This controller is found on IPQ806x SoC.
-
-+config MTD_NAND_MTK
-+ tristate "Support for NAND controller on MTK SoCs"
-+ depends on HAS_DMA
-+ help
-+ Enables support for NAND controller on MTK SoCs.
-+ This controller is found on mt27xx, mt81xx, mt65xx SoCs.
-+
- endif # MTD_NAND
---- a/drivers/mtd/nand/Makefile
-+++ b/drivers/mtd/nand/Makefile
-@@ -57,5 +57,6 @@ obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_n
- obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o
- obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/
- obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o
-+obj-$(CONFIG_MTD_NAND_MTK) += mtk_nand.o mtk_ecc.o
-
- nand-objs := nand_base.o nand_bbt.o nand_timings.o
---- /dev/null
-+++ b/drivers/mtd/nand/mtk_ecc.c
-@@ -0,0 +1,527 @@
-+/*
-+ * MTK ECC controller driver.
-+ * Copyright (C) 2016 MediaTek Inc.
-+ * Authors: Xiaolei Li <xiaolei.li@mediatek.com>
-+ * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.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 <linux/platform_device.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/interrupt.h>
-+#include <linux/clk.h>
-+#include <linux/module.h>
-+#include <linux/iopoll.h>
-+#include <linux/of.h>
-+#include <linux/of_platform.h>
-+#include <linux/semaphore.h>
-+
-+#include "mtk_ecc.h"
-+
-+#define ECC_ENCCON (0x00)
-+#define ENC_EN (1)
-+#define ENC_DE (0)
-+#define ECC_ENCCNFG (0x04)
-+#define ECC_CNFG_4BIT (0)
-+#define ECC_CNFG_6BIT (1)
-+#define ECC_CNFG_8BIT (2)
-+#define ECC_CNFG_10BIT (3)
-+#define ECC_CNFG_12BIT (4)
-+#define ECC_CNFG_14BIT (5)
-+#define ECC_CNFG_16BIT (6)
-+#define ECC_CNFG_18BIT (7)
-+#define ECC_CNFG_20BIT (8)
-+#define ECC_CNFG_22BIT (9)
-+#define ECC_CNFG_24BIT (0xa)
-+#define ECC_CNFG_28BIT (0xb)
-+#define ECC_CNFG_32BIT (0xc)
-+#define ECC_CNFG_36BIT (0xd)
-+#define ECC_CNFG_40BIT (0xe)
-+#define ECC_CNFG_44BIT (0xf)
-+#define ECC_CNFG_48BIT (0x10)
-+#define ECC_CNFG_52BIT (0x11)
-+#define ECC_CNFG_56BIT (0x12)
-+#define ECC_CNFG_60BIT (0x13)
-+#define ECC_MODE_SHIFT (5)
-+#define ECC_MS_SHIFT (16)
-+#define ECC_ENCDIADDR (0x08)
-+#define ECC_ENCIDLE (0x0C)
-+#define ENC_IDLE BIT(0)
-+#define ECC_ENCPAR(x) (0x10 + (x) * sizeof(u32))
-+#define ECC_ENCIRQ_EN (0x80)
-+#define ENC_IRQEN BIT(0)
-+#define ECC_ENCIRQ_STA (0x84)
-+#define ECC_DECCON (0x100)
-+#define DEC_EN (1)
-+#define DEC_DE (0)
-+#define ECC_DECCNFG (0x104)
-+#define DEC_EMPTY_EN BIT(31)
-+#define DEC_CNFG_CORRECT (0x3 << 12)
-+#define ECC_DECIDLE (0x10C)
-+#define DEC_IDLE BIT(0)
-+#define ECC_DECENUM0 (0x114)
-+#define ERR_MASK (0x3f)
-+#define ECC_DECDONE (0x124)
-+#define ECC_DECIRQ_EN (0x200)
-+#define DEC_IRQEN BIT(0)
-+#define ECC_DECIRQ_STA (0x204)
-+
-+#define ECC_TIMEOUT (500000)
-+
-+#define ECC_IDLE_REG(x) ((x) == ECC_ENC ? ECC_ENCIDLE : ECC_DECIDLE)
-+#define ECC_IDLE_MASK(x) ((x) == ECC_ENC ? ENC_IDLE : DEC_IDLE)
-+#define ECC_IRQ_REG(x) ((x) == ECC_ENC ? ECC_ENCIRQ_EN : ECC_DECIRQ_EN)
-+#define ECC_IRQ_EN(x) ((x) == ECC_ENC ? ENC_IRQEN : DEC_IRQEN)
-+#define ECC_CTL_REG(x) ((x) == ECC_ENC ? ECC_ENCCON : ECC_DECCON)
-+#define ECC_CODEC_ENABLE(x) ((x) == ECC_ENC ? ENC_EN : DEC_EN)
-+#define ECC_CODEC_DISABLE(x) ((x) == ECC_ENC ? ENC_DE : DEC_DE)
-+
-+struct mtk_ecc {
-+ struct device *dev;
-+ void __iomem *regs;
-+ struct clk *clk;
-+
-+ struct completion done;
-+ struct semaphore sem;
-+ u32 sec_mask;
-+};
-+
-+static inline void mtk_ecc_codec_wait_idle(struct mtk_ecc *ecc,
-+ enum mtk_ecc_codec codec)
-+{
-+ struct device *dev = ecc->dev;
-+ u32 val;
-+ int ret;
-+
-+ ret = readl_poll_timeout_atomic(ecc->regs + ECC_IDLE_REG(codec), val,
-+ val & ECC_IDLE_MASK(codec),
-+ 10, ECC_TIMEOUT);
-+ if (ret)
-+ dev_warn(dev, "%s NOT idle\n",
-+ codec == ECC_ENC ? "encoder" : "decoder");
-+}
-+
-+static irqreturn_t mtk_ecc_irq(int irq, void *id)
-+{
-+ struct mtk_ecc *ecc = id;
-+ enum mtk_ecc_codec codec;
-+ u32 dec, enc;
-+
-+ dec = readw(ecc->regs + ECC_DECIRQ_STA) & DEC_IRQEN;
-+ if (dec) {
-+ codec = ECC_DEC;
-+ dec = readw(ecc->regs + ECC_DECDONE);
-+ if (dec & ecc->sec_mask) {
-+ ecc->sec_mask = 0;
-+ complete(&ecc->done);
-+ } else
-+ return IRQ_HANDLED;
-+ } else {
-+ enc = readl(ecc->regs + ECC_ENCIRQ_STA) & ENC_IRQEN;
-+ if (enc) {
-+ codec = ECC_ENC;
-+ complete(&ecc->done);
-+ } else
-+ return IRQ_NONE;
-+ }
-+
-+ writel(0, ecc->regs + ECC_IRQ_REG(codec));
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static void mtk_ecc_config(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
-+{
-+ u32 ecc_bit = ECC_CNFG_4BIT, dec_sz, enc_sz;
-+ u32 reg;
-+
-+ switch (config->strength) {
-+ case 4:
-+ ecc_bit = ECC_CNFG_4BIT;
-+ break;
-+ case 6:
-+ ecc_bit = ECC_CNFG_6BIT;
-+ break;
-+ case 8:
-+ ecc_bit = ECC_CNFG_8BIT;
-+ break;
-+ case 10:
-+ ecc_bit = ECC_CNFG_10BIT;
-+ break;
-+ case 12:
-+ ecc_bit = ECC_CNFG_12BIT;
-+ break;
-+ case 14:
-+ ecc_bit = ECC_CNFG_14BIT;
-+ break;
-+ case 16:
-+ ecc_bit = ECC_CNFG_16BIT;
-+ break;
-+ case 18:
-+ ecc_bit = ECC_CNFG_18BIT;
-+ break;
-+ case 20:
-+ ecc_bit = ECC_CNFG_20BIT;
-+ break;
-+ case 22:
-+ ecc_bit = ECC_CNFG_22BIT;
-+ break;
-+ case 24:
-+ ecc_bit = ECC_CNFG_24BIT;
-+ break;
-+ case 28:
-+ ecc_bit = ECC_CNFG_28BIT;
-+ break;
-+ case 32:
-+ ecc_bit = ECC_CNFG_32BIT;
-+ break;
-+ case 36:
-+ ecc_bit = ECC_CNFG_36BIT;
-+ break;
-+ case 40:
-+ ecc_bit = ECC_CNFG_40BIT;
-+ break;
-+ case 44:
-+ ecc_bit = ECC_CNFG_44BIT;
-+ break;
-+ case 48:
-+ ecc_bit = ECC_CNFG_48BIT;
-+ break;
-+ case 52:
-+ ecc_bit = ECC_CNFG_52BIT;
-+ break;
-+ case 56:
-+ ecc_bit = ECC_CNFG_56BIT;
-+ break;
-+ case 60:
-+ ecc_bit = ECC_CNFG_60BIT;
-+ break;
-+ default:
-+ dev_err(ecc->dev, "invalid strength %d\n", config->strength);
-+ }
-+
-+ if (config->codec == ECC_ENC) {
-+ /* configure ECC encoder (in bits) */
-+ enc_sz = config->enc_len << 3;
-+
-+ reg = ecc_bit | (config->ecc_mode << ECC_MODE_SHIFT);
-+ reg |= (enc_sz << ECC_MS_SHIFT);
-+ writel(reg, ecc->regs + ECC_ENCCNFG);
-+
-+ if (config->ecc_mode != ECC_NFI_MODE)
-+ writel(lower_32_bits(config->addr),
-+ ecc->regs + ECC_ENCDIADDR);
-+
-+ } else {
-+ /* configure ECC decoder (in bits) */
-+ dec_sz = config->dec_len;
-+
-+ reg = ecc_bit | (config->ecc_mode << ECC_MODE_SHIFT);
-+ reg |= (dec_sz << ECC_MS_SHIFT) | DEC_CNFG_CORRECT;
-+ reg |= DEC_EMPTY_EN;
-+ writel(reg, ecc->regs + ECC_DECCNFG);
-+
-+ if (config->sec_mask)
-+ ecc->sec_mask = 1 << (config->sec_mask - 1);
-+ }
-+}
-+
-+void mtk_ecc_get_stats(struct mtk_ecc *ecc, struct mtk_ecc_stats *stats,
-+ int sectors)
-+{
-+ u32 offset, i, err;
-+ u32 bitflips = 0;
-+
-+ stats->corrected = 0;
-+ stats->failed = 0;
-+
-+ for (i = 0; i < sectors; i++) {
-+ offset = (i >> 2) << 2;
-+ err = readl(ecc->regs + ECC_DECENUM0 + offset);
-+ err = err >> ((i % 4) * 8);
-+ err &= ERR_MASK;
-+ if (err == ERR_MASK) {
-+ /* uncorrectable errors */
-+ stats->failed++;
-+ continue;
-+ }
-+
-+ stats->corrected += err;
-+ bitflips = max_t(u32, bitflips, err);
-+ }
-+
-+ stats->bitflips = bitflips;
-+}
-+EXPORT_SYMBOL(mtk_ecc_get_stats);
-+
-+void mtk_ecc_release(struct mtk_ecc *ecc)
-+{
-+ clk_disable_unprepare(ecc->clk);
-+ put_device(ecc->dev);
-+}
-+EXPORT_SYMBOL(mtk_ecc_release);
-+
-+static struct mtk_ecc *mtk_ecc_get(struct device_node *np)
-+{
-+ struct platform_device *pdev;
-+ struct mtk_ecc *ecc;
-+
-+ pdev = of_find_device_by_node(np);
-+ if (!pdev || !platform_get_drvdata(pdev))
-+ return ERR_PTR(-EPROBE_DEFER);
-+
-+ get_device(&pdev->dev);
-+ ecc = platform_get_drvdata(pdev);
-+ clk_prepare_enable(ecc->clk);
-+ mtk_ecc_hw_init(ecc);
-+
-+ return ecc;
-+}
-+
-+struct mtk_ecc *of_mtk_ecc_get(struct device_node *of_node)
-+{
-+ struct mtk_ecc *ecc = NULL;
-+ struct device_node *np;
-+
-+ np = of_parse_phandle(of_node, "ecc-engine", 0);
-+ if (np) {
-+ ecc = mtk_ecc_get(np);
-+ of_node_put(np);
-+ }
-+
-+ return ecc;
-+}
-+EXPORT_SYMBOL(of_mtk_ecc_get);
-+
-+int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
-+{
-+ enum mtk_ecc_codec codec = config->codec;
-+ int ret;
-+
-+ ret = down_interruptible(&ecc->sem);
-+ if (ret) {
-+ dev_err(ecc->dev, "interrupted when attempting to lock\n");
-+ return ret;
-+ }
-+
-+ mtk_ecc_codec_wait_idle(ecc, codec);
-+ mtk_ecc_config(ecc, config);
-+ writew(ECC_CODEC_ENABLE(codec), ecc->regs + ECC_CTL_REG(codec));
-+
-+ init_completion(&ecc->done);
-+ writew(ECC_IRQ_EN(codec), ecc->regs + ECC_IRQ_REG(codec));
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(mtk_ecc_enable);
-+
-+void mtk_ecc_disable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
-+{
-+ enum mtk_ecc_codec codec = config->codec;
-+
-+ mtk_ecc_codec_wait_idle(ecc, codec);
-+ writew(0, ecc->regs + ECC_IRQ_REG(codec));
-+ writew(ECC_CODEC_DISABLE(codec), ecc->regs + ECC_CTL_REG(codec));
-+ up(&ecc->sem);
-+}
-+EXPORT_SYMBOL(mtk_ecc_disable);
-+
-+int mtk_ecc_wait_irq_done(struct mtk_ecc *ecc, enum mtk_ecc_codec codec)
-+{
-+ int ret;
-+
-+ ret = wait_for_completion_timeout(&ecc->done, msecs_to_jiffies(500));
-+ if (!ret) {
-+ dev_err(ecc->dev, "%s timeout - interrupt did not arrive)\n",
-+ (codec == ECC_ENC) ? "encoder" : "decoder");
-+ return -ETIMEDOUT;
-+ }
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(mtk_ecc_wait_irq_done);
-+
-+int mtk_ecc_encode_non_nfi_mode(struct mtk_ecc *ecc,
-+ struct mtk_ecc_config *config, u8 *data, u32 bytes)
-+{
-+ dma_addr_t addr;
-+ u32 *p, len, i;
-+ int ret = 0;
-+
-+ addr = dma_map_single(ecc->dev, data, bytes, DMA_TO_DEVICE);
-+ ret = dma_mapping_error(ecc->dev, addr);
-+ if (ret) {
-+ dev_err(ecc->dev, "dma mapping error\n");
-+ return -EINVAL;
-+ }
-+
-+ config->codec = ECC_ENC;
-+ config->addr = addr;
-+ ret = mtk_ecc_enable(ecc, config);
-+ if (ret) {
-+ dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE);
-+ return ret;
-+ }
-+
-+ ret = mtk_ecc_wait_irq_done(ecc, ECC_ENC);
-+ if (ret)
-+ goto timeout;
-+
-+ mtk_ecc_codec_wait_idle(ecc, ECC_ENC);
-+
-+ /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
-+ len = (config->strength * ECC_PARITY_BITS + 7) >> 3;
-+ p = (u32 *) (data + bytes);
-+
-+ /* write the parity bytes generated by the ECC back to the OOB region */
-+ for (i = 0; i < len; i++)
-+ p[i] = readl(ecc->regs + ECC_ENCPAR(i));
-+timeout:
-+
-+ dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE);
-+ mtk_ecc_disable(ecc, config);
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL(mtk_ecc_encode_non_nfi_mode);
-+
-+void mtk_ecc_hw_init(struct mtk_ecc *ecc)
-+{
-+ mtk_ecc_codec_wait_idle(ecc, ECC_ENC);
-+ writew(ENC_DE, ecc->regs + ECC_ENCCON);
-+
-+ mtk_ecc_codec_wait_idle(ecc, ECC_DEC);
-+ writel(DEC_DE, ecc->regs + ECC_DECCON);
-+}
-+
-+void mtk_ecc_update_strength(u32 *p)
-+{
-+ u32 ecc[] = {4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36,
-+ 40, 44, 48, 52, 56, 60};
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(ecc); i++) {
-+ if (*p <= ecc[i]) {
-+ if (!i)
-+ *p = ecc[i];
-+ else if (*p != ecc[i])
-+ *p = ecc[i - 1];
-+ return;
-+ }
-+ }
-+
-+ *p = ecc[ARRAY_SIZE(ecc) - 1];
-+}
-+EXPORT_SYMBOL(mtk_ecc_update_strength);
-+
-+static int mtk_ecc_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct mtk_ecc *ecc;
-+ struct resource *res;
-+ int irq, ret;
-+
-+ ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL);
-+ if (!ecc)
-+ return -ENOMEM;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ ecc->regs = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(ecc->regs)) {
-+ dev_err(dev, "failed to map regs: %ld\n", PTR_ERR(ecc->regs));
-+ return PTR_ERR(ecc->regs);
-+ }
-+
-+ ecc->clk = devm_clk_get(dev, NULL);
-+ if (IS_ERR(ecc->clk)) {
-+ dev_err(dev, "failed to get clock: %ld\n", PTR_ERR(ecc->clk));
-+ return PTR_ERR(ecc->clk);
-+ }
-+
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq < 0) {
-+ dev_err(dev, "failed to get irq\n");
-+ return -EINVAL;
-+ }
-+
-+ ret = dma_set_mask(dev, DMA_BIT_MASK(32));
-+ if (ret) {
-+ dev_err(dev, "failed to set DMA mask\n");
-+ return ret;
-+ }
-+
-+ ret = devm_request_irq(dev, irq, mtk_ecc_irq, 0x0, "mtk-ecc", ecc);
-+ if (ret) {
-+ dev_err(dev, "failed to request irq\n");
-+ return -EINVAL;
-+ }
-+
-+ ecc->dev = dev;
-+ sema_init(&ecc->sem, 1);
-+ platform_set_drvdata(pdev, ecc);
-+ dev_info(dev, "probed\n");
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM_SLEEP
-+static int mtk_ecc_suspend(struct device *dev)
-+{
-+ struct mtk_ecc *ecc = dev_get_drvdata(dev);
-+
-+ clk_disable_unprepare(ecc->clk);
-+
-+ return 0;
-+}
-+
-+static int mtk_ecc_resume(struct device *dev)
-+{
-+ struct mtk_ecc *ecc = dev_get_drvdata(dev);
-+ int ret;
-+
-+ ret = clk_prepare_enable(ecc->clk);
-+ if (ret) {
-+ dev_err(dev, "failed to enable clk\n");
-+ return ret;
-+ }
-+
-+ mtk_ecc_hw_init(ecc);
-+
-+ return 0;
-+}
-+
-+static SIMPLE_DEV_PM_OPS(mtk_ecc_pm_ops, mtk_ecc_suspend, mtk_ecc_resume);
-+#endif
-+
-+static const struct of_device_id mtk_ecc_dt_match[] = {
-+ { .compatible = "mediatek,mt2701-ecc" },
-+ {},
-+};
-+
-+MODULE_DEVICE_TABLE(of, mtk_ecc_dt_match);
-+
-+static struct platform_driver mtk_ecc_driver = {
-+ .probe = mtk_ecc_probe,
-+ .driver = {
-+ .name = "mtk-ecc",
-+ .of_match_table = of_match_ptr(mtk_ecc_dt_match),
-+#ifdef CONFIG_PM_SLEEP
-+ .pm = &mtk_ecc_pm_ops,
-+#endif
-+ },
-+};
-+
-+module_platform_driver(mtk_ecc_driver);
-+
-+MODULE_AUTHOR("Xiaolei Li <xiaolei.li@mediatek.com>");
-+MODULE_AUTHOR("Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>");
-+MODULE_DESCRIPTION("MTK Nand ECC Driver");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/mtd/nand/mtk_ecc.h
-@@ -0,0 +1,53 @@
-+/*
-+ * MTK SDG1 ECC controller
-+ *
-+ * Copyright (c) 2016 Mediatek
-+ * Authors: Xiaolei Li <xiaolei.li@mediatek.com>
-+ * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.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.
-+ */
-+
-+#ifndef __DRIVERS_MTD_NAND_MTK_ECC_H__
-+#define __DRIVERS_MTD_NAND_MTK_ECC_H__
-+
-+#include <linux/types.h>
-+
-+#define ECC_PARITY_BITS (14)
-+
-+enum mtk_ecc_mode {ECC_DMA_MODE = 0, ECC_NFI_MODE = 1};
-+enum mtk_ecc_codec {ECC_ENC, ECC_DEC};
-+
-+struct device_node;
-+struct mtk_ecc;
-+
-+struct mtk_ecc_stats {
-+ u32 corrected;
-+ u32 bitflips;
-+ u32 failed;
-+};
-+
-+struct mtk_ecc_config {
-+ enum mtk_ecc_mode ecc_mode;
-+ enum mtk_ecc_codec codec;
-+ dma_addr_t addr;
-+ u32 sec_mask;
-+ u32 strength;
-+ u32 enc_len;
-+ u32 dec_len;
-+};
-+
-+int mtk_ecc_enable(struct mtk_ecc *, struct mtk_ecc_config *);
-+void mtk_ecc_disable(struct mtk_ecc *, struct mtk_ecc_config *);
-+int mtk_ecc_encode_non_nfi_mode(struct mtk_ecc *, struct mtk_ecc_config *,
-+ u8 *, u32);
-+void mtk_ecc_get_stats(struct mtk_ecc *, struct mtk_ecc_stats *, int);
-+int mtk_ecc_wait_irq_done(struct mtk_ecc *, enum mtk_ecc_codec);
-+void mtk_ecc_hw_init(struct mtk_ecc *);
-+void mtk_ecc_update_strength(u32 *);
-+
-+struct mtk_ecc *of_mtk_ecc_get(struct device_node *);
-+void mtk_ecc_release(struct mtk_ecc *);
-+
-+#endif
---- /dev/null
-+++ b/drivers/mtd/nand/mtk_nand.c
-@@ -0,0 +1,1432 @@
-+/*
-+ * MTK NAND Flash controller driver.
-+ * Copyright (C) 2016 MediaTek Inc.
-+ * Authors: Xiaolei Li <xiaolei.li@mediatek.com>
-+ * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.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 <linux/platform_device.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/interrupt.h>
-+#include <linux/delay.h>
-+#include <linux/clk.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/module.h>
-+#include <linux/iopoll.h>
-+#include <linux/of.h>
-+#include "mtk_ecc.h"
-+
-+/* NAND controller register definition */
-+#define NFI_CNFG (0x00)
-+#define CNFG_AHB BIT(0)
-+#define CNFG_READ_EN BIT(1)
-+#define CNFG_DMA_BURST_EN BIT(2)
-+#define CNFG_BYTE_RW BIT(6)
-+#define CNFG_HW_ECC_EN BIT(8)
-+#define CNFG_AUTO_FMT_EN BIT(9)
-+#define CNFG_OP_CUST (6 << 12)
-+#define NFI_PAGEFMT (0x04)
-+#define PAGEFMT_FDM_ECC_SHIFT (12)
-+#define PAGEFMT_FDM_SHIFT (8)
-+#define PAGEFMT_SPARE_16 (0)
-+#define PAGEFMT_SPARE_26 (1)
-+#define PAGEFMT_SPARE_27 (2)
-+#define PAGEFMT_SPARE_28 (3)
-+#define PAGEFMT_SPARE_32 (4)
-+#define PAGEFMT_SPARE_36 (5)
-+#define PAGEFMT_SPARE_40 (6)
-+#define PAGEFMT_SPARE_44 (7)
-+#define PAGEFMT_SPARE_48 (8)
-+#define PAGEFMT_SPARE_49 (9)
-+#define PAGEFMT_SPARE_50 (0xa)
-+#define PAGEFMT_SPARE_51 (0xb)
-+#define PAGEFMT_SPARE_52 (0xc)
-+#define PAGEFMT_SPARE_62 (0xd)
-+#define PAGEFMT_SPARE_63 (0xe)
-+#define PAGEFMT_SPARE_64 (0xf)
-+#define PAGEFMT_SPARE_SHIFT (4)
-+#define PAGEFMT_SEC_SEL_512 BIT(2)
-+#define PAGEFMT_512_2K (0)
-+#define PAGEFMT_2K_4K (1)
-+#define PAGEFMT_4K_8K (2)
-+#define PAGEFMT_8K_16K (3)
-+/* NFI control */
-+#define NFI_CON (0x08)
-+#define CON_FIFO_FLUSH BIT(0)
-+#define CON_NFI_RST BIT(1)
-+#define CON_BRD BIT(8) /* burst read */
-+#define CON_BWR BIT(9) /* burst write */
-+#define CON_SEC_SHIFT (12)
-+/* Timming control register */
-+#define NFI_ACCCON (0x0C)
-+#define NFI_INTR_EN (0x10)
-+#define INTR_AHB_DONE_EN BIT(6)
-+#define NFI_INTR_STA (0x14)
-+#define NFI_CMD (0x20)
-+#define NFI_ADDRNOB (0x30)
-+#define NFI_COLADDR (0x34)
-+#define NFI_ROWADDR (0x38)
-+#define NFI_STRDATA (0x40)
-+#define STAR_EN (1)
-+#define STAR_DE (0)
-+#define NFI_CNRNB (0x44)
-+#define NFI_DATAW (0x50)
-+#define NFI_DATAR (0x54)
-+#define NFI_PIO_DIRDY (0x58)
-+#define PIO_DI_RDY (0x01)
-+#define NFI_STA (0x60)
-+#define STA_CMD BIT(0)
-+#define STA_ADDR BIT(1)
-+#define STA_BUSY BIT(8)
-+#define STA_EMP_PAGE BIT(12)
-+#define NFI_FSM_CUSTDATA (0xe << 16)
-+#define NFI_FSM_MASK (0xf << 16)
-+#define NFI_ADDRCNTR (0x70)
-+#define CNTR_MASK GENMASK(16, 12)
-+#define NFI_STRADDR (0x80)
-+#define NFI_BYTELEN (0x84)
-+#define NFI_CSEL (0x90)
-+#define NFI_FDML(x) (0xA0 + (x) * sizeof(u32) * 2)
-+#define NFI_FDMM(x) (0xA4 + (x) * sizeof(u32) * 2)
-+#define NFI_FDM_MAX_SIZE (8)
-+#define NFI_MASTER_STA (0x224)
-+#define MASTER_STA_MASK (0x0FFF)
-+#define NFI_EMPTY_THRESH (0x23C)
-+
-+#define MTK_NAME "mtk-nand"
-+#define KB(x) ((x) * 1024UL)
-+#define MB(x) (KB(x) * 1024UL)
-+
-+#define MTK_TIMEOUT (500000)
-+#define MTK_RESET_TIMEOUT (1000000)
-+#define MTK_MAX_SECTOR (16)
-+#define MTK_NAND_MAX_NSELS (2)
-+
-+typedef void (*bad_mark_swap)(struct mtd_info *, uint8_t *buf, int raw);
-+struct mtk_nfc_bad_mark_ctl {
-+ bad_mark_swap bm_swap;
-+ u32 sec;
-+ u32 pos;
-+};
-+
-+/*
-+ * FDM: region used to store free OOB data
-+ */
-+struct mtk_nfc_fdm {
-+ u32 reg_size;
-+ u32 ecc_size;
-+};
-+
-+struct mtk_nfc_nand_chip {
-+ struct list_head node;
-+ struct nand_chip nand;
-+
-+ struct mtk_nfc_bad_mark_ctl bad_mark;
-+ struct mtk_nfc_fdm fdm;
-+ u32 spare_per_sector;
-+
-+ int nsels;
-+ u8 sels[0];
-+ /* nothing after this field */
-+};
-+
-+struct mtk_nfc_clk {
-+ struct clk *nfi_clk;
-+ struct clk *pad_clk;
-+};
-+
-+struct mtk_nfc {
-+ struct nand_hw_control controller;
-+ struct mtk_ecc_config ecc_cfg;
-+ struct mtk_nfc_clk clk;
-+ struct mtk_ecc *ecc;
-+
-+ struct device *dev;
-+ void __iomem *regs;
-+
-+ struct completion done;
-+ struct list_head chips;
-+
-+ u8 *buffer;
-+};
-+
-+static inline struct mtk_nfc_nand_chip *to_mtk_nand(struct nand_chip *nand)
-+{
-+ return container_of(nand, struct mtk_nfc_nand_chip, nand);
-+}
-+
-+static inline uint8_t *data_ptr(struct nand_chip *chip, const uint8_t *p, int i)
-+{
-+ return (uint8_t *) p + i * chip->ecc.size;
-+}
-+
-+static inline uint8_t *oob_ptr(struct nand_chip *chip, int i)
-+{
-+ struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
-+ uint8_t *poi;
-+
-+ if (i < mtk_nand->bad_mark.sec)
-+ poi = chip->oob_poi + (i + 1) * mtk_nand->fdm.reg_size;
-+ else if (i == mtk_nand->bad_mark.sec)
-+ poi = chip->oob_poi;
-+ else
-+ poi = chip->oob_poi + i * mtk_nand->fdm.reg_size;
-+
-+ return poi;
-+}
-+
-+static inline int mtk_data_len(struct nand_chip *chip)
-+{
-+ struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
-+
-+ return chip->ecc.size + mtk_nand->spare_per_sector;
-+}
-+
-+static inline uint8_t *mtk_data_ptr(struct nand_chip *chip, int i)
-+{
-+ struct mtk_nfc *nfc = nand_get_controller_data(chip);
-+
-+ return nfc->buffer + i * mtk_data_len(chip);
-+}
-+
-+static inline uint8_t *mtk_oob_ptr(struct nand_chip *chip, int i)
-+{
-+ struct mtk_nfc *nfc = nand_get_controller_data(chip);
-+
-+ return nfc->buffer + i * mtk_data_len(chip) + chip->ecc.size;
-+}
-+
-+static inline void nfi_writel(struct mtk_nfc *nfc, u32 val, u32 reg)
-+{
-+ writel(val, nfc->regs + reg);
-+}
-+
-+static inline void nfi_writew(struct mtk_nfc *nfc, u16 val, u32 reg)
-+{
-+ writew(val, nfc->regs + reg);
-+}
-+
-+static inline void nfi_writeb(struct mtk_nfc *nfc, u8 val, u32 reg)
-+{
-+ writeb(val, nfc->regs + reg);
-+}
-+
-+static inline u32 nfi_readl(struct mtk_nfc *nfc, u32 reg)
-+{
-+ return readl_relaxed(nfc->regs + reg);
-+}
-+
-+static inline u16 nfi_readw(struct mtk_nfc *nfc, u32 reg)
-+{
-+ return readw_relaxed(nfc->regs + reg);
-+}
-+
-+static inline u8 nfi_readb(struct mtk_nfc *nfc, u32 reg)
-+{
-+ return readb_relaxed(nfc->regs + reg);
-+}
-+
-+static void mtk_nfc_hw_reset(struct mtk_nfc *nfc)
-+{
-+ struct device *dev = nfc->dev;
-+ u32 val;
-+ int ret;
-+
-+ /* reset all registers and force the NFI master to terminate */
-+ nfi_writel(nfc, CON_FIFO_FLUSH | CON_NFI_RST, NFI_CON);
-+
-+ /* wait for the master to finish the last transaction */
-+ ret = readl_poll_timeout(nfc->regs + NFI_MASTER_STA, val,
-+ !(val & MASTER_STA_MASK), 50, MTK_RESET_TIMEOUT);
-+ if (ret)
-+ dev_warn(dev, "master active in reset [0x%x] = 0x%x\n",
-+ NFI_MASTER_STA, val);
-+
-+ /* ensure any status register affected by the NFI master is reset */
-+ nfi_writel(nfc, CON_FIFO_FLUSH | CON_NFI_RST, NFI_CON);
-+ nfi_writew(nfc, STAR_DE, NFI_STRDATA);
-+}
-+
-+static int mtk_nfc_send_command(struct mtk_nfc *nfc, u8 command)
-+{
-+ struct device *dev = nfc->dev;
-+ u32 val;
-+ int ret;
-+
-+ nfi_writel(nfc, command, NFI_CMD);
-+
-+ ret = readl_poll_timeout_atomic(nfc->regs + NFI_STA, val,
-+ !(val & STA_CMD), 10, MTK_TIMEOUT);
-+ if (ret) {
-+ dev_warn(dev, "nfi core timed out entering command mode\n");
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+static int mtk_nfc_send_address(struct mtk_nfc *nfc, int addr)
-+{
-+ struct device *dev = nfc->dev;
-+ u32 val;
-+ int ret;
-+
-+ nfi_writel(nfc, addr, NFI_COLADDR);
-+ nfi_writel(nfc, 0, NFI_ROWADDR);
-+ nfi_writew(nfc, 1, NFI_ADDRNOB);
-+
-+ ret = readl_poll_timeout_atomic(nfc->regs + NFI_STA, val,
-+ !(val & STA_ADDR), 10, MTK_TIMEOUT);
-+ if (ret) {
-+ dev_warn(dev, "nfi core timed out entering address mode\n");
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+static int mtk_nfc_hw_runtime_config(struct mtd_info *mtd)
-+{
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
-+ struct mtk_nfc *nfc = nand_get_controller_data(chip);
-+ u32 fmt, spare;
-+
-+ if (!mtd->writesize)
-+ return 0;
-+
-+ spare = mtk_nand->spare_per_sector;
-+
-+ switch (mtd->writesize) {
-+ case 512:
-+ fmt = PAGEFMT_512_2K | PAGEFMT_SEC_SEL_512;
-+ break;
-+ case KB(2):
-+ if (chip->ecc.size == 512)
-+ fmt = PAGEFMT_2K_4K | PAGEFMT_SEC_SEL_512;
-+ else
-+ fmt = PAGEFMT_512_2K;
-+ break;
-+ case KB(4):
-+ if (chip->ecc.size == 512)
-+ fmt = PAGEFMT_4K_8K | PAGEFMT_SEC_SEL_512;
-+ else
-+ fmt = PAGEFMT_2K_4K;
-+ break;
-+ case KB(8):
-+ if (chip->ecc.size == 512)
-+ fmt = PAGEFMT_8K_16K | PAGEFMT_SEC_SEL_512;
-+ else
-+ fmt = PAGEFMT_4K_8K;
-+ break;
-+ case KB(16):
-+ fmt = PAGEFMT_8K_16K;
-+ break;
-+ default:
-+ dev_err(nfc->dev, "invalid page len: %d\n", mtd->writesize);
-+ return -EINVAL;
-+ }
-+
-+ /* the hardware doubles the value for this eccsize so let's halve it */
-+ if (chip->ecc.size == 1024)
-+ spare >>= 1;
-+
-+ switch (spare) {
-+ case 16:
-+ fmt |= (PAGEFMT_SPARE_16 << PAGEFMT_SPARE_SHIFT);
-+ break;
-+ case 26:
-+ fmt |= (PAGEFMT_SPARE_26 << PAGEFMT_SPARE_SHIFT);
-+ break;
-+ case 27:
-+ fmt |= (PAGEFMT_SPARE_27 << PAGEFMT_SPARE_SHIFT);
-+ break;
-+ case 28:
-+ fmt |= (PAGEFMT_SPARE_28 << PAGEFMT_SPARE_SHIFT);
-+ break;
-+ case 32:
-+ fmt |= (PAGEFMT_SPARE_32 << PAGEFMT_SPARE_SHIFT);
-+ break;
-+ case 36:
-+ fmt |= (PAGEFMT_SPARE_36 << PAGEFMT_SPARE_SHIFT);
-+ break;
-+ case 40:
-+ fmt |= (PAGEFMT_SPARE_40 << PAGEFMT_SPARE_SHIFT);
-+ break;
-+ case 44:
-+ fmt |= (PAGEFMT_SPARE_44 << PAGEFMT_SPARE_SHIFT);
-+ break;
-+ case 48:
-+ fmt |= (PAGEFMT_SPARE_48 << PAGEFMT_SPARE_SHIFT);
-+ break;
-+ case 49:
-+ fmt |= (PAGEFMT_SPARE_49 << PAGEFMT_SPARE_SHIFT);
-+ break;
-+ case 50:
-+ fmt |= (PAGEFMT_SPARE_50 << PAGEFMT_SPARE_SHIFT);
-+ break;
-+ case 51:
-+ fmt |= (PAGEFMT_SPARE_51 << PAGEFMT_SPARE_SHIFT);
-+ break;
-+ case 52:
-+ fmt |= (PAGEFMT_SPARE_52 << PAGEFMT_SPARE_SHIFT);
-+ break;
-+ case 62:
-+ fmt |= (PAGEFMT_SPARE_62 << PAGEFMT_SPARE_SHIFT);
-+ break;
-+ case 63:
-+ fmt |= (PAGEFMT_SPARE_63 << PAGEFMT_SPARE_SHIFT);
-+ break;
-+ case 64:
-+ fmt |= (PAGEFMT_SPARE_64 << PAGEFMT_SPARE_SHIFT);
-+ break;
-+ default:
-+ dev_err(nfc->dev, "invalid spare per sector %d\n", spare);
-+ return -EINVAL;
-+ }
-+
-+ fmt |= mtk_nand->fdm.reg_size << PAGEFMT_FDM_SHIFT;
-+ fmt |= mtk_nand->fdm.ecc_size << PAGEFMT_FDM_ECC_SHIFT;
-+ nfi_writew(nfc, fmt, NFI_PAGEFMT);
-+
-+ nfc->ecc_cfg.strength = chip->ecc.strength;
-+ nfc->ecc_cfg.enc_len = chip->ecc.size + mtk_nand->fdm.ecc_size;
-+ nfc->ecc_cfg.dec_len = (nfc->ecc_cfg.enc_len << 3)
-+ + chip->ecc.strength * ECC_PARITY_BITS;
-+
-+ return 0;
-+}
-+
-+static void mtk_nfc_select_chip(struct mtd_info *mtd, int chip)
-+{
-+ struct nand_chip *nand = mtd_to_nand(mtd);
-+ struct mtk_nfc *nfc = nand_get_controller_data(nand);
-+ struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(nand);
-+
-+ if (chip < 0)
-+ return;
-+
-+ mtk_nfc_hw_runtime_config(mtd);
-+
-+ nfi_writel(nfc, mtk_nand->sels[chip], NFI_CSEL);
-+}
-+
-+static int mtk_nfc_dev_ready(struct mtd_info *mtd)
-+{
-+ struct mtk_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd));
-+
-+ if (nfi_readl(nfc, NFI_STA) & STA_BUSY)
-+ return 0;
-+
-+ return 1;
-+}
-+
-+static void mtk_nfc_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
-+{
-+ struct mtk_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd));
-+
-+ if (ctrl & NAND_ALE)
-+ mtk_nfc_send_address(nfc, dat);
-+ else if (ctrl & NAND_CLE) {
-+ mtk_nfc_hw_reset(nfc);
-+
-+ nfi_writew(nfc, CNFG_OP_CUST, NFI_CNFG);
-+ mtk_nfc_send_command(nfc, dat);
-+ }
-+}
-+
-+static inline void mtk_nfc_wait_ioready(struct mtk_nfc *nfc)
-+{
-+ int rc;
-+ u8 val;
-+
-+ rc = readb_poll_timeout_atomic(nfc->regs + NFI_PIO_DIRDY, val,
-+ val & PIO_DI_RDY, 10, MTK_TIMEOUT);
-+ if (rc < 0)
-+ dev_err(nfc->dev, "data not ready\n");
-+}
-+
-+static inline uint8_t mtk_nfc_read_byte(struct mtd_info *mtd)
-+{
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct mtk_nfc *nfc = nand_get_controller_data(chip);
-+ u32 reg;
-+
-+ reg = nfi_readl(nfc, NFI_STA) & NFI_FSM_MASK;
-+ if (reg != NFI_FSM_CUSTDATA) {
-+ reg = nfi_readw(nfc, NFI_CNFG);
-+ reg |= CNFG_BYTE_RW | CNFG_READ_EN;
-+ nfi_writew(nfc, reg, NFI_CNFG);
-+
-+ reg = (MTK_MAX_SECTOR << CON_SEC_SHIFT) | CON_BRD;
-+ nfi_writel(nfc, reg, NFI_CON);
-+
-+ /* trigger to fetch data */
-+ nfi_writew(nfc, STAR_EN, NFI_STRDATA);
-+ }
-+
-+ mtk_nfc_wait_ioready(nfc);
-+
-+ return nfi_readb(nfc, NFI_DATAR);
-+}
-+
-+static void mtk_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
-+{
-+ int i;
-+
-+ for (i = 0; i < len; i++)
-+ buf[i] = mtk_nfc_read_byte(mtd);
-+}
-+
-+static void mtk_nfc_write_byte(struct mtd_info *mtd, uint8_t byte)
-+{
-+ struct mtk_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd));
-+ u32 reg;
-+
-+ reg = nfi_readl(nfc, NFI_STA) & NFI_FSM_MASK;
-+
-+ if (reg != NFI_FSM_CUSTDATA) {
-+ reg = nfi_readw(nfc, NFI_CNFG) | CNFG_BYTE_RW;
-+ nfi_writew(nfc, reg, NFI_CNFG);
-+
-+ reg = MTK_MAX_SECTOR << CON_SEC_SHIFT | CON_BWR;
-+ nfi_writel(nfc, reg, NFI_CON);
-+
-+ nfi_writew(nfc, STAR_EN, NFI_STRDATA);
-+ }
-+
-+ mtk_nfc_wait_ioready(nfc);
-+ nfi_writeb(nfc, byte, NFI_DATAW);
-+}
-+
-+static void mtk_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
-+{
-+ int i;
-+
-+ for (i = 0; i < len; i++)
-+ mtk_nfc_write_byte(mtd, buf[i]);
-+}
-+
-+static int mtk_nfc_sector_encode(struct nand_chip *chip, u8 *data)
-+{
-+ struct mtk_nfc *nfc = nand_get_controller_data(chip);
-+ struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
-+ int size = chip->ecc.size + mtk_nand->fdm.reg_size;
-+
-+ nfc->ecc_cfg.ecc_mode = ECC_DMA_MODE;
-+ nfc->ecc_cfg.codec = ECC_ENC;
-+ return mtk_ecc_encode_non_nfi_mode(nfc->ecc, &nfc->ecc_cfg, data, size);
-+}
-+
-+static void mtk_nfc_no_bad_mark_swap(struct mtd_info *a, uint8_t *b, int c)
-+{
-+ /* nope */
-+}
-+
-+static void mtk_nfc_bad_mark_swap(struct mtd_info *mtd, uint8_t *buf, int raw)
-+{
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct mtk_nfc_nand_chip *nand = to_mtk_nand(chip);
-+ u32 bad_pos = nand->bad_mark.pos;
-+
-+ if (raw)
-+ bad_pos += nand->bad_mark.sec * mtk_data_len(chip);
-+ else
-+ bad_pos += nand->bad_mark.sec * chip->ecc.size;
-+
-+ swap(chip->oob_poi[0], buf[bad_pos]);
-+}
-+
-+static int mtk_nfc_format_subpage(struct mtd_info *mtd, uint32_t offset,
-+ uint32_t len, const uint8_t *buf)
-+{
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
-+ struct mtk_nfc *nfc = nand_get_controller_data(chip);
-+ struct mtk_nfc_fdm *fdm = &mtk_nand->fdm;
-+ u32 start, end;
-+ int i, ret;
-+
-+ start = offset / chip->ecc.size;
-+ end = DIV_ROUND_UP(offset + len, chip->ecc.size);
-+
-+ memset(nfc->buffer, 0xff, mtd->writesize + mtd->oobsize);
-+ for (i = 0; i < chip->ecc.steps; i++) {
-+
-+ memcpy(mtk_data_ptr(chip, i), data_ptr(chip, buf, i),
-+ chip->ecc.size);
-+
-+ if (start > i || i >= end)
-+ continue;
-+
-+ if (i == mtk_nand->bad_mark.sec)
-+ mtk_nand->bad_mark.bm_swap(mtd, nfc->buffer, 1);
-+
-+ memcpy(mtk_oob_ptr(chip, i), oob_ptr(chip, i), fdm->reg_size);
-+
-+ /* program the CRC back to the OOB */
-+ ret = mtk_nfc_sector_encode(chip, mtk_data_ptr(chip, i));
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static void mtk_nfc_format_page(struct mtd_info *mtd, const uint8_t *buf)
-+{
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
-+ struct mtk_nfc *nfc = nand_get_controller_data(chip);
-+ struct mtk_nfc_fdm *fdm = &mtk_nand->fdm;
-+ u32 i;
-+
-+ memset(nfc->buffer, 0xff, mtd->writesize + mtd->oobsize);
-+ for (i = 0; i < chip->ecc.steps; i++) {
-+ if (buf)
-+ memcpy(mtk_data_ptr(chip, i), data_ptr(chip, buf, i),
-+ chip->ecc.size);
-+
-+ if (i == mtk_nand->bad_mark.sec)
-+ mtk_nand->bad_mark.bm_swap(mtd, nfc->buffer, 1);
-+
-+ memcpy(mtk_oob_ptr(chip, i), oob_ptr(chip, i), fdm->reg_size);
-+ }
-+}
-+
-+static inline void mtk_nfc_read_fdm(struct nand_chip *chip, u32 start,
-+ u32 sectors)
-+{
-+ struct mtk_nfc *nfc = nand_get_controller_data(chip);
-+ u32 *p;
-+ int i;
-+
-+ for (i = 0; i < sectors; i++) {
-+ p = (u32 *) oob_ptr(chip, start + i);
-+ p[0] = nfi_readl(nfc, NFI_FDML(i));
-+ p[1] = nfi_readl(nfc, NFI_FDMM(i));
-+ }
-+}
-+
-+static inline void mtk_nfc_write_fdm(struct nand_chip *chip)
-+{
-+ struct mtk_nfc *nfc = nand_get_controller_data(chip);
-+ u32 *p;
-+ int i;
-+
-+ for (i = 0; i < chip->ecc.steps ; i++) {
-+ p = (u32 *) oob_ptr(chip, i);
-+ nfi_writel(nfc, p[0], NFI_FDML(i));
-+ nfi_writel(nfc, p[1], NFI_FDMM(i));
-+ }
-+}
-+
-+static int mtk_nfc_do_write_page(struct mtd_info *mtd, struct nand_chip *chip,
-+ const uint8_t *buf, int page, int len)
-+{
-+
-+ struct mtk_nfc *nfc = nand_get_controller_data(chip);
-+ struct device *dev = nfc->dev;
-+ dma_addr_t addr;
-+ u32 reg;
-+ int ret;
-+
-+ addr = dma_map_single(dev, (void *) buf, len, DMA_TO_DEVICE);
-+ ret = dma_mapping_error(nfc->dev, addr);
-+ if (ret) {
-+ dev_err(nfc->dev, "dma mapping error\n");
-+ return -EINVAL;
-+ }
-+
-+ reg = nfi_readw(nfc, NFI_CNFG) | CNFG_AHB | CNFG_DMA_BURST_EN;
-+ nfi_writew(nfc, reg, NFI_CNFG);
-+
-+ nfi_writel(nfc, chip->ecc.steps << CON_SEC_SHIFT, NFI_CON);
-+ nfi_writel(nfc, lower_32_bits(addr), NFI_STRADDR);
-+ nfi_writew(nfc, INTR_AHB_DONE_EN, NFI_INTR_EN);
-+
-+ init_completion(&nfc->done);
-+
-+ reg = nfi_readl(nfc, NFI_CON) | CON_BWR;
-+ nfi_writel(nfc, reg, NFI_CON);
-+ nfi_writew(nfc, STAR_EN, NFI_STRDATA);
-+
-+ ret = wait_for_completion_timeout(&nfc->done, msecs_to_jiffies(500));
-+ if (!ret) {
-+ dev_err(dev, "program ahb done timeout\n");
-+ nfi_writew(nfc, 0, NFI_INTR_EN);
-+ ret = -ETIMEDOUT;
-+ goto timeout;
-+ }
-+
-+ ret = readl_poll_timeout_atomic(nfc->regs + NFI_ADDRCNTR, reg,
-+ (reg & CNTR_MASK) >= chip->ecc.steps, 10, MTK_TIMEOUT);
-+ if (ret)
-+ dev_err(dev, "hwecc write timeout\n");
-+
-+timeout:
-+
-+ dma_unmap_single(nfc->dev, addr, len, DMA_TO_DEVICE);
-+ nfi_writel(nfc, 0, NFI_CON);
-+
-+ return ret;
-+}
-+
-+static int mtk_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
-+ const uint8_t *buf, int page, int raw)
-+{
-+ struct mtk_nfc *nfc = nand_get_controller_data(chip);
-+ struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
-+ size_t len;
-+ const u8 *bufpoi;
-+ u32 reg;
-+ int ret;
-+
-+ if (!raw) {
-+ /* OOB => FDM: from register, ECC: from HW */
-+ reg = nfi_readw(nfc, NFI_CNFG) | CNFG_AUTO_FMT_EN;
-+ nfi_writew(nfc, reg | CNFG_HW_ECC_EN, NFI_CNFG);
-+
-+ nfc->ecc_cfg.codec = ECC_ENC;
-+ nfc->ecc_cfg.ecc_mode = ECC_NFI_MODE;
-+ ret = mtk_ecc_enable(nfc->ecc, &nfc->ecc_cfg);
-+ if (ret) {
-+ /* clear NFI config */
-+ reg = nfi_readw(nfc, NFI_CNFG);
-+ reg &= ~(CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN);
-+ nfi_writew(nfc, reg, NFI_CNFG);
-+
-+ return ret;
-+ }
-+
-+ memcpy(nfc->buffer, buf, mtd->writesize);
-+ mtk_nand->bad_mark.bm_swap(mtd, nfc->buffer, raw);
-+ bufpoi = nfc->buffer;
-+
-+ /* write OOB into the FDM registers (OOB area in MTK NAND) */
-+ mtk_nfc_write_fdm(chip);
-+ } else
-+ bufpoi = buf;
-+
-+ len = mtd->writesize + (raw ? mtd->oobsize : 0);
-+ ret = mtk_nfc_do_write_page(mtd, chip, bufpoi, page, len);
-+
-+ if (!raw)
-+ mtk_ecc_disable(nfc->ecc, &nfc->ecc_cfg);
-+
-+ return ret;
-+}
-+
-+static int mtk_nfc_write_page_hwecc(struct mtd_info *mtd,
-+ struct nand_chip *chip, const uint8_t *buf, int oob_on, int page)
-+{
-+ return mtk_nfc_write_page(mtd, chip, buf, page, 0);
-+}
-+
-+static int mtk_nfc_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
-+ const uint8_t *buf, int oob_on, int pg)
-+{
-+ struct mtk_nfc *nfc = nand_get_controller_data(chip);
-+
-+ mtk_nfc_format_page(mtd, buf);
-+ return mtk_nfc_write_page(mtd, chip, nfc->buffer, pg, 1);
-+}
-+
-+static int mtk_nfc_write_subpage_hwecc(struct mtd_info *mtd,
-+ struct nand_chip *chip, uint32_t offset, uint32_t data_len,
-+ const uint8_t *buf, int oob_on, int page)
-+{
-+ struct mtk_nfc *nfc = nand_get_controller_data(chip);
-+ int ret;
-+
-+ ret = mtk_nfc_format_subpage(mtd, offset, data_len, buf);
-+ if (ret < 0)
-+ return ret;
-+
-+ /* use the data in the private buffer (now with FDM and CRC) */
-+ return mtk_nfc_write_page(mtd, chip, nfc->buffer, page, 1);
-+}
-+
-+static int mtk_nfc_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
-+ int page)
-+{
-+ int ret;
-+
-+ chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
-+
-+ ret = mtk_nfc_write_page_raw(mtd, chip, NULL, 1, page);
-+ if (ret < 0)
-+ return -EIO;
-+
-+ chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
-+ ret = chip->waitfunc(mtd, chip);
-+
-+ return ret & NAND_STATUS_FAIL ? -EIO : 0;
-+}
-+
-+static int mtk_nfc_update_ecc_stats(struct mtd_info *mtd, u8 *buf, u32 sectors)
-+{
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct mtk_nfc *nfc = nand_get_controller_data(chip);
-+ struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
-+ struct mtk_ecc_stats stats;
-+ int rc, i;
-+
-+ rc = nfi_readl(nfc, NFI_STA) & STA_EMP_PAGE;
-+ if (rc) {
-+ memset(buf, 0xff, sectors * chip->ecc.size);
-+ for (i = 0; i < sectors; i++)
-+ memset(oob_ptr(chip, i), 0xff, mtk_nand->fdm.reg_size);
-+ return 0;
-+ }
-+
-+ mtk_ecc_get_stats(nfc->ecc, &stats, sectors);
-+ mtd->ecc_stats.corrected += stats.corrected;
-+ mtd->ecc_stats.failed += stats.failed;
-+
-+ return stats.bitflips;
-+}
-+
-+static int mtk_nfc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
-+ uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi,
-+ int page, int raw)
-+{
-+ struct mtk_nfc *nfc = nand_get_controller_data(chip);
-+ struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
-+ u32 spare = mtk_nand->spare_per_sector;
-+ u32 column, sectors, start, end, reg;
-+ dma_addr_t addr;
-+ int bitflips;
-+ size_t len;
-+ u8 *buf;
-+ int rc;
-+
-+ start = data_offs / chip->ecc.size;
-+ end = DIV_ROUND_UP(data_offs + readlen, chip->ecc.size);
-+
-+ sectors = end - start;
-+ column = start * (chip->ecc.size + spare);
-+
-+ len = sectors * chip->ecc.size + (raw ? sectors * spare : 0);
-+ buf = bufpoi + start * chip->ecc.size;
-+
-+ if (column != 0)
-+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, column, -1);
-+
-+ addr = dma_map_single(nfc->dev, buf, len, DMA_FROM_DEVICE);
-+ rc = dma_mapping_error(nfc->dev, addr);
-+ if (rc) {
-+ dev_err(nfc->dev, "dma mapping error\n");
-+
-+ return -EINVAL;
-+ }
-+
-+ reg = nfi_readw(nfc, NFI_CNFG);
-+ reg |= CNFG_READ_EN | CNFG_DMA_BURST_EN | CNFG_AHB;
-+ if (!raw) {
-+ reg |= CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN;
-+ nfi_writew(nfc, reg, NFI_CNFG);
-+
-+ nfc->ecc_cfg.ecc_mode = ECC_NFI_MODE;
-+ nfc->ecc_cfg.sec_mask = sectors;
-+ nfc->ecc_cfg.codec = ECC_DEC;
-+ rc = mtk_ecc_enable(nfc->ecc, &nfc->ecc_cfg);
-+ if (rc) {
-+ dev_err(nfc->dev, "ecc enable\n");
-+ /* clear NFI_CNFG */
-+ reg &= ~(CNFG_DMA_BURST_EN | CNFG_AHB | CNFG_READ_EN |
-+ CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN);
-+ nfi_writew(nfc, reg, NFI_CNFG);
-+ dma_unmap_single(nfc->dev, addr, len, DMA_FROM_DEVICE);
-+
-+ return rc;
-+ }
-+ } else
-+ nfi_writew(nfc, reg, NFI_CNFG);
-+
-+ nfi_writel(nfc, sectors << CON_SEC_SHIFT, NFI_CON);
-+ nfi_writew(nfc, INTR_AHB_DONE_EN, NFI_INTR_EN);
-+ nfi_writel(nfc, lower_32_bits(addr), NFI_STRADDR);
-+
-+ init_completion(&nfc->done);
-+ reg = nfi_readl(nfc, NFI_CON) | CON_BRD;
-+ nfi_writel(nfc, reg, NFI_CON);
-+ nfi_writew(nfc, STAR_EN, NFI_STRDATA);
-+
-+ rc = wait_for_completion_timeout(&nfc->done, msecs_to_jiffies(500));
-+ if (!rc)
-+ dev_warn(nfc->dev, "read ahb/dma done timeout\n");
-+
-+ rc = readl_poll_timeout_atomic(nfc->regs + NFI_BYTELEN, reg,
-+ (reg & CNTR_MASK) >= sectors, 10, MTK_TIMEOUT);
-+ if (rc < 0) {
-+ dev_err(nfc->dev, "subpage done timeout\n");
-+ bitflips = -EIO;
-+ } else {
-+ bitflips = 0;
-+ if (!raw) {
-+ rc = mtk_ecc_wait_irq_done(nfc->ecc, ECC_DEC);
-+ bitflips = rc < 0 ? -ETIMEDOUT :
-+ mtk_nfc_update_ecc_stats(mtd, buf, sectors);
-+ mtk_nfc_read_fdm(chip, start, sectors);
-+ }
-+ }
-+
-+ dma_unmap_single(nfc->dev, addr, len, DMA_FROM_DEVICE);
-+
-+ if (raw)
-+ goto done;
-+
-+ mtk_ecc_disable(nfc->ecc, &nfc->ecc_cfg);
-+
-+ if (clamp(mtk_nand->bad_mark.sec, start, end) == mtk_nand->bad_mark.sec)
-+ mtk_nand->bad_mark.bm_swap(mtd, bufpoi, raw);
-+done:
-+ nfi_writel(nfc, 0, NFI_CON);
-+
-+ return bitflips;
-+}
-+
-+static int mtk_nfc_read_subpage_hwecc(struct mtd_info *mtd,
-+ struct nand_chip *chip, uint32_t off, uint32_t len, uint8_t *p, int pg)
-+{
-+ return mtk_nfc_read_subpage(mtd, chip, off, len, p, pg, 0);
-+}
-+
-+static int mtk_nfc_read_page_hwecc(struct mtd_info *mtd,
-+ struct nand_chip *chip, uint8_t *p, int oob_on, int pg)
-+{
-+ return mtk_nfc_read_subpage(mtd, chip, 0, mtd->writesize, p, pg, 0);
-+}
-+
-+static int mtk_nfc_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
-+ uint8_t *buf, int oob_on, int page)
-+{
-+ struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
-+ struct mtk_nfc *nfc = nand_get_controller_data(chip);
-+ struct mtk_nfc_fdm *fdm = &mtk_nand->fdm;
-+ int i, ret;
-+
-+ memset(nfc->buffer, 0xff, mtd->writesize + mtd->oobsize);
-+ ret = mtk_nfc_read_subpage(mtd, chip, 0, mtd->writesize, nfc->buffer,
-+ page, 1);
-+ if (ret < 0)
-+ return ret;
-+
-+ for (i = 0; i < chip->ecc.steps; i++) {
-+ memcpy(oob_ptr(chip, i), mtk_oob_ptr(chip, i), fdm->reg_size);
-+ if (i == mtk_nand->bad_mark.sec)
-+ mtk_nand->bad_mark.bm_swap(mtd, nfc->buffer, 1);
-+
-+ if (buf)
-+ memcpy(data_ptr(chip, buf, i), mtk_data_ptr(chip, i),
-+ chip->ecc.size);
-+ }
-+
-+ return ret;
-+}
-+
-+static int mtk_nfc_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip,
-+ int page)
-+{
-+ chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
-+
-+ return mtk_nfc_read_page_raw(mtd, chip, NULL, 1, page);
-+}
-+
-+static inline void mtk_nfc_hw_init(struct mtk_nfc *nfc)
-+{
-+ nfi_writel(nfc, 0x10804211, NFI_ACCCON);
-+ nfi_writew(nfc, 0xf1, NFI_CNRNB);
-+ nfi_writew(nfc, PAGEFMT_8K_16K, NFI_PAGEFMT);
-+
-+ mtk_nfc_hw_reset(nfc);
-+
-+ nfi_readl(nfc, NFI_INTR_STA);
-+ nfi_writel(nfc, 0, NFI_INTR_EN);
-+}
-+
-+static irqreturn_t mtk_nfc_irq(int irq, void *id)
-+{
-+ struct mtk_nfc *nfc = id;
-+ u16 sta, ien;
-+
-+ sta = nfi_readw(nfc, NFI_INTR_STA);
-+ ien = nfi_readw(nfc, NFI_INTR_EN);
-+
-+ if (!(sta & ien))
-+ return IRQ_NONE;
-+
-+ nfi_writew(nfc, ~sta & ien, NFI_INTR_EN);
-+ complete(&nfc->done);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static int mtk_nfc_enable_clk(struct device *dev, struct mtk_nfc_clk *clk)
-+{
-+ int ret;
-+
-+ ret = clk_prepare_enable(clk->nfi_clk);
-+ if (ret) {
-+ dev_err(dev, "failed to enable nfi clk\n");
-+ return ret;
-+ }
-+
-+ ret = clk_prepare_enable(clk->pad_clk);
-+ if (ret) {
-+ dev_err(dev, "failed to enable pad clk\n");
-+ clk_disable_unprepare(clk->nfi_clk);
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static void mtk_nfc_disable_clk(struct mtk_nfc_clk *clk)
-+{
-+ clk_disable_unprepare(clk->nfi_clk);
-+ clk_disable_unprepare(clk->pad_clk);
-+}
-+
-+static int mtk_nfc_ooblayout_free(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oob_region)
-+{
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
-+ struct mtk_nfc_fdm *fdm = &mtk_nand->fdm;
-+ u32 eccsteps;
-+
-+ eccsteps = mtd->writesize / chip->ecc.size;
-+
-+ if (section >= eccsteps)
-+ return -ERANGE;
-+
-+ oob_region->length = fdm->reg_size - fdm->ecc_size;
-+ oob_region->offset = section * fdm->reg_size + fdm->ecc_size;
-+
-+ return 0;
-+}
-+
-+static int mtk_nfc_ooblayout_ecc(struct mtd_info *mtd, int section,
-+ struct mtd_oob_region *oob_region)
-+{
-+ struct nand_chip *chip = mtd_to_nand(mtd);
-+ struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip);
-+ u32 eccsteps;
-+
-+ if (section)
-+ return -ERANGE;
-+
-+ eccsteps = mtd->writesize / chip->ecc.size;
-+ oob_region->offset = mtk_nand->fdm.reg_size * eccsteps;
-+ oob_region->length = mtd->oobsize - oob_region->offset;
-+
-+ return 0;
-+}
-+
-+static const struct mtd_ooblayout_ops mtk_nfc_ooblayout_ops = {
-+ .free = mtk_nfc_ooblayout_free,
-+ .ecc = mtk_nfc_ooblayout_ecc,
-+};
-+
-+static void mtk_nfc_set_fdm(struct mtk_nfc_fdm *fdm, struct mtd_info *mtd)
-+{
-+ struct nand_chip *nand = mtd_to_nand(mtd);
-+ struct mtk_nfc_nand_chip *chip = to_mtk_nand(nand);
-+ u32 ecc_bytes;
-+
-+ ecc_bytes = DIV_ROUND_UP(nand->ecc.strength * ECC_PARITY_BITS, 8);
-+
-+ fdm->reg_size = chip->spare_per_sector - ecc_bytes;
-+ if (fdm->reg_size > NFI_FDM_MAX_SIZE)
-+ fdm->reg_size = NFI_FDM_MAX_SIZE;
-+
-+ /* bad block mark storage */
-+ fdm->ecc_size = 1;
-+}
-+
-+static void mtk_nfc_set_bad_mark_ctl(struct mtk_nfc_bad_mark_ctl *bm_ctl,
-+ struct mtd_info *mtd)
-+{
-+ struct nand_chip *nand = mtd_to_nand(mtd);
-+
-+ if (mtd->writesize == 512)
-+ bm_ctl->bm_swap = mtk_nfc_no_bad_mark_swap;
-+ else {
-+ bm_ctl->bm_swap = mtk_nfc_bad_mark_swap;
-+ bm_ctl->sec = mtd->writesize / mtk_data_len(nand);
-+ bm_ctl->pos = mtd->writesize % mtk_data_len(nand);
-+ }
-+}
-+
-+static void mtk_nfc_set_spare_per_sector(u32 *sps, struct mtd_info *mtd)
-+{
-+ struct nand_chip *nand = mtd_to_nand(mtd);
-+ u32 spare[] = {16, 26, 27, 28, 32, 36, 40, 44,
-+ 48, 49, 50, 51, 52, 62, 63, 64};
-+ u32 eccsteps, i;
-+
-+ eccsteps = mtd->writesize / nand->ecc.size;
-+ *sps = mtd->oobsize / eccsteps;
-+
-+ if (nand->ecc.size == 1024)
-+ *sps >>= 1;
-+
-+ for (i = 0; i < ARRAY_SIZE(spare); i++) {
-+ if (*sps <= spare[i]) {
-+ if (!i)
-+ *sps = spare[i];
-+ else if (*sps != spare[i])
-+ *sps = spare[i - 1];
-+ break;
-+ }
-+ }
-+
-+ if (i >= ARRAY_SIZE(spare))
-+ *sps = spare[ARRAY_SIZE(spare) - 1];
-+
-+ if (nand->ecc.size == 1024)
-+ *sps <<= 1;
-+}
-+
-+static int mtk_nfc_ecc_init(struct device *dev, struct mtd_info *mtd)
-+{
-+ struct nand_chip *nand = mtd_to_nand(mtd);
-+ u32 spare;
-+
-+ /* support only ecc hw mode */
-+ if (nand->ecc.mode != NAND_ECC_HW) {
-+ dev_err(dev, "ecc.mode not supported\n");
-+ return -EINVAL;
-+ }
-+
-+ /* if optional DT settings are not present */
-+ if (!nand->ecc.size || !nand->ecc.strength) {
-+
-+ /* controller only supports sizes 512 and 1024 */
-+ nand->ecc.size = (mtd->writesize > 512) ? 1024 : 512;
-+
-+ /* get controller valid values */
-+ mtk_nfc_set_spare_per_sector(&spare, mtd);
-+ spare = spare - NFI_FDM_MAX_SIZE;
-+ nand->ecc.strength = (spare << 3) / ECC_PARITY_BITS;
-+ }
-+
-+ mtk_ecc_update_strength(&nand->ecc.strength);
-+
-+ dev_info(dev, "eccsize %d eccstrength %d\n",
-+ nand->ecc.size, nand->ecc.strength);
-+
-+ return 0;
-+}
-+
-+static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc,
-+ struct device_node *np)
-+{
-+ struct mtk_nfc_nand_chip *chip;
-+ struct nand_chip *nand;
-+ struct mtd_info *mtd;
-+ int nsels, len;
-+ u32 tmp;
-+ int ret;
-+ int i;
-+
-+ if (!of_get_property(np, "reg", &nsels))
-+ return -ENODEV;
-+
-+ nsels /= sizeof(u32);
-+ if (!nsels || nsels > MTK_NAND_MAX_NSELS) {
-+ dev_err(dev, "invalid reg property size %d\n", nsels);
-+ return -EINVAL;
-+ }
-+
-+ chip = devm_kzalloc(dev,
-+ sizeof(*chip) + nsels * sizeof(u8), GFP_KERNEL);
-+ if (!chip)
-+ return -ENOMEM;
-+
-+ chip->nsels = nsels;
-+ for (i = 0; i < nsels; i++) {
-+ ret = of_property_read_u32_index(np, "reg", i, &tmp);
-+ if (ret) {
-+ dev_err(dev, "reg property failure : %d\n", ret);
-+ return ret;
-+ }
-+ chip->sels[i] = tmp;
-+ }
-+
-+ nand = &chip->nand;
-+ nand->controller = &nfc->controller;
-+
-+ nand_set_flash_node(nand, np);
-+ nand_set_controller_data(nand, nfc);
-+
-+ nand->options |= NAND_USE_BOUNCE_BUFFER | NAND_SUBPAGE_READ;
-+ nand->dev_ready = mtk_nfc_dev_ready;
-+ nand->select_chip = mtk_nfc_select_chip;
-+ nand->write_byte = mtk_nfc_write_byte;
-+ nand->write_buf = mtk_nfc_write_buf;
-+ nand->read_byte = mtk_nfc_read_byte;
-+ nand->read_buf = mtk_nfc_read_buf;
-+ nand->cmd_ctrl = mtk_nfc_cmd_ctrl;
-+
-+ /* set default mode in case dt entry is missing */
-+ nand->ecc.mode = NAND_ECC_HW;
-+
-+ nand->ecc.write_subpage = mtk_nfc_write_subpage_hwecc;
-+ nand->ecc.write_page_raw = mtk_nfc_write_page_raw;
-+ nand->ecc.write_page = mtk_nfc_write_page_hwecc;
-+ nand->ecc.write_oob_raw = mtk_nfc_write_oob_std;
-+ nand->ecc.write_oob = mtk_nfc_write_oob_std;
-+
-+ nand->ecc.read_subpage = mtk_nfc_read_subpage_hwecc;
-+ nand->ecc.read_page_raw = mtk_nfc_read_page_raw;
-+ nand->ecc.read_page = mtk_nfc_read_page_hwecc;
-+ nand->ecc.read_oob_raw = mtk_nfc_read_oob_std;
-+ nand->ecc.read_oob = mtk_nfc_read_oob_std;
-+
-+ mtd = nand_to_mtd(nand);
-+ mtd->owner = THIS_MODULE;
-+ mtd->dev.parent = dev;
-+ mtd->name = MTK_NAME;
-+ mtd_set_ooblayout(mtd, &mtk_nfc_ooblayout_ops);
-+
-+ mtk_nfc_hw_init(nfc);
-+
-+ ret = nand_scan_ident(mtd, nsels, NULL);
-+ if (ret)
-+ return -ENODEV;
-+
-+ /* store bbt magic in page, cause OOB is not protected */
-+ if (nand->bbt_options & NAND_BBT_USE_FLASH)
-+ nand->bbt_options |= NAND_BBT_NO_OOB;
-+
-+ ret = mtk_nfc_ecc_init(dev, mtd);
-+ if (ret)
-+ return -EINVAL;
-+
-+ mtk_nfc_set_spare_per_sector(&chip->spare_per_sector, mtd);
-+ mtk_nfc_set_fdm(&chip->fdm, mtd);
-+ mtk_nfc_set_bad_mark_ctl(&chip->bad_mark, mtd);
-+
-+ len = mtd->writesize + mtd->oobsize;
-+ nfc->buffer = devm_kzalloc(dev, len, GFP_KERNEL);
-+ if (!nfc->buffer)
-+ return -ENOMEM;
-+
-+ ret = nand_scan_tail(mtd);
-+ if (ret)
-+ return -ENODEV;
-+
-+ ret = mtd_device_parse_register(mtd, NULL, NULL, NULL, 0);
-+ if (ret) {
-+ dev_err(dev, "mtd parse partition error\n");
-+ nand_release(mtd);
-+ return ret;
-+ }
-+
-+ list_add_tail(&chip->node, &nfc->chips);
-+
-+ return 0;
-+}
-+
-+static int mtk_nfc_nand_chips_init(struct device *dev, struct mtk_nfc *nfc)
-+{
-+ struct device_node *np = dev->of_node;
-+ struct device_node *nand_np;
-+ int ret;
-+
-+ for_each_child_of_node(np, nand_np) {
-+ ret = mtk_nfc_nand_chip_init(dev, nfc, nand_np);
-+ if (ret) {
-+ of_node_put(nand_np);
-+ return ret;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static int mtk_nfc_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct device_node *np = dev->of_node;
-+ struct mtk_nfc *nfc;
-+ struct resource *res;
-+ int ret, irq;
-+
-+ nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
-+ if (!nfc)
-+ return -ENOMEM;
-+
-+ spin_lock_init(&nfc->controller.lock);
-+ init_waitqueue_head(&nfc->controller.wq);
-+ INIT_LIST_HEAD(&nfc->chips);
-+
-+ /* probe defer if not ready */
-+ nfc->ecc = of_mtk_ecc_get(np);
-+ if (IS_ERR(nfc->ecc))
-+ return PTR_ERR(nfc->ecc);
-+ else if (!nfc->ecc)
-+ return -ENODEV;
-+
-+ nfc->dev = dev;
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ nfc->regs = devm_ioremap_resource(dev, res);
-+ if (IS_ERR(nfc->regs)) {
-+ ret = PTR_ERR(nfc->regs);
-+ dev_err(dev, "no nfi base\n");
-+ goto release_ecc;
-+ }
-+
-+ nfc->clk.nfi_clk = devm_clk_get(dev, "nfi_clk");
-+ if (IS_ERR(nfc->clk.nfi_clk)) {
-+ dev_err(dev, "no clk\n");
-+ ret = PTR_ERR(nfc->clk.nfi_clk);
-+ goto release_ecc;
-+ }
-+
-+ nfc->clk.pad_clk = devm_clk_get(dev, "pad_clk");
-+ if (IS_ERR(nfc->clk.pad_clk)) {
-+ dev_err(dev, "no pad clk\n");
-+ ret = PTR_ERR(nfc->clk.pad_clk);
-+ goto release_ecc;
-+ }
-+
-+ ret = mtk_nfc_enable_clk(dev, &nfc->clk);
-+ if (ret)
-+ goto release_ecc;
-+
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq < 0) {
-+ dev_err(dev, "no nfi irq resource\n");
-+ ret = -EINVAL;
-+ goto clk_disable;
-+ }
-+
-+ ret = devm_request_irq(dev, irq, mtk_nfc_irq, 0x0, "mtk-nand", nfc);
-+ if (ret) {
-+ dev_err(dev, "failed to request nfi irq\n");
-+ goto clk_disable;
-+ }
-+
-+ ret = dma_set_mask(dev, DMA_BIT_MASK(32));
-+ if (ret) {
-+ dev_err(dev, "failed to set dma mask\n");
-+ goto clk_disable;
-+ }
-+
-+ platform_set_drvdata(pdev, nfc);
-+
-+ ret = mtk_nfc_nand_chips_init(dev, nfc);
-+ if (ret) {
-+ dev_err(dev, "failed to init nand chips\n");
-+ goto clk_disable;
-+ }
-+
-+ return 0;
-+
-+clk_disable:
-+ mtk_nfc_disable_clk(&nfc->clk);
-+
-+release_ecc:
-+ mtk_ecc_release(nfc->ecc);
-+
-+ return ret;
-+}
-+
-+static int mtk_nfc_remove(struct platform_device *pdev)
-+{
-+ struct mtk_nfc *nfc = platform_get_drvdata(pdev);
-+ struct mtk_nfc_nand_chip *chip;
-+
-+ while (!list_empty(&nfc->chips)) {
-+ chip = list_first_entry(&nfc->chips, struct mtk_nfc_nand_chip,
-+ node);
-+ nand_release(nand_to_mtd(&chip->nand));
-+ list_del(&chip->node);
-+ }
-+
-+ mtk_ecc_release(nfc->ecc);
-+ mtk_nfc_disable_clk(&nfc->clk);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM_SLEEP
-+static int mtk_nfc_suspend(struct device *dev)
-+{
-+ struct mtk_nfc *nfc = dev_get_drvdata(dev);
-+
-+ mtk_nfc_disable_clk(&nfc->clk);
-+
-+ return 0;
-+}
-+
-+static int mtk_nfc_resume(struct device *dev)
-+{
-+ struct mtk_nfc *nfc = dev_get_drvdata(dev);
-+ struct mtk_nfc_nand_chip *chip;
-+ struct nand_chip *nand;
-+ struct mtd_info *mtd;
-+ int ret;
-+ u32 i;
-+
-+ udelay(200);
-+
-+ ret = mtk_nfc_enable_clk(dev, &nfc->clk);
-+ if (ret)
-+ return ret;
-+
-+ mtk_nfc_hw_init(nfc);
-+
-+ list_for_each_entry(chip, &nfc->chips, node) {
-+ nand = &chip->nand;
-+ mtd = nand_to_mtd(nand);
-+ for (i = 0; i < chip->nsels; i++) {
-+ nand->select_chip(mtd, i);
-+ nand->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
-+ }
-+ }
-+
-+ return 0;
-+}
-+static SIMPLE_DEV_PM_OPS(mtk_nfc_pm_ops, mtk_nfc_suspend, mtk_nfc_resume);
-+#endif
-+
-+static const struct of_device_id mtk_nfc_id_table[] = {
-+ { .compatible = "mediatek,mt2701-nfc" },
-+ {}
-+};
-+MODULE_DEVICE_TABLE(of, mtk_nfc_id_table);
-+
-+static struct platform_driver mtk_nfc_driver = {
-+ .probe = mtk_nfc_probe,
-+ .remove = mtk_nfc_remove,
-+ .driver = {
-+ .name = MTK_NAME,
-+ .of_match_table = mtk_nfc_id_table,
-+#ifdef CONFIG_PM_SLEEP
-+ .pm = &mtk_nfc_pm_ops,
-+#endif
-+ },
-+};
-+
-+module_platform_driver(mtk_nfc_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Xiaolei Li <xiaolei.li@mediatek.com>");
-+MODULE_AUTHOR("Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>");
-+MODULE_DESCRIPTION("MTK Nand Flash Controller Driver");
+++ /dev/null
-From 5dc0d474396e04e6c140d71f0e113eb1c03501c5 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 17 May 2016 05:44:10 +0200
-Subject: [PATCH 076/102] mtd: nand: add power domains to the mediatek driver
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/mtd/nand/mtk_nand.c | 13 ++++++++++++-
- 1 file changed, 12 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/nand/mtk_nand.c
-+++ b/drivers/mtd/nand/mtk_nand.c
-@@ -16,6 +16,7 @@
-
- #include <linux/platform_device.h>
- #include <linux/dma-mapping.h>
-+#include <linux/pm_runtime.h>
- #include <linux/interrupt.h>
- #include <linux/delay.h>
- #include <linux/clk.h>
-@@ -102,6 +103,7 @@
- #define NFI_MASTER_STA (0x224)
- #define MASTER_STA_MASK (0x0FFF)
- #define NFI_EMPTY_THRESH (0x23C)
-+#define NFI_ACCCON1 (0x244)
-
- #define MTK_NAME "mtk-nand"
- #define KB(x) ((x) * 1024UL)
-@@ -539,6 +541,8 @@ static void mtk_nfc_bad_mark_swap(struct
- struct mtk_nfc_nand_chip *nand = to_mtk_nand(chip);
- u32 bad_pos = nand->bad_mark.pos;
-
-+ return;
-+
- if (raw)
- bad_pos += nand->bad_mark.sec * mtk_data_len(chip);
- else
-@@ -946,7 +950,8 @@ static int mtk_nfc_read_oob_std(struct m
-
- static inline void mtk_nfc_hw_init(struct mtk_nfc *nfc)
- {
-- nfi_writel(nfc, 0x10804211, NFI_ACCCON);
-+ nfi_writel(nfc, 0x30c77fff, NFI_ACCCON);
-+ nfi_writel(nfc, 0xC03222, NFI_ACCCON1);
- nfi_writew(nfc, 0xf1, NFI_CNRNB);
- nfi_writew(nfc, PAGEFMT_8K_16K, NFI_PAGEFMT);
-
-@@ -1328,6 +1333,9 @@ static int mtk_nfc_probe(struct platform
- goto clk_disable;
- }
-
-+ pm_runtime_enable(dev);
-+ pm_runtime_get_sync(dev);
-+
- platform_set_drvdata(pdev, nfc);
-
- ret = mtk_nfc_nand_chips_init(dev, nfc);
-@@ -1362,6 +1370,9 @@ static int mtk_nfc_remove(struct platfor
- mtk_ecc_release(nfc->ecc);
- mtk_nfc_disable_clk(&nfc->clk);
-
-+ pm_runtime_put_sync(&pdev->dev);
-+ pm_runtime_disable(&pdev->dev);
-+
- return 0;
- }
-
+++ /dev/null
-From b1c85818c3fb00022dc125bb62d657d3fd3cf49c Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Sat, 7 May 2016 06:31:08 +0200
-Subject: [PATCH 077/102] net-next: mediatek: use mdiobus_free() in favour of
- kfree()
-
-The driver currently uses kfree() to clear the mii_bus. This is not the
-correct way to clear the memory and mdiobus_free() should be used instead.
-This patch fixes the two instances where this happens in the driver.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -280,7 +280,7 @@ static int mtk_mdio_init(struct mtk_eth
- return 0;
-
- err_free_bus:
-- kfree(eth->mii_bus);
-+ mdiobus_free(eth->mii_bus);
-
- err_put_node:
- of_node_put(mii_np);
-@@ -295,7 +295,7 @@ static void mtk_mdio_cleanup(struct mtk_
-
- mdiobus_unregister(eth->mii_bus);
- of_node_put(eth->mii_bus->dev.of_node);
-- kfree(eth->mii_bus);
-+ mdiobus_free(eth->mii_bus);
- }
-
- static inline void mtk_irq_disable(struct mtk_eth *eth, u32 mask)
+++ /dev/null
-From 09313f26999e2685e0b9434374e7308e1f447e55 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 22 Apr 2016 11:05:23 +0200
-Subject: [PATCH 078/102] net-next: mediatek: fix gigabit and flow control
- advertisement
-
-The current code will not setup the PHYs advertisement features correctly.
-Fix this and properly advertise Gigabit features and properly handle
-asymmetric pause frames.
-
-Signed-off-by: Sean Wang <keyhaede@gmail.com>
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++++++++++++++++++----
- 1 file changed, 26 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -133,6 +133,8 @@ static int mtk_mdio_read(struct mii_bus
- static void mtk_phy_link_adjust(struct net_device *dev)
- {
- struct mtk_mac *mac = netdev_priv(dev);
-+ u16 lcl_adv = 0, rmt_adv = 0;
-+ u8 flowctrl;
- 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 |
-@@ -150,11 +152,30 @@ static void mtk_phy_link_adjust(struct n
- if (mac->phy_dev->link)
- mcr |= MAC_MCR_FORCE_LINK;
-
-- if (mac->phy_dev->duplex)
-+ 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;
-+ if (mac->phy_dev->pause)
-+ rmt_adv = LPA_PAUSE_CAP;
-+ if (mac->phy_dev->asym_pause)
-+ rmt_adv |= LPA_PAUSE_ASYM;
-+
-+ if (mac->phy_dev->advertising & ADVERTISED_Pause)
-+ lcl_adv |= ADVERTISE_PAUSE_CAP;
-+ if (mac->phy_dev->advertising & ADVERTISED_Asym_Pause)
-+ lcl_adv |= ADVERTISE_PAUSE_ASYM;
-+
-+ flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
-+
-+ if (flowctrl & FLOW_CTRL_TX)
-+ mcr |= MAC_MCR_FORCE_TX_FC;
-+ if (flowctrl & FLOW_CTRL_RX)
-+ mcr |= MAC_MCR_FORCE_RX_FC;
-+
-+ netif_dbg(mac->hw, link, dev, "rx pause %s, tx pause %s\n",
-+ flowctrl & FLOW_CTRL_RX ? "enabled" : "disabled",
-+ flowctrl & FLOW_CTRL_TX ? "enabled" : "disabled");
-+ }
-
- mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
-
-@@ -236,7 +257,8 @@ static int mtk_phy_connect(struct mtk_ma
- 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->supported &= PHY_GBIT_FEATURES | SUPPORTED_Pause |
-+ SUPPORTED_Asym_Pause;
- mac->phy_dev->advertising = mac->phy_dev->supported |
- ADVERTISED_Autoneg;
- phy_start_aneg(mac->phy_dev);
+++ /dev/null
-From 09f0b50ae838bd6e2bbf0aa22de9f352122297de Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 22 Apr 2016 11:06:03 +0200
-Subject: [PATCH 079/102] net-next: mediatek: add fixed-phy support
-
-The MT7623 SoC has a builtin gigabit switch. If we want to use it, GMAC1
-needs to be configured using a fixed link speed and flow control settings.
-The easiest way to do this is to used the fixed-phy driver, allowing us to
-reuse the existing mdio polling code to setup the MAC.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -229,6 +229,9 @@ static int mtk_phy_connect(struct mtk_ma
- u32 val, ge_mode;
-
- np = of_parse_phandle(mac->of_node, "phy-handle", 0);
-+ if (!np && of_phy_is_fixed_link(mac->of_node))
-+ if (!of_phy_register_fixed_link(mac->of_node))
-+ np = of_node_get(mac->of_node);
- if (!np)
- return -ENODEV;
-
-@@ -257,6 +260,9 @@ static int mtk_phy_connect(struct mtk_ma
- mac->phy_dev->autoneg = AUTONEG_ENABLE;
- mac->phy_dev->speed = 0;
- mac->phy_dev->duplex = 0;
-+ if (of_phy_is_fixed_link(mac->of_node))
-+ mac->phy_dev->supported |= SUPPORTED_Pause |
-+ SUPPORTED_Asym_Pause;
- mac->phy_dev->supported &= PHY_GBIT_FEATURES | SUPPORTED_Pause |
- SUPPORTED_Asym_Pause;
- mac->phy_dev->advertising = mac->phy_dev->supported |
+++ /dev/null
-From 25eaa5d6483a5899e6bf48b47f762f05c186b4b6 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 22 Apr 2016 11:08:43 +0200
-Subject: [PATCH 080/102] net-next: mediatek: properly handle RGMII modes
-
-If an external Gigabit PHY is connected to either of the MACs we need to
-be able to tell the PHY to use a delay. Not doing so will result in heavy
-packet loss and/or data corruption when using PHYs such as the IC+ IP1001.
-We tell the PHY which MII delay mode to use via the devictree.
-
-The ethernet driver needs to be adapted to handle all 3 rgmii-*id modes
-in the same way as normal rgmii when setting up the MAC.
-
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -236,6 +236,9 @@ static int mtk_phy_connect(struct mtk_ma
- return -ENODEV;
-
- switch (of_get_phy_mode(np)) {
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
-+ case PHY_INTERFACE_MODE_RGMII_RXID:
-+ case PHY_INTERFACE_MODE_RGMII_ID:
- case PHY_INTERFACE_MODE_RGMII:
- ge_mode = 0;
- break;
+++ /dev/null
-From 81cdbda2a08375b9d5915567d2210bf2433e7332 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Sat, 23 Apr 2016 11:57:21 +0200
-Subject: [PATCH 081/102] net-next: mediatek: fix DQL support
-
-The MTK ethernet core has 2 MACs both sitting on the same DMA ring. The
-current code will assign the TX traffic of each MAC to its own DQL. This
-results in the amount of data, that DQL says is in the queue incorrect. As
-the data from multiple devices is infact enqueued. This makes any decision
-based on these value non deterministic. Fix this by tracking all TX
-traffic, regardless of the MAC it belongs to in the DQL of all devices
-using the DMA.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 33 ++++++++++++++++-----------
- 1 file changed, 20 insertions(+), 13 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -656,7 +656,16 @@ static int mtk_tx_map(struct sk_buff *sk
- WRITE_ONCE(itxd->txd3, (TX_DMA_SWC | TX_DMA_PLEN0(skb_headlen(skb)) |
- (!nr_frags * TX_DMA_LS0)));
-
-- netdev_sent_queue(dev, skb->len);
-+ /* we have a single DMA ring so BQL needs to be updated for all devices
-+ * sitting on this ring
-+ */
-+ for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ if (!eth->netdev[i])
-+ continue;
-+
-+ netdev_sent_queue(eth->netdev[i], skb->len);
-+ }
-+
- skb_tx_timestamp(skb);
-
- ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2);
-@@ -884,21 +893,18 @@ static int mtk_poll_tx(struct mtk_eth *e
- 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];
-+ int total = 0, done = 0;
-+ unsigned int bytes = 0;
- 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) {
-+ while ((cpu != dma) && done < budget) {
- u32 next_cpu = desc->txd2;
- int mac;
-
-@@ -918,9 +924,8 @@ static int mtk_poll_tx(struct mtk_eth *e
- }
-
- if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) {
-- bytes[mac] += skb->len;
-- done[mac]++;
-- budget--;
-+ bytes += skb->len;
-+ done++;
- }
- mtk_tx_unmap(eth->dev, tx_buf);
-
-@@ -933,11 +938,13 @@ static int mtk_poll_tx(struct mtk_eth *e
-
- mtk_w32(eth, cpu, MTK_QTX_CRX_PTR);
-
-+ /* we have a single DMA ring so BQL needs to be updated for all devices
-+ * sitting on this ring
-+ */
- for (i = 0; i < MTK_MAC_COUNT; i++) {
-- if (!eth->netdev[i] || !done[i])
-+ if (!eth->netdev[i])
- continue;
-- netdev_completed_queue(eth->netdev[i], done[i], bytes[i]);
-- total += done[i];
-+ netdev_completed_queue(eth->netdev[i], done, bytes);
- }
-
- /* read hw index again make sure no new tx packet */
+++ /dev/null
-From 51ca1e9f141499fd7c95bff5401215b706656754 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Sat, 23 Apr 2016 09:06:05 +0200
-Subject: [PATCH 082/102] net-next: mediatek: add missing return code check
-
-The code fails to check if the scratch memory was properly allocated. Add
-this check and return with an error if the allocation failed.
-
-Signed-off-by: Sean Wang <keyhaede@gmail.com>
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -498,6 +498,9 @@ static int mtk_init_fq_dma(struct mtk_et
-
- eth->scratch_head = kcalloc(cnt, MTK_QDMA_PAGE_SIZE,
- GFP_KERNEL);
-+ if (unlikely(!eth->scratch_head))
-+ return -ENOMEM;
-+
- dma_addr = dma_map_single(eth->dev,
- eth->scratch_head, cnt * MTK_QDMA_PAGE_SIZE,
- DMA_FROM_DEVICE);
+++ /dev/null
-From b48745c534ced06005d2ba57198b54a6a160b39d Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Sat, 23 Apr 2016 09:18:28 +0200
-Subject: [PATCH 083/102] net-next: mediatek: fix missing free of scratch
- memory
-
-Scratch memory gets allocated in mtk_init_fq_dma() but the corresponding
-code to free it is missing inside mtk_dma_free() causing a memory leak.
-With this patch applied, we can run ifconfig/up/down several thousand
-times without any problems.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 18 +++++++++++++-----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++
- 2 files changed, 15 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -484,14 +484,14 @@ static inline void mtk_rx_get_desc(struc
- /* the qdma core needs scratch memory to be setup */
- static int mtk_init_fq_dma(struct mtk_eth *eth)
- {
-- dma_addr_t phy_ring_head, phy_ring_tail;
-+ dma_addr_t 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,
-+ ð->phy_scratch_ring,
- GFP_ATOMIC | __GFP_ZERO);
- if (unlikely(!eth->scratch_ring))
- return -ENOMEM;
-@@ -508,19 +508,19 @@ static int mtk_init_fq_dma(struct mtk_et
- return -ENOMEM;
-
- memset(eth->scratch_ring, 0x0, sizeof(struct mtk_tx_dma) * cnt);
-- phy_ring_tail = phy_ring_head +
-+ phy_ring_tail = eth->phy_scratch_ring +
- (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 +
-+ eth->scratch_ring[i].txd2 = (eth->phy_scratch_ring +
- ((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, eth->phy_scratch_ring, 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);
-@@ -1220,6 +1220,14 @@ static void mtk_dma_free(struct mtk_eth
- for (i = 0; i < MTK_MAC_COUNT; i++)
- if (eth->netdev[i])
- netdev_reset_queue(eth->netdev[i]);
-+ if (eth->scratch_ring) {
-+ dma_free_coherent(eth->dev,
-+ MTK_DMA_SIZE * sizeof(struct mtk_tx_dma),
-+ eth->scratch_ring,
-+ eth->phy_scratch_ring);
-+ eth->scratch_ring = NULL;
-+ eth->phy_scratch_ring = 0;
-+ }
- mtk_tx_clean(eth);
- mtk_rx_clean(eth);
- kfree(eth->scratch_head);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -357,6 +357,7 @@ struct mtk_rx_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
-+ * @phy_scratch_ring: physical address of scratch_ring
- * @scratch_head: The scratch memory that scratch_ring points to.
- * @clk_ethif: The ethif clock
- * @clk_esw: The switch clock
-@@ -384,6 +385,7 @@ struct mtk_eth {
- struct mtk_rx_ring rx_ring;
- struct napi_struct rx_napi;
- struct mtk_tx_dma *scratch_ring;
-+ dma_addr_t phy_scratch_ring;
- void *scratch_head;
- struct clk *clk_ethif;
- struct clk *clk_esw;
+++ /dev/null
-From 1eea1536dbbbfda418751ec6f5387acb521ddb97 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Sat, 23 Apr 2016 09:25:00 +0200
-Subject: [PATCH 084/102] net-next: mediatek: invalid buffer lookup in
- mtk_tx_map()
-
-The lookup of the tx_buffer in the error path inside mtk_tx_map() uses the
-wrong descriptor pointer. This looks like a copy & paste error. Change the
-code to use the correct pointer.
-
-Signed-off-by: Sean Wang <keyhaede@gmail.com>
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -686,7 +686,7 @@ static int mtk_tx_map(struct sk_buff *sk
-
- err_dma:
- do {
-- tx_buf = mtk_desc_to_tx_buf(ring, txd);
-+ tx_buf = mtk_desc_to_tx_buf(ring, itxd);
-
- /* unmap dma */
- mtk_tx_unmap(&dev->dev, tx_buf);
+++ /dev/null
-From 98aac832925a99afee8722cdfd5a848dd6086b8f Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Sat, 23 Apr 2016 09:28:25 +0200
-Subject: [PATCH 085/102] net-next: mediatek: dropped rx packets are not being
- counted properly
-
-There are 2 places inside mtk_poll_rx where rx_dropped is not being
-incremented properly. Fix this by adding the missing code to increment
-the counter.
-
-Signed-off-by: Sean Wang <keyhaede@gmail.com>
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -841,6 +841,7 @@ static int mtk_poll_rx(struct napi_struc
- DMA_FROM_DEVICE);
- if (unlikely(dma_mapping_error(&netdev->dev, dma_addr))) {
- skb_free_frag(new_data);
-+ netdev->stats.rx_dropped++;
- goto release_desc;
- }
-
-@@ -848,6 +849,7 @@ static int mtk_poll_rx(struct napi_struc
- skb = build_skb(data, ring->frag_size);
- if (unlikely(!skb)) {
- put_page(virt_to_head_page(new_data));
-+ netdev->stats.rx_dropped++;
- goto release_desc;
- }
- skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
+++ /dev/null
-From 5077ac38a86023124ebbe24cd1b7ecbd0f8edaff Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 3 May 2016 03:06:59 +0200
-Subject: [PATCH 086/102] net-next: mediatek: add next data pointer coherency
- protection
-
-The QDMA engine can fail to update the register pointing to the next TX
-descriptor if this bit does not get set in the QDMA configuration register.
-Not setting this bit can result in invalid values inside the TX rings
-registers which will causes TX stalls.
-
-Signed-off-by: Sean Wang <keyhaede@gmail.com>
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 +
- 2 files changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1292,7 +1292,7 @@ static int mtk_start_dma(struct mtk_eth
- 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_RX_BT_32DWORDS | MTK_NDP_CO_PRO,
- MTK_QDMA_GLO_CFG);
-
- return 0;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -91,6 +91,7 @@
- #define MTK_QDMA_GLO_CFG 0x1A04
- #define MTK_RX_2B_OFFSET BIT(31)
- #define MTK_RX_BT_32DWORDS (3 << 11)
-+#define MTK_NDP_CO_PRO BIT(10)
- #define MTK_TX_WB_DDONE BIT(6)
- #define MTK_DMA_SIZE_16DWORDS (2 << 4)
- #define MTK_RX_DMA_BUSY BIT(3)
+++ /dev/null
-From f9a08e142fd87c72a7803203ce4ecc94806046ca Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 3 May 2016 03:14:07 +0200
-Subject: [PATCH 087/102] net-next: mediatek: disable all interrupts during
- probe
-
-The current code only disables those IRQs that we will later use. To
-ensure that we have a predefined state, we really want to disable all IRQs.
-Change the code to disable all IRQs to achieve this.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1406,7 +1406,7 @@ static int __init mtk_hw_init(struct mtk
-
- /* 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_irq_disable(eth, ~0);
- mtk_w32(eth, RST_GL_PSE, MTK_RST_GL);
- mtk_w32(eth, 0, MTK_RST_GL);
-
+++ /dev/null
-From 34ea0f209e0759158e363039852a04b1facc3acd Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 3 May 2016 02:55:27 +0200
-Subject: [PATCH 088/102] net-next: mediatek: fix threshold value
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The logic to calculate the threshold value for stopping the TX queue is
-bad. Currently it will always use 1/2 of the rings size, which is way too
-much. Set the threshold to MAX_SKB_FRAGS. This makes sure that the queue
-is stopped when there is not enough room to accept an additional segment.Â
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1043,8 +1043,7 @@ static int mtk_tx_alloc(struct mtk_eth *
- 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);
-+ ring->thresh = MAX_SKB_FRAGS;
-
- /* make sure that all changes to the dma ring are flushed before we
- * continue
+++ /dev/null
-From 2cbf3f95a49925317ef4138ceaf7f7f30f353f0f Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 3 May 2016 03:17:53 +0200
-Subject: [PATCH 089/102] net-next: mediatek: increase watchdog_timeo
-
-During stress testing, after reducing the threshold value, we have seen
-TX timeouts that were caused by the watchdog_timeo value being too low.
-Increase the value to 5 * HZ which is a value commonly used by many other
-drivers.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1720,7 +1720,7 @@ static int mtk_add_mac(struct mtk_eth *e
- mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
-
- SET_NETDEV_DEV(eth->netdev[id], eth->dev);
-- eth->netdev[id]->watchdog_timeo = HZ;
-+ eth->netdev[id]->watchdog_timeo = 5 * HZ;
- 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 &
+++ /dev/null
-From 94425de9ede5ef0eafbfced65140c30e7c0b6c0d Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 3 May 2016 03:01:13 +0200
-Subject: [PATCH 090/102] net-next: mediatek: fix off by one in the TX ring
- allocation
-
-The TX ring setup has an off by one error causing it to not utilise all
-descriptors. This has the side effect that we need to reset the next
-pointer at runtime to make it work. Fix the off by one and remove the
-code fixing the ring at runtime.
-
-Signed-off-by: Sean Wang <keyhaede@gmail.com>
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -934,7 +934,6 @@ static int mtk_poll_tx(struct mtk_eth *e
- }
- mtk_tx_unmap(eth->dev, tx_buf);
-
-- ring->last_free->txd2 = next_cpu;
- ring->last_free = desc;
- atomic_inc(&ring->free_count);
-
-@@ -1042,7 +1041,7 @@ static int mtk_tx_alloc(struct mtk_eth *
-
- 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->last_free = &ring->dma[MTK_DMA_SIZE - 1];
- ring->thresh = MAX_SKB_FRAGS;
-
- /* make sure that all changes to the dma ring are flushed before we
+++ /dev/null
-From 1473b4cce85760c0202a08e6a48ec51867dc1bf7 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 3 May 2016 04:01:38 +0200
-Subject: [PATCH 091/102] net-next: mediatek: only wake the queue if it is
- stopped
-
-The current code unconditionally wakes up the queue at the end of each
-tx_poll action. Change the code to only wake up the queues if any of
-them have actually been stopped before.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 17 ++++++++++++++++-
- 1 file changed, 16 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -716,6 +716,20 @@ static inline int mtk_cal_txd_req(struct
- return nfrags;
- }
-
-+static int mtk_queue_stopped(struct mtk_eth *eth)
-+{
-+ int i;
-+
-+ for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ if (!eth->netdev[i])
-+ continue;
-+ if (netif_queue_stopped(eth->netdev[i]))
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
- static void mtk_wake_queue(struct mtk_eth *eth)
- {
- int i;
-@@ -960,7 +974,8 @@ static int mtk_poll_tx(struct mtk_eth *e
- if (!total)
- return 0;
-
-- if (atomic_read(&ring->free_count) > ring->thresh)
-+ if (mtk_queue_stopped(eth) &&
-+ (atomic_read(&ring->free_count) > ring->thresh))
- mtk_wake_queue(eth);
-
- return total;
+++ /dev/null
-From 538020913db04d199ce4d7e845444880e8200b5f Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 3 May 2016 05:40:38 +0200
-Subject: [PATCH 092/102] net-next: mediatek: remove superfluous queue wake up
- call
-
-The code checks if the queue should be stopped because we are below the
-threshold of free descriptors only to check if it should be started again.
-If we do end up in a state where we are at the threshold limit, it makes
-more sense to just stop the queue and wait for the next IRQ to trigger the
-TX housekeeping again. There is no rush in enqueuing the next packet, it
-needs to wait for all the others in the queue to be dispatched first
-anyway.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 ++-----
- 1 file changed, 2 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -795,12 +795,9 @@ static int mtk_start_xmit(struct sk_buff
- if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0)
- goto drop;
-
-- if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) {
-+ if (unlikely(atomic_read(&ring->free_count) <= ring->thresh))
- mtk_stop_queue(eth);
-- if (unlikely(atomic_read(&ring->free_count) >
-- ring->thresh))
-- mtk_wake_queue(eth);
-- }
-+
- spin_unlock_irqrestore(ð->page_lock, flags);
-
- return NETDEV_TX_OK;
+++ /dev/null
-From 31428406bf4b9da2a322ae947096414ff0489fb5 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 3 May 2016 03:57:01 +0200
-Subject: [PATCH 093/102] net-next: mediatek: remove superfluous register
- reads
-
-The driver was originally written for MIPS based SoC. These required the
-IRQ mask register to be read after writing it to ensure that the content
-was actually applied. As this version only works on ARM based SoC, we can
-safely remove the 2 reads as they ware not required.
-
-Signed-off-by: Sean Wang <keyhaede@gmail.com>
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ----
- 1 file changed, 4 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -335,8 +335,6 @@ static inline void mtk_irq_disable(struc
-
- 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)
-@@ -345,8 +343,6 @@ static inline void mtk_irq_enable(struct
-
- 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)
+++ /dev/null
-From 441d87495f33fd444a2b2a16f6df07892dac3f89 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 3 May 2016 04:12:35 +0200
-Subject: [PATCH 094/102] net-next: mediatek: don't use intermediate variables
- to store IRQ masks
-
-The code currently uses variables to store and never modify the bit masks
-of interrupts. This is legacy code from an early version of the driver
-that supported MIPS based SoCs where the IRQ bits depended on the actual
-SoC. As the bits are the same for all ARM based SoC using this driver we
-can remove the intermediate variables.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 ++++++++++------------
- 1 file changed, 10 insertions(+), 12 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -806,7 +806,7 @@ drop:
- }
-
- static int mtk_poll_rx(struct napi_struct *napi, int budget,
-- struct mtk_eth *eth, u32 rx_intr)
-+ struct mtk_eth *eth)
- {
- struct mtk_rx_ring *ring = ð->rx_ring;
- int idx = ring->calc_idx;
-@@ -894,7 +894,7 @@ release_desc:
- }
-
- if (done < budget)
-- mtk_w32(eth, rx_intr, MTK_QMTK_INT_STATUS);
-+ mtk_w32(eth, MTK_RX_DONE_INT, MTK_QMTK_INT_STATUS);
-
- return done;
- }
-@@ -977,28 +977,26 @@ static int mtk_poll_tx(struct mtk_eth *e
- 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;
-+ u32 status, status2, mask;
- 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)
-+ if (status & MTK_TX_DONE_INT)
- tx_done = mtk_poll_tx(eth, budget, &tx_again);
-
-- if (status & rx_intr)
-- rx_done = mtk_poll_rx(napi, budget, eth, rx_intr);
-+ if (status & MTK_RX_DONE_INT)
-+ rx_done = mtk_poll_rx(napi, budget, eth);
-
-- if (unlikely(status2 & status_intr)) {
-+ if (unlikely(status2 & (MTK_GDM1_AF | MTK_GDM2_AF))) {
- mtk_stats_update(eth);
-- mtk_w32(eth, status_intr, MTK_INT_STATUS2);
-+ mtk_w32(eth, (MTK_GDM1_AF | MTK_GDM2_AF),
-+ MTK_INT_STATUS2);
- }
-
- if (unlikely(netif_msg_intr(eth))) {
-@@ -1016,7 +1014,7 @@ static int mtk_poll(struct napi_struct *
- return budget;
-
- napi_complete(napi);
-- mtk_irq_enable(eth, tx_intr | rx_intr);
-+ mtk_irq_enable(eth, MTK_RX_DONE_INT | MTK_RX_DONE_INT);
-
- return rx_done;
- }
+++ /dev/null
-From dd08d1ac4cfc86fbea5ee207b9615922ede88ec6 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 17 May 2016 06:01:45 +0200
-Subject: [PATCH 095/102] net-next: mediatek: add IRQ locking
-
-The code that enables and disables IRQs is missing proper locking. After
-adding the IRQ separation patch and routing the putting the RX and TX IRQs
-on different cores we experienced IRQ stalls. Fix this by adding proper
-locking. We use a dedicated lock to reduce the latency if the IRQ code.
-Otherwise it might wait for bottom code to finish before reenabling or
-disabling IRQs.
-
-Signed-off-by: Sean Wang <keyhaede@gmail.com>
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 +++++++
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 +
- 2 files changed, 8 insertions(+)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -331,18 +331,24 @@ static void mtk_mdio_cleanup(struct mtk_
-
- static inline void mtk_irq_disable(struct mtk_eth *eth, u32 mask)
- {
-+ unsigned long flags;
- u32 val;
-
-+ spin_lock_irqsave(ð->irq_lock, flags);
- val = mtk_r32(eth, MTK_QDMA_INT_MASK);
- mtk_w32(eth, val & ~mask, MTK_QDMA_INT_MASK);
-+ spin_unlock_irqrestore(ð->irq_lock, flags);
- }
-
- static inline void mtk_irq_enable(struct mtk_eth *eth, u32 mask)
- {
-+ unsigned long flags;
- u32 val;
-
-+ spin_lock_irqsave(ð->irq_lock, flags);
- val = mtk_r32(eth, MTK_QDMA_INT_MASK);
- mtk_w32(eth, val | mask, MTK_QDMA_INT_MASK);
-+ spin_unlock_irqrestore(ð->irq_lock, flags);
- }
-
- static int mtk_set_mac_address(struct net_device *dev, void *p)
-@@ -1771,6 +1777,7 @@ static int mtk_probe(struct platform_dev
- return -EADDRNOTAVAIL;
-
- spin_lock_init(ð->page_lock);
-+ spin_lock_init(ð->irq_lock);
-
- eth->ethsys = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
- "mediatek,ethsys");
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -373,6 +373,7 @@ struct mtk_eth {
- void __iomem *base;
- struct reset_control *rstc;
- spinlock_t page_lock;
-+ spinlock_t irq_lock;
- struct net_device dummy_dev;
- struct net_device *netdev[MTK_MAX_DEVS];
- struct mtk_mac *mac[MTK_MAX_DEVS];
+++ /dev/null
-From 190df1a9dbf4d8809b7f991194ce60e47f2290a2 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Wed, 23 Mar 2016 18:31:48 +0100
-Subject: [PATCH 096/102] net-next: mediatek: add support for IRQ grouping
-
-The ethernet core has 3 IRQs. using the IRQ grouping registers we are able
-to separate TX and RX IRQs, which allows us to service them on separate
-cores. This patch splits the irq handler into 2 separate functions, one for
-TX and another for RX. The TX housekeeping is split out into its own NAPI
-handler.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 156 +++++++++++++++++----------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 15 ++-
- 2 files changed, 111 insertions(+), 60 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -905,14 +905,13 @@ release_desc:
- return done;
- }
-
--static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again)
-+static int mtk_poll_tx(struct mtk_eth *eth, int budget)
- {
- struct mtk_tx_ring *ring = ð->tx_ring;
- struct mtk_tx_dma *desc;
- struct sk_buff *skb;
- struct mtk_tx_buf *tx_buf;
-- int total = 0, done = 0;
-- unsigned int bytes = 0;
-+ unsigned int bytes = 0, done = 0;
- u32 cpu, dma;
- static int condition;
- int i;
-@@ -964,63 +963,82 @@ static int mtk_poll_tx(struct mtk_eth *e
- netdev_completed_queue(eth->netdev[i], done, bytes);
- }
-
-- /* 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;
--
- if (mtk_queue_stopped(eth) &&
- (atomic_read(&ring->free_count) > ring->thresh))
- mtk_wake_queue(eth);
-
-- return total;
-+ return done;
- }
-
--static int mtk_poll(struct napi_struct *napi, int budget)
-+static void mtk_handle_status_irq(struct mtk_eth *eth)
- {
-- struct mtk_eth *eth = container_of(napi, struct mtk_eth, rx_napi);
-- u32 status, status2, mask;
-- 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_done = 0;
-- rx_done = 0;
-- tx_again = 0;
--
-- if (status & MTK_TX_DONE_INT)
-- tx_done = mtk_poll_tx(eth, budget, &tx_again);
--
-- if (status & MTK_RX_DONE_INT)
-- rx_done = mtk_poll_rx(napi, budget, eth);
-+ u32 status2 = mtk_r32(eth, MTK_INT_STATUS2);
-
- if (unlikely(status2 & (MTK_GDM1_AF | MTK_GDM2_AF))) {
- mtk_stats_update(eth);
- mtk_w32(eth, (MTK_GDM1_AF | MTK_GDM2_AF),
- MTK_INT_STATUS2);
- }
-+}
-+
-+static int mtk_napi_tx(struct napi_struct *napi, int budget)
-+{
-+ struct mtk_eth *eth = container_of(napi, struct mtk_eth, tx_napi);
-+ u32 status, mask;
-+ int tx_done = 0;
-+
-+ mtk_handle_status_irq(eth);
-+ mtk_w32(eth, MTK_TX_DONE_INT, MTK_QMTK_INT_STATUS);
-+ tx_done = mtk_poll_tx(eth, budget);
-
- if (unlikely(netif_msg_intr(eth))) {
-+ status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
- 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);
-+ dev_info(eth->dev,
-+ "done tx %d, intr 0x%08x/0x%x\n",
-+ tx_done, status, mask);
- }
-
-- if (tx_again || rx_done == budget)
-+ if (tx_done == budget)
- return budget;
-
- status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
-- if (status & (tx_intr | rx_intr))
-+ if (status & MTK_TX_DONE_INT)
- return budget;
-
- napi_complete(napi);
-- mtk_irq_enable(eth, MTK_RX_DONE_INT | MTK_RX_DONE_INT);
-+ mtk_irq_enable(eth, MTK_TX_DONE_INT);
-+
-+ return tx_done;
-+}
-+
-+static int mtk_napi_rx(struct napi_struct *napi, int budget)
-+{
-+ struct mtk_eth *eth = container_of(napi, struct mtk_eth, rx_napi);
-+ u32 status, mask;
-+ int rx_done = 0;
-+
-+ mtk_handle_status_irq(eth);
-+ mtk_w32(eth, MTK_RX_DONE_INT, MTK_QMTK_INT_STATUS);
-+ rx_done = mtk_poll_rx(napi, budget, eth);
-+
-+ if (unlikely(netif_msg_intr(eth))) {
-+ status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
-+ mask = mtk_r32(eth, MTK_QDMA_INT_MASK);
-+ dev_info(eth->dev,
-+ "done rx %d, intr 0x%08x/0x%x\n",
-+ rx_done, status, mask);
-+ }
-+
-+ if (rx_done == budget)
-+ return budget;
-+
-+ status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
-+ if (status & MTK_RX_DONE_INT)
-+ return budget;
-+
-+ napi_complete(napi);
-+ mtk_irq_enable(eth, MTK_RX_DONE_INT);
-
- return rx_done;
- }
-@@ -1256,22 +1274,26 @@ static void mtk_tx_timeout(struct net_de
- schedule_work(ð->pending_work);
- }
-
--static irqreturn_t mtk_handle_irq(int irq, void *_eth)
-+static irqreturn_t mtk_handle_irq_rx(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(napi_schedule_prep(ð->rx_napi))) {
-+ __napi_schedule(ð->rx_napi);
-+ mtk_irq_disable(eth, MTK_RX_DONE_INT);
-+ }
-
-- if (likely(status & (MTK_RX_DONE_INT | MTK_TX_DONE_INT))) {
-- if (likely(napi_schedule_prep(ð->rx_napi)))
-- __napi_schedule(ð->rx_napi);
-- } else {
-- mtk_w32(eth, status, MTK_QMTK_INT_STATUS);
-+ return IRQ_HANDLED;
-+}
-+
-+static irqreturn_t mtk_handle_irq_tx(int irq, void *_eth)
-+{
-+ struct mtk_eth *eth = _eth;
-+
-+ if (likely(napi_schedule_prep(ð->tx_napi))) {
-+ __napi_schedule(ð->tx_napi);
-+ mtk_irq_disable(eth, MTK_TX_DONE_INT);
- }
-- mtk_irq_disable(eth, (MTK_RX_DONE_INT | MTK_TX_DONE_INT));
-
- return IRQ_HANDLED;
- }
-@@ -1284,7 +1306,7 @@ static void mtk_poll_controller(struct n
- u32 int_mask = MTK_TX_DONE_INT | MTK_RX_DONE_INT;
-
- mtk_irq_disable(eth, int_mask);
-- mtk_handle_irq(dev->irq, dev);
-+ mtk_handle_irq(dev->irq[0], dev);
- mtk_irq_enable(eth, int_mask);
- }
- #endif
-@@ -1320,6 +1342,7 @@ static int mtk_open(struct net_device *d
- if (err)
- return err;
-
-+ napi_enable(ð->tx_napi);
- napi_enable(ð->rx_napi);
- mtk_irq_enable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT);
- }
-@@ -1368,6 +1391,7 @@ static int mtk_stop(struct net_device *d
- return 0;
-
- mtk_irq_disable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT);
-+ napi_disable(ð->tx_napi);
- napi_disable(ð->rx_napi);
-
- mtk_stop_dma(eth, MTK_QDMA_GLO_CFG);
-@@ -1405,7 +1429,11 @@ static int __init mtk_hw_init(struct mtk
- /* Enable RX VLan Offloading */
- mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-
-- err = devm_request_irq(eth->dev, eth->irq, mtk_handle_irq, 0,
-+ err = devm_request_irq(eth->dev, eth->irq[1], mtk_handle_irq_tx, 0,
-+ dev_name(eth->dev), eth);
-+ if (err)
-+ return err;
-+ err = devm_request_irq(eth->dev, eth->irq[2], mtk_handle_irq_rx, 0,
- dev_name(eth->dev), eth);
- if (err)
- return err;
-@@ -1421,7 +1449,11 @@ static int __init mtk_hw_init(struct mtk
- mtk_w32(eth, 0, MTK_RST_GL);
-
- /* FE int grouping */
-- mtk_w32(eth, 0, MTK_FE_INT_GRP);
-+ mtk_w32(eth, MTK_TX_DONE_INT, MTK_PDMA_INT_GRP1);
-+ mtk_w32(eth, MTK_RX_DONE_INT, MTK_PDMA_INT_GRP2);
-+ mtk_w32(eth, MTK_TX_DONE_INT, MTK_QDMA_INT_GRP1);
-+ mtk_w32(eth, MTK_RX_DONE_INT, MTK_QDMA_INT_GRP2);
-+ mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
-
- for (i = 0; i < 2; i++) {
- u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
-@@ -1469,7 +1501,9 @@ static void mtk_uninit(struct net_device
- phy_disconnect(mac->phy_dev);
- mtk_mdio_cleanup(eth);
- mtk_irq_disable(eth, ~0);
-- free_irq(dev->irq, dev);
-+ free_irq(eth->irq[0], dev);
-+ free_irq(eth->irq[1], dev);
-+ free_irq(eth->irq[2], dev);
- }
-
- static int mtk_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-@@ -1744,10 +1778,10 @@ static int mtk_add_mac(struct mtk_eth *e
- dev_err(eth->dev, "error bringing up device\n");
- goto free_netdev;
- }
-- eth->netdev[id]->irq = eth->irq;
-+ eth->netdev[id]->irq = eth->irq[0];
- 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);
-+ eth->netdev[id]->base_addr, eth->irq[0]);
-
- return 0;
-
-@@ -1764,6 +1798,7 @@ static int mtk_probe(struct platform_dev
- struct mtk_soc_data *soc;
- struct mtk_eth *eth;
- int err;
-+ int i;
-
- match = of_match_device(of_mtk_match, &pdev->dev);
- soc = (struct mtk_soc_data *)match->data;
-@@ -1799,10 +1834,12 @@ static int mtk_probe(struct platform_dev
- 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;
-+ for (i = 0; i < 3; i++) {
-+ eth->irq[i] = platform_get_irq(pdev, i);
-+ if (eth->irq[i] < 0) {
-+ dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
-+ return -ENXIO;
-+ }
- }
-
- eth->clk_ethif = devm_clk_get(&pdev->dev, "ethif");
-@@ -1843,7 +1880,9 @@ static int mtk_probe(struct platform_dev
- * for NAPI to work
- */
- init_dummy_netdev(ð->dummy_dev);
-- netif_napi_add(ð->dummy_dev, ð->rx_napi, mtk_poll,
-+ netif_napi_add(ð->dummy_dev, ð->tx_napi, mtk_napi_tx,
-+ MTK_NAPI_WEIGHT);
-+ netif_napi_add(ð->dummy_dev, ð->rx_napi, mtk_napi_rx,
- MTK_NAPI_WEIGHT);
-
- platform_set_drvdata(pdev, eth);
-@@ -1864,6 +1903,7 @@ static int mtk_remove(struct platform_de
- clk_disable_unprepare(eth->clk_gp1);
- clk_disable_unprepare(eth->clk_gp2);
-
-+ netif_napi_del(ð->tx_napi);
- netif_napi_del(ð->rx_napi);
- mtk_cleanup(eth);
- platform_set_drvdata(pdev, NULL);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -68,6 +68,10 @@
- /* Unicast Filter MAC Address Register - High */
- #define MTK_GDMA_MAC_ADRH(x) (0x50C + (x * 0x1000))
-
-+/* PDMA Interrupt grouping registers */
-+#define MTK_PDMA_INT_GRP1 0xa50
-+#define MTK_PDMA_INT_GRP2 0xa54
-+
- /* QDMA TX Queue Configuration Registers */
- #define MTK_QTX_CFG(x) (0x1800 + (x * 0x10))
- #define QDMA_RES_THRES 4
-@@ -125,6 +129,11 @@
- #define MTK_TX_DONE_INT (MTK_TX_DONE_INT0 | MTK_TX_DONE_INT1 | \
- MTK_TX_DONE_INT2 | MTK_TX_DONE_INT3)
-
-+/* QDMA Interrupt grouping registers */
-+#define MTK_QDMA_INT_GRP1 0x1a20
-+#define MTK_QDMA_INT_GRP2 0x1a24
-+#define MTK_RLS_DONE_INT BIT(0)
-+
- /* QDMA Interrupt Status Register */
- #define MTK_QDMA_INT_MASK 0x1A1C
-
-@@ -356,7 +365,8 @@ struct mtk_rx_ring {
- * @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
-+ * @tx_napi: The TX NAPI struct
-+ * @rx_napi: The RX NAPI struct
- * @scratch_ring: Newer SoCs need memory for a second HW managed TX ring
- * @phy_scratch_ring: physical address of scratch_ring
- * @scratch_head: The scratch memory that scratch_ring points to.
-@@ -377,7 +387,7 @@ struct mtk_eth {
- struct net_device dummy_dev;
- struct net_device *netdev[MTK_MAX_DEVS];
- struct mtk_mac *mac[MTK_MAX_DEVS];
-- int irq;
-+ int irq[3];
- u32 msg_enable;
- unsigned long sysclk;
- struct regmap *ethsys;
-@@ -385,6 +395,7 @@ struct mtk_eth {
- atomic_t dma_refcnt;
- struct mtk_tx_ring tx_ring;
- struct mtk_rx_ring rx_ring;
-+ struct napi_struct tx_napi;
- struct napi_struct rx_napi;
- struct mtk_tx_dma *scratch_ring;
- dma_addr_t phy_scratch_ring;
+++ /dev/null
-From 7c955062aaa563b1894671af3ae250460b3fa82d Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Thu, 5 May 2016 10:01:56 +0200
-Subject: [PATCH 097/102] net-next: mediatek: change my email address
-
-The old address is no longer valid. Use the my new one instead.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -7,7 +7,7 @@
- * 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 John Crispin <john@phrozen.org>
- * Copyright (C) 2009-2016 Felix Fietkau <nbd@nbd.name>
- * Copyright (C) 2013-2016 Michael Lee <igvtee@gmail.com>
- */
-@@ -1929,5 +1929,5 @@ static struct platform_driver mtk_driver
- module_platform_driver(mtk_driver);
-
- MODULE_LICENSE("GPL");
--MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
-+MODULE_AUTHOR("John Crispin <john@phrozen.org>");
- MODULE_DESCRIPTION("Ethernet driver for MediaTek SoC");
+++ /dev/null
-From cd1343c14328a5de1a58c47b81b8a2febb31d542 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 10 May 2016 11:16:30 +0200
-Subject: [PATCH 098/102] net-next: mediatek: only trigger the tx watchdog
- reset when all devices are stalled
-
-Signed-off-by: Sean Wang <keyhaede@gmail.com>
-Signed-off-by: John Crispin <john@phrozen.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 14 ++++++++++++--
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 +
- 2 files changed, 13 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1267,11 +1267,21 @@ static void mtk_tx_timeout(struct net_de
- {
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
-+ int i, reset = 0;
-
- eth->netdev[mac->id]->stats.tx_errors++;
- netif_err(eth, tx_err, dev,
- "transmit timed out\n");
-- schedule_work(ð->pending_work);
-+
-+ for (i = 0; i < MTK_MAC_COUNT; i++) {
-+ if (!eth->netdev[i] ||
-+ time_after(jiffies, dev_trans_start(eth->netdev[i]) +
-+ MTK_WDT_TIMEOUT))
-+ reset++;
-+ }
-+
-+ if (reset == MTK_MAC_COUNT)
-+ schedule_work(ð->pending_work);
- }
-
- static irqreturn_t mtk_handle_irq_rx(int irq, void *_eth)
-@@ -1765,7 +1775,7 @@ static int mtk_add_mac(struct mtk_eth *e
- mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
-
- SET_NETDEV_DEV(eth->netdev[id], eth->dev);
-- eth->netdev[id]->watchdog_timeo = 5 * HZ;
-+ eth->netdev[id]->watchdog_timeo = MTK_WDT_TIMEOUT;
- 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 &
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -15,6 +15,7 @@
- #ifndef MTK_ETH_H
- #define MTK_ETH_H
-
-+#define MTK_WDT_TIMEOUT (4 * HZ)
- #define MTK_QDMA_PAGE_SIZE 2048
- #define MTK_MAX_RX_LENGTH 1536
- #define MTK_TX_DMA_BUF_LEN 0x3fff
+++ /dev/null
-From 2023b1652745fec5e691a5c9a9742ba6dd45e466 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Wed, 4 May 2016 15:44:01 +0200
-Subject: [PATCH 099/102] MAINTAINERS: change my email address
-
-The old address is no longer valid. Use the my new one instead.
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- MAINTAINERS | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -6904,7 +6904,7 @@ F: include/uapi/linux/uvcvideo.h
-
- MEDIATEK ETHERNET DRIVER
- M: Felix Fietkau <nbd@nbd.name>
--M: John Crispin <blogic@openwrt.org>
-+M: John Crispin <john@phrozen.org>
- L: netdev@vger.kernel.org
- S: Maintained
- F: drivers/net/ethernet/mediatek/
+++ /dev/null
-From 69c89cb453c0beac5d8349108cee8f6806e5db19 Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Tue, 17 May 2016 05:49:17 +0200
-Subject: [PATCH 100/102] MAINTAINERS: add Sean as mediatek ethernet
- maintainer
-
-Sean has been busy doing most of the QA and stress testing of the driver.
-Add him to the list of maintainers.
-
-Signed-off-by: Sean Wang <keyhaede@gmail.com>
-Signed-off-by: John Crispin <john@phrozen.org>
----
- MAINTAINERS | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -6905,6 +6905,7 @@ F: include/uapi/linux/uvcvideo.h
- MEDIATEK ETHERNET DRIVER
- M: Felix Fietkau <nbd@nbd.name>
- M: John Crispin <john@phrozen.org>
-+M: Sean Wang <keyhaede@gmail.com>
- L: netdev@vger.kernel.org
- S: Maintained
- F: drivers/net/ethernet/mediatek/
+++ /dev/null
-From 6b8a7257e7bcb56782c3f8048311670fe6a80209 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Mon, 11 Apr 2016 03:11:54 +0200
-Subject: [PATCH 101/102] net: mediatek add gsw/mt7530 driver
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/ethernet/mediatek/Makefile | 2 +-
- drivers/net/ethernet/mediatek/gsw_mt7620.h | 251 +++++++
- drivers/net/ethernet/mediatek/gsw_mt7623.c | 1084 +++++++++++++++++++++++++++
- 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 +
- 7 files changed, 2199 insertions(+), 30 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
-
---- 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
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/gsw_mt7620.h
-@@ -0,0 +1,251 @@
-+/* 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@nbd.name>
-+ * 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;
-+ bool wllll;
-+};
-+
-+/* 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
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/gsw_mt7623.c
-@@ -0,0 +1,1084 @@
-+/* 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@nbd.name>
-+ * 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/of_mdio.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"
-+
-+#define ETHSYS_CLKCFG0 0x2c
-+#define ETHSYS_TRGMII_CLK_SEL362_5 BIT(11)
-+
-+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);
-+}
-+
-+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 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, 0x700c);
-+
-+ for (i = 0; i < 5; i++)
-+ if (reg & BIT(i)) {
-+ unsigned int link;
-+
-+ link = mt7530_mdio_r32(gsw,
-+ 0x3008 + (i * 0x100)) & 0x1;
-+
-+ if (link)
-+ dev_info(gsw->dev,
-+ "port %d link up\n", i);
-+ else
-+ dev_info(gsw->dev,
-+ "port %d link down\n", i);
-+ }
-+
-+// mt7620_handle_carrier(eth);
-+ mt7530_mdio_w32(gsw, 0x700c, 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);
-+}
-+
-+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);
-+
-+ pr_err("Enable Training Mode in MT7530\n");
-+ read_data = mt7530_mdio_r32(gsw, 0x7A40);
-+ read_data |= 0xC0000000;
-+ mt7530_mdio_w32(gsw, 0x7A40, read_data); /* Enable Training Mode in MT7530 */
-+ err_total_flag = 0;
-+ pr_err("Adjust RXC delay in MT7623\n");
-+ read_data = 0x0;
-+ while (err_total_flag == 0 && read_data != 0x68) {
-+ pr_err("2nd Enable EDGE CHK in MT7623\n");
-+ /* 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;
-+ u32 val;
-+
-+ 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;
-+
-+ /* pr_err("Calibration begin ........\n"); */
-+ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x40) | 0x80000000;
-+ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x40);
-+ read_data = mt7530_mdio_r32(gsw, 0x7a10);
-+ /* pr_err("TRGMII_7530_RD_0 is %x\n", read_data); */
-+
-+ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base + 0x04);
-+ read_data &= 0x3fffffff;
-+ mt7530_mdio_w32(gsw, TRGMII_7530_base + 0x04, read_data); /* RX clock gating in MT7530 */
-+
-+ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base + 0x78);
-+ read_data |= 0x00002000;
-+ mt7530_mdio_w32(gsw, TRGMII_7530_base + 0x78, read_data); /* Set TX OE edge in MT7530 */
-+
-+ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base);
-+ read_data |= 0x80000000;
-+ mt7530_mdio_w32(gsw, TRGMII_7530_base, read_data); /* Assert RX reset in MT7530 */
-+
-+ 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("Enable Training Mode in MT7623\n"); */
-+ /*Enable Training Mode in MT7623 */
-+ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x40) | 0x80000000;
-+ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x40);
-+ if (gsw->trgmii_force == 2000) {
-+ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x40) | 0xC0000000;
-+ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x40);
-+ } else {
-+ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x40) | 0x80000000;
-+ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x40);
-+ }
-+ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x078) & 0xfffff0ff;
-+ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x078);
-+ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x50) & 0xfffff0ff;
-+ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x50);
-+ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x58) & 0xfffff0ff;
-+ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x58);
-+ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x60) & 0xfffff0ff;
-+ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x60);
-+ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x68) & 0xfffff0ff;
-+ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x68);
-+ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x70) & 0xfffff0ff;
-+ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x70);
-+ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x78) & 0x00000800;
-+ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x78);
-+ err_total_flag = 0;
-+ /* pr_err("Adjust RXC delay in MT7530\n"); */
-+ read_data = 0x0;
-+ while (err_total_flag == 0 && (read_data != 0x68)) {
-+ /* pr_err("2nd Enable EDGE CHK in MT7530\n"); */
-+ /* Enable EDGE CHK in MT7530 */
-+ for (i = 0; i < 5; i++) {
-+ 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("2nd Disable EDGE CHK in MT7530\n"); */
-+ err_cnt[i] =
-+ mt7530_mdio_r32(gsw, TRGMII_7530_RD_0 + i * 8);
-+ /* pr_err("***** MT7530 %dth bit ERR_CNT =%x\n",i, err_cnt[i]); */
-+ /* pr_err("MT7530 %dth bit ERR_CNT =%x\n",i, err_cnt[i]); */
-+ err_cnt[i] >>= 8;
-+ err_cnt[i] &= 0x0000ff0f;
-+ rd_wd = err_cnt[i] >> 8;
-+ rd_wd &= 0x000000ff;
-+ err_cnt[i] &= 0x0000000f;
-+ /* read_data = mt7530_mdio_r32(gsw,0x7a10,&read_data); */
-+ 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 */
-+ 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);
-+ }
-+ /*Adjust RXC delay */
-+ if (err_total_flag == 0) {
-+ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base);
-+ read_data |= 0x80000000;
-+ mt7530_mdio_w32(gsw, TRGMII_7530_base, read_data); /* Assert RX reset in MT7530 */
-+
-+ read_data =
-+ mt7530_mdio_r32(gsw, TRGMII_7530_base + 0x04);
-+ read_data &= 0x3fffffff;
-+ mt7530_mdio_w32(gsw, TRGMII_7530_base + 0x04, read_data); /* RX clock gating in MT7530 */
-+
-+ 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]);
-+ /* Calculate RXD delay = (TAP_A + TAP_B)/2 */
-+ final_tap[i] = (tap_a[i] + tap_b[i]) / 2;
-+ /* pr_err("########****** MT7530 %dth bit Final Tap = %d\n", i, final_tap[i]); */
-+
-+ 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)
-+{
-+
-+ u32 regValue;
-+
-+ /* 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);
-+
-+// udelay(120); /* for MT7623 bring up test */
-+
-+ _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);
-+
-+ regValue = mt7530_mdio_r32(gsw, 0x7830);
-+ regValue &= 0xFFFFFFFC;
-+ regValue |= 0x00000001;
-+ mt7530_mdio_w32(gsw, 0x7830, regValue);
-+
-+ regValue = mt7530_mdio_r32(gsw, 0x7a40);
-+ regValue &= ~(0x1 << 30);
-+ regValue &= ~(0x1 << 28);
-+ mt7530_mdio_w32(gsw, 0x7a40, regValue);
-+
-+ mt7530_mdio_w32(gsw, 0x7a78, 0x55);
-+// udelay(100); /* for mt7623 bring up test */
-+
-+ 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 */
-+ regValue = mt7530_mdio_r32(gsw, 0x7a00);
-+ regValue |= (0x1 << 31);
-+ mt7530_mdio_w32(gsw, 0x7a00, regValue);
-+ mdelay(1);
-+ regValue &= ~(0x1 << 31);
-+ mt7530_mdio_w32(gsw, 0x7a00, regValue);
-+ 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);
-+ /* Assert MT7623 RXC reset */
-+ mtk_switch_m32(gsw, 0, TRGMII_RCK_CTRL_RX_RST, GSW_TRGMII_RCK_CTRL);
-+
-+ /* Hardware reset Switch */
-+ device_reset(eth->dev);
-+
-+ /* 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);
-+ if (gsw->eth->mac[0] &&
-+ of_phy_is_fixed_link(gsw->eth->mac[0]->of_node))
-+ /* Enable Port 6 */
-+ val &= ~MHWTRAP_P6_DIS;
-+ else
-+ /* Disable Port 6 */
-+ val |= MHWTRAP_P6_DIS;
-+ if (gsw->eth->mac[1] &&
-+ of_phy_is_fixed_link(gsw->eth->mac[1]->of_node)) {
-+ /* Enable Port 5 */
-+ val &= ~MHWTRAP_P5_DIS;
-+ /* Port 5 as PHY */
-+ val &= ~MHWTRAP_P5_MAC_SEL;
-+ } else {
-+ /* Disable Port 5 */
-+ val |= MHWTRAP_P5_DIS;
-+ /* Port 5 as GMAC */
-+ val |= MHWTRAP_P5_MAC_SEL;
-+ val |= BIT(7);
-+ mt7530_mdio_w32(gsw, MT7530_PMCR_P(5), 0x8000);
-+ }
-+ /* gphy to port 0/4 */
-+ if (gsw->wllll)
-+ val |= BIT(20);
-+ else
-+ val &= ~BIT(20);
-+
-+ /* 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);
-+ dev_info(gsw->dev, "Setting MHWTRAP to 0x%08x\n", val);
-+
-+ val = mt7530_mdio_r32(gsw, 0x7800);
-+ val = (val >> 9) & 0x3;
-+ if (val == 0x3) {
-+ xtal_mode = 1;
-+ /* 25Mhz Xtal - do nothing */
-+ } else if (val == 0x2) {
-+ /* 40Mhz */
-+ xtal_mode = 2;
-+
-+ /* 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);
-+ } else {
-+ xtal_mode = 3;
-+ /* 20Mhz Xtal - TODO */
-+ }
-+
-+ /* RGMII */
-+ _mtk_mdio_write(gsw->eth, 0, 14, 0x1);
-+
-+ /* set MT7530 central align */
-+ val = mt7530_mdio_r32(gsw, 0x7830);
-+ val &= ~1;
-+ val |= 1<<1;
-+ mt7530_mdio_w32(gsw, 0x7830, val);
-+
-+ val = mt7530_mdio_r32(gsw, 0x7a40);
-+ val &= ~(1<<30);
-+ mt7530_mdio_w32(gsw, 0x7a40, val);
-+
-+ mt7530_mdio_w32(gsw, 0x7a78, 0x855);
-+
-+ /* delay setting for 10/1000M */
-+ mt7530_mdio_w32(gsw, 0x7b00, 0x104);
-+ mt7530_mdio_w32(gsw, 0x7b04, 0x10);
-+
-+ /* lower Tx Driving */
-+ mt7530_mdio_w32(gsw, 0x7a54, 0x88);
-+ mt7530_mdio_w32(gsw, 0x7a5c, 0x88);
-+ mt7530_mdio_w32(gsw, 0x7a64, 0x88);
-+ mt7530_mdio_w32(gsw, 0x7a6c, 0x88);
-+ mt7530_mdio_w32(gsw, 0x7a74, 0x88);
-+ mt7530_mdio_w32(gsw, 0x7a7c, 0x88);
-+ mt7530_mdio_w32(gsw, 0x7810, 0x11);
-+
-+ /* Set MT7623/MT7683 TX Driving */
-+ mtk_switch_w32(gsw, 0x88, 0x354);
-+ mtk_switch_w32(gsw, 0x88, 0x35c);
-+ mtk_switch_w32(gsw, 0x88, 0x364);
-+ mtk_switch_w32(gsw, 0x88, 0x36c);
-+ mtk_switch_w32(gsw, 0x88, 0x374);
-+ mtk_switch_w32(gsw, 0x88, 0x37c);
-+
-+ /* Set GE2 driving and slew rate */
-+ regmap_write(gsw->pctl, 0xF00, 0xe00);
-+ /* set GE2 TDSEL */
-+ regmap_write(gsw->pctl, 0x4C0, 0x5);
-+ /* set GE2 TUNE */
-+ regmap_write(gsw->pctl, 0xED0, 0x0);
-+
-+ regmap_write(gsw->pctl, 0xb70, 0);
-+ regmap_write(gsw->pctl, 0x250, 0xffff);
-+ regmap_write(gsw->pctl, 0x260, 0xff);
-+ regmap_write(gsw->pctl, 0x380, 0x37);
-+ regmap_write(gsw->pctl, 0x390, 0x40);
-+
-+ mt7530_trgmii_clock_setting(gsw, xtal_mode);
-+
-+ //LANWANPartition(gsw);
-+
-+ /* 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 &= ~(1<<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;
-+ gsw->eth = eth;
-+ eth->sw_priv = gsw;
-+
-+ mt7623_hw_init(eth, gsw, np);
-+
-+ if (request_threaded_irq(gsw->irq, gsw_interrupt_mt7623, NULL, 0,
-+ "gsw", eth))
-+ pr_err("fail to request irq\n");
-+ mt7530_mdio_w32(gsw, 0x7008, 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->trgmii_force = 2000;
-+ 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;
-+ }
-+
-+ gsw->wllll = of_property_read_bool(np, "mediatek,wllll");
-+
-+ pm_runtime_enable(&pdev->dev);
-+ pm_runtime_get_sync(&pdev->dev);
-+
-+ ret = clk_set_rate(gsw->clk_trgpll, 500000000);
-+ if (ret)
-+ return ret;
-+
-+ regmap_write(gsw->ethsys, 0x34, 0x800000);
-+ regmap_write(gsw->ethsys, 0x34, 0x0);
-+
-+ 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");
---- /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;
-+}
---- /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
---- 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
- 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");
-@@ -1421,15 +1424,6 @@ static int __init mtk_hw_init(struct mtk
- 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));
-
-@@ -1452,6 +1446,8 @@ static int __init mtk_hw_init(struct mtk
- if (err)
- return err;
-
-+ mtk_gsw_init(eth);
-+
- /* disable delay and normal interrupt */
- mtk_w32(eth, 0, MTK_QDMA_DELAY_INT);
- mtk_irq_disable(eth, ~0);
-@@ -1479,6 +1475,8 @@ static int __init mtk_hw_init(struct mtk
- mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
- }
-
-+ mt7623_gsw_config(eth);
-+
- return 0;
- }
-
-@@ -1734,7 +1732,7 @@ static int mtk_add_mac(struct mtk_eth *e
- {
- struct mtk_mac *mac;
- const __be32 *_id = of_get_property(np, "reg", NULL);
-- int id, err;
-+ int id;
-
- if (!_id) {
- dev_err(eth->dev, "missing mac id\n");
-@@ -1768,8 +1766,8 @@ static int mtk_add_mac(struct mtk_eth *e
- GFP_KERNEL);
- if (!mac->hw_stats) {
- dev_err(eth->dev, "failed to allocate counter memory\n");
-- err = -ENOMEM;
-- goto free_netdev;
-+ free_netdev(eth->netdev[id]);
-+ return -ENOMEM;
- }
- spin_lock_init(&mac->hw_stats->stats_lock);
- mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
-@@ -1783,21 +1781,9 @@ static int mtk_add_mac(struct mtk_eth *e
- 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[0];
-- netif_info(eth, probe, eth->netdev[id],
-- "mediatek frame engine at 0x%08lx, irq %d\n",
-- eth->netdev[id]->base_addr, eth->irq[0]);
-
- return 0;
--
--free_netdev:
-- free_netdev(eth->netdev[id]);
-- return err;
- }
-
- static int mtk_probe(struct platform_device *pdev)
-@@ -1865,14 +1851,13 @@ static int mtk_probe(struct platform_dev
- 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);
- INIT_WORK(ð->pending_work, mtk_pending_work);
-
-- 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"))
-@@ -1886,6 +1871,22 @@ static int mtk_probe(struct platform_dev
- goto err_free_dev;
- }
-
-+ err = mtk_hw_init(eth);
-+ if (err)
-+ return err;
-+
-+ for (i = 0; i < MTK_MAX_DEVS; i++) {
-+ if (!eth->netdev[i])
-+ continue;
-+ err = register_netdev(eth->netdev[i]);
-+ if (err)
-+ dev_err(eth->dev, "error bringing up device\n");
-+ else
-+ netif_info(eth, probe, eth->netdev[i],
-+ "mediatek frame engine at 0x%08lx, irq %d\n",
-+ eth->netdev[i]->base_addr, eth->irq[0]);
-+ }
-+
- /* we run 2 devices on the same DMA ring so we need a dummy device
- * for NAPI to work
- */
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -407,6 +407,9 @@ struct mtk_eth {
- struct clk *clk_gp2;
- struct mii_bus *mii_bus;
- struct work_struct pending_work;
-+
-+ struct device_node *switch_np;
-+ void *sw_priv;
- };
-
- /* struct mtk_mac - the structure that holds the info about the MACs of the
-@@ -434,4 +437,6 @@ void mtk_stats_update_mac(struct mtk_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 */
+++ /dev/null
-From c1ff5519a7fd849da5d169036d8175383f807962 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Mon, 11 Apr 2016 06:00:23 +0200
-Subject: [PATCH 102/102] net: mediatek: v4.4 backports
-
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 13 ++++++++-----
- 1 file changed, 8 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -217,7 +217,7 @@ static int mtk_phy_connect_node(struct m
-
- 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;
-@@ -1396,6 +1396,7 @@ static int mtk_stop(struct net_device *d
- 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);
-
-@@ -1595,11 +1596,13 @@ static int mtk_set_settings(struct net_d
- {
- 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);
+++ /dev/null
---- a/drivers/mtd/nand/mtk_nand.c
-+++ b/drivers/mtd/nand/mtk_nand.c
-@@ -1017,8 +1017,8 @@ static int mtk_nfc_ooblayout_free(struct
- if (section >= eccsteps)
- return -ERANGE;
-
-- oob_region->length = fdm->reg_size - fdm->ecc_size;
-- oob_region->offset = section * fdm->reg_size + fdm->ecc_size;
-+ oob_region->length = fdm->reg_size - 1;
-+ oob_region->offset = section * fdm->reg_size + 1;
-
- return 0;
- }
-@@ -1058,7 +1058,7 @@ static void mtk_nfc_set_fdm(struct mtk_n
- fdm->reg_size = NFI_FDM_MAX_SIZE;
-
- /* bad block mark storage */
-- fdm->ecc_size = 1;
-+ fdm->ecc_size = fdm->reg_size;
- }
-
- static void mtk_nfc_set_bad_mark_ctl(struct mtk_nfc_bad_mark_ctl *bm_ctl,
+++ /dev/null
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -775,6 +775,8 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
- mt6589-aquaris5.dtb \
- mt6592-evb.dtb \
- mt7623-evb.dtb \
-+ mt7623-eMMC.dtb \
-+ mt7623-NAND.dtb \
- mt8127-moose.dtb \
- mt8135-evbp1.dtb
- dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb
+++ /dev/null
---- a/drivers/mtd/devices/block2mtd.c
-+++ b/drivers/mtd/devices/block2mtd.c
-@@ -32,6 +32,8 @@
- #include <linux/slab.h>
- #include <linux/major.h>
-
-+static const char * const block2mtd_probe_types[] = { "cmdlinepart", NULL };
-+
- /* Info for the block device */
- struct block2mtd_dev {
- struct list_head list;
-@@ -227,6 +229,7 @@ static struct block2mtd_dev *add_device(
- #endif
- const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
- struct block_device *bdev = ERR_PTR(-ENODEV);
-+ struct mtd_part_parser_data ppdata = { 0 };
- struct block2mtd_dev *dev;
- struct mtd_partition *part;
- char *name;
-@@ -307,11 +310,7 @@ static struct block2mtd_dev *add_device(
- dev->mtd.priv = dev;
- dev->mtd.owner = THIS_MODULE;
-
-- part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL);
-- part->name = name;
-- part->offset = 0;
-- part->size = dev->mtd.size;
-- if (mtd_device_register(&dev->mtd, part, 1)) {
-+ if (mtd_device_parse_register(&dev->mtd, block2mtd_probe_types, &ppdata, NULL, 0)) {
- /* Device didn't get added, so free the entry */
- goto err_destroy_mutex;
- }
--- /dev/null
+--- 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)
+
--- /dev/null
+From 1e021917e634b173d466bf0dd3d2ae84e51a77ff Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 27 Jul 2014 09:38:50 +0100
+Subject: [PATCH 001/102] 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(-)
+
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -890,7 +890,8 @@ void phy_state_machine(struct work_struc
+ /* 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;
+ }
+@@ -973,7 +974,8 @@ void phy_state_machine(struct work_struc
+ 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);
+@@ -985,7 +987,8 @@ void phy_state_machine(struct work_struc
+ 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;
+ }
+--- 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;
+
--- /dev/null
+From 7c5b29de78f1b15c5bde40a6ca4510fc09588457 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 004/102] 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
+
+--- /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 */
--- /dev/null
+From a4c507d052390b42d7e8c59241e3c336796f730f 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 009/102] 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
+
+--- a/drivers/clk/mediatek/Kconfig
++++ b/drivers/clk/mediatek/Kconfig
+@@ -6,6 +6,14 @@
+ ---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 ARCH_MEDIATEK || COMPILE_TEST
+--- 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
+--- a/drivers/clk/mediatek/clk-gate.c
++++ b/drivers/clk/mediatek/clk-gate.c
+@@ -61,6 +61,26 @@
+ 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_mtk_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_mtk_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 @@
+ 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 @@
+ .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 *mtk_clk_register_gate(
+ const char *name,
+ const char *parent_name,
+--- a/drivers/clk/mediatek/clk-gate.h
++++ b/drivers/clk/mediatek/clk-gate.h
+@@ -36,6 +36,8 @@
+
+ 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,
+--- /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 = ð_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);
+--- a/drivers/clk/mediatek/clk-mtk.c
++++ b/drivers/clk/mediatek/clk-mtk.c
+@@ -244,3 +244,28 @@
+ 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;
++ }
++}
+--- a/drivers/clk/mediatek/clk-mtk.h
++++ b/drivers/clk/mediatek/clk-mtk.h
+@@ -121,7 +121,8 @@
+ .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, \
+@@ -156,8 +157,36 @@
+ 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);
+
--- /dev/null
+From 3ba0020ea70ffb5503eff1823be7fa5ceda38286 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 011/102] 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(+)
+
+--- a/drivers/clk/mediatek/clk-mt2701.c
++++ b/drivers/clk/mediatek/clk-mt2701.c
+@@ -665,6 +665,8 @@ static void __init mtk_infrasys_init(str
+ 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(stru
+ 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);
+
--- /dev/null
+From 32fa899c6ab79953e4f470fb23c38bcc40edc5c8 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 012/102] 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(+)
+
+--- a/arch/arm/mach-mediatek/Kconfig
++++ b/arch/arm/mach-mediatek/Kconfig
+@@ -14,6 +14,10 @@
+ bool "MediaTek MT2701 SoCs support"
+ default ARCH_MEDIATEK
+
++config MACH_MT2701
++ bool "MediaTek MT2701 SoCs support"
++ default ARCH_MEDIATEK
++
+ config MACH_MT6589
+ bool "MediaTek MT6589 SoCs support"
+ default ARCH_MEDIATEK
--- /dev/null
+From f7121d2b19ddad33a09408a2c5923bfd95da8533 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 6 Jan 2016 20:06:49 +0100
+Subject: [PATCH 017/102] 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(+)
+
+--- a/drivers/clk/mediatek/clk-mt2701.c
++++ b/drivers/clk/mediatek/clk-mt2701.c
+@@ -1000,6 +1000,8 @@
+ 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);
+
--- /dev/null
+From 05be818061b9f2a0fa5ad0cde6881917ff14a2f2 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 6 Jan 2016 21:55:10 +0100
+Subject: [PATCH 024/102] 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
+
+--- /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";
++ };
++ };
--- /dev/null
+From 8ab1d4e0a9a68e03f472dee1c036a01d0198c20c Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Tue, 5 Jan 2016 20:20:04 +0100
+Subject: [PATCH 025/102] 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
+
+--- a/arch/arm/mach-mediatek/Kconfig
++++ b/arch/arm/mach-mediatek/Kconfig
+@@ -29,6 +29,7 @@
+ config MACH_MT7623
+ bool "MediaTek MT7623 SoCs support"
+ default ARCH_MEDIATEK
++ select MIGHT_HAVE_PCI
+
+ config MACH_MT8127
+ bool "MediaTek MT8127 SoCs support"
+--- a/drivers/pci/host/Kconfig
++++ b/drivers/pci/host/Kconfig
+@@ -301,4 +301,15 @@
+ To compile this driver as a module, choose M here: the
+ module will be called vmd.
+
++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
+--- a/drivers/pci/host/Makefile
++++ b/drivers/pci/host/Makefile
+@@ -33,3 +33,4 @@
+ obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
+ obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
+ obj-$(CONFIG_VMD) += vmd.o
++obj-$(CONFIG_PCIE_MTK) += pcie-mediatek.o
+--- /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);
--- /dev/null
+From 59aafd667d2880c90776931b6102b8252214d93c Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 21 Feb 2016 13:52:12 +0100
+Subject: [PATCH 026/102] 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(-)
+
+--- a/drivers/clk/mediatek/clk-mt2701.c
++++ b/drivers/clk/mediatek/clk-mt2701.c
+@@ -1043,6 +1043,8 @@
+ 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);
+
--- /dev/null
+From 5238c5d1d38661955ed3b52f45c46e00bfc9eb6e Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 7 Apr 2016 07:18:35 +0200
+Subject: [PATCH 052/102] clk: dont disable unused clocks
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/clk/clk.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- 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;
--- /dev/null
+From c8fd103d6c07af5db47f061b70759b7c69169656 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 31 Mar 2016 06:46:51 +0200
+Subject: [PATCH 053/102] clk: mediatek: enable critical clocks
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/clk/mediatek/clk-mt2701.c | 22 ++++++++++++++++++++--
+ 1 file changed, 20 insertions(+), 2 deletions(-)
+
+--- a/drivers/clk/mediatek/clk-mt2701.c
++++ b/drivers/clk/mediatek/clk-mt2701.c
+@@ -573,6 +573,20 @@ static const struct mtk_gate top_clks[]
+ GATE_TOP_AUD(CLK_TOP_AUD_I2S6_MCLK, "aud_i2s6_mclk", "aud_k6_src_div", 28),
+ };
+
++static struct clk_onecell_data *mt7623_top_clk_data __initdata;
++static struct clk_onecell_data *mt7623_pll_clk_data __initdata;
++
++static void __init mtk_clk_enable_critical(void)
++{
++ if (!mt7623_top_clk_data || !mt7623_pll_clk_data)
++ return;
++
++ clk_prepare_enable(mt7623_pll_clk_data->clks[CLK_APMIXED_ARMPLL]);
++ clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_MEM_SEL]);
++ clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_DDRPHYCFG_SEL]);
++ clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_RTC_SEL]);
++}
++
+ static void __init mtk_topckgen_init(struct device_node *node)
+ {
+ struct clk_onecell_data *clk_data;
+@@ -585,7 +599,7 @@ static void __init mtk_topckgen_init(str
+ return;
+ }
+
+- clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
++ mt7623_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
+
+ mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
+ clk_data);
+@@ -606,6 +620,8 @@ static void __init mtk_topckgen_init(str
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
++
++ mtk_clk_enable_critical();
+ }
+ CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt2701-topckgen", mtk_topckgen_init);
+
+@@ -1202,7 +1218,7 @@ static void __init mtk_apmixedsys_init(s
+ struct clk_onecell_data *clk_data;
+ int r;
+
+- clk_data = mtk_alloc_clk_data(ARRAY_SIZE(apmixed_plls));
++ mt7623_pll_clk_data = clk_data = mtk_alloc_clk_data(ARRAY_SIZE(apmixed_plls));
+ if (!clk_data)
+ return;
+
+@@ -1213,6 +1229,8 @@ static void __init mtk_apmixedsys_init(s
+ if (r)
+ pr_err("%s(): could not register clock provider: %d\n",
+ __func__, r);
++
++ mtk_clk_enable_critical();
+ }
+ CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt2701-apmixedsys",
+ mtk_apmixedsys_init);
--- /dev/null
+From 1387d4f0ebf4b48c09f2ea0d27a02936c3fa0010 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 31 Mar 2016 02:26:37 +0200
+Subject: [PATCH 054/102] clk: mediatek: Export CPU mux clocks for CPU
+ frequency control
+
+This patch adds CPU mux clocks which are used by Mediatek cpufreq driver
+for intermediate clock source switching.
+
+Signed-off-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
+---
+ drivers/clk/mediatek/Makefile | 2 +-
+ drivers/clk/mediatek/clk-cpumux.c | 127 ++++++++++++++++++++++++++++++++
+ drivers/clk/mediatek/clk-cpumux.h | 22 ++++++
+ drivers/clk/mediatek/clk-mt2701.c | 8 ++
+ drivers/clk/mediatek/clk-mt8173.c | 23 ++++++
+ include/dt-bindings/clock/mt2701-clk.h | 3 +-
+ include/dt-bindings/clock/mt8173-clk.h | 4 +-
+ 7 files changed, 186 insertions(+), 3 deletions(-)
+ create mode 100644 drivers/clk/mediatek/clk-cpumux.c
+ create mode 100644 drivers/clk/mediatek/clk-cpumux.h
+
+--- a/drivers/clk/mediatek/Makefile
++++ b/drivers/clk/mediatek/Makefile
+@@ -1,4 +1,4 @@
+-obj-$(CONFIG_COMMON_CLK_MEDIATEK) += 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 clk-cpumux.o
+ obj-$(CONFIG_RESET_CONTROLLER) += reset.o
+ obj-$(CONFIG_COMMON_CLK_MT2701) += clk-mt2701.o
+ obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-cpumux.c
+@@ -0,0 +1,127 @@
++/*
++ * Copyright (c) 2015 Linaro Ltd.
++ * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.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 <linux/clk-provider.h>
++#include <linux/mfd/syscon.h>
++#include <linux/slab.h>
++
++#include "clk-mtk.h"
++#include "clk-cpumux.h"
++
++struct mtk_clk_cpumux {
++ struct clk_hw hw;
++ struct regmap *regmap;
++ u32 reg;
++ u32 mask;
++ u8 shift;
++};
++
++static inline struct mtk_clk_cpumux *to_mtk_clk_mux(struct clk_hw *_hw)
++{
++ return container_of(_hw, struct mtk_clk_cpumux, hw);
++}
++
++static u8 clk_cpumux_get_parent(struct clk_hw *hw)
++{
++ struct mtk_clk_cpumux *mux = to_mtk_clk_mux(hw);
++ int num_parents = clk_hw_get_num_parents(hw);
++ unsigned int val;
++
++ regmap_read(mux->regmap, mux->reg, &val);
++
++ val >>= mux->shift;
++ val &= mux->mask;
++
++ if (val >= num_parents)
++ return -EINVAL;
++
++ return val;
++}
++
++static int clk_cpumux_set_parent(struct clk_hw *hw, u8 index)
++{
++ struct mtk_clk_cpumux *mux = to_mtk_clk_mux(hw);
++ u32 mask, val;
++
++ val = index << mux->shift;
++ mask = mux->mask << mux->shift;
++
++ return regmap_update_bits(mux->regmap, mux->reg, mask, val);
++}
++
++static const struct clk_ops clk_cpumux_ops = {
++ .get_parent = clk_cpumux_get_parent,
++ .set_parent = clk_cpumux_set_parent,
++};
++
++static struct clk __init *mtk_clk_register_cpumux(const struct mtk_composite *mux,
++ struct regmap *regmap)
++{
++ struct mtk_clk_cpumux *cpumux;
++ struct clk *clk;
++ struct clk_init_data init;
++
++ cpumux = kzalloc(sizeof(*cpumux), GFP_KERNEL);
++ if (!cpumux)
++ return ERR_PTR(-ENOMEM);
++
++ init.name = mux->name;
++ init.ops = &clk_cpumux_ops;
++ init.parent_names = mux->parent_names;
++ init.num_parents = mux->num_parents;
++ init.flags = mux->flags;
++
++ cpumux->reg = mux->mux_reg;
++ cpumux->shift = mux->mux_shift;
++ cpumux->mask = BIT(mux->mux_width) - 1;
++ cpumux->regmap = regmap;
++ cpumux->hw.init = &init;
++
++ clk = clk_register(NULL, &cpumux->hw);
++ if (IS_ERR(clk))
++ kfree(cpumux);
++
++ return clk;
++}
++
++int __init mtk_clk_register_cpumuxes(struct device_node *node,
++ const struct mtk_composite *clks, int num,
++ struct clk_onecell_data *clk_data)
++{
++ int i;
++ struct clk *clk;
++ struct regmap *regmap;
++
++ regmap = syscon_node_to_regmap(node);
++ if (IS_ERR(regmap)) {
++ pr_err("Cannot find regmap for %s: %ld\n", node->full_name,
++ PTR_ERR(regmap));
++ return PTR_ERR(regmap);
++ }
++
++ for (i = 0; i < num; i++) {
++ const struct mtk_composite *mux = &clks[i];
++
++ clk = mtk_clk_register_cpumux(mux, regmap);
++ if (IS_ERR(clk)) {
++ pr_err("Failed to register clk %s: %ld\n",
++ mux->name, PTR_ERR(clk));
++ continue;
++ }
++
++ clk_data->clks[mux->id] = clk;
++ }
++
++ return 0;
++}
+--- /dev/null
++++ b/drivers/clk/mediatek/clk-cpumux.h
+@@ -0,0 +1,22 @@
++/*
++ * Copyright (c) 2015 Linaro Ltd.
++ * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.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 __DRV_CLK_CPUMUX_H
++#define __DRV_CLK_CPUMUX_H
++
++int mtk_clk_register_cpumuxes(struct device_node *node,
++ const struct mtk_composite *clks, int num,
++ struct clk_onecell_data *clk_data);
++
++#endif /* __DRV_CLK_CPUMUX_H */
+--- a/drivers/clk/mediatek/clk-mt2701.c
++++ b/drivers/clk/mediatek/clk-mt2701.c
+@@ -18,6 +18,7 @@
+
+ #include "clk-mtk.h"
+ #include "clk-gate.h"
++#include "clk-cpumux.h"
+
+ #include <dt-bindings/clock/mt2701-clk.h>
+
+@@ -465,6 +466,10 @@
+ "mmpll"
+ };
+
++static const struct mtk_composite cpu_muxes[] __initconst = {
++ MUX(CLK_INFRA_CPUSEL, "infra_cpu_sel", cpu_parents, 0x0000, 2, 2),
++};
++
+ 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),
+@@ -677,6 +682,9 @@
+ mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
+ clk_data);
+
++ mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
++ 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",
+--- a/drivers/clk/mediatek/clk-mt8173.c
++++ b/drivers/clk/mediatek/clk-mt8173.c
+@@ -18,6 +18,7 @@
+
+ #include "clk-mtk.h"
+ #include "clk-gate.h"
++#include "clk-cpumux.h"
+
+ #include <dt-bindings/clock/mt8173-clk.h>
+
+@@ -525,6 +526,25 @@
+ "apll2_div5"
+ };
+
++static const char * const ca53_parents[] __initconst = {
++ "clk26m",
++ "armca7pll",
++ "mainpll",
++ "univpll"
++};
++
++static const char * const ca57_parents[] __initconst = {
++ "clk26m",
++ "armca15pll",
++ "mainpll",
++ "univpll"
++};
++
++static const struct mtk_composite cpu_muxes[] __initconst = {
++ MUX(CLK_INFRA_CA53SEL, "infra_ca53_sel", ca53_parents, 0x0000, 0, 2),
++ MUX(CLK_INFRA_CA57SEL, "infra_ca57_sel", ca57_parents, 0x0000, 2, 2),
++};
++
+ static const struct mtk_composite top_muxes[] __initconst = {
+ /* CLK_CFG_0 */
+ MUX(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, 0x0040, 0, 3),
+@@ -948,6 +968,9 @@
+ clk_data);
+ mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
+
++ mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
++ 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",
+--- a/include/dt-bindings/clock/mt2701-clk.h
++++ b/include/dt-bindings/clock/mt2701-clk.h
+@@ -221,7 +221,8 @@
+ #define CLK_INFRA_PMICWRAP 17
+ #define CLK_INFRA_DDCCI 18
+ #define CLK_INFRA_CLK_13M 19
+-#define CLK_INFRA_NR 20
++#define CLK_INFRA_CPUSEL 20
++#define CLK_INFRA_NR 21
+
+ /* PERICFG */
+
+--- a/include/dt-bindings/clock/mt8173-clk.h
++++ b/include/dt-bindings/clock/mt8173-clk.h
+@@ -193,7 +193,9 @@
+ #define CLK_INFRA_PMICSPI 10
+ #define CLK_INFRA_PMICWRAP 11
+ #define CLK_INFRA_CLK_13M 12
+-#define CLK_INFRA_NR_CLK 13
++#define CLK_INFRA_CA53SEL 13
++#define CLK_INFRA_CA57SEL 14
++#define CLK_INFRA_NR_CLK 15
+
+ /* PERI_SYS */
+
--- /dev/null
+From 60f4e41b367bdb29530468c91c1e613b17a37755 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Wed, 30 Mar 2016 23:48:53 +0200
+Subject: [PATCH 055/102] cpufreq: mediatek: add driver
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ drivers/cpufreq/Kconfig.arm | 9 +
+ drivers/cpufreq/Makefile | 1 +
+ drivers/cpufreq/mt7623-cpufreq.c | 389 ++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 399 insertions(+)
+ create mode 100644 drivers/cpufreq/mt7623-cpufreq.c
+
+--- a/drivers/cpufreq/Kconfig.arm
++++ b/drivers/cpufreq/Kconfig.arm
+@@ -81,6 +81,15 @@ config ARM_KIRKWOOD_CPUFREQ
+ This adds the CPUFreq driver for Marvell Kirkwood
+ SoCs.
+
++config ARM_MT7623_CPUFREQ
++ bool "Mediatek MT7623 CPUFreq support"
++ depends on ARCH_MEDIATEK && REGULATOR
++ depends on ARM || (ARM_CPU_TOPOLOGY && COMPILE_TEST)
++ depends on !CPU_THERMAL || THERMAL=y
++ select PM_OPP
++ help
++ This adds the CPUFreq driver support for Mediatek MT7623 SoC.
++
+ config ARM_MT8173_CPUFREQ
+ bool "Mediatek MT8173 CPUFreq support"
+ depends on ARCH_MEDIATEK && REGULATOR
+--- a/drivers/cpufreq/Makefile
++++ b/drivers/cpufreq/Makefile
+@@ -57,6 +57,7 @@ obj-$(CONFIG_ARM_HISI_ACPU_CPUFREQ) += h
+ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
+ obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o
+ obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
++obj-$(CONFIG_ARM_MT7623_CPUFREQ) += mt7623-cpufreq.o
+ obj-$(CONFIG_ARM_MT8173_CPUFREQ) += mt8173-cpufreq.o
+ obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
+ obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o
+--- /dev/null
++++ b/drivers/cpufreq/mt7623-cpufreq.c
+@@ -0,0 +1,389 @@
++/*
++ * Copyright (c) 2015 Linaro Ltd.
++ * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.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 <linux/clk.h>
++#include <linux/cpu.h>
++#include <linux/cpu_cooling.h>
++#include <linux/cpufreq.h>
++#include <linux/cpumask.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/pm_opp.h>
++#include <linux/regulator/consumer.h>
++#include <linux/slab.h>
++#include <linux/thermal.h>
++
++#define VOLT_TOL (10000)
++
++/*
++ * When scaling the clock frequency of a CPU clock domain, the clock source
++ * needs to be switched to another stable PLL clock temporarily until
++ * the original PLL becomes stable at target frequency.
++ */
++struct mtk_cpu_dvfs_info {
++ struct device *cpu_dev;
++ struct regulator *proc_reg;
++ struct clk *cpu_clk;
++ struct clk *inter_clk;
++ struct thermal_cooling_device *cdev;
++ int intermediate_voltage;
++};
++
++static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc)
++{
++ return regulator_set_voltage(info->proc_reg, vproc,
++ vproc + VOLT_TOL);
++}
++
++static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
++ unsigned int index)
++{
++ struct cpufreq_frequency_table *freq_table = policy->freq_table;
++ struct clk *cpu_clk = policy->clk;
++ struct clk *armpll = clk_get_parent(cpu_clk);
++ struct mtk_cpu_dvfs_info *info = policy->driver_data;
++ struct device *cpu_dev = info->cpu_dev;
++ struct dev_pm_opp *opp;
++ long freq_hz, old_freq_hz;
++ int vproc, old_vproc, inter_vproc, target_vproc, ret;
++
++ inter_vproc = info->intermediate_voltage;
++
++ old_freq_hz = clk_get_rate(cpu_clk);
++ old_vproc = regulator_get_voltage(info->proc_reg);
++
++ freq_hz = freq_table[index].frequency * 1000;
++
++ rcu_read_lock();
++ opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
++ if (IS_ERR(opp)) {
++ rcu_read_unlock();
++ pr_err("cpu%d: failed to find OPP for %ld\n",
++ policy->cpu, freq_hz);
++ return PTR_ERR(opp);
++ }
++ vproc = dev_pm_opp_get_voltage(opp);
++ rcu_read_unlock();
++
++ /*
++ * If the new voltage or the intermediate voltage is higher than the
++ * current voltage, scale up voltage first.
++ */
++ target_vproc = (inter_vproc > vproc) ? inter_vproc : vproc;
++ if (old_vproc < target_vproc) {
++ ret = mtk_cpufreq_set_voltage(info, target_vproc);
++ if (ret) {
++ pr_err("cpu%d: failed to scale up voltage!\n",
++ policy->cpu);
++ mtk_cpufreq_set_voltage(info, old_vproc);
++ return ret;
++ }
++ }
++
++ /* Reparent the CPU clock to intermediate clock. */
++ ret = clk_set_parent(cpu_clk, info->inter_clk);
++ if (ret) {
++ pr_err("cpu%d: failed to re-parent cpu clock!\n",
++ policy->cpu);
++ mtk_cpufreq_set_voltage(info, old_vproc);
++ WARN_ON(1);
++ return ret;
++ }
++
++ /* Set the original PLL to target rate. */
++ ret = clk_set_rate(armpll, freq_hz);
++ if (ret) {
++ pr_err("cpu%d: failed to scale cpu clock rate!\n",
++ policy->cpu);
++ clk_set_parent(cpu_clk, armpll);
++ mtk_cpufreq_set_voltage(info, old_vproc);
++ return ret;
++ }
++
++ /* Set parent of CPU clock back to the original PLL. */
++ ret = clk_set_parent(cpu_clk, armpll);
++ if (ret) {
++ pr_err("cpu%d: failed to re-parent cpu clock!\n",
++ policy->cpu);
++ mtk_cpufreq_set_voltage(info, inter_vproc);
++ WARN_ON(1);
++ return ret;
++ }
++
++ /*
++ * If the new voltage is lower than the intermediate voltage or the
++ * original voltage, scale down to the new voltage.
++ */
++ if (vproc < inter_vproc || vproc < old_vproc) {
++ ret = mtk_cpufreq_set_voltage(info, vproc);
++ if (ret) {
++ pr_err("cpu%d: failed to scale down voltage!\n",
++ policy->cpu);
++ clk_set_parent(cpu_clk, info->inter_clk);
++ clk_set_rate(armpll, old_freq_hz);
++ clk_set_parent(cpu_clk, armpll);
++ return ret;
++ }
++ }
++
++ return 0;
++}
++
++static void mtk_cpufreq_ready(struct cpufreq_policy *policy)
++{
++ struct mtk_cpu_dvfs_info *info = policy->driver_data;
++ struct device_node *np = of_node_get(info->cpu_dev->of_node);
++
++ if (WARN_ON(!np))
++ return;
++
++ if (of_find_property(np, "#cooling-cells", NULL)) {
++ info->cdev = of_cpufreq_cooling_register(np,
++ policy->related_cpus);
++
++ if (IS_ERR(info->cdev)) {
++ dev_err(info->cpu_dev,
++ "running cpufreq without cooling device: %ld\n",
++ PTR_ERR(info->cdev));
++
++ info->cdev = NULL;
++ }
++ }
++
++ of_node_put(np);
++}
++
++static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
++{
++ struct device *cpu_dev;
++ struct regulator *proc_reg = ERR_PTR(-ENODEV);
++ struct clk *cpu_clk = ERR_PTR(-ENODEV);
++ struct clk *inter_clk = ERR_PTR(-ENODEV);
++ struct dev_pm_opp *opp;
++ unsigned long rate;
++ int ret;
++
++ cpu_dev = get_cpu_device(cpu);
++ if (!cpu_dev) {
++ pr_err("failed to get cpu%d device\n", cpu);
++ return -ENODEV;
++ }
++
++ cpu_clk = clk_get(cpu_dev, "cpu");
++ if (IS_ERR(cpu_clk)) {
++ if (PTR_ERR(cpu_clk) == -EPROBE_DEFER)
++ pr_warn("cpu clk for cpu%d not ready, retry.\n", cpu);
++ else
++ pr_err("failed to get cpu clk for cpu%d\n", cpu);
++
++ ret = PTR_ERR(cpu_clk);
++ return ret;
++ }
++
++ inter_clk = clk_get(cpu_dev, "intermediate");
++ if (IS_ERR(inter_clk)) {
++ if (PTR_ERR(inter_clk) == -EPROBE_DEFER)
++ pr_warn("intermediate clk for cpu%d not ready, retry.\n",
++ cpu);
++ else
++ pr_err("failed to get intermediate clk for cpu%d\n",
++ cpu);
++
++ ret = PTR_ERR(inter_clk);
++ goto out_free_resources;
++ }
++
++ proc_reg = regulator_get_exclusive(cpu_dev, "proc");
++ if (IS_ERR(proc_reg)) {
++ if (PTR_ERR(proc_reg) == -EPROBE_DEFER)
++ pr_warn("proc regulator for cpu%d not ready, retry.\n",
++ cpu);
++ else
++ pr_err("failed to get proc regulator for cpu%d\n",
++ cpu);
++
++ ret = PTR_ERR(proc_reg);
++ goto out_free_resources;
++ }
++
++ ret = dev_pm_opp_of_add_table(cpu_dev);
++ if (ret) {
++ pr_warn("no OPP table for cpu%d\n", cpu);
++ goto out_free_resources;
++ }
++
++ /* Search a safe voltage for intermediate frequency. */
++ rate = clk_get_rate(inter_clk);
++ rcu_read_lock();
++ opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate);
++ if (IS_ERR(opp)) {
++ rcu_read_unlock();
++ pr_err("failed to get intermediate opp for cpu%d\n", cpu);
++ ret = PTR_ERR(opp);
++ goto out_free_opp_table;
++ }
++ info->intermediate_voltage = dev_pm_opp_get_voltage(opp);
++ rcu_read_unlock();
++
++ info->cpu_dev = cpu_dev;
++ info->proc_reg = proc_reg;
++ info->cpu_clk = cpu_clk;
++ info->inter_clk = inter_clk;
++
++ return 0;
++
++out_free_opp_table:
++ dev_pm_opp_of_remove_table(cpu_dev);
++
++out_free_resources:
++ if (!IS_ERR(proc_reg))
++ regulator_put(proc_reg);
++ if (!IS_ERR(cpu_clk))
++ clk_put(cpu_clk);
++ if (!IS_ERR(inter_clk))
++ clk_put(inter_clk);
++
++ return ret;
++}
++
++static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info)
++{
++ if (!IS_ERR(info->proc_reg))
++ regulator_put(info->proc_reg);
++ if (!IS_ERR(info->cpu_clk))
++ clk_put(info->cpu_clk);
++ if (!IS_ERR(info->inter_clk))
++ clk_put(info->inter_clk);
++
++ dev_pm_opp_of_remove_table(info->cpu_dev);
++}
++
++static int mtk_cpufreq_init(struct cpufreq_policy *policy)
++{
++ struct mtk_cpu_dvfs_info *info;
++ struct cpufreq_frequency_table *freq_table;
++ int ret;
++
++ info = kzalloc(sizeof(*info), GFP_KERNEL);
++ if (!info)
++ return -ENOMEM;
++
++ ret = mtk_cpu_dvfs_info_init(info, policy->cpu);
++ if (ret) {
++ pr_err("%s failed to initialize dvfs info for cpu%d\n",
++ __func__, policy->cpu);
++ goto out_free_dvfs_info;
++ }
++
++ ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table);
++ if (ret) {
++ pr_err("failed to init cpufreq table for cpu%d: %d\n",
++ policy->cpu, ret);
++ goto out_release_dvfs_info;
++ }
++
++ ret = cpufreq_table_validate_and_show(policy, freq_table);
++ if (ret) {
++ pr_err("%s: invalid frequency table: %d\n", __func__, ret);
++ goto out_free_cpufreq_table;
++ }
++
++ /* CPUs in the same cluster share a clock and power domain. */
++ cpumask_setall(policy->cpus);
++ policy->driver_data = info;
++ policy->clk = info->cpu_clk;
++
++ return 0;
++
++out_free_cpufreq_table:
++ dev_pm_opp_free_cpufreq_table(info->cpu_dev, &freq_table);
++
++out_release_dvfs_info:
++ mtk_cpu_dvfs_info_release(info);
++
++out_free_dvfs_info:
++ kfree(info);
++
++ return ret;
++}
++
++static int mtk_cpufreq_exit(struct cpufreq_policy *policy)
++{
++ struct mtk_cpu_dvfs_info *info = policy->driver_data;
++
++ cpufreq_cooling_unregister(info->cdev);
++ dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table);
++ mtk_cpu_dvfs_info_release(info);
++ kfree(info);
++
++ return 0;
++}
++
++static struct cpufreq_driver mt7623_cpufreq_driver = {
++ .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
++ .verify = cpufreq_generic_frequency_table_verify,
++ .target_index = mtk_cpufreq_set_target,
++ .get = cpufreq_generic_get,
++ .init = mtk_cpufreq_init,
++ .exit = mtk_cpufreq_exit,
++ .ready = mtk_cpufreq_ready,
++ .name = "mtk-cpufreq",
++ .attr = cpufreq_generic_attr,
++};
++
++static int mt7623_cpufreq_probe(struct platform_device *pdev)
++{
++ int ret;
++
++ ret = cpufreq_register_driver(&mt7623_cpufreq_driver);
++ if (ret)
++ pr_err("failed to register mtk cpufreq driver\n");
++
++ return ret;
++}
++
++static struct platform_driver mt7623_cpufreq_platdrv = {
++ .driver = {
++ .name = "mt7623-cpufreq",
++ },
++ .probe = mt7623_cpufreq_probe,
++};
++
++static int mt7623_cpufreq_driver_init(void)
++{
++ struct platform_device *pdev;
++ int err;
++
++ if (!of_machine_is_compatible("mediatek,mt7623"))
++ return -ENODEV;
++
++ err = platform_driver_register(&mt7623_cpufreq_platdrv);
++ if (err)
++ return err;
++
++ /*
++ * Since there's no place to hold device registration code and no
++ * device tree based way to match cpufreq driver yet, both the driver
++ * and the device registration codes are put here to handle defer
++ * probing.
++ */
++ pdev = platform_device_register_simple("mt7623-cpufreq", -1, NULL, 0);
++ if (IS_ERR(pdev)) {
++ pr_err("failed to register mtk-cpufreq platform device\n");
++ return PTR_ERR(pdev);
++ }
++
++ return 0;
++}
++device_initcall(mt7623_cpufreq_driver_init);
--- /dev/null
+From 6f5941c93bdf7649f392f1263b9068d360ceab4d Mon Sep 17 00:00:00 2001
+From: John Crispin <john@phrozen.org>
+Date: Fri, 6 May 2016 02:55:48 +0200
+Subject: [PATCH 071/102] pwm: add pwm-mediatek
+
+Signed-off-by: John Crispin <john@phrozen.org>
+---
+ arch/arm/boot/dts/mt7623-evb.dts | 17 +++
+ arch/arm/boot/dts/mt7623.dtsi | 22 ++++
+ drivers/pwm/Kconfig | 9 ++
+ drivers/pwm/Makefile | 1 +
+ drivers/pwm/pwm-mediatek.c | 230 ++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 279 insertions(+)
+ create mode 100644 drivers/pwm/pwm-mediatek.c
+
+--- a/arch/arm/boot/dts/mt7623-evb.dts
++++ b/arch/arm/boot/dts/mt7623-evb.dts
+@@ -26,8 +26,25 @@
+ memory {
+ reg = <0 0x80000000 0 0x40000000>;
+ };
++/*
++ pwm_pins: pwm {
++ pins_pwm1 {
++ pinmux = <MT7623_PIN_204_PWM1_FUNC_PWM1>;
++ };
++
++ pins_pwm2 {
++ pinmux = <MT7623_PIN_205_PWM2_FUNC_PWM2>;
++ };
++ };*/
++
+ };
+
+ &uart2 {
+ status = "okay";
+ };
++
++/*&pwm {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_pins>;
++ status = "okay";
++};*/
+--- a/drivers/pwm/Kconfig
++++ b/drivers/pwm/Kconfig
+@@ -282,6 +282,15 @@
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-mtk-disp.
+
++config PWM_MEDIATEK
++ tristate "MediaTek PWM support"
++ depends on ARCH_MEDIATEK || COMPILE_TEST
++ help
++ Generic PWM framework driver for Mediatek ARM SoC.
++
++ To compile this driver as a module, choose M here: the module
++ will be called pwm-mxs.
++
+ config PWM_MXS
+ tristate "Freescale MXS PWM support"
+ depends on ARCH_MXS && OF
+--- a/drivers/pwm/Makefile
++++ b/drivers/pwm/Makefile
+@@ -25,6 +25,7 @@
+ obj-$(CONFIG_PWM_LPSS_PCI) += pwm-lpss-pci.o
+ obj-$(CONFIG_PWM_LPSS_PLATFORM) += pwm-lpss-platform.o
+ obj-$(CONFIG_PWM_MESON) += pwm-meson.o
++obj-$(CONFIG_PWM_MEDIATEK) += pwm-mediatek.o
+ obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o
+ obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
+ obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o
+--- /dev/null
++++ b/drivers/pwm/pwm-mediatek.c
+@@ -0,0 +1,230 @@
++/*
++ * Mediatek Pulse Width Modulator driver
++ *
++ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2. This program is licensed "as is" without any
++ * warranty of any kind, whether express or implied.
++ */
++
++#include <linux/err.h>
++#include <linux/io.h>
++#include <linux/ioport.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/clk.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/pwm.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++
++#define NUM_PWM 5
++
++/* PWM registers and bits definitions */
++#define PWMCON 0x00
++#define PWMHDUR 0x04
++#define PWMLDUR 0x08
++#define PWMGDUR 0x0c
++#define PWMWAVENUM 0x28
++#define PWMDWIDTH 0x2c
++#define PWMTHRES 0x30
++
++/**
++ * struct mtk_pwm_chip - struct representing pwm chip
++ *
++ * @mmio_base: base address of pwm chip
++ * @chip: linux pwm chip representation
++ */
++struct mtk_pwm_chip {
++ void __iomem *mmio_base;
++ struct pwm_chip chip;
++ struct clk *clk_top;
++ struct clk *clk_main;
++ struct clk *clk_pwm[NUM_PWM];
++};
++
++static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
++{
++ return container_of(chip, struct mtk_pwm_chip, chip);
++}
++
++static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
++ unsigned long offset)
++{
++ return ioread32(chip->mmio_base + 0x10 + (num * 0x40) + offset);
++}
++
++static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
++ unsigned int num, unsigned long offset,
++ unsigned long val)
++{
++ iowrite32(val, chip->mmio_base + 0x10 + (num * 0x40) + offset);
++}
++
++static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
++ int duty_ns, int period_ns)
++{
++ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
++ u32 resolution = 100 / 4;
++ u32 clkdiv = 0;
++
++ resolution = 1000000000 / (clk_get_rate(pc->clk_pwm[pwm->hwpwm]));
++
++ while (period_ns / resolution > 8191) {
++ clkdiv++;
++ resolution *= 2;
++ }
++
++ if (clkdiv > 7)
++ return -1;
++
++ mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | BIT(3) | clkdiv);
++ mtk_pwm_writel(pc, pwm->hwpwm, PWMDWIDTH, period_ns / resolution);
++ mtk_pwm_writel(pc, pwm->hwpwm, PWMTHRES, duty_ns / resolution);
++ return 0;
++}
++
++static int mtk_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
++ u32 val;
++ int ret;
++
++ ret = clk_prepare(pc->clk_pwm[pwm->hwpwm]);
++ if (ret < 0)
++ return ret;
++
++ val = ioread32(pc->mmio_base);
++ val |= BIT(pwm->hwpwm);
++ iowrite32(val, pc->mmio_base);
++
++ return 0;
++}
++
++static void mtk_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++ struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
++ u32 val;
++
++ val = ioread32(pc->mmio_base);
++ val &= ~BIT(pwm->hwpwm);
++ iowrite32(val, pc->mmio_base);
++ clk_unprepare(pc->clk_pwm[pwm->hwpwm]);
++}
++
++static const struct pwm_ops mtk_pwm_ops = {
++ .config = mtk_pwm_config,
++ .enable = mtk_pwm_enable,
++ .disable = mtk_pwm_disable,
++ .owner = THIS_MODULE,
++};
++
++static int mtk_pwm_probe(struct platform_device *pdev)
++{
++ struct mtk_pwm_chip *pc;
++ struct resource *r;
++ int ret;
++
++ pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
++ if (!pc)
++ return -ENOMEM;
++
++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ pc->mmio_base = devm_ioremap_resource(&pdev->dev, r);
++ if (IS_ERR(pc->mmio_base))
++ return PTR_ERR(pc->mmio_base);
++
++ pc->clk_main = devm_clk_get(&pdev->dev, "main");
++ if (IS_ERR(pc->clk_main))
++ return PTR_ERR(pc->clk_main);
++
++ pc->clk_top = devm_clk_get(&pdev->dev, "top");
++ if (IS_ERR(pc->clk_top))
++ return PTR_ERR(pc->clk_top);
++
++ pc->clk_pwm[0] = devm_clk_get(&pdev->dev, "pwm1");
++ if (IS_ERR(pc->clk_pwm[0]))
++ return PTR_ERR(pc->clk_pwm[0]);
++
++ pc->clk_pwm[1] = devm_clk_get(&pdev->dev, "pwm2");
++ if (IS_ERR(pc->clk_pwm[1]))
++ return PTR_ERR(pc->clk_pwm[1]);
++
++ pc->clk_pwm[2] = devm_clk_get(&pdev->dev, "pwm3");
++ if (IS_ERR(pc->clk_pwm[2]))
++ return PTR_ERR(pc->clk_pwm[2]);
++
++ pc->clk_pwm[3] = devm_clk_get(&pdev->dev, "pwm4");
++ if (IS_ERR(pc->clk_pwm[3]))
++ return PTR_ERR(pc->clk_pwm[3]);
++
++ pc->clk_pwm[4] = devm_clk_get(&pdev->dev, "pwm5");
++ if (IS_ERR(pc->clk_pwm[4]))
++ return PTR_ERR(pc->clk_pwm[4]);
++
++ ret = clk_prepare(pc->clk_top);
++ if (ret < 0)
++ return ret;
++
++ ret = clk_prepare(pc->clk_main);
++ if (ret < 0)
++ goto disable_clk_top;
++
++ platform_set_drvdata(pdev, pc);
++
++ pc->chip.dev = &pdev->dev;
++ pc->chip.ops = &mtk_pwm_ops;
++ pc->chip.base = -1;
++ pc->chip.npwm = NUM_PWM;
++
++ ret = pwmchip_add(&pc->chip);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
++ goto disable_clk_main;
++ }
++
++ return 0;
++
++disable_clk_main:
++ clk_unprepare(pc->clk_main);
++disable_clk_top:
++ clk_unprepare(pc->clk_top);
++
++ return ret;
++}
++
++static int mtk_pwm_remove(struct platform_device *pdev)
++{
++ struct mtk_pwm_chip *pc = platform_get_drvdata(pdev);
++ int i;
++
++ for (i = 0; i < NUM_PWM; i++)
++ pwm_disable(&pc->chip.pwms[i]);
++
++ return pwmchip_remove(&pc->chip);
++}
++
++static const struct of_device_id mtk_pwm_of_match[] = {
++ { .compatible = "mediatek,mt7623-pwm" },
++ { }
++};
++
++MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
++
++static struct platform_driver mtk_pwm_driver = {
++ .driver = {
++ .name = "mtk-pwm",
++ .owner = THIS_MODULE,
++ .of_match_table = mtk_pwm_of_match,
++ },
++ .probe = mtk_pwm_probe,
++ .remove = mtk_pwm_remove,
++};
++
++module_platform_driver(mtk_pwm_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
++MODULE_ALIAS("platform:mtk-pwm");
--- /dev/null
+From 6b8a7257e7bcb56782c3f8048311670fe6a80209 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Mon, 11 Apr 2016 03:11:54 +0200
+Subject: [PATCH 101/102] net: mediatek add gsw/mt7530 driver
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/net/ethernet/mediatek/Makefile | 2 +-
+ drivers/net/ethernet/mediatek/gsw_mt7620.h | 251 +++++++
+ drivers/net/ethernet/mediatek/gsw_mt7623.c | 1084 +++++++++++++++++++++++++++
+ 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 +
+ 7 files changed, 2199 insertions(+), 30 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
+
+--- 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
+--- /dev/null
++++ b/drivers/net/ethernet/mediatek/gsw_mt7620.h
+@@ -0,0 +1,251 @@
++/* 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@nbd.name>
++ * 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;
++ bool wllll;
++};
++
++/* 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
+--- /dev/null
++++ b/drivers/net/ethernet/mediatek/gsw_mt7623.c
+@@ -0,0 +1,1084 @@
++/* 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@nbd.name>
++ * 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/of_mdio.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"
++
++#define ETHSYS_CLKCFG0 0x2c
++#define ETHSYS_TRGMII_CLK_SEL362_5 BIT(11)
++
++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);
++}
++
++int mt7623_gsw_config(struct mtk_eth *eth)
++{
++ if (eth->mii_bus && mdiobus_get_phy(eth->mii_bus, 0x1f))
++ mt7530_probe(eth->dev, NULL, eth->mii_bus, 1);
++
++ return 0;
++}
++
++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, 0x700c);
++
++ for (i = 0; i < 5; i++)
++ if (reg & BIT(i)) {
++ unsigned int link;
++
++ link = mt7530_mdio_r32(gsw,
++ 0x3008 + (i * 0x100)) & 0x1;
++
++ if (link)
++ dev_info(gsw->dev,
++ "port %d link up\n", i);
++ else
++ dev_info(gsw->dev,
++ "port %d link down\n", i);
++ }
++
++// mt7620_handle_carrier(eth);
++ mt7530_mdio_w32(gsw, 0x700c, 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);
++}
++
++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);
++
++ pr_err("Enable Training Mode in MT7530\n");
++ read_data = mt7530_mdio_r32(gsw, 0x7A40);
++ read_data |= 0xC0000000;
++ mt7530_mdio_w32(gsw, 0x7A40, read_data); /* Enable Training Mode in MT7530 */
++ err_total_flag = 0;
++ pr_err("Adjust RXC delay in MT7623\n");
++ read_data = 0x0;
++ while (err_total_flag == 0 && read_data != 0x68) {
++ pr_err("2nd Enable EDGE CHK in MT7623\n");
++ /* 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;
++ u32 val;
++
++ 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;
++
++ /* pr_err("Calibration begin ........\n"); */
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x40) | 0x80000000;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x40);
++ read_data = mt7530_mdio_r32(gsw, 0x7a10);
++ /* pr_err("TRGMII_7530_RD_0 is %x\n", read_data); */
++
++ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base + 0x04);
++ read_data &= 0x3fffffff;
++ mt7530_mdio_w32(gsw, TRGMII_7530_base + 0x04, read_data); /* RX clock gating in MT7530 */
++
++ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base + 0x78);
++ read_data |= 0x00002000;
++ mt7530_mdio_w32(gsw, TRGMII_7530_base + 0x78, read_data); /* Set TX OE edge in MT7530 */
++
++ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base);
++ read_data |= 0x80000000;
++ mt7530_mdio_w32(gsw, TRGMII_7530_base, read_data); /* Assert RX reset in MT7530 */
++
++ 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("Enable Training Mode in MT7623\n"); */
++ /*Enable Training Mode in MT7623 */
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x40) | 0x80000000;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x40);
++ if (gsw->trgmii_force == 2000) {
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x40) | 0xC0000000;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x40);
++ } else {
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x40) | 0x80000000;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x40);
++ }
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x078) & 0xfffff0ff;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x078);
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x50) & 0xfffff0ff;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x50);
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x58) & 0xfffff0ff;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x58);
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x60) & 0xfffff0ff;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x60);
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x68) & 0xfffff0ff;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x68);
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x70) & 0xfffff0ff;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x70);
++ val = mtk_switch_r32(gsw, TRGMII_7623_base + 0x78) & 0x00000800;
++ mtk_switch_w32(gsw, val, TRGMII_7623_base + 0x78);
++ err_total_flag = 0;
++ /* pr_err("Adjust RXC delay in MT7530\n"); */
++ read_data = 0x0;
++ while (err_total_flag == 0 && (read_data != 0x68)) {
++ /* pr_err("2nd Enable EDGE CHK in MT7530\n"); */
++ /* Enable EDGE CHK in MT7530 */
++ for (i = 0; i < 5; i++) {
++ 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("2nd Disable EDGE CHK in MT7530\n"); */
++ err_cnt[i] =
++ mt7530_mdio_r32(gsw, TRGMII_7530_RD_0 + i * 8);
++ /* pr_err("***** MT7530 %dth bit ERR_CNT =%x\n",i, err_cnt[i]); */
++ /* pr_err("MT7530 %dth bit ERR_CNT =%x\n",i, err_cnt[i]); */
++ err_cnt[i] >>= 8;
++ err_cnt[i] &= 0x0000ff0f;
++ rd_wd = err_cnt[i] >> 8;
++ rd_wd &= 0x000000ff;
++ err_cnt[i] &= 0x0000000f;
++ /* read_data = mt7530_mdio_r32(gsw,0x7a10,&read_data); */
++ 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 */
++ 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);
++ }
++ /*Adjust RXC delay */
++ if (err_total_flag == 0) {
++ read_data = mt7530_mdio_r32(gsw, TRGMII_7530_base);
++ read_data |= 0x80000000;
++ mt7530_mdio_w32(gsw, TRGMII_7530_base, read_data); /* Assert RX reset in MT7530 */
++
++ read_data =
++ mt7530_mdio_r32(gsw, TRGMII_7530_base + 0x04);
++ read_data &= 0x3fffffff;
++ mt7530_mdio_w32(gsw, TRGMII_7530_base + 0x04, read_data); /* RX clock gating in MT7530 */
++
++ 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]);
++ /* Calculate RXD delay = (TAP_A + TAP_B)/2 */
++ final_tap[i] = (tap_a[i] + tap_b[i]) / 2;
++ /* pr_err("########****** MT7530 %dth bit Final Tap = %d\n", i, final_tap[i]); */
++
++ 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)
++{
++
++ u32 regValue;
++
++ /* 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);
++
++// udelay(120); /* for MT7623 bring up test */
++
++ _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);
++
++ regValue = mt7530_mdio_r32(gsw, 0x7830);
++ regValue &= 0xFFFFFFFC;
++ regValue |= 0x00000001;
++ mt7530_mdio_w32(gsw, 0x7830, regValue);
++
++ regValue = mt7530_mdio_r32(gsw, 0x7a40);
++ regValue &= ~(0x1 << 30);
++ regValue &= ~(0x1 << 28);
++ mt7530_mdio_w32(gsw, 0x7a40, regValue);
++
++ mt7530_mdio_w32(gsw, 0x7a78, 0x55);
++// udelay(100); /* for mt7623 bring up test */
++
++ 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 */
++ regValue = mt7530_mdio_r32(gsw, 0x7a00);
++ regValue |= (0x1 << 31);
++ mt7530_mdio_w32(gsw, 0x7a00, regValue);
++ mdelay(1);
++ regValue &= ~(0x1 << 31);
++ mt7530_mdio_w32(gsw, 0x7a00, regValue);
++ 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);
++ /* Assert MT7623 RXC reset */
++ mtk_switch_m32(gsw, 0, TRGMII_RCK_CTRL_RX_RST, GSW_TRGMII_RCK_CTRL);
++
++ /* Hardware reset Switch */
++ device_reset(eth->dev);
++
++ /* 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);
++ if (gsw->eth->mac[0] &&
++ of_phy_is_fixed_link(gsw->eth->mac[0]->of_node))
++ /* Enable Port 6 */
++ val &= ~MHWTRAP_P6_DIS;
++ else
++ /* Disable Port 6 */
++ val |= MHWTRAP_P6_DIS;
++ if (gsw->eth->mac[1] &&
++ of_phy_is_fixed_link(gsw->eth->mac[1]->of_node)) {
++ /* Enable Port 5 */
++ val &= ~MHWTRAP_P5_DIS;
++ /* Port 5 as PHY */
++ val &= ~MHWTRAP_P5_MAC_SEL;
++ } else {
++ /* Disable Port 5 */
++ val |= MHWTRAP_P5_DIS;
++ /* Port 5 as GMAC */
++ val |= MHWTRAP_P5_MAC_SEL;
++ val |= BIT(7);
++ mt7530_mdio_w32(gsw, MT7530_PMCR_P(5), 0x8000);
++ }
++ /* gphy to port 0/4 */
++ if (gsw->wllll)
++ val |= BIT(20);
++ else
++ val &= ~BIT(20);
++
++ /* 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);
++ dev_info(gsw->dev, "Setting MHWTRAP to 0x%08x\n", val);
++
++ val = mt7530_mdio_r32(gsw, 0x7800);
++ val = (val >> 9) & 0x3;
++ if (val == 0x3) {
++ xtal_mode = 1;
++ /* 25Mhz Xtal - do nothing */
++ } else if (val == 0x2) {
++ /* 40Mhz */
++ xtal_mode = 2;
++
++ /* 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);
++ } else {
++ xtal_mode = 3;
++ /* 20Mhz Xtal - TODO */
++ }
++
++ /* RGMII */
++ _mtk_mdio_write(gsw->eth, 0, 14, 0x1);
++
++ /* set MT7530 central align */
++ val = mt7530_mdio_r32(gsw, 0x7830);
++ val &= ~1;
++ val |= 1<<1;
++ mt7530_mdio_w32(gsw, 0x7830, val);
++
++ val = mt7530_mdio_r32(gsw, 0x7a40);
++ val &= ~(1<<30);
++ mt7530_mdio_w32(gsw, 0x7a40, val);
++
++ mt7530_mdio_w32(gsw, 0x7a78, 0x855);
++
++ /* delay setting for 10/1000M */
++ mt7530_mdio_w32(gsw, 0x7b00, 0x104);
++ mt7530_mdio_w32(gsw, 0x7b04, 0x10);
++
++ /* lower Tx Driving */
++ mt7530_mdio_w32(gsw, 0x7a54, 0x88);
++ mt7530_mdio_w32(gsw, 0x7a5c, 0x88);
++ mt7530_mdio_w32(gsw, 0x7a64, 0x88);
++ mt7530_mdio_w32(gsw, 0x7a6c, 0x88);
++ mt7530_mdio_w32(gsw, 0x7a74, 0x88);
++ mt7530_mdio_w32(gsw, 0x7a7c, 0x88);
++ mt7530_mdio_w32(gsw, 0x7810, 0x11);
++
++ /* Set MT7623/MT7683 TX Driving */
++ mtk_switch_w32(gsw, 0x88, 0x354);
++ mtk_switch_w32(gsw, 0x88, 0x35c);
++ mtk_switch_w32(gsw, 0x88, 0x364);
++ mtk_switch_w32(gsw, 0x88, 0x36c);
++ mtk_switch_w32(gsw, 0x88, 0x374);
++ mtk_switch_w32(gsw, 0x88, 0x37c);
++
++ /* Set GE2 driving and slew rate */
++ regmap_write(gsw->pctl, 0xF00, 0xe00);
++ /* set GE2 TDSEL */
++ regmap_write(gsw->pctl, 0x4C0, 0x5);
++ /* set GE2 TUNE */
++ regmap_write(gsw->pctl, 0xED0, 0x0);
++
++ regmap_write(gsw->pctl, 0xb70, 0);
++ regmap_write(gsw->pctl, 0x250, 0xffff);
++ regmap_write(gsw->pctl, 0x260, 0xff);
++ regmap_write(gsw->pctl, 0x380, 0x37);
++ regmap_write(gsw->pctl, 0x390, 0x40);
++
++ mt7530_trgmii_clock_setting(gsw, xtal_mode);
++
++ //LANWANPartition(gsw);
++
++ /* 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 &= ~(1<<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;
++ gsw->eth = eth;
++ eth->sw_priv = gsw;
++
++ mt7623_hw_init(eth, gsw, np);
++
++ if (request_threaded_irq(gsw->irq, gsw_interrupt_mt7623, NULL, 0,
++ "gsw", eth))
++ pr_err("fail to request irq\n");
++ mt7530_mdio_w32(gsw, 0x7008, 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->trgmii_force = 2000;
++ 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;
++ }
++
++ gsw->wllll = of_property_read_bool(np, "mediatek,wllll");
++
++ pm_runtime_enable(&pdev->dev);
++ pm_runtime_get_sync(&pdev->dev);
++
++ ret = clk_set_rate(gsw->clk_trgpll, 500000000);
++ if (ret)
++ return ret;
++
++ regmap_write(gsw->ethsys, 0x34, 0x800000);
++ regmap_write(gsw->ethsys, 0x34, 0x0);
++
++ 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");
+--- /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;
++}
+--- /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
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -25,6 +25,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)");
+@@ -74,14 +77,14 @@
+ 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");
+ return -1;
+ }
+
+-static u32 _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr,
++u32 _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr,
+ u32 phy_register, u32 write_data)
+ {
+ if (mtk_mdio_busy_wait(eth))
+@@ -100,7 +103,7 @@
+ return 0;
+ }
+
+-static u32 _mtk_mdio_read(struct mtk_eth *eth, int phy_addr, int phy_reg)
++u32 _mtk_mdio_read(struct mtk_eth *eth, int phy_addr, int phy_reg)
+ {
+ u32 d;
+
+@@ -155,7 +158,7 @@
+
+ val = (speed == SPEED_1000) ?
+ RCK_CTRL_RGMII_1000 : RCK_CTRL_RGMII_10_100;
+- mtk_w32(eth, val, TRGMII_RCK_CTRL);
++ mtk_w32(eth, val, _TRGMII_RCK_CTRL);
+
+ val = (speed == SPEED_1000) ?
+ TCK_CTRL_RGMII_1000 : TCK_CTRL_RGMII_10_100;
+@@ -1833,15 +1836,6 @@
+ }
+ regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
+
+- /* 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));
+
+@@ -1851,6 +1845,8 @@
+ /* Enable RX VLan Offloading */
+ mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
+
++ mtk_gsw_init(eth);
++
+ /* disable delay and normal interrupt */
+ mtk_w32(eth, 0, MTK_QDMA_DELAY_INT);
+ mtk_w32(eth, 0, MTK_PDMA_DELAY_INT);
+@@ -1879,6 +1875,8 @@
+ mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
+ }
+
++ mt7623_gsw_config(eth);
++
+ return 0;
+ }
+
+@@ -2379,6 +2377,9 @@
+ if (!eth)
+ return -ENOMEM;
+
++ eth->switch_np = of_parse_phandle(pdev->dev.of_node,
++ "mediatek,switch", 0);
++
+ eth->dev = &pdev->dev;
+ eth->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(eth->base))
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -314,7 +314,7 @@
+ MAC_MCR_FORCE_DPX | MAC_MCR_FORCE_LINK)
+
+ /* TRGMII RXC control register */
+-#define TRGMII_RCK_CTRL 0x10300
++#define _TRGMII_RCK_CTRL 0x10300
+ #define DQSI0(x) ((x << 0) & GENMASK(6, 0))
+ #define DQSI1(x) ((x << 8) & GENMASK(14, 8))
+ #define RXCTL_DMWTLAT(x) ((x << 16) & GENMASK(18, 16))
+@@ -554,6 +554,9 @@
+ struct mii_bus *mii_bus;
+ struct work_struct pending_work;
+ unsigned long state;
++
++ struct device_node *switch_np;
++ void *sw_priv;
+ };
+
+ /* struct mtk_mac - the structure that holds the info about the MACs of the
+@@ -586,4 +589,6 @@
+ 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 */
--- /dev/null
+--- a/drivers/mtd/nand/mtk_nand.c
++++ b/drivers/mtd/nand/mtk_nand.c
+@@ -1017,8 +1017,8 @@ static int mtk_nfc_ooblayout_free(struct
+ if (section >= eccsteps)
+ return -ERANGE;
+
+- oob_region->length = fdm->reg_size - fdm->ecc_size;
+- oob_region->offset = section * fdm->reg_size + fdm->ecc_size;
++ oob_region->length = fdm->reg_size - 1;
++ oob_region->offset = section * fdm->reg_size + 1;
+
+ return 0;
+ }
+@@ -1058,7 +1058,7 @@ static void mtk_nfc_set_fdm(struct mtk_n
+ fdm->reg_size = NFI_FDM_MAX_SIZE;
+
+ /* bad block mark storage */
+- fdm->ecc_size = 1;
++ fdm->ecc_size = fdm->reg_size;
+ }
+
+ static void mtk_nfc_set_bad_mark_ctl(struct mtk_nfc_bad_mark_ctl *bm_ctl,
--- /dev/null
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -775,6 +775,8 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
+ mt6589-aquaris5.dtb \
+ mt6592-evb.dtb \
+ mt7623-evb.dtb \
++ mt7623-eMMC.dtb \
++ mt7623-NAND.dtb \
+ mt8127-moose.dtb \
+ mt8135-evbp1.dtb
+ dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb
--- /dev/null
+--- a/drivers/mtd/devices/block2mtd.c
++++ b/drivers/mtd/devices/block2mtd.c
+@@ -32,6 +32,8 @@
+ #include <linux/slab.h>
+ #include <linux/major.h>
+
++static const char * const block2mtd_probe_types[] = { "cmdlinepart", NULL };
++
+ /* Info for the block device */
+ struct block2mtd_dev {
+ struct list_head list;
+@@ -227,6 +229,7 @@ static struct block2mtd_dev *add_device(
+ #endif
+ const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
+ struct block_device *bdev = ERR_PTR(-ENODEV);
++ struct mtd_part_parser_data ppdata = { 0 };
+ struct block2mtd_dev *dev;
+ struct mtd_partition *part;
+ char *name;
+@@ -307,11 +310,7 @@ static struct block2mtd_dev *add_device(
+ dev->mtd.priv = dev;
+ dev->mtd.owner = THIS_MODULE;
+
+- part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL);
+- part->name = name;
+- part->offset = 0;
+- part->size = dev->mtd.size;
+- if (mtd_device_register(&dev->mtd, part, 1)) {
++ if (mtd_device_parse_register(&dev->mtd, block2mtd_probe_types, &ppdata, NULL, 0)) {
+ /* Device didn't get added, so free the entry */
+ goto err_destroy_mutex;
+ }