mediatek: bump to v4.9
authorJohn Crispin <john@phrozen.org>
Thu, 16 Feb 2017 08:53:03 +0000 (09:53 +0100)
committerJohn Crispin <john@phrozen.org>
Thu, 16 Feb 2017 08:53:30 +0000 (09:53 +0100)
Signed-off-by: John Crispin <john@phrozen.org>
127 files changed:
target/linux/mediatek/Makefile
target/linux/mediatek/config-4.4 [deleted file]
target/linux/mediatek/files/arch/arm/boot/dts/_mt7623.dtsi
target/linux/mediatek/patches-4.4/0001-NET-multi-phy-support.patch [deleted file]
target/linux/mediatek/patches-4.4/0002-soc-mediatek-Separate-scpsys-driver-common-code.patch [deleted file]
target/linux/mediatek/patches-4.4/0003-soc-mediatek-Init-MT8173-scpsys-driver-earlier.patch [deleted file]
target/linux/mediatek/patches-4.4/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch [deleted file]
target/linux/mediatek/patches-4.4/0005-soc-mediatek-Add-MT2701-MT7623-scpsys-driver.patch [deleted file]
target/linux/mediatek/patches-4.4/0006-clk-mediatek-Refine-the-makefile-to-support-multiple.patch [deleted file]
target/linux/mediatek/patches-4.4/0007-dt-bindings-ARM-Mediatek-Document-bindings-for-MT270.patch [deleted file]
target/linux/mediatek/patches-4.4/0008-clk-mediatek-Add-dt-bindings-for-MT2701-clocks.patch [deleted file]
target/linux/mediatek/patches-4.4/0009-clk-mediatek-Add-MT2701-clock-support.patch [deleted file]
target/linux/mediatek/patches-4.4/0010-reset-mediatek-mt2701-reset-controller-dt-binding-fi.patch [deleted file]
target/linux/mediatek/patches-4.4/0011-reset-mediatek-mt2701-reset-driver.patch [deleted file]
target/linux/mediatek/patches-4.4/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch [deleted file]
target/linux/mediatek/patches-4.4/0013-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt2.patch [deleted file]
target/linux/mediatek/patches-4.4/0014-pinctrl-dt-bindings-Add-pinfunc-header-file-for-mt27.patch [deleted file]
target/linux/mediatek/patches-4.4/0015-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt7.patch [deleted file]
target/linux/mediatek/patches-4.4/0016-pinctrl-dt-bindings-Add-pinctrl-file-for-mt7623.patch [deleted file]
target/linux/mediatek/patches-4.4/0017-clk-add-hifsys-reset.patch [deleted file]
target/linux/mediatek/patches-4.4/0018-dt-bindings-Add-a-binding-for-Mediatek-xHCI-host-con.patch [deleted file]
target/linux/mediatek/patches-4.4/0019-xhci-mediatek-support-MTK-xHCI-host-controller.patch [deleted file]
target/linux/mediatek/patches-4.4/0020-arm64-dts-mediatek-add-xHCI-usb-phy-for-mt8173.patch [deleted file]
target/linux/mediatek/patches-4.4/0021-Document-DT-Add-bindings-for-mediatek-MT7623-SoC-Pla.patch [deleted file]
target/linux/mediatek/patches-4.4/0022-soc-mediatek-add-compat-string-for-mt7623-to-scpsys.patch [deleted file]
target/linux/mediatek/patches-4.4/0023-ARM-dts-mediatek-add-MT7623-basic-support.patch [deleted file]
target/linux/mediatek/patches-4.4/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch [deleted file]
target/linux/mediatek/patches-4.4/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch [deleted file]
target/linux/mediatek/patches-4.4/0026-scpsys-various-fixes.patch [deleted file]
target/linux/mediatek/patches-4.4/0027-soc-mediatek-PMIC-wrap-Clear-the-vldclr-if-state-mac.patch [deleted file]
target/linux/mediatek/patches-4.4/0028-ARM-mediatek-add-MT7623-smp-bringup-code.patch [deleted file]
target/linux/mediatek/patches-4.4/0029-soc-mediatek-PMIC-wrap-clear-the-STAUPD_TRIG-bit-of-.patch [deleted file]
target/linux/mediatek/patches-4.4/0030-ARM-mediatek-add-mt2701-smp-bringup-code.patch [deleted file]
target/linux/mediatek/patches-4.4/0031-dt-bindings-ARM-Mediatek-add-MT2701-7623-string-to-t.patch [deleted file]
target/linux/mediatek/patches-4.4/0032-soc-mediatek-PMIC-wrap-don-t-duplicate-the-wrapper-d.patch [deleted file]
target/linux/mediatek/patches-4.4/0033-soc-mediatek-PMIC-wrap-add-wrapper-callbacks-for-ini.patch [deleted file]
target/linux/mediatek/patches-4.4/0034-soc-mediatek-PMIC-wrap-split-SoC-specific-init-into-.patch [deleted file]
target/linux/mediatek/patches-4.4/0035-soc-mediatek-PMIC-wrap-WRAP_INT_EN-needs-a-different.patch [deleted file]
target/linux/mediatek/patches-4.4/0036-soc-mediatek-PMIC-wrap-SPI_WRITE-needs-a-different-b.patch [deleted file]
target/linux/mediatek/patches-4.4/0037-soc-mediatek-PMIC-wrap-move-wdt_src-into-the-pmic_wr.patch [deleted file]
target/linux/mediatek/patches-4.4/0038-soc-mediatek-PMIC-wrap-remove-pwrap_is_mt8135-and-pw.patch [deleted file]
target/linux/mediatek/patches-4.4/0039-soc-mediatek-PMIC-wrap-add-a-slave-specific-struct.patch [deleted file]
target/linux/mediatek/patches-4.4/0040-soc-mediatek-PMIC-wrap-add-mt6323-slave-support.patch [deleted file]
target/linux/mediatek/patches-4.4/0041-soc-mediatek-PMIC-wrap-add-MT2701-7623-support.patch [deleted file]
target/linux/mediatek/patches-4.4/0042-dt-bindings-mfd-Add-bindings-for-the-MediaTek-MT6323.patch [deleted file]
target/linux/mediatek/patches-4.4/0043-mfd-mt6397-int_con-and-int_status-may-vary-in-locati.patch [deleted file]
target/linux/mediatek/patches-4.4/0044-mfd-mt6397-add-support-for-different-Slave-types.patch [deleted file]
target/linux/mediatek/patches-4.4/0045-mfd-mt6397-add-MT6323-support-to-MT6397-driver.patch [deleted file]
target/linux/mediatek/patches-4.4/0046-regulator-Add-document-for-MT6323-regulator.patch [deleted file]
target/linux/mediatek/patches-4.4/0047-regulator-mt6323-Add-support-for-MT6323-regulator.patch [deleted file]
target/linux/mediatek/patches-4.4/0048-net-next-mediatek-document-MediaTek-SoC-ethernet-bin.patch [deleted file]
target/linux/mediatek/patches-4.4/0049-net-next-mediatek-add-support-for-MT7623-ethernet.patch [deleted file]
target/linux/mediatek/patches-4.4/0050-net-next-mediatek-add-Kconfig-and-Makefile.patch [deleted file]
target/linux/mediatek/patches-4.4/0051-net-next-mediatek-add-an-entry-to-MAINTAINERS.patch [deleted file]
target/linux/mediatek/patches-4.4/0052-clk-dont-disable-unused-clocks.patch [deleted file]
target/linux/mediatek/patches-4.4/0053-clk-mediatek-enable-critical-clocks.patch [deleted file]
target/linux/mediatek/patches-4.4/0054-clk-mediatek-Export-CPU-mux-clocks-for-CPU-frequency.patch [deleted file]
target/linux/mediatek/patches-4.4/0055-cpufreq-mediatek-add-driver.patch [deleted file]
target/linux/mediatek/patches-4.4/0056-arm-mediatek-make-a7-timer-work-Signed-off-by-John-C.patch [deleted file]
target/linux/mediatek/patches-4.4/0057-net-mediatek-checking-for-IS_ERR-instead-of-NULL.patch [deleted file]
target/linux/mediatek/patches-4.4/0058-net-mediatek-unlock-on-error-in-mtk_tx_map.patch [deleted file]
target/linux/mediatek/patches-4.4/0059-net-mediatek-use-dma_addr_t-correctly.patch [deleted file]
target/linux/mediatek/patches-4.4/0060-net-mediatek-remove-incorrect-dma_mask-assignment.patch [deleted file]
target/linux/mediatek/patches-4.4/0061-net-mediatek-check-device_reset-return-code.patch [deleted file]
target/linux/mediatek/patches-4.4/0062-net-mediatek-watchdog_timeo-was-not-set.patch [deleted file]
target/linux/mediatek/patches-4.4/0063-net-mediatek-mtk_cal_txd_req-returns-bad-value.patch [deleted file]
target/linux/mediatek/patches-4.4/0064-net-mediatek-remove-superflous-reset-call.patch [deleted file]
target/linux/mediatek/patches-4.4/0065-net-mediatek-fix-stop-and-wakeup-of-queue.patch [deleted file]
target/linux/mediatek/patches-4.4/0066-net-mediatek-fix-mtk_pending_work.patch [deleted file]
target/linux/mediatek/patches-4.4/0067-net-mediatek-fix-TX-locking.patch [deleted file]
target/linux/mediatek/patches-4.4/0068-net-mediatek-move-the-pending_work-struct-to-the-dev.patch [deleted file]
target/linux/mediatek/patches-4.4/0069-net-mediatek-do-not-set-the-QID-field-in-the-TX-DMA-.patch [deleted file]
target/linux/mediatek/patches-4.4/0070-net-mediatek-update-the-IRQ-part-of-the-binding-docu.patch [deleted file]
target/linux/mediatek/patches-4.4/0071-pwm-add-pwm-mediatek.patch [deleted file]
target/linux/mediatek/patches-4.4/0072-mtd-backport-v4.7-0day-patches-from-Boris.patch [deleted file]
target/linux/mediatek/patches-4.4/0073-of-mtd-prepare-helper-reading-NAND-ECC-algo-from-DT.patch [deleted file]
target/linux/mediatek/patches-4.4/0074-mtd-mediatek-device-tree-docs-for-MTK-Smart-Device-G.patch [deleted file]
target/linux/mediatek/patches-4.4/0075-mtd-mediatek-driver-for-MTK-Smart-Device-Gen1-NAND.patch [deleted file]
target/linux/mediatek/patches-4.4/0076-mtd-nand-add-power-domains-to-the-mediatek-driver.patch [deleted file]
target/linux/mediatek/patches-4.4/0077-net-next-mediatek-use-mdiobus_free-in-favour-of-kfre.patch [deleted file]
target/linux/mediatek/patches-4.4/0078-net-next-mediatek-fix-gigabit-and-flow-control-adver.patch [deleted file]
target/linux/mediatek/patches-4.4/0079-net-next-mediatek-add-fixed-phy-support.patch [deleted file]
target/linux/mediatek/patches-4.4/0080-net-next-mediatek-properly-handle-RGMII-modes.patch [deleted file]
target/linux/mediatek/patches-4.4/0081-net-next-mediatek-fix-DQL-support.patch [deleted file]
target/linux/mediatek/patches-4.4/0082-net-next-mediatek-add-missing-return-code-check.patch [deleted file]
target/linux/mediatek/patches-4.4/0083-net-next-mediatek-fix-missing-free-of-scratch-memory.patch [deleted file]
target/linux/mediatek/patches-4.4/0084-net-next-mediatek-invalid-buffer-lookup-in-mtk_tx_ma.patch [deleted file]
target/linux/mediatek/patches-4.4/0085-net-next-mediatek-dropped-rx-packets-are-not-being-c.patch [deleted file]
target/linux/mediatek/patches-4.4/0086-net-next-mediatek-add-next-data-pointer-coherency-pr.patch [deleted file]
target/linux/mediatek/patches-4.4/0087-net-next-mediatek-disable-all-interrupts-during-prob.patch [deleted file]
target/linux/mediatek/patches-4.4/0088-net-next-mediatek-fix-threshold-value.patch [deleted file]
target/linux/mediatek/patches-4.4/0089-net-next-mediatek-increase-watchdog_timeo.patch [deleted file]
target/linux/mediatek/patches-4.4/0090-net-next-mediatek-fix-off-by-one-in-the-TX-ring-allo.patch [deleted file]
target/linux/mediatek/patches-4.4/0091-net-next-mediatek-only-wake-the-queue-if-it-is-stopp.patch [deleted file]
target/linux/mediatek/patches-4.4/0092-net-next-mediatek-remove-superfluous-queue-wake-up-c.patch [deleted file]
target/linux/mediatek/patches-4.4/0093-net-next-mediatek-remove-superfluous-register-reads.patch [deleted file]
target/linux/mediatek/patches-4.4/0094-net-next-mediatek-don-t-use-intermediate-variables-t.patch [deleted file]
target/linux/mediatek/patches-4.4/0095-net-next-mediatek-add-IRQ-locking.patch [deleted file]
target/linux/mediatek/patches-4.4/0096-net-next-mediatek-add-support-for-IRQ-grouping.patch [deleted file]
target/linux/mediatek/patches-4.4/0097-net-next-mediatek-change-my-email-address.patch [deleted file]
target/linux/mediatek/patches-4.4/0098-net-next-mediatek-only-trigger-the-tx-watchdog-reset.patch [deleted file]
target/linux/mediatek/patches-4.4/0099-MAINTAINERS-change-my-email-address.patch [deleted file]
target/linux/mediatek/patches-4.4/0100-MAINTAINERS-add-Sean-as-mediatek-ethernet-maintainer.patch [deleted file]
target/linux/mediatek/patches-4.4/0101-net-mediatek-add-gsw-mt7530-driver.patch [deleted file]
target/linux/mediatek/patches-4.4/0102-net-mediatek-v4.4-backports.patch [deleted file]
target/linux/mediatek/patches-4.4/0103-nand_fixes.patch [deleted file]
target/linux/mediatek/patches-4.4/0200-devicetree.patch [deleted file]
target/linux/mediatek/patches-4.4/0201-block2mtd.patch [deleted file]
target/linux/mediatek/patches-4.9/0000-pinctrl-esw.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0001-NET-multi-phy-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0009-clk-mediatek-Add-MT2701-clock-support.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0011-reset-mediatek-mt2701-reset-driver.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0017-clk-add-hifsys-reset.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0026-scpsys-various-fixes.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0052-clk-dont-disable-unused-clocks.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0053-clk-mediatek-enable-critical-clocks.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0054-clk-mediatek-Export-CPU-mux-clocks-for-CPU-frequency.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0055-cpufreq-mediatek-add-driver.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0071-pwm-add-pwm-mediatek.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0101-net-mediatek-add-gsw-mt7530-driver.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0103-nand_fixes.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0200-devicetree.patch [new file with mode: 0644]
target/linux/mediatek/patches-4.9/0201-block2mtd.patch [new file with mode: 0644]

index e3eecd5886c29fe90c5a5bbb5945cb1fcc481822..0b495ef70ebacf581184735c56eb711886c5b09f 100644 (file)
@@ -10,7 +10,7 @@ CPU_TYPE:=cortex-a7
 CPU_SUBTYPE:=neon-vfpv4
 MAINTAINER:=John Crispin <john@phrozen.org>
 
-KERNEL_PATCHVER:=4.4
+KERNEL_PATCHVER:=4.9
 
 KERNELNAME:=Image dtbs zImage
 
diff --git a/target/linux/mediatek/config-4.4 b/target/linux/mediatek/config-4.4
deleted file mode 100644 (file)
index 56e721b..0000000
+++ /dev/null
@@ -1,415 +0,0 @@
-# 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
index 87be1b80920ce6dd6f8a3d628dcafc029e4ebae0..0f91194e8af2ce5b286113d3237f9650c9a37680 100644 (file)
@@ -17,7 +17,7 @@
 #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"
 
diff --git a/target/linux/mediatek/patches-4.4/0001-NET-multi-phy-support.patch b/target/linux/mediatek/patches-4.4/0001-NET-multi-phy-support.patch
deleted file mode 100644 (file)
index b60eac0..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-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;
diff --git a/target/linux/mediatek/patches-4.4/0002-soc-mediatek-Separate-scpsys-driver-common-code.patch b/target/linux/mediatek/patches-4.4/0002-soc-mediatek-Separate-scpsys-driver-common-code.patch
deleted file mode 100644 (file)
index 194e669..0000000
+++ /dev/null
@@ -1,665 +0,0 @@
-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 */
diff --git a/target/linux/mediatek/patches-4.4/0003-soc-mediatek-Init-MT8173-scpsys-driver-earlier.patch b/target/linux/mediatek/patches-4.4/0003-soc-mediatek-Init-MT8173-scpsys-driver-earlier.patch
deleted file mode 100644 (file)
index 46af964..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-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);
diff --git a/target/linux/mediatek/patches-4.4/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch b/target/linux/mediatek/patches-4.4/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch
deleted file mode 100644 (file)
index 132d6c8..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-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 */
diff --git a/target/linux/mediatek/patches-4.4/0005-soc-mediatek-Add-MT2701-MT7623-scpsys-driver.patch b/target/linux/mediatek/patches-4.4/0005-soc-mediatek-Add-MT2701-MT7623-scpsys-driver.patch
deleted file mode 100644 (file)
index 2f2337a..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-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");
diff --git a/target/linux/mediatek/patches-4.4/0006-clk-mediatek-Refine-the-makefile-to-support-multiple.patch b/target/linux/mediatek/patches-4.4/0006-clk-mediatek-Refine-the-makefile-to-support-multiple.patch
deleted file mode 100644 (file)
index d4bac23..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-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
diff --git a/target/linux/mediatek/patches-4.4/0007-dt-bindings-ARM-Mediatek-Document-bindings-for-MT270.patch b/target/linux/mediatek/patches-4.4/0007-dt-bindings-ARM-Mediatek-Document-bindings-for-MT270.patch
deleted file mode 100644 (file)
index fd21c0b..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-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
diff --git a/target/linux/mediatek/patches-4.4/0008-clk-mediatek-Add-dt-bindings-for-MT2701-clocks.patch b/target/linux/mediatek/patches-4.4/0008-clk-mediatek-Add-dt-bindings-for-MT2701-clocks.patch
deleted file mode 100644 (file)
index 422a5be..0000000
+++ /dev/null
@@ -1,499 +0,0 @@
-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 */
diff --git a/target/linux/mediatek/patches-4.4/0009-clk-mediatek-Add-MT2701-clock-support.patch b/target/linux/mediatek/patches-4.4/0009-clk-mediatek-Add-MT2701-clock-support.patch
deleted file mode 100644 (file)
index 6f8f68a..0000000
+++ /dev/null
@@ -1,1431 +0,0 @@
-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 = &eth_cg_regs,                   \
-+              .shift = _shift,                        \
-+              .ops = &mtk_clk_gate_ops_no_setclr_inv, \
-+      }
-+
-+static const struct mtk_gate eth_clks[] __initconst = {
-+      GATE_HIF(CLK_ETHSYS_HSDMA, "hsdma_clk", "ethif_sel", 5),
-+      GATE_HIF(CLK_ETHSYS_ESW, "esw_clk", "ethpll_500m_ck", 6),
-+      GATE_HIF(CLK_ETHSYS_GP2, "gp2_clk", "trgpll", 7),
-+      GATE_HIF(CLK_ETHSYS_GP1, "gp1_clk", "ethpll_500m_ck", 8),
-+      GATE_HIF(CLK_ETHSYS_PCM, "pcm_clk", "ethif_sel", 11),
-+      GATE_HIF(CLK_ETHSYS_GDMA, "gdma_clk", "ethif_sel", 14),
-+      GATE_HIF(CLK_ETHSYS_I2S, "i2s_clk", "ethif_sel", 17),
-+      GATE_HIF(CLK_ETHSYS_CRYPTO, "crypto_clk", "ethif_sel", 29),
-+};
-+
-+static void __init mtk_ethsys_init(struct device_node *node)
-+{
-+      struct clk_onecell_data *clk_data;
-+      int r;
-+
-+      clk_data = mtk_alloc_clk_data(CLK_ETHSYS_NR);
-+
-+      mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks),
-+                                              clk_data);
-+
-+      r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-+      if (r)
-+              pr_err("%s(): could not register clock provider: %d\n",
-+                      __func__, r);
-+}
-+CLK_OF_DECLARE(mtk_ethsys, "mediatek,mt2701-ethsys", mtk_ethsys_init);
-+
-+static const struct mtk_gate_regs bdp0_cg_regs __initconst = {
-+      .set_ofs = 0x0104,
-+      .clr_ofs = 0x0108,
-+      .sta_ofs = 0x0100,
-+};
-+
-+static const struct mtk_gate_regs bdp1_cg_regs __initconst = {
-+      .set_ofs = 0x0114,
-+      .clr_ofs = 0x0118,
-+      .sta_ofs = 0x0110,
-+};
-+
-+#define GATE_BDP0(_id, _name, _parent, _shift) {      \
-+              .id = _id,                              \
-+              .name = _name,                          \
-+              .parent_name = _parent,                 \
-+              .regs = &bdp0_cg_regs,                  \
-+              .shift = _shift,                        \
-+              .ops = &mtk_clk_gate_ops_setclr_inv,    \
-+      }
-+
-+#define GATE_BDP1(_id, _name, _parent, _shift) {      \
-+              .id = _id,                              \
-+              .name = _name,                          \
-+              .parent_name = _parent,                 \
-+              .regs = &bdp1_cg_regs,                  \
-+              .shift = _shift,                        \
-+              .ops = &mtk_clk_gate_ops_setclr_inv,    \
-+      }
-+
-+static const struct mtk_gate bdp_clks[] __initconst = {
-+      GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0),
-+      GATE_BDP0(CLK_BDP_BRG_DRAM, "brg_dram", "mm_sel", 1),
-+      GATE_BDP0(CLK_BDP_LARB_DRAM, "larb_dram", "mm_sel", 2),
-+      GATE_BDP0(CLK_BDP_WR_VDI_PXL, "wr_vdi_pxl", "hdmi_0_deep340m", 3),
-+      GATE_BDP0(CLK_BDP_WR_VDI_DRAM, "wr_vdi_dram", "mm_sel", 4),
-+      GATE_BDP0(CLK_BDP_WR_B, "wr_bclk", "mm_sel", 5),
-+      GATE_BDP0(CLK_BDP_DGI_IN, "dgi_in", "dpi1_sel", 6),
-+      GATE_BDP0(CLK_BDP_DGI_OUT, "dgi_out", "dpi_sel", 7),
-+      GATE_BDP0(CLK_BDP_FMT_MAST_27, "fmt_mast_27", "dpi1_sel", 8),
-+      GATE_BDP0(CLK_BDP_FMT_B, "fmt_bclk", "mm_sel", 9),
-+      GATE_BDP0(CLK_BDP_OSD_B, "osd_bclk", "mm_sel", 10),
-+      GATE_BDP0(CLK_BDP_OSD_DRAM, "osd_dram", "mm_sel", 11),
-+      GATE_BDP0(CLK_BDP_OSD_AGENT, "osd_agent", "osd_sel", 12),
-+      GATE_BDP0(CLK_BDP_OSD_PXL, "osd_pxl", "dpi1_sel", 13),
-+      GATE_BDP0(CLK_BDP_RLE_B, "rle_bclk", "mm_sel", 14),
-+      GATE_BDP0(CLK_BDP_RLE_AGENT, "rle_agent", "mm_sel", 15),
-+      GATE_BDP0(CLK_BDP_RLE_DRAM, "rle_dram", "mm_sel", 16),
-+      GATE_BDP0(CLK_BDP_F27M, "f27m", "di_sel", 17),
-+      GATE_BDP0(CLK_BDP_F27M_VDOUT, "f27m_vdout", "di_sel", 18),
-+      GATE_BDP0(CLK_BDP_F27_74_74, "f27_74_74", "di_sel", 19),
-+      GATE_BDP0(CLK_BDP_F2FS, "f2fs", "di_sel", 20),
-+      GATE_BDP0(CLK_BDP_F2FS74_148, "f2fs74_148", "di_sel", 21),
-+      GATE_BDP0(CLK_BDP_FB, "fbclk", "mm_sel", 22),
-+      GATE_BDP0(CLK_BDP_VDO_DRAM, "vdo_dram", "mm_sel", 23),
-+      GATE_BDP0(CLK_BDP_VDO_2FS, "vdo_2fs", "di_sel", 24),
-+      GATE_BDP0(CLK_BDP_VDO_B, "vdo_bclk", "mm_sel", 25),
-+      GATE_BDP0(CLK_BDP_WR_DI_PXL, "wr_di_pxl", "di_sel", 26),
-+      GATE_BDP0(CLK_BDP_WR_DI_DRAM, "wr_di_dram", "mm_sel", 27),
-+      GATE_BDP0(CLK_BDP_WR_DI_B, "wr_di_bclk", "mm_sel", 28),
-+      GATE_BDP0(CLK_BDP_NR_PXL, "nr_pxl", "nr_sel", 29),
-+      GATE_BDP0(CLK_BDP_NR_DRAM, "nr_dram", "mm_sel", 30),
-+      GATE_BDP0(CLK_BDP_NR_B, "nr_bclk", "mm_sel", 31),
-+      GATE_BDP1(CLK_BDP_RX_F, "rx_fclk", "hadds2_fbclk", 0),
-+      GATE_BDP1(CLK_BDP_RX_X, "rx_xclk", "clk26m", 1),
-+      GATE_BDP1(CLK_BDP_RXPDT, "rxpdtclk", "hdmi_0_pix340m", 2),
-+      GATE_BDP1(CLK_BDP_RX_CSCL_N, "rx_cscl_n", "clk26m", 3),
-+      GATE_BDP1(CLK_BDP_RX_CSCL, "rx_cscl", "clk26m", 4),
-+      GATE_BDP1(CLK_BDP_RX_DDCSCL_N, "rx_ddcscl_n", "hdmi_scl_rx", 5),
-+      GATE_BDP1(CLK_BDP_RX_DDCSCL, "rx_ddcscl", "hdmi_scl_rx", 6),
-+      GATE_BDP1(CLK_BDP_RX_VCO, "rx_vcoclk", "hadds2pll_294m", 7),
-+      GATE_BDP1(CLK_BDP_RX_DP, "rx_dpclk", "hdmi_0_pll340m", 8),
-+      GATE_BDP1(CLK_BDP_RX_P, "rx_pclk", "hdmi_0_pll340m", 9),
-+      GATE_BDP1(CLK_BDP_RX_M, "rx_mclk", "hadds2pll_294m", 10),
-+      GATE_BDP1(CLK_BDP_RX_PLL, "rx_pllclk", "hdmi_0_pix340m", 11),
-+      GATE_BDP1(CLK_BDP_BRG_RT_B, "brg_rt_bclk", "mm_sel", 12),
-+      GATE_BDP1(CLK_BDP_BRG_RT_DRAM, "brg_rt_dram", "mm_sel", 13),
-+      GATE_BDP1(CLK_BDP_LARBRT_DRAM, "larbrt_dram", "mm_sel", 14),
-+      GATE_BDP1(CLK_BDP_TMDS_SYN, "tmds_syn", "hdmi_0_pll340m", 15),
-+      GATE_BDP1(CLK_BDP_HDMI_MON, "hdmi_mon", "hdmi_0_mon", 16),
-+};
-+
-+static void __init mtk_bdpsys_init(struct device_node *node)
-+{
-+      struct clk_onecell_data *clk_data;
-+      int r;
-+
-+      clk_data = mtk_alloc_clk_data(CLK_BDP_NR);
-+
-+      mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks),
-+                                              clk_data);
-+
-+      r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-+      if (r)
-+              pr_err("%s(): could not register clock provider: %d\n",
-+                      __func__, r);
-+}
-+CLK_OF_DECLARE(mtk_bdpsys, "mediatek,mt2701-bdpsys", mtk_bdpsys_init);
-+
-+#define MT8590_PLL_FMAX               (2000 * MHZ)
-+#define CON0_MT8590_RST_BAR   BIT(27)
-+
-+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \
-+                      _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) {  \
-+              .id = _id,                                              \
-+              .name = _name,                                          \
-+              .reg = _reg,                                            \
-+              .pwr_reg = _pwr_reg,                                    \
-+              .en_mask = _en_mask,                                    \
-+              .flags = _flags,                                        \
-+              .rst_bar_mask = CON0_MT8590_RST_BAR,                    \
-+              .fmax = MT8590_PLL_FMAX,                                \
-+              .pcwbits = _pcwbits,                                    \
-+              .pd_reg = _pd_reg,                                      \
-+              .pd_shift = _pd_shift,                                  \
-+              .tuner_reg = _tuner_reg,                                \
-+              .pcw_reg = _pcw_reg,                                    \
-+              .pcw_shift = _pcw_shift,                                \
-+      }
-+
-+static const struct mtk_pll_data apmixed_plls[] = {
-+      PLL(CLK_APMIXED_ARMPLL, "armpll", 0x200, 0x20c, 0x80000001, 0,
-+                              21, 0x204, 24, 0x0, 0x204, 0),
-+      PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x210, 0x21c, 0xf0000001,
-+                HAVE_RST_BAR, 21, 0x210, 4, 0x0, 0x214, 0),
-+      PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x220, 0x22c, 0xf3000001,
-+                HAVE_RST_BAR, 7, 0x220, 4, 0x0, 0x224, 14),
-+      PLL(CLK_APMIXED_MMPLL, "mmpll", 0x230, 0x23c, 0x00000001, 0,
-+                              21, 0x230, 4, 0x0, 0x234, 0),
-+      PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x240, 0x24c, 0x00000001, 0,
-+                              21, 0x240, 4, 0x0, 0x244, 0),
-+      PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x250, 0x25c, 0x00000001, 0,
-+                              21, 0x250, 4, 0x0, 0x254, 0),
-+      PLL(CLK_APMIXED_AUD1PLL, "aud1pll", 0x270, 0x27c, 0x00000001, 0,
-+                              31, 0x270, 4, 0x0, 0x274, 0),
-+      PLL(CLK_APMIXED_TRGPLL, "trgpll", 0x280, 0x28c, 0x00000001, 0,
-+                              31, 0x280, 4, 0x0, 0x284, 0),
-+      PLL(CLK_APMIXED_ETHPLL, "ethpll", 0x290, 0x29c, 0x00000001, 0,
-+                              31, 0x290, 4, 0x0, 0x294, 0),
-+      PLL(CLK_APMIXED_VDECPLL, "vdecpll", 0x2a0, 0x2ac, 0x00000001, 0,
-+                              31, 0x2a0, 4, 0x0, 0x2a4, 0),
-+      PLL(CLK_APMIXED_HADDS2PLL, "hadds2pll", 0x2b0, 0x2bc, 0x00000001, 0,
-+                              31, 0x2b0, 4, 0x0, 0x2b4, 0),
-+      PLL(CLK_APMIXED_AUD2PLL, "aud2pll", 0x2c0, 0x2cc, 0x00000001, 0,
-+                              31, 0x2c0, 4, 0x0, 0x2c4, 0),
-+      PLL(CLK_APMIXED_TVD2PLL, "tvd2pll", 0x2d0, 0x2dc, 0x00000001, 0,
-+                              21, 0x2d0, 4, 0x0, 0x2d4, 0),
-+};
-+
-+static void __init mtk_apmixedsys_init(struct device_node *node)
-+{
-+      struct clk_onecell_data *clk_data;
-+      int r;
-+
-+      clk_data = mtk_alloc_clk_data(ARRAY_SIZE(apmixed_plls));
-+      if (!clk_data)
-+              return;
-+
-+      mtk_clk_register_plls(node, apmixed_plls, ARRAY_SIZE(apmixed_plls),
-+                                                              clk_data);
-+
-+      r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-+      if (r)
-+              pr_err("%s(): could not register clock provider: %d\n",
-+                      __func__, r);
-+}
-+CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt2701-apmixedsys",
-+                                                      mtk_apmixedsys_init);
---- 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);
diff --git a/target/linux/mediatek/patches-4.4/0010-reset-mediatek-mt2701-reset-controller-dt-binding-fi.patch b/target/linux/mediatek/patches-4.4/0010-reset-mediatek-mt2701-reset-controller-dt-binding-fi.patch
deleted file mode 100644 (file)
index b5b10e7..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-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 */
diff --git a/target/linux/mediatek/patches-4.4/0011-reset-mediatek-mt2701-reset-driver.patch b/target/linux/mediatek/patches-4.4/0011-reset-mediatek-mt2701-reset-driver.patch
deleted file mode 100644 (file)
index 18d4fbf..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-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);
diff --git a/target/linux/mediatek/patches-4.4/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch b/target/linux/mediatek/patches-4.4/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch
deleted file mode 100644 (file)
index 479334a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-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
diff --git a/target/linux/mediatek/patches-4.4/0013-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt2.patch b/target/linux/mediatek/patches-4.4/0013-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt2.patch
deleted file mode 100644 (file)
index af1ad66..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-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.
diff --git a/target/linux/mediatek/patches-4.4/0014-pinctrl-dt-bindings-Add-pinfunc-header-file-for-mt27.patch b/target/linux/mediatek/patches-4.4/0014-pinctrl-dt-bindings-Add-pinfunc-header-file-for-mt27.patch
deleted file mode 100644 (file)
index 0df6d18..0000000
+++ /dev/null
@@ -1,3792 +0,0 @@
-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(&reg_addr, offset);
-+
-       if (input)
-               /* Different SoC has different alignment offset. */
-               reg_addr = CLR_ADDR(reg_addr, pctl);
-@@ -347,6 +352,7 @@ static int mtk_pconf_parse_conf(struct 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(&reg_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 */
diff --git a/target/linux/mediatek/patches-4.4/0015-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt7.patch b/target/linux/mediatek/patches-4.4/0015-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt7.patch
deleted file mode 100644 (file)
index fcd39c4..0000000
+++ /dev/null
@@ -1,547 +0,0 @@
-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 */
-+
diff --git a/target/linux/mediatek/patches-4.4/0016-pinctrl-dt-bindings-Add-pinctrl-file-for-mt7623.patch b/target/linux/mediatek/patches-4.4/0016-pinctrl-dt-bindings-Add-pinctrl-file-for-mt7623.patch
deleted file mode 100644 (file)
index 3428fce..0000000
+++ /dev/null
@@ -1,2379 +0,0 @@
-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)
diff --git a/target/linux/mediatek/patches-4.4/0017-clk-add-hifsys-reset.patch b/target/linux/mediatek/patches-4.4/0017-clk-add-hifsys-reset.patch
deleted file mode 100644 (file)
index d7d151c..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-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 */
diff --git a/target/linux/mediatek/patches-4.4/0018-dt-bindings-Add-a-binding-for-Mediatek-xHCI-host-con.patch b/target/linux/mediatek/patches-4.4/0018-dt-bindings-Add-a-binding-for-Mediatek-xHCI-host-con.patch
deleted file mode 100644 (file)
index 9c178f2..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-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>;
-+};
diff --git a/target/linux/mediatek/patches-4.4/0019-xhci-mediatek-support-MTK-xHCI-host-controller.patch b/target/linux/mediatek/patches-4.4/0019-xhci-mediatek-support-MTK-xHCI-host-controller.patch
deleted file mode 100644 (file)
index f081439..0000000
+++ /dev/null
@@ -1,1525 +0,0 @@
-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;
diff --git a/target/linux/mediatek/patches-4.4/0020-arm64-dts-mediatek-add-xHCI-usb-phy-for-mt8173.patch b/target/linux/mediatek/patches-4.4/0020-arm64-dts-mediatek-add-xHCI-usb-phy-for-mt8173.patch
deleted file mode 100644 (file)
index 50c03ee..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-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>;
diff --git a/target/linux/mediatek/patches-4.4/0021-Document-DT-Add-bindings-for-mediatek-MT7623-SoC-Pla.patch b/target/linux/mediatek/patches-4.4/0021-Document-DT-Add-bindings-for-mediatek-MT7623-SoC-Pla.patch
deleted file mode 100644 (file)
index 223c226..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-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
diff --git a/target/linux/mediatek/patches-4.4/0022-soc-mediatek-add-compat-string-for-mt7623-to-scpsys.patch b/target/linux/mediatek/patches-4.4/0022-soc-mediatek-add-compat-string-for-mt7623-to-scpsys.patch
deleted file mode 100644 (file)
index 453b612..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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 */
-       }
- };
diff --git a/target/linux/mediatek/patches-4.4/0023-ARM-dts-mediatek-add-MT7623-basic-support.patch b/target/linux/mediatek/patches-4.4/0023-ARM-dts-mediatek-add-MT7623-basic-support.patch
deleted file mode 100644 (file)
index c1f2690..0000000
+++ /dev/null
@@ -1,1079 +0,0 @@
-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";
-+};
-+
-+&eth {
-+      status = "okay";
-+};
-+
-+&gmac1 {
-+      mac-address = [00 11 22 33 44 56];
-+      status = "okay";
-+};
-+
-+&gmac2 {
-+      mac-address = [00 11 22 33 44 55];
-+      status = "okay";
-+};
-+
-+&gsw {
-+      pinctrl-names = "default";
-+      pinctrl-0 = <&eth_default>;
-+      mediatek,reset-pin = <&pio 15 0>;
-+      status = "okay";
-+};
---- /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>,
-+                       <&ethsys CLK_ETHSYS_ESW>,
-+                       <&ethsys CLK_ETHSYS_GP2>,
-+                       <&ethsys CLK_ETHSYS_GP1>;
-+              clock-names = "ethif", "esw", "gp2", "gp1";
-+              interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_LOW
-+                            GIC_SPI 199 IRQ_TYPE_LEVEL_LOW
-+                            GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
-+              power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
-+
-+              resets = <&ethsys 6>;
-+              reset-names = "eth";
-+
-+              mediatek,ethsys = <&ethsys>;
-+              mediatek,pctl = <&syscfg_pctl_a>;
-+
-+              mediatek,switch = <&gsw>;
-+
-+              #address-cells = <1>;
-+              #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 = <&ethsys 2>;
-+              reset-names = "eth";
-+              clocks = <&apmixedsys CLK_APMIXED_TRGPLL>;
-+              clock-names = "trgpll";
-+              mt7530-supply = <&mt6323_vpa_reg>;
-+              mediatek,pctl-regmap = <&syscfg_pctl_a>;
-+              mediatek,ethsys = <&ethsys>;
-+              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,
diff --git a/target/linux/mediatek/patches-4.4/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch b/target/linux/mediatek/patches-4.4/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch
deleted file mode 100644 (file)
index d6fe977..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-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";
-+              };
-+      };
diff --git a/target/linux/mediatek/patches-4.4/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch b/target/linux/mediatek/patches-4.4/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch
deleted file mode 100644 (file)
index bcb109d..0000000
+++ /dev/null
@@ -1,698 +0,0 @@
-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);
diff --git a/target/linux/mediatek/patches-4.4/0026-scpsys-various-fixes.patch b/target/linux/mediatek/patches-4.4/0026-scpsys-various-fixes.patch
deleted file mode 100644 (file)
index 7ec3033..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-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 */
diff --git a/target/linux/mediatek/patches-4.4/0027-soc-mediatek-PMIC-wrap-Clear-the-vldclr-if-state-mac.patch b/target/linux/mediatek/patches-4.4/0027-soc-mediatek-PMIC-wrap-Clear-the-vldclr-if-state-mac.patch
deleted file mode 100644 (file)
index 964373b..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-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);
diff --git a/target/linux/mediatek/patches-4.4/0028-ARM-mediatek-add-MT7623-smp-bringup-code.patch b/target/linux/mediatek/patches-4.4/0028-ARM-mediatek-add-MT7623-smp-bringup-code.patch
deleted file mode 100644 (file)
index 4aacd26..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-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;
diff --git a/target/linux/mediatek/patches-4.4/0029-soc-mediatek-PMIC-wrap-clear-the-STAUPD_TRIG-bit-of-.patch b/target/linux/mediatek/patches-4.4/0029-soc-mediatek-PMIC-wrap-clear-the-STAUPD_TRIG-bit-of-.patch
deleted file mode 100644 (file)
index eb936a7..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-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);
diff --git a/target/linux/mediatek/patches-4.4/0030-ARM-mediatek-add-mt2701-smp-bringup-code.patch b/target/linux/mediatek/patches-4.4/0030-ARM-mediatek-add-mt2701-smp-bringup-code.patch
deleted file mode 100644 (file)
index 790ccca..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-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 = {
diff --git a/target/linux/mediatek/patches-4.4/0031-dt-bindings-ARM-Mediatek-add-MT2701-7623-string-to-t.patch b/target/linux/mediatek/patches-4.4/0031-dt-bindings-ARM-Mediatek-add-MT2701-7623-string-to-t.patch
deleted file mode 100644 (file)
index 186b2f4..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-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
diff --git a/target/linux/mediatek/patches-4.4/0032-soc-mediatek-PMIC-wrap-don-t-duplicate-the-wrapper-d.patch b/target/linux/mediatek/patches-4.4/0032-soc-mediatek-PMIC-wrap-don-t-duplicate-the-wrapper-d.patch
deleted file mode 100644 (file)
index 8092e96..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-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");
diff --git a/target/linux/mediatek/patches-4.4/0033-soc-mediatek-PMIC-wrap-add-wrapper-callbacks-for-ini.patch b/target/linux/mediatek/patches-4.4/0033-soc-mediatek-PMIC-wrap-add-wrapper-callbacks-for-ini.patch
deleted file mode 100644 (file)
index 9368a85..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-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",
diff --git a/target/linux/mediatek/patches-4.4/0034-soc-mediatek-PMIC-wrap-split-SoC-specific-init-into-.patch b/target/linux/mediatek/patches-4.4/0034-soc-mediatek-PMIC-wrap-split-SoC-specific-init-into-.patch
deleted file mode 100644 (file)
index 6d9c99a..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-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[] = {
diff --git a/target/linux/mediatek/patches-4.4/0035-soc-mediatek-PMIC-wrap-WRAP_INT_EN-needs-a-different.patch b/target/linux/mediatek/patches-4.4/0035-soc-mediatek-PMIC-wrap-WRAP_INT_EN-needs-a-different.patch
deleted file mode 100644 (file)
index 42fbe2e..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-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,
diff --git a/target/linux/mediatek/patches-4.4/0036-soc-mediatek-PMIC-wrap-SPI_WRITE-needs-a-different-b.patch b/target/linux/mediatek/patches-4.4/0036-soc-mediatek-PMIC-wrap-SPI_WRITE-needs-a-different-b.patch
deleted file mode 100644 (file)
index a80bd73..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-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,
- };
diff --git a/target/linux/mediatek/patches-4.4/0037-soc-mediatek-PMIC-wrap-move-wdt_src-into-the-pmic_wr.patch b/target/linux/mediatek/patches-4.4/0037-soc-mediatek-PMIC-wrap-move-wdt_src-into-the-pmic_wr.patch
deleted file mode 100644 (file)
index 1e2c587..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-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);
diff --git a/target/linux/mediatek/patches-4.4/0038-soc-mediatek-PMIC-wrap-remove-pwrap_is_mt8135-and-pw.patch b/target/linux/mediatek/patches-4.4/0038-soc-mediatek-PMIC-wrap-remove-pwrap_is_mt8135-and-pw.patch
deleted file mode 100644 (file)
index 001793f..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-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);
diff --git a/target/linux/mediatek/patches-4.4/0039-soc-mediatek-PMIC-wrap-add-a-slave-specific-struct.patch b/target/linux/mediatek/patches-4.4/0039-soc-mediatek-PMIC-wrap-add-a-slave-specific-struct.patch
deleted file mode 100644 (file)
index dea271a..0000000
+++ /dev/null
@@ -1,297 +0,0 @@
-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");
diff --git a/target/linux/mediatek/patches-4.4/0040-soc-mediatek-PMIC-wrap-add-mt6323-slave-support.patch b/target/linux/mediatek/patches-4.4/0040-soc-mediatek-PMIC-wrap-add-mt6323-slave-support.patch
deleted file mode 100644 (file)
index 51f0628..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-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,
-       }, {
diff --git a/target/linux/mediatek/patches-4.4/0041-soc-mediatek-PMIC-wrap-add-MT2701-7623-support.patch b/target/linux/mediatek/patches-4.4/0041-soc-mediatek-PMIC-wrap-add-MT2701-7623-support.patch
deleted file mode 100644 (file)
index a50a34a..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-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,
-       }, {
diff --git a/target/linux/mediatek/patches-4.4/0042-dt-bindings-mfd-Add-bindings-for-the-MediaTek-MT6323.patch b/target/linux/mediatek/patches-4.4/0042-dt-bindings-mfd-Add-bindings-for-the-MediaTek-MT6323.patch
deleted file mode 100644 (file)
index 701ee67..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-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"
diff --git a/target/linux/mediatek/patches-4.4/0043-mfd-mt6397-int_con-and-int_status-may-vary-in-locati.patch b/target/linux/mediatek/patches-4.4/0043-mfd-mt6397-int_con-and-int_status-may-vary-in-locati.patch
deleted file mode 100644 (file)
index 6b433b0..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-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__ */
diff --git a/target/linux/mediatek/patches-4.4/0044-mfd-mt6397-add-support-for-different-Slave-types.patch b/target/linux/mediatek/patches-4.4/0044-mfd-mt6397-add-support-for-different-Slave-types.patch
deleted file mode 100644 (file)
index bae05fb..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-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;
- }
diff --git a/target/linux/mediatek/patches-4.4/0045-mfd-mt6397-add-MT6323-support-to-MT6397-driver.patch b/target/linux/mediatek/patches-4.4/0045-mfd-mt6397-add-MT6323-support-to-MT6397-driver.patch
deleted file mode 100644 (file)
index d673a0a..0000000
+++ /dev/null
@@ -1,519 +0,0 @@
-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__ */
diff --git a/target/linux/mediatek/patches-4.4/0046-regulator-Add-document-for-MT6323-regulator.patch b/target/linux/mediatek/patches-4.4/0046-regulator-Add-document-for-MT6323-regulator.patch
deleted file mode 100644 (file)
index d706314..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-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>;
-+                      };
-+              };
-+      };
diff --git a/target/linux/mediatek/patches-4.4/0047-regulator-mt6323-Add-support-for-MT6323-regulator.patch b/target/linux/mediatek/patches-4.4/0047-regulator-mt6323-Add-support-for-MT6323-regulator.patch
deleted file mode 100644 (file)
index 6456c27..0000000
+++ /dev/null
@@ -1,538 +0,0 @@
-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, &regval);
-+      if (ret != 0) {
-+              dev_err(&rdev->dev, "Failed to get enable reg: %d\n", ret);
-+              return ret;
-+      }
-+
-+      return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
-+}
-+
-+static int mt6323_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode)
-+{
-+      int ret, val = 0;
-+      struct mt6323_regulator_info *info = rdev_get_drvdata(rdev);
-+
-+      if (!info->modeset_mask) {
-+              dev_err(&rdev->dev, "regulator %s doesn't support set_mode\n",
-+                      info->desc.name);
-+              return -EINVAL;
-+      }
-+
-+      switch (mode) {
-+      case REGULATOR_MODE_STANDBY:
-+              val = MT6323_LDO_MODE_LP;
-+              break;
-+      case REGULATOR_MODE_NORMAL:
-+              val = MT6323_LDO_MODE_NORMAL;
-+              break;
-+      default:
-+              return -EINVAL;
-+      }
-+
-+      val <<= ffs(info->modeset_mask) - 1;
-+
-+      ret = regmap_update_bits(rdev->regmap, info->modeset_reg,
-+                                info->modeset_mask, val);
-+
-+      return ret;
-+}
-+
-+static unsigned int mt6323_ldo_get_mode(struct regulator_dev *rdev)
-+{
-+      unsigned int val;
-+      unsigned int mode;
-+      int ret;
-+      struct mt6323_regulator_info *info = rdev_get_drvdata(rdev);
-+
-+      if (!info->modeset_mask) {
-+              dev_err(&rdev->dev, "regulator %s doesn't support get_mode\n",
-+                      info->desc.name);
-+              return -EINVAL;
-+      }
-+
-+      ret = regmap_read(rdev->regmap, info->modeset_reg, &val);
-+      if (ret < 0)
-+              return ret;
-+
-+      val &= info->modeset_mask;
-+      val >>= ffs(info->modeset_mask) - 1;
-+
-+      if (val & 0x1)
-+              mode = REGULATOR_MODE_STANDBY;
-+      else
-+              mode = REGULATOR_MODE_NORMAL;
-+
-+      return mode;
-+}
-+
-+static struct regulator_ops mt6323_volt_range_ops = {
-+      .list_voltage = regulator_list_voltage_linear_range,
-+      .map_voltage = regulator_map_voltage_linear_range,
-+      .set_voltage_sel = regulator_set_voltage_sel_regmap,
-+      .get_voltage_sel = regulator_get_voltage_sel_regmap,
-+      .set_voltage_time_sel = regulator_set_voltage_time_sel,
-+      .enable = regulator_enable_regmap,
-+      .disable = regulator_disable_regmap,
-+      .is_enabled = regulator_is_enabled_regmap,
-+      .get_status = mt6323_get_status,
-+};
-+
-+static struct regulator_ops mt6323_volt_table_ops = {
-+      .list_voltage = regulator_list_voltage_table,
-+      .map_voltage = regulator_map_voltage_iterate,
-+      .set_voltage_sel = regulator_set_voltage_sel_regmap,
-+      .get_voltage_sel = regulator_get_voltage_sel_regmap,
-+      .set_voltage_time_sel = regulator_set_voltage_time_sel,
-+      .enable = regulator_enable_regmap,
-+      .disable = regulator_disable_regmap,
-+      .is_enabled = regulator_is_enabled_regmap,
-+      .get_status = mt6323_get_status,
-+      .set_mode = mt6323_ldo_set_mode,
-+      .get_mode = mt6323_ldo_get_mode,
-+};
-+
-+static struct regulator_ops mt6323_volt_fixed_ops = {
-+      .list_voltage = regulator_list_voltage_linear,
-+      .enable = regulator_enable_regmap,
-+      .disable = regulator_disable_regmap,
-+      .is_enabled = regulator_is_enabled_regmap,
-+      .get_status = mt6323_get_status,
-+      .set_mode = mt6323_ldo_set_mode,
-+      .get_mode = mt6323_ldo_get_mode,
-+};
-+
-+/* The array is indexed by id(MT6323_ID_XXX) */
-+static struct mt6323_regulator_info mt6323_regulators[] = {
-+      MT6323_BUCK("buck_vproc", VPROC, 700000, 1493750, 6250,
-+              buck_volt_range1, MT6323_VPROC_CON7, MT6323_VPROC_CON9, 0x7f,
-+              MT6323_VPROC_CON10, MT6323_VPROC_CON5),
-+      MT6323_BUCK("buck_vsys", VSYS, 1400000, 2987500, 12500,
-+              buck_volt_range2, MT6323_VSYS_CON7, MT6323_VSYS_CON9, 0x7f,
-+              MT6323_VSYS_CON10, MT6323_VSYS_CON5),
-+      MT6323_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
-+              buck_volt_range3, MT6323_VPA_CON7, MT6323_VPA_CON9,
-+              0x3f, MT6323_VPA_CON10, MT6323_VPA_CON5),
-+      MT6323_REG_FIXED("ldo_vtcxo", VTCXO, MT6323_ANALDO_CON1, 10, 2800000,
-+              MT6323_ANALDO_CON1, 0x2),
-+      MT6323_REG_FIXED("ldo_vcn28", VCN28, MT6323_ANALDO_CON19, 12, 2800000,
-+              MT6323_ANALDO_CON20, 0x2),
-+      MT6323_LDO("ldo_vcn33_bt", VCN33_BT, ldo_volt_table1,
-+              MT6323_ANALDO_CON16, 7, MT6323_ANALDO_CON16, 0xC,
-+              MT6323_ANALDO_CON21, 0x2),
-+      MT6323_LDO("ldo_vcn33_wifi", VCN33_WIFI, ldo_volt_table1,
-+              MT6323_ANALDO_CON17, 12, MT6323_ANALDO_CON16, 0xC,
-+              MT6323_ANALDO_CON21, 0x2),
-+      MT6323_REG_FIXED("ldo_va", VA, MT6323_ANALDO_CON2, 14, 2800000,
-+              MT6323_ANALDO_CON2, 0x2),
-+      MT6323_LDO("ldo_vcama", VCAMA, ldo_volt_table2,
-+              MT6323_ANALDO_CON4, 15, MT6323_ANALDO_CON10, 0x60, -1, 0),
-+      MT6323_REG_FIXED("ldo_vio28", VIO28, MT6323_DIGLDO_CON0, 14, 2800000,
-+              MT6323_DIGLDO_CON0, 0x2),
-+      MT6323_REG_FIXED("ldo_vusb", VUSB, MT6323_DIGLDO_CON2, 14, 3300000,
-+              MT6323_DIGLDO_CON2, 0x2),
-+      MT6323_LDO("ldo_vmc", VMC, ldo_volt_table3,
-+              MT6323_DIGLDO_CON3, 12, MT6323_DIGLDO_CON24, 0x10,
-+              MT6323_DIGLDO_CON3, 0x2),
-+      MT6323_LDO("ldo_vmch", VMCH, ldo_volt_table4,
-+              MT6323_DIGLDO_CON5, 14, MT6323_DIGLDO_CON26, 0x80,
-+              MT6323_DIGLDO_CON5, 0x2),
-+      MT6323_LDO("ldo_vemc3v3", VEMC3V3, ldo_volt_table4,
-+              MT6323_DIGLDO_CON6, 14, MT6323_DIGLDO_CON27, 0x80,
-+              MT6323_DIGLDO_CON6, 0x2),
-+      MT6323_LDO("ldo_vgp1", VGP1, ldo_volt_table5,
-+              MT6323_DIGLDO_CON7, 15, MT6323_DIGLDO_CON28, 0xE0,
-+              MT6323_DIGLDO_CON7, 0x2),
-+      MT6323_LDO("ldo_vgp2", VGP2, ldo_volt_table6,
-+              MT6323_DIGLDO_CON8, 15, MT6323_DIGLDO_CON29, 0xE0,
-+              MT6323_DIGLDO_CON8, 0x2),
-+      MT6323_LDO("ldo_vgp3", VGP3, ldo_volt_table7,
-+              MT6323_DIGLDO_CON9, 15, MT6323_DIGLDO_CON30, 0x60,
-+              MT6323_DIGLDO_CON9, 0x2),
-+      MT6323_REG_FIXED("ldo_vcn18", VCN18, MT6323_DIGLDO_CON11, 14, 1800000,
-+              MT6323_DIGLDO_CON11, 0x2),
-+      MT6323_LDO("ldo_vsim1", VSIM1, ldo_volt_table8,
-+              MT6323_DIGLDO_CON13, 15, MT6323_DIGLDO_CON34, 0x20,
-+              MT6323_DIGLDO_CON13, 0x2),
-+      MT6323_LDO("ldo_vsim2", VSIM2, ldo_volt_table8,
-+              MT6323_DIGLDO_CON14, 15, MT6323_DIGLDO_CON35, 0x20,
-+              MT6323_DIGLDO_CON14, 0x2),
-+      MT6323_REG_FIXED("ldo_vrtc", VRTC, MT6323_DIGLDO_CON15, 8, 2800000,
-+              -1, 0),
-+      MT6323_LDO("ldo_vcamaf", VCAMAF, ldo_volt_table5,
-+              MT6323_DIGLDO_CON31, 15, MT6323_DIGLDO_CON32, 0xE0,
-+              MT6323_DIGLDO_CON31, 0x2),
-+      MT6323_LDO("ldo_vibr", VIBR, ldo_volt_table5,
-+              MT6323_DIGLDO_CON39, 15, MT6323_DIGLDO_CON40, 0xE0,
-+              MT6323_DIGLDO_CON39, 0x2),
-+      MT6323_REG_FIXED("ldo_vrf18", VRF18, MT6323_DIGLDO_CON45, 15, 1825000,
-+              MT6323_DIGLDO_CON45, 0x2),
-+      MT6323_LDO("ldo_vm", VM, ldo_volt_table9,
-+              MT6323_DIGLDO_CON47, 14, MT6323_DIGLDO_CON48, 0x30,
-+              MT6323_DIGLDO_CON47, 0x2),
-+      MT6323_REG_FIXED("ldo_vio18", VIO18, MT6323_DIGLDO_CON49, 14, 1800000,
-+              MT6323_DIGLDO_CON49, 0x2),
-+      MT6323_LDO("ldo_vcamd", VCAMD, ldo_volt_table10,
-+              MT6323_DIGLDO_CON51, 14, MT6323_DIGLDO_CON52, 0x60,
-+              MT6323_DIGLDO_CON51, 0x2),
-+      MT6323_REG_FIXED("ldo_vcamio", VCAMIO, MT6323_DIGLDO_CON53, 14, 1800000,
-+              MT6323_DIGLDO_CON53, 0x2),
-+};
-+
-+static int mt6323_set_buck_vosel_reg(struct platform_device *pdev)
-+{
-+      struct mt6397_chip *mt6323 = dev_get_drvdata(pdev->dev.parent);
-+      int i;
-+      u32 regval;
-+
-+      for (i = 0; i < MT6323_MAX_REGULATOR; i++) {
-+              if (mt6323_regulators[i].vselctrl_reg) {
-+                      if (regmap_read(mt6323->regmap,
-+                              mt6323_regulators[i].vselctrl_reg,
-+                              &regval) < 0) {
-+                              dev_err(&pdev->dev,
-+                                      "Failed to read buck ctrl\n");
-+                              return -EIO;
-+                      }
-+
-+                      if (regval & mt6323_regulators[i].vselctrl_mask) {
-+                              mt6323_regulators[i].desc.vsel_reg =
-+                              mt6323_regulators[i].vselon_reg;
-+                      }
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int mt6323_regulator_probe(struct platform_device *pdev)
-+{
-+      struct mt6397_chip *mt6323 = dev_get_drvdata(pdev->dev.parent);
-+      struct regulator_config config = {};
-+      struct regulator_dev *rdev;
-+      int i;
-+      u32 reg_value;
-+
-+      /* Query buck controller to select activated voltage register part */
-+      if (mt6323_set_buck_vosel_reg(pdev))
-+              return -EIO;
-+
-+      /* Read PMIC chip revision to update constraints and voltage table */
-+      if (regmap_read(mt6323->regmap, MT6323_CID, &reg_value) < 0) {
-+              dev_err(&pdev->dev, "Failed to read Chip ID\n");
-+              return -EIO;
-+      }
-+      dev_info(&pdev->dev, "Chip ID = 0x%x\n", reg_value);
-+
-+      for (i = 0; i < MT6323_MAX_REGULATOR; i++) {
-+              config.dev = &pdev->dev;
-+              config.driver_data = &mt6323_regulators[i];
-+              config.regmap = mt6323->regmap;
-+              rdev = devm_regulator_register(&pdev->dev,
-+                              &mt6323_regulators[i].desc, &config);
-+              if (IS_ERR(rdev)) {
-+                      dev_err(&pdev->dev, "failed to register %s\n",
-+                              mt6323_regulators[i].desc.name);
-+                      return PTR_ERR(rdev);
-+              }
-+      }
-+      return 0;
-+}
-+
-+static const struct platform_device_id mt6323_platform_ids[] = {
-+      {"mt6323-regulator", 0},
-+      { /* sentinel */ },
-+};
-+MODULE_DEVICE_TABLE(platform, mt6323_platform_ids);
-+
-+static const struct of_device_id mt6323_of_match[] = {
-+      { .compatible = "mediatek,mt6323-regulator", },
-+      { /* sentinel */ },
-+};
-+MODULE_DEVICE_TABLE(of, mt6323_of_match);
-+
-+static struct platform_driver mt6323_regulator_driver = {
-+      .driver = {
-+              .name = "mt6323-regulator",
-+              .of_match_table = of_match_ptr(mt6323_of_match),
-+      },
-+      .probe = mt6323_regulator_probe,
-+      .id_table = mt6323_platform_ids,
-+};
-+
-+module_platform_driver(mt6323_regulator_driver);
-+
-+MODULE_AUTHOR("Chen Zhong <chen.zhong@mediatek.com>");
-+MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6397 PMIC");
-+MODULE_LICENSE("GPL v2");
---- /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 */
diff --git a/target/linux/mediatek/patches-4.4/0048-net-next-mediatek-document-MediaTek-SoC-ethernet-bin.patch b/target/linux/mediatek/patches-4.4/0048-net-next-mediatek-document-MediaTek-SoC-ethernet-bin.patch
deleted file mode 100644 (file)
index 8721d77..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-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>,
-+               <&ethsys CLK_ETHSYS_ESW>,
-+               <&ethsys CLK_ETHSYS_GP2>,
-+               <&ethsys CLK_ETHSYS_GP1>;
-+      clock-names = "ethif", "esw", "gp2", "gp1";
-+      interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_LOW>;
-+      power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
-+      resets = <&ethsys MT2701_ETHSYS_ETH_RST>;
-+      reset-names = "eth";
-+      mediatek,ethsys = <&ethsys>;
-+      mediatek,pctl = <&syscfg_pctl_a>;
-+      #address-cells = <1>;
-+      #size-cells = <0>;
-+
-+      gmac1: mac@0 {
-+              compatible = "mediatek,eth-mac";
-+              reg = <0>;
-+              phy-handle = <&phy0>;
-+      };
-+
-+      gmac2: mac@1 {
-+              compatible = "mediatek,eth-mac";
-+              reg = <1>;
-+              phy-handle = <&phy1>;
-+      };
-+
-+      mdio-bus {
-+              phy0: ethernet-phy@0 {
-+                      reg = <0>;
-+                      phy-mode = "rgmii";
-+              };
-+
-+              phy1: ethernet-phy@1 {
-+                      reg = <1>;
-+                      phy-mode = "rgmii";
-+              };
-+      };
-+};
diff --git a/target/linux/mediatek/patches-4.4/0049-net-next-mediatek-add-support-for-MT7623-ethernet.patch b/target/linux/mediatek/patches-4.4/0049-net-next-mediatek-add-support-for-MT7623-ethernet.patch
deleted file mode 100644 (file)
index 9d44592..0000000
+++ /dev/null
@@ -1,2262 +0,0 @@
-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(&eth->mac[i]->hw_stats->stats_lock)) {
-+                      mtk_stats_update_mac(eth->mac[i]);
-+                      spin_unlock(&eth->mac[i]->hw_stats->stats_lock);
-+              }
-+      }
-+}
-+
-+static struct rtnl_link_stats64 *mtk_get_stats64(struct net_device *dev,
-+                                      struct rtnl_link_stats64 *storage)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+      struct mtk_hw_stats *hw_stats = mac->hw_stats;
-+      unsigned int start;
-+
-+      if (netif_running(dev) && netif_device_present(dev)) {
-+              if (spin_trylock(&hw_stats->stats_lock)) {
-+                      mtk_stats_update_mac(mac);
-+                      spin_unlock(&hw_stats->stats_lock);
-+              }
-+      }
-+
-+      do {
-+              start = u64_stats_fetch_begin_irq(&hw_stats->syncp);
-+              storage->rx_packets = hw_stats->rx_packets;
-+              storage->tx_packets = hw_stats->tx_packets;
-+              storage->rx_bytes = hw_stats->rx_bytes;
-+              storage->tx_bytes = hw_stats->tx_bytes;
-+              storage->collisions = hw_stats->tx_collisions;
-+              storage->rx_length_errors = hw_stats->rx_short_errors +
-+                      hw_stats->rx_long_errors;
-+              storage->rx_over_errors = hw_stats->rx_overflow;
-+              storage->rx_crc_errors = hw_stats->rx_fcs_errors;
-+              storage->rx_errors = hw_stats->rx_checksum_errors;
-+              storage->tx_aborted_errors = hw_stats->tx_skip;
-+      } while (u64_stats_fetch_retry_irq(&hw_stats->syncp, start));
-+
-+      storage->tx_errors = dev->stats.tx_errors;
-+      storage->rx_dropped = dev->stats.rx_dropped;
-+      storage->tx_dropped = dev->stats.tx_dropped;
-+
-+      return storage;
-+}
-+
-+static inline int mtk_max_frag_size(int mtu)
-+{
-+      /* make sure buf_size will be at least MTK_MAX_RX_LENGTH */
-+      if (mtu + MTK_RX_ETH_HLEN < MTK_MAX_RX_LENGTH)
-+              mtu = MTK_MAX_RX_LENGTH - MTK_RX_ETH_HLEN;
-+
-+      return SKB_DATA_ALIGN(MTK_RX_HLEN + mtu) +
-+              SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-+}
-+
-+static inline int mtk_max_buf_size(int frag_size)
-+{
-+      int buf_size = frag_size - NET_SKB_PAD - NET_IP_ALIGN -
-+                     SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-+
-+      WARN_ON(buf_size < MTK_MAX_RX_LENGTH);
-+
-+      return buf_size;
-+}
-+
-+static inline void mtk_rx_get_desc(struct mtk_rx_dma *rxd,
-+                                 struct mtk_rx_dma *dma_rxd)
-+{
-+      rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
-+      rxd->rxd2 = READ_ONCE(dma_rxd->rxd2);
-+      rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
-+      rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
-+}
-+
-+/* the qdma core needs scratch memory to be setup */
-+static int mtk_init_fq_dma(struct mtk_eth *eth)
-+{
-+      unsigned int phy_ring_head, phy_ring_tail;
-+      int cnt = MTK_DMA_SIZE;
-+      dma_addr_t dma_addr;
-+      int i;
-+
-+      eth->scratch_ring = dma_alloc_coherent(eth->dev,
-+                                             cnt * sizeof(struct mtk_tx_dma),
-+                                             &phy_ring_head,
-+                                             GFP_ATOMIC | __GFP_ZERO);
-+      if (unlikely(!eth->scratch_ring))
-+              return -ENOMEM;
-+
-+      eth->scratch_head = kcalloc(cnt, MTK_QDMA_PAGE_SIZE,
-+                                  GFP_KERNEL);
-+      dma_addr = dma_map_single(eth->dev,
-+                                eth->scratch_head, cnt * MTK_QDMA_PAGE_SIZE,
-+                                DMA_FROM_DEVICE);
-+      if (unlikely(dma_mapping_error(eth->dev, dma_addr)))
-+              return -ENOMEM;
-+
-+      memset(eth->scratch_ring, 0x0, sizeof(struct mtk_tx_dma) * cnt);
-+      phy_ring_tail = phy_ring_head +
-+                      (sizeof(struct mtk_tx_dma) * (cnt - 1));
-+
-+      for (i = 0; i < cnt; i++) {
-+              eth->scratch_ring[i].txd1 =
-+                                      (dma_addr + (i * MTK_QDMA_PAGE_SIZE));
-+              if (i < cnt - 1)
-+                      eth->scratch_ring[i].txd2 = (phy_ring_head +
-+                              ((i + 1) * sizeof(struct mtk_tx_dma)));
-+              eth->scratch_ring[i].txd3 = TX_DMA_SDL(MTK_QDMA_PAGE_SIZE);
-+      }
-+
-+      mtk_w32(eth, phy_ring_head, MTK_QDMA_FQ_HEAD);
-+      mtk_w32(eth, phy_ring_tail, MTK_QDMA_FQ_TAIL);
-+      mtk_w32(eth, (cnt << 16) | cnt, MTK_QDMA_FQ_CNT);
-+      mtk_w32(eth, MTK_QDMA_PAGE_SIZE << 16, MTK_QDMA_FQ_BLEN);
-+
-+      return 0;
-+}
-+
-+static inline void *mtk_qdma_phys_to_virt(struct mtk_tx_ring *ring, u32 desc)
-+{
-+      void *ret = ring->dma;
-+
-+      return ret + (desc - ring->phys);
-+}
-+
-+static inline struct mtk_tx_buf *mtk_desc_to_tx_buf(struct mtk_tx_ring *ring,
-+                                                  struct mtk_tx_dma *txd)
-+{
-+      int idx = txd - ring->dma;
-+
-+      return &ring->buf[idx];
-+}
-+
-+static void mtk_tx_unmap(struct device *dev, struct mtk_tx_buf *tx_buf)
-+{
-+      if (tx_buf->flags & MTK_TX_FLAGS_SINGLE0) {
-+              dma_unmap_single(dev,
-+                               dma_unmap_addr(tx_buf, dma_addr0),
-+                               dma_unmap_len(tx_buf, dma_len0),
-+                               DMA_TO_DEVICE);
-+      } else if (tx_buf->flags & MTK_TX_FLAGS_PAGE0) {
-+              dma_unmap_page(dev,
-+                             dma_unmap_addr(tx_buf, dma_addr0),
-+                             dma_unmap_len(tx_buf, dma_len0),
-+                             DMA_TO_DEVICE);
-+      }
-+      tx_buf->flags = 0;
-+      if (tx_buf->skb &&
-+          (tx_buf->skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC))
-+              dev_kfree_skb_any(tx_buf->skb);
-+      tx_buf->skb = NULL;
-+}
-+
-+static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
-+                    int tx_num, struct mtk_tx_ring *ring, bool gso)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+      struct mtk_eth *eth = mac->hw;
-+      struct mtk_tx_dma *itxd, *txd;
-+      struct mtk_tx_buf *tx_buf;
-+      unsigned long flags;
-+      dma_addr_t mapped_addr;
-+      unsigned int nr_frags;
-+      int i, n_desc = 1;
-+      u32 txd4 = 0;
-+
-+      itxd = ring->next_free;
-+      if (itxd == ring->last_free)
-+              return -ENOMEM;
-+
-+      /* set the forward port */
-+      txd4 |= (mac->id + 1) << TX_DMA_FPORT_SHIFT;
-+
-+      tx_buf = mtk_desc_to_tx_buf(ring, itxd);
-+      memset(tx_buf, 0, sizeof(*tx_buf));
-+
-+      if (gso)
-+              txd4 |= TX_DMA_TSO;
-+
-+      /* TX Checksum offload */
-+      if (skb->ip_summed == CHECKSUM_PARTIAL)
-+              txd4 |= TX_DMA_CHKSUM;
-+
-+      /* VLAN header offload */
-+      if (skb_vlan_tag_present(skb))
-+              txd4 |= TX_DMA_INS_VLAN | skb_vlan_tag_get(skb);
-+
-+      mapped_addr = dma_map_single(&dev->dev, skb->data,
-+                                   skb_headlen(skb), DMA_TO_DEVICE);
-+      if (unlikely(dma_mapping_error(&dev->dev, mapped_addr)))
-+              return -ENOMEM;
-+
-+      /* normally we can rely on the stack not calling this more than once,
-+       * however we have 2 queues running ont he same ring so we need to lock
-+       * the ring access
-+       */
-+      spin_lock_irqsave(&eth->page_lock, flags);
-+      WRITE_ONCE(itxd->txd1, mapped_addr);
-+      tx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
-+      dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr);
-+      dma_unmap_len_set(tx_buf, dma_len0, skb_headlen(skb));
-+
-+      /* TX SG offload */
-+      txd = itxd;
-+      nr_frags = skb_shinfo(skb)->nr_frags;
-+      for (i = 0; i < nr_frags; i++) {
-+              struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
-+              unsigned int offset = 0;
-+              int frag_size = skb_frag_size(frag);
-+
-+              while (frag_size) {
-+                      bool last_frag = false;
-+                      unsigned int frag_map_size;
-+
-+                      txd = mtk_qdma_phys_to_virt(ring, txd->txd2);
-+                      if (txd == ring->last_free)
-+                              goto err_dma;
-+
-+                      n_desc++;
-+                      frag_map_size = min(frag_size, MTK_TX_DMA_BUF_LEN);
-+                      mapped_addr = skb_frag_dma_map(&dev->dev, frag, offset,
-+                                                     frag_map_size,
-+                                                     DMA_TO_DEVICE);
-+                      if (unlikely(dma_mapping_error(&dev->dev, mapped_addr)))
-+                              goto err_dma;
-+
-+                      if (i == nr_frags - 1 &&
-+                          (frag_size - frag_map_size) == 0)
-+                              last_frag = true;
-+
-+                      WRITE_ONCE(txd->txd1, mapped_addr);
-+                      WRITE_ONCE(txd->txd3, (TX_DMA_SWC |
-+                                             TX_DMA_PLEN0(frag_map_size) |
-+                                             last_frag * TX_DMA_LS0) |
-+                                             mac->id);
-+                      WRITE_ONCE(txd->txd4, 0);
-+
-+                      tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC;
-+                      tx_buf = mtk_desc_to_tx_buf(ring, txd);
-+                      memset(tx_buf, 0, sizeof(*tx_buf));
-+
-+                      tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
-+                      dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr);
-+                      dma_unmap_len_set(tx_buf, dma_len0, frag_map_size);
-+                      frag_size -= frag_map_size;
-+                      offset += frag_map_size;
-+              }
-+      }
-+
-+      /* store skb to cleanup */
-+      tx_buf->skb = skb;
-+
-+      WRITE_ONCE(itxd->txd4, txd4);
-+      WRITE_ONCE(itxd->txd3, (TX_DMA_SWC | TX_DMA_PLEN0(skb_headlen(skb)) |
-+                              (!nr_frags * TX_DMA_LS0)));
-+
-+      spin_unlock_irqrestore(&eth->page_lock, flags);
-+
-+      netdev_sent_queue(dev, skb->len);
-+      skb_tx_timestamp(skb);
-+
-+      ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2);
-+      atomic_sub(n_desc, &ring->free_count);
-+
-+      /* make sure that all changes to the dma ring are flushed before we
-+       * continue
-+       */
-+      wmb();
-+
-+      if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) || !skb->xmit_more)
-+              mtk_w32(eth, txd->txd2, MTK_QTX_CTX_PTR);
-+
-+      return 0;
-+
-+err_dma:
-+      do {
-+              tx_buf = mtk_desc_to_tx_buf(ring, txd);
-+
-+              /* unmap dma */
-+              mtk_tx_unmap(&dev->dev, tx_buf);
-+
-+              itxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
-+              itxd = mtk_qdma_phys_to_virt(ring, itxd->txd2);
-+      } while (itxd != txd);
-+
-+      return -ENOMEM;
-+}
-+
-+static inline int mtk_cal_txd_req(struct sk_buff *skb)
-+{
-+      int i, nfrags;
-+      struct skb_frag_struct *frag;
-+
-+      nfrags = 1;
-+      if (skb_is_gso(skb)) {
-+              for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-+                      frag = &skb_shinfo(skb)->frags[i];
-+                      nfrags += DIV_ROUND_UP(frag->size, MTK_TX_DMA_BUF_LEN);
-+              }
-+      } else {
-+              nfrags += skb_shinfo(skb)->nr_frags;
-+      }
-+
-+      return DIV_ROUND_UP(nfrags, 2);
-+}
-+
-+static int mtk_start_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+      struct mtk_eth *eth = mac->hw;
-+      struct mtk_tx_ring *ring = &eth->tx_ring;
-+      struct net_device_stats *stats = &dev->stats;
-+      bool gso = false;
-+      int tx_num;
-+
-+      tx_num = mtk_cal_txd_req(skb);
-+      if (unlikely(atomic_read(&ring->free_count) <= tx_num)) {
-+              netif_stop_queue(dev);
-+              netif_err(eth, tx_queued, dev,
-+                        "Tx Ring full when queue awake!\n");
-+              return NETDEV_TX_BUSY;
-+      }
-+
-+      /* TSO: fill MSS info in tcp checksum field */
-+      if (skb_is_gso(skb)) {
-+              if (skb_cow_head(skb, 0)) {
-+                      netif_warn(eth, tx_err, dev,
-+                                 "GSO expand head fail.\n");
-+                      goto drop;
-+              }
-+
-+              if (skb_shinfo(skb)->gso_type &
-+                              (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
-+                      gso = true;
-+                      tcp_hdr(skb)->check = htons(skb_shinfo(skb)->gso_size);
-+              }
-+      }
-+
-+      if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0)
-+              goto drop;
-+
-+      if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) {
-+              netif_stop_queue(dev);
-+              if (unlikely(atomic_read(&ring->free_count) >
-+                           ring->thresh))
-+                      netif_wake_queue(dev);
-+      }
-+
-+      return NETDEV_TX_OK;
-+
-+drop:
-+      stats->tx_dropped++;
-+      dev_kfree_skb(skb);
-+      return NETDEV_TX_OK;
-+}
-+
-+static int mtk_poll_rx(struct napi_struct *napi, int budget,
-+                     struct mtk_eth *eth, u32 rx_intr)
-+{
-+      struct mtk_rx_ring *ring = &eth->rx_ring;
-+      int idx = ring->calc_idx;
-+      struct sk_buff *skb;
-+      u8 *data, *new_data;
-+      struct mtk_rx_dma *rxd, trxd;
-+      int done = 0;
-+
-+      while (done < budget) {
-+              struct net_device *netdev;
-+              unsigned int pktlen;
-+              dma_addr_t dma_addr;
-+              int mac = 0;
-+
-+              idx = NEXT_RX_DESP_IDX(idx);
-+              rxd = &ring->dma[idx];
-+              data = ring->data[idx];
-+
-+              mtk_rx_get_desc(&trxd, rxd);
-+              if (!(trxd.rxd2 & RX_DMA_DONE))
-+                      break;
-+
-+              /* find out which mac the packet come from. values start at 1 */
-+              mac = (trxd.rxd4 >> RX_DMA_FPORT_SHIFT) &
-+                    RX_DMA_FPORT_MASK;
-+              mac--;
-+
-+              netdev = eth->netdev[mac];
-+
-+              /* alloc new buffer */
-+              new_data = napi_alloc_frag(ring->frag_size);
-+              if (unlikely(!new_data)) {
-+                      netdev->stats.rx_dropped++;
-+                      goto release_desc;
-+              }
-+              dma_addr = dma_map_single(&eth->netdev[mac]->dev,
-+                                        new_data + NET_SKB_PAD,
-+                                        ring->buf_size,
-+                                        DMA_FROM_DEVICE);
-+              if (unlikely(dma_mapping_error(&netdev->dev, dma_addr))) {
-+                      skb_free_frag(new_data);
-+                      goto release_desc;
-+              }
-+
-+              /* receive data */
-+              skb = build_skb(data, ring->frag_size);
-+              if (unlikely(!skb)) {
-+                      put_page(virt_to_head_page(new_data));
-+                      goto release_desc;
-+              }
-+              skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
-+
-+              dma_unmap_single(&netdev->dev, trxd.rxd1,
-+                               ring->buf_size, DMA_FROM_DEVICE);
-+              pktlen = RX_DMA_GET_PLEN0(trxd.rxd2);
-+              skb->dev = netdev;
-+              skb_put(skb, pktlen);
-+              if (trxd.rxd4 & RX_DMA_L4_VALID)
-+                      skb->ip_summed = CHECKSUM_UNNECESSARY;
-+              else
-+                      skb_checksum_none_assert(skb);
-+              skb->protocol = eth_type_trans(skb, netdev);
-+
-+              if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX &&
-+                  RX_DMA_VID(trxd.rxd3))
-+                      __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
-+                                             RX_DMA_VID(trxd.rxd3));
-+              napi_gro_receive(napi, skb);
-+
-+              ring->data[idx] = new_data;
-+              rxd->rxd1 = (unsigned int)dma_addr;
-+
-+release_desc:
-+              rxd->rxd2 = RX_DMA_PLEN0(ring->buf_size);
-+
-+              ring->calc_idx = idx;
-+              /* make sure that all changes to the dma ring are flushed before
-+               * we continue
-+               */
-+              wmb();
-+              mtk_w32(eth, ring->calc_idx, MTK_QRX_CRX_IDX0);
-+              done++;
-+      }
-+
-+      if (done < budget)
-+              mtk_w32(eth, rx_intr, MTK_QMTK_INT_STATUS);
-+
-+      return done;
-+}
-+
-+static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again)
-+{
-+      struct mtk_tx_ring *ring = &eth->tx_ring;
-+      struct mtk_tx_dma *desc;
-+      struct sk_buff *skb;
-+      struct mtk_tx_buf *tx_buf;
-+      int total = 0, done[MTK_MAX_DEVS];
-+      unsigned int bytes[MTK_MAX_DEVS];
-+      u32 cpu, dma;
-+      static int condition;
-+      int i;
-+
-+      memset(done, 0, sizeof(done));
-+      memset(bytes, 0, sizeof(bytes));
-+
-+      cpu = mtk_r32(eth, MTK_QTX_CRX_PTR);
-+      dma = mtk_r32(eth, MTK_QTX_DRX_PTR);
-+
-+      desc = mtk_qdma_phys_to_virt(ring, cpu);
-+
-+      while ((cpu != dma) && budget) {
-+              u32 next_cpu = desc->txd2;
-+              int mac;
-+
-+              desc = mtk_qdma_phys_to_virt(ring, desc->txd2);
-+              if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0)
-+                      break;
-+
-+              mac = (desc->txd4 >> TX_DMA_FPORT_SHIFT) &
-+                     TX_DMA_FPORT_MASK;
-+              mac--;
-+
-+              tx_buf = mtk_desc_to_tx_buf(ring, desc);
-+              skb = tx_buf->skb;
-+              if (!skb) {
-+                      condition = 1;
-+                      break;
-+              }
-+
-+              if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) {
-+                      bytes[mac] += skb->len;
-+                      done[mac]++;
-+                      budget--;
-+              }
-+              mtk_tx_unmap(eth->dev, tx_buf);
-+
-+              ring->last_free->txd2 = next_cpu;
-+              ring->last_free = desc;
-+              atomic_inc(&ring->free_count);
-+
-+              cpu = next_cpu;
-+      }
-+
-+      mtk_w32(eth, cpu, MTK_QTX_CRX_PTR);
-+
-+      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+              if (!eth->netdev[i] || !done[i])
-+                      continue;
-+              netdev_completed_queue(eth->netdev[i], done[i], bytes[i]);
-+              total += done[i];
-+      }
-+
-+      /* read hw index again make sure no new tx packet */
-+      if (cpu != dma || cpu != mtk_r32(eth, MTK_QTX_DRX_PTR))
-+              *tx_again = true;
-+      else
-+              mtk_w32(eth, MTK_TX_DONE_INT, MTK_QMTK_INT_STATUS);
-+
-+      if (!total)
-+              return 0;
-+
-+      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+              if (!eth->netdev[i] ||
-+                  unlikely(!netif_queue_stopped(eth->netdev[i])))
-+                      continue;
-+              if (atomic_read(&ring->free_count) > ring->thresh)
-+                      netif_wake_queue(eth->netdev[i]);
-+      }
-+
-+      return total;
-+}
-+
-+static int mtk_poll(struct napi_struct *napi, int budget)
-+{
-+      struct mtk_eth *eth = container_of(napi, struct mtk_eth, rx_napi);
-+      u32 status, status2, mask, tx_intr, rx_intr, status_intr;
-+      int tx_done, rx_done;
-+      bool tx_again = false;
-+
-+      status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
-+      status2 = mtk_r32(eth, MTK_INT_STATUS2);
-+      tx_intr = MTK_TX_DONE_INT;
-+      rx_intr = MTK_RX_DONE_INT;
-+      status_intr = (MTK_GDM1_AF | MTK_GDM2_AF);
-+      tx_done = 0;
-+      rx_done = 0;
-+      tx_again = 0;
-+
-+      if (status & tx_intr)
-+              tx_done = mtk_poll_tx(eth, budget, &tx_again);
-+
-+      if (status & rx_intr)
-+              rx_done = mtk_poll_rx(napi, budget, eth, rx_intr);
-+
-+      if (unlikely(status2 & status_intr)) {
-+              mtk_stats_update(eth);
-+              mtk_w32(eth, status_intr, MTK_INT_STATUS2);
-+      }
-+
-+      if (unlikely(netif_msg_intr(eth))) {
-+              mask = mtk_r32(eth, MTK_QDMA_INT_MASK);
-+              netdev_info(eth->netdev[0],
-+                          "done tx %d, rx %d, intr 0x%08x/0x%x\n",
-+                          tx_done, rx_done, status, mask);
-+      }
-+
-+      if (tx_again || rx_done == budget)
-+              return budget;
-+
-+      status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
-+      if (status & (tx_intr | rx_intr))
-+              return budget;
-+
-+      napi_complete(napi);
-+      mtk_irq_enable(eth, tx_intr | rx_intr);
-+
-+      return rx_done;
-+}
-+
-+static int mtk_tx_alloc(struct mtk_eth *eth)
-+{
-+      struct mtk_tx_ring *ring = &eth->tx_ring;
-+      int i, sz = sizeof(*ring->dma);
-+
-+      ring->buf = kcalloc(MTK_DMA_SIZE, sizeof(*ring->buf),
-+                             GFP_KERNEL);
-+      if (!ring->buf)
-+              goto no_tx_mem;
-+
-+      ring->dma = dma_alloc_coherent(eth->dev,
-+                                        MTK_DMA_SIZE * sz,
-+                                        &ring->phys,
-+                                        GFP_ATOMIC | __GFP_ZERO);
-+      if (!ring->dma)
-+              goto no_tx_mem;
-+
-+      memset(ring->dma, 0, MTK_DMA_SIZE * sz);
-+      for (i = 0; i < MTK_DMA_SIZE; i++) {
-+              int next = (i + 1) % MTK_DMA_SIZE;
-+              u32 next_ptr = ring->phys + next * sz;
-+
-+              ring->dma[i].txd2 = next_ptr;
-+              ring->dma[i].txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
-+      }
-+
-+      atomic_set(&ring->free_count, MTK_DMA_SIZE - 2);
-+      ring->next_free = &ring->dma[0];
-+      ring->last_free = &ring->dma[MTK_DMA_SIZE - 2];
-+      ring->thresh = max((unsigned long)MTK_DMA_SIZE >> 2,
-+                            MAX_SKB_FRAGS);
-+
-+      /* make sure that all changes to the dma ring are flushed before we
-+       * continue
-+       */
-+      wmb();
-+
-+      mtk_w32(eth, ring->phys, MTK_QTX_CTX_PTR);
-+      mtk_w32(eth, ring->phys, MTK_QTX_DTX_PTR);
-+      mtk_w32(eth,
-+              ring->phys + ((MTK_DMA_SIZE - 1) * sz),
-+              MTK_QTX_CRX_PTR);
-+      mtk_w32(eth,
-+              ring->phys + ((MTK_DMA_SIZE - 1) * sz),
-+              MTK_QTX_DRX_PTR);
-+
-+      return 0;
-+
-+no_tx_mem:
-+      return -ENOMEM;
-+}
-+
-+static void mtk_tx_clean(struct mtk_eth *eth)
-+{
-+      struct mtk_tx_ring *ring = &eth->tx_ring;
-+      int i;
-+
-+      if (ring->buf) {
-+              for (i = 0; i < MTK_DMA_SIZE; i++)
-+                      mtk_tx_unmap(eth->dev, &ring->buf[i]);
-+              kfree(ring->buf);
-+              ring->buf = NULL;
-+      }
-+
-+      if (ring->dma) {
-+              dma_free_coherent(eth->dev,
-+                                MTK_DMA_SIZE * sizeof(*ring->dma),
-+                                ring->dma,
-+                                ring->phys);
-+              ring->dma = NULL;
-+      }
-+}
-+
-+static int mtk_rx_alloc(struct mtk_eth *eth)
-+{
-+      struct mtk_rx_ring *ring = &eth->rx_ring;
-+      int i;
-+
-+      ring->frag_size = mtk_max_frag_size(ETH_DATA_LEN);
-+      ring->buf_size = mtk_max_buf_size(ring->frag_size);
-+      ring->data = kcalloc(MTK_DMA_SIZE, sizeof(*ring->data),
-+                           GFP_KERNEL);
-+      if (!ring->data)
-+              return -ENOMEM;
-+
-+      for (i = 0; i < MTK_DMA_SIZE; i++) {
-+              ring->data[i] = netdev_alloc_frag(ring->frag_size);
-+              if (!ring->data[i])
-+                      return -ENOMEM;
-+      }
-+
-+      ring->dma = dma_alloc_coherent(eth->dev,
-+                                     MTK_DMA_SIZE * sizeof(*ring->dma),
-+                                     &ring->phys,
-+                                     GFP_ATOMIC | __GFP_ZERO);
-+      if (!ring->dma)
-+              return -ENOMEM;
-+
-+      for (i = 0; i < MTK_DMA_SIZE; i++) {
-+              dma_addr_t dma_addr = dma_map_single(eth->dev,
-+                              ring->data[i] + NET_SKB_PAD,
-+                              ring->buf_size,
-+                              DMA_FROM_DEVICE);
-+              if (unlikely(dma_mapping_error(eth->dev, dma_addr)))
-+                      return -ENOMEM;
-+              ring->dma[i].rxd1 = (unsigned int)dma_addr;
-+
-+              ring->dma[i].rxd2 = RX_DMA_PLEN0(ring->buf_size);
-+      }
-+      ring->calc_idx = MTK_DMA_SIZE - 1;
-+      /* make sure that all changes to the dma ring are flushed before we
-+       * continue
-+       */
-+      wmb();
-+
-+      mtk_w32(eth, eth->rx_ring.phys, MTK_QRX_BASE_PTR0);
-+      mtk_w32(eth, MTK_DMA_SIZE, MTK_QRX_MAX_CNT0);
-+      mtk_w32(eth, eth->rx_ring.calc_idx, MTK_QRX_CRX_IDX0);
-+      mtk_w32(eth, MTK_PST_DRX_IDX0, MTK_QDMA_RST_IDX);
-+      mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES, MTK_QTX_CFG(0));
-+
-+      return 0;
-+}
-+
-+static void mtk_rx_clean(struct mtk_eth *eth)
-+{
-+      struct mtk_rx_ring *ring = &eth->rx_ring;
-+      int i;
-+
-+      if (ring->data && ring->dma) {
-+              for (i = 0; i < MTK_DMA_SIZE; i++) {
-+                      if (!ring->data[i])
-+                              continue;
-+                      if (!ring->dma[i].rxd1)
-+                              continue;
-+                      dma_unmap_single(eth->dev,
-+                                       ring->dma[i].rxd1,
-+                                       ring->buf_size,
-+                                       DMA_FROM_DEVICE);
-+                      skb_free_frag(ring->data[i]);
-+              }
-+              kfree(ring->data);
-+              ring->data = NULL;
-+      }
-+
-+      if (ring->dma) {
-+              dma_free_coherent(eth->dev,
-+                                MTK_DMA_SIZE * sizeof(*ring->dma),
-+                                ring->dma,
-+                                ring->phys);
-+              ring->dma = NULL;
-+      }
-+}
-+
-+/* wait for DMA to finish whatever it is doing before we start using it again */
-+static int mtk_dma_busy_wait(struct mtk_eth *eth)
-+{
-+      unsigned long t_start = jiffies;
-+
-+      while (1) {
-+              if (!(mtk_r32(eth, MTK_QDMA_GLO_CFG) &
-+                    (MTK_RX_DMA_BUSY | MTK_TX_DMA_BUSY)))
-+                      return 0;
-+              if (time_after(jiffies, t_start + MTK_DMA_BUSY_TIMEOUT))
-+                      break;
-+      }
-+
-+      dev_err(eth->dev, "DMA init timeout\n");
-+      return -1;
-+}
-+
-+static int mtk_dma_init(struct mtk_eth *eth)
-+{
-+      int err;
-+
-+      if (mtk_dma_busy_wait(eth))
-+              return -EBUSY;
-+
-+      /* QDMA needs scratch memory for internal reordering of the
-+       * descriptors
-+       */
-+      err = mtk_init_fq_dma(eth);
-+      if (err)
-+              return err;
-+
-+      err = mtk_tx_alloc(eth);
-+      if (err)
-+              return err;
-+
-+      err = mtk_rx_alloc(eth);
-+      if (err)
-+              return err;
-+
-+      /* Enable random early drop and set drop threshold automatically */
-+      mtk_w32(eth, FC_THRES_DROP_MODE | FC_THRES_DROP_EN | FC_THRES_MIN,
-+              MTK_QDMA_FC_THRES);
-+      mtk_w32(eth, 0x0, MTK_QDMA_HRED2);
-+
-+      return 0;
-+}
-+
-+static void mtk_dma_free(struct mtk_eth *eth)
-+{
-+      int i;
-+
-+      for (i = 0; i < MTK_MAC_COUNT; i++)
-+              if (eth->netdev[i])
-+                      netdev_reset_queue(eth->netdev[i]);
-+      mtk_tx_clean(eth);
-+      mtk_rx_clean(eth);
-+      kfree(eth->scratch_head);
-+}
-+
-+static void mtk_tx_timeout(struct net_device *dev)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+      struct mtk_eth *eth = mac->hw;
-+
-+      eth->netdev[mac->id]->stats.tx_errors++;
-+      netif_err(eth, tx_err, dev,
-+                "transmit timed out\n");
-+      schedule_work(&mac->pending_work);
-+}
-+
-+static irqreturn_t mtk_handle_irq(int irq, void *_eth)
-+{
-+      struct mtk_eth *eth = _eth;
-+      u32 status;
-+
-+      status = mtk_r32(eth, MTK_QMTK_INT_STATUS);
-+      if (unlikely(!status))
-+              return IRQ_NONE;
-+
-+      if (likely(status & (MTK_RX_DONE_INT | MTK_TX_DONE_INT))) {
-+              if (likely(napi_schedule_prep(&eth->rx_napi)))
-+                      __napi_schedule(&eth->rx_napi);
-+      } else {
-+              mtk_w32(eth, status, MTK_QMTK_INT_STATUS);
-+      }
-+      mtk_irq_disable(eth, (MTK_RX_DONE_INT | MTK_TX_DONE_INT));
-+
-+      return IRQ_HANDLED;
-+}
-+
-+#ifdef CONFIG_NET_POLL_CONTROLLER
-+static void mtk_poll_controller(struct net_device *dev)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+      struct mtk_eth *eth = mac->hw;
-+      u32 int_mask = MTK_TX_DONE_INT | MTK_RX_DONE_INT;
-+
-+      mtk_irq_disable(eth, int_mask);
-+      mtk_handle_irq(dev->irq, dev);
-+      mtk_irq_enable(eth, int_mask);
-+}
-+#endif
-+
-+static int mtk_start_dma(struct mtk_eth *eth)
-+{
-+      int err;
-+
-+      err = mtk_dma_init(eth);
-+      if (err) {
-+              mtk_dma_free(eth);
-+              return err;
-+      }
-+
-+      mtk_w32(eth,
-+              MTK_TX_WB_DDONE | MTK_RX_DMA_EN | MTK_TX_DMA_EN |
-+              MTK_RX_2B_OFFSET | MTK_DMA_SIZE_16DWORDS |
-+              MTK_RX_BT_32DWORDS,
-+              MTK_QDMA_GLO_CFG);
-+
-+      return 0;
-+}
-+
-+static int mtk_open(struct net_device *dev)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+      struct mtk_eth *eth = mac->hw;
-+
-+      /* we run 2 netdevs on the same dma ring so we only bring it up once */
-+      if (!atomic_read(&eth->dma_refcnt)) {
-+              int err = mtk_start_dma(eth);
-+
-+              if (err)
-+                      return err;
-+
-+              napi_enable(&eth->rx_napi);
-+              mtk_irq_enable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT);
-+      }
-+      atomic_inc(&eth->dma_refcnt);
-+
-+      phy_start(mac->phy_dev);
-+      netif_start_queue(dev);
-+
-+      return 0;
-+}
-+
-+static void mtk_stop_dma(struct mtk_eth *eth, u32 glo_cfg)
-+{
-+      unsigned long flags;
-+      u32 val;
-+      int i;
-+
-+      /* stop the dma engine */
-+      spin_lock_irqsave(&eth->page_lock, flags);
-+      val = mtk_r32(eth, glo_cfg);
-+      mtk_w32(eth, val & ~(MTK_TX_WB_DDONE | MTK_RX_DMA_EN | MTK_TX_DMA_EN),
-+              glo_cfg);
-+      spin_unlock_irqrestore(&eth->page_lock, flags);
-+
-+      /* wait for dma stop */
-+      for (i = 0; i < 10; i++) {
-+              val = mtk_r32(eth, glo_cfg);
-+              if (val & (MTK_TX_DMA_BUSY | MTK_RX_DMA_BUSY)) {
-+                      msleep(20);
-+                      continue;
-+              }
-+              break;
-+      }
-+}
-+
-+static int mtk_stop(struct net_device *dev)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+      struct mtk_eth *eth = mac->hw;
-+
-+      netif_tx_disable(dev);
-+      phy_stop(mac->phy_dev);
-+
-+      /* only shutdown DMA if this is the last user */
-+      if (!atomic_dec_and_test(&eth->dma_refcnt))
-+              return 0;
-+
-+      mtk_irq_disable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT);
-+      napi_disable(&eth->rx_napi);
-+
-+      mtk_stop_dma(eth, MTK_QDMA_GLO_CFG);
-+
-+      mtk_dma_free(eth);
-+
-+      return 0;
-+}
-+
-+static int __init mtk_hw_init(struct mtk_eth *eth)
-+{
-+      int err, i;
-+
-+      /* reset the frame engine */
-+      reset_control_assert(eth->rstc);
-+      usleep_range(10, 20);
-+      reset_control_deassert(eth->rstc);
-+      usleep_range(10, 20);
-+
-+      /* Set GE2 driving and slew rate */
-+      regmap_write(eth->pctl, GPIO_DRV_SEL10, 0xa00);
-+
-+      /* set GE2 TDSEL */
-+      regmap_write(eth->pctl, GPIO_OD33_CTRL8, 0x5);
-+
-+      /* set GE2 TUNE */
-+      regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0);
-+
-+      /* GE1, Force 1000M/FD, FC ON */
-+      mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(0));
-+
-+      /* GE2, Force 1000M/FD, FC ON */
-+      mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(1));
-+
-+      /* Enable RX VLan Offloading */
-+      mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-+
-+      err = devm_request_irq(eth->dev, eth->irq, mtk_handle_irq, 0,
-+                             dev_name(eth->dev), eth);
-+      if (err)
-+              return err;
-+
-+      err = mtk_mdio_init(eth);
-+      if (err)
-+              return err;
-+
-+      /* disable delay and normal interrupt */
-+      mtk_w32(eth, 0, MTK_QDMA_DELAY_INT);
-+      mtk_irq_disable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT);
-+      mtk_w32(eth, RST_GL_PSE, MTK_RST_GL);
-+      mtk_w32(eth, 0, MTK_RST_GL);
-+
-+      /* FE int grouping */
-+      mtk_w32(eth, 0, MTK_FE_INT_GRP);
-+
-+      for (i = 0; i < 2; i++) {
-+              u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
-+
-+              /* setup the forward port to send frame to QDMA */
-+              val &= ~0xffff;
-+              val |= 0x5555;
-+
-+              /* Enable RX checksum */
-+              val |= MTK_GDMA_ICS_EN | MTK_GDMA_TCS_EN | MTK_GDMA_UCS_EN;
-+
-+              /* setup the mac dma */
-+              mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
-+      }
-+
-+      return 0;
-+}
-+
-+static int __init mtk_init(struct net_device *dev)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+      struct mtk_eth *eth = mac->hw;
-+      const char *mac_addr;
-+
-+      mac_addr = of_get_mac_address(mac->of_node);
-+      if (mac_addr)
-+              ether_addr_copy(dev->dev_addr, mac_addr);
-+
-+      /* If the mac address is invalid, use random mac address  */
-+      if (!is_valid_ether_addr(dev->dev_addr)) {
-+              random_ether_addr(dev->dev_addr);
-+              dev_err(eth->dev, "generated random MAC address %pM\n",
-+                      dev->dev_addr);
-+              dev->addr_assign_type = NET_ADDR_RANDOM;
-+      }
-+
-+      return mtk_phy_connect(mac);
-+}
-+
-+static void mtk_uninit(struct net_device *dev)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+      struct mtk_eth *eth = mac->hw;
-+
-+      phy_disconnect(mac->phy_dev);
-+      mtk_mdio_cleanup(eth);
-+      mtk_irq_disable(eth, ~0);
-+      free_irq(dev->irq, dev);
-+}
-+
-+static int mtk_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+
-+      switch (cmd) {
-+      case SIOCGMIIPHY:
-+      case SIOCGMIIREG:
-+      case SIOCSMIIREG:
-+              return phy_mii_ioctl(mac->phy_dev, ifr, cmd);
-+      default:
-+              break;
-+      }
-+
-+      return -EOPNOTSUPP;
-+}
-+
-+static void mtk_pending_work(struct work_struct *work)
-+{
-+      struct mtk_mac *mac = container_of(work, struct mtk_mac, pending_work);
-+      struct mtk_eth *eth = mac->hw;
-+      struct net_device *dev = eth->netdev[mac->id];
-+      int err;
-+
-+      rtnl_lock();
-+      mtk_stop(dev);
-+
-+      err = mtk_open(dev);
-+      if (err) {
-+              netif_alert(eth, ifup, dev,
-+                          "Driver up/down cycle failed, closing device.\n");
-+              dev_close(dev);
-+      }
-+      rtnl_unlock();
-+}
-+
-+static int mtk_cleanup(struct mtk_eth *eth)
-+{
-+      int i;
-+
-+      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+              struct mtk_mac *mac = netdev_priv(eth->netdev[i]);
-+
-+              if (!eth->netdev[i])
-+                      continue;
-+
-+              unregister_netdev(eth->netdev[i]);
-+              free_netdev(eth->netdev[i]);
-+              cancel_work_sync(&mac->pending_work);
-+      }
-+
-+      return 0;
-+}
-+
-+static int mtk_get_settings(struct net_device *dev,
-+                          struct ethtool_cmd *cmd)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+      int err;
-+
-+      err = phy_read_status(mac->phy_dev);
-+      if (err)
-+              return -ENODEV;
-+
-+      return phy_ethtool_gset(mac->phy_dev, cmd);
-+}
-+
-+static int mtk_set_settings(struct net_device *dev,
-+                          struct ethtool_cmd *cmd)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+
-+      if (cmd->phy_address != mac->phy_dev->mdio.addr) {
-+              mac->phy_dev = mdiobus_get_phy(mac->hw->mii_bus,
-+                                             cmd->phy_address);
-+              if (!mac->phy_dev)
-+                      return -ENODEV;
-+      }
-+
-+      return phy_ethtool_sset(mac->phy_dev, cmd);
-+}
-+
-+static void mtk_get_drvinfo(struct net_device *dev,
-+                          struct ethtool_drvinfo *info)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+
-+      strlcpy(info->driver, mac->hw->dev->driver->name, sizeof(info->driver));
-+      strlcpy(info->bus_info, dev_name(mac->hw->dev), sizeof(info->bus_info));
-+      info->n_stats = ARRAY_SIZE(mtk_ethtool_stats);
-+}
-+
-+static u32 mtk_get_msglevel(struct net_device *dev)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+
-+      return mac->hw->msg_enable;
-+}
-+
-+static void mtk_set_msglevel(struct net_device *dev, u32 value)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+
-+      mac->hw->msg_enable = value;
-+}
-+
-+static int mtk_nway_reset(struct net_device *dev)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+
-+      return genphy_restart_aneg(mac->phy_dev);
-+}
-+
-+static u32 mtk_get_link(struct net_device *dev)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+      int err;
-+
-+      err = genphy_update_link(mac->phy_dev);
-+      if (err)
-+              return ethtool_op_get_link(dev);
-+
-+      return mac->phy_dev->link;
-+}
-+
-+static void mtk_get_strings(struct net_device *dev, u32 stringset, u8 *data)
-+{
-+      int i;
-+
-+      switch (stringset) {
-+      case ETH_SS_STATS:
-+              for (i = 0; i < ARRAY_SIZE(mtk_ethtool_stats); i++) {
-+                      memcpy(data, mtk_ethtool_stats[i].str, ETH_GSTRING_LEN);
-+                      data += ETH_GSTRING_LEN;
-+              }
-+              break;
-+      }
-+}
-+
-+static int mtk_get_sset_count(struct net_device *dev, int sset)
-+{
-+      switch (sset) {
-+      case ETH_SS_STATS:
-+              return ARRAY_SIZE(mtk_ethtool_stats);
-+      default:
-+              return -EOPNOTSUPP;
-+      }
-+}
-+
-+static void mtk_get_ethtool_stats(struct net_device *dev,
-+                                struct ethtool_stats *stats, u64 *data)
-+{
-+      struct mtk_mac *mac = netdev_priv(dev);
-+      struct mtk_hw_stats *hwstats = mac->hw_stats;
-+      u64 *data_src, *data_dst;
-+      unsigned int start;
-+      int i;
-+
-+      if (netif_running(dev) && netif_device_present(dev)) {
-+              if (spin_trylock(&hwstats->stats_lock)) {
-+                      mtk_stats_update_mac(mac);
-+                      spin_unlock(&hwstats->stats_lock);
-+              }
-+      }
-+
-+      do {
-+              data_src = (u64*)hwstats;
-+              data_dst = data;
-+              start = u64_stats_fetch_begin_irq(&hwstats->syncp);
-+
-+              for (i = 0; i < ARRAY_SIZE(mtk_ethtool_stats); i++)
-+                      *data_dst++ = *(data_src + mtk_ethtool_stats[i].offset);
-+      } while (u64_stats_fetch_retry_irq(&hwstats->syncp, start));
-+}
-+
-+static struct ethtool_ops mtk_ethtool_ops = {
-+      .get_settings           = mtk_get_settings,
-+      .set_settings           = mtk_set_settings,
-+      .get_drvinfo            = mtk_get_drvinfo,
-+      .get_msglevel           = mtk_get_msglevel,
-+      .set_msglevel           = mtk_set_msglevel,
-+      .nway_reset             = mtk_nway_reset,
-+      .get_link               = mtk_get_link,
-+      .get_strings            = mtk_get_strings,
-+      .get_sset_count         = mtk_get_sset_count,
-+      .get_ethtool_stats      = mtk_get_ethtool_stats,
-+};
-+
-+static const struct net_device_ops mtk_netdev_ops = {
-+      .ndo_init               = mtk_init,
-+      .ndo_uninit             = mtk_uninit,
-+      .ndo_open               = mtk_open,
-+      .ndo_stop               = mtk_stop,
-+      .ndo_start_xmit         = mtk_start_xmit,
-+      .ndo_set_mac_address    = mtk_set_mac_address,
-+      .ndo_validate_addr      = eth_validate_addr,
-+      .ndo_do_ioctl           = mtk_do_ioctl,
-+      .ndo_change_mtu         = eth_change_mtu,
-+      .ndo_tx_timeout         = mtk_tx_timeout,
-+      .ndo_get_stats64        = mtk_get_stats64,
-+#ifdef CONFIG_NET_POLL_CONTROLLER
-+      .ndo_poll_controller    = mtk_poll_controller,
-+#endif
-+};
-+
-+static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
-+{
-+      struct mtk_mac *mac;
-+      const __be32 *_id = of_get_property(np, "reg", NULL);
-+      int id, err;
-+
-+      if (!_id) {
-+              dev_err(eth->dev, "missing mac id\n");
-+              return -EINVAL;
-+      }
-+
-+      id = be32_to_cpup(_id);
-+      if (id >= MTK_MAC_COUNT) {
-+              dev_err(eth->dev, "%d is not a valid mac id\n", id);
-+              return -EINVAL;
-+      }
-+
-+      if (eth->netdev[id]) {
-+              dev_err(eth->dev, "duplicate mac id found: %d\n", id);
-+              return -EINVAL;
-+      }
-+
-+      eth->netdev[id] = alloc_etherdev(sizeof(*mac));
-+      if (!eth->netdev[id]) {
-+              dev_err(eth->dev, "alloc_etherdev failed\n");
-+              return -ENOMEM;
-+      }
-+      mac = netdev_priv(eth->netdev[id]);
-+      eth->mac[id] = mac;
-+      mac->id = id;
-+      mac->hw = eth;
-+      mac->of_node = np;
-+      INIT_WORK(&mac->pending_work, mtk_pending_work);
-+
-+      mac->hw_stats = devm_kzalloc(eth->dev,
-+                                   sizeof(*mac->hw_stats),
-+                                   GFP_KERNEL);
-+      if (!mac->hw_stats) {
-+              dev_err(eth->dev, "failed to allocate counter memory\n");
-+              err = -ENOMEM;
-+              goto free_netdev;
-+      }
-+      spin_lock_init(&mac->hw_stats->stats_lock);
-+      mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
-+
-+      SET_NETDEV_DEV(eth->netdev[id], eth->dev);
-+      eth->netdev[id]->netdev_ops = &mtk_netdev_ops;
-+      eth->netdev[id]->base_addr = (unsigned long)eth->base;
-+      eth->netdev[id]->vlan_features = MTK_HW_FEATURES &
-+              ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX);
-+      eth->netdev[id]->features |= MTK_HW_FEATURES;
-+      eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops;
-+
-+      err = register_netdev(eth->netdev[id]);
-+      if (err) {
-+              dev_err(eth->dev, "error bringing up device\n");
-+              goto free_netdev;
-+      }
-+      eth->netdev[id]->irq = eth->irq;
-+      netif_info(eth, probe, eth->netdev[id],
-+                 "mediatek frame engine at 0x%08lx, irq %d\n",
-+                 eth->netdev[id]->base_addr, eth->netdev[id]->irq);
-+
-+      return 0;
-+
-+free_netdev:
-+      free_netdev(eth->netdev[id]);
-+      return err;
-+}
-+
-+static int mtk_probe(struct platform_device *pdev)
-+{
-+      struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+      struct device_node *mac_np;
-+      const struct of_device_id *match;
-+      struct mtk_soc_data *soc;
-+      struct mtk_eth *eth;
-+      int err;
-+
-+      pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
-+      pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
-+
-+      device_reset(&pdev->dev);
-+
-+      match = of_match_device(of_mtk_match, &pdev->dev);
-+      soc = (struct mtk_soc_data *)match->data;
-+
-+      eth = devm_kzalloc(&pdev->dev, sizeof(*eth), GFP_KERNEL);
-+      if (!eth)
-+              return -ENOMEM;
-+
-+      eth->base = devm_ioremap_resource(&pdev->dev, res);
-+      if (!eth->base)
-+              return -EADDRNOTAVAIL;
-+
-+      spin_lock_init(&eth->page_lock);
-+
-+      eth->ethsys = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
-+                                                    "mediatek,ethsys");
-+      if (IS_ERR(eth->ethsys)) {
-+              dev_err(&pdev->dev, "no ethsys regmap found\n");
-+              return PTR_ERR(eth->ethsys);
-+      }
-+
-+      eth->pctl = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
-+                                                  "mediatek,pctl");
-+      if (IS_ERR(eth->pctl)) {
-+              dev_err(&pdev->dev, "no pctl regmap found\n");
-+              return PTR_ERR(eth->pctl);
-+      }
-+
-+      eth->rstc = devm_reset_control_get(&pdev->dev, "eth");
-+      if (IS_ERR(eth->rstc)) {
-+              dev_err(&pdev->dev, "no eth reset found\n");
-+              return PTR_ERR(eth->rstc);
-+      }
-+
-+      eth->irq = platform_get_irq(pdev, 0);
-+      if (eth->irq < 0) {
-+              dev_err(&pdev->dev, "no IRQ resource found\n");
-+              return -ENXIO;
-+      }
-+
-+      eth->clk_ethif = devm_clk_get(&pdev->dev, "ethif");
-+      eth->clk_esw = devm_clk_get(&pdev->dev, "esw");
-+      eth->clk_gp1 = devm_clk_get(&pdev->dev, "gp1");
-+      eth->clk_gp2 = devm_clk_get(&pdev->dev, "gp2");
-+      if (IS_ERR(eth->clk_esw) || IS_ERR(eth->clk_gp1) ||
-+          IS_ERR(eth->clk_gp2) || IS_ERR(eth->clk_ethif))
-+              return -ENODEV;
-+
-+      clk_prepare_enable(eth->clk_ethif);
-+      clk_prepare_enable(eth->clk_esw);
-+      clk_prepare_enable(eth->clk_gp1);
-+      clk_prepare_enable(eth->clk_gp2);
-+
-+      eth->dev = &pdev->dev;
-+      eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE);
-+
-+      err = mtk_hw_init(eth);
-+      if (err)
-+              return err;
-+
-+      for_each_child_of_node(pdev->dev.of_node, mac_np) {
-+              if (!of_device_is_compatible(mac_np,
-+                                           "mediatek,eth-mac"))
-+                      continue;
-+
-+              if (!of_device_is_available(mac_np))
-+                      continue;
-+
-+              err = mtk_add_mac(eth, mac_np);
-+              if (err)
-+                      goto err_free_dev;
-+      }
-+
-+      /* we run 2 devices on the same DMA ring so we need a dummy device
-+       * for NAPI to work
-+       */
-+      init_dummy_netdev(&eth->dummy_dev);
-+      netif_napi_add(&eth->dummy_dev, &eth->rx_napi, mtk_poll,
-+                     MTK_NAPI_WEIGHT);
-+
-+      platform_set_drvdata(pdev, eth);
-+
-+      return 0;
-+
-+err_free_dev:
-+      mtk_cleanup(eth);
-+      return err;
-+}
-+
-+static int mtk_remove(struct platform_device *pdev)
-+{
-+      struct mtk_eth *eth = platform_get_drvdata(pdev);
-+
-+      clk_disable_unprepare(eth->clk_ethif);
-+      clk_disable_unprepare(eth->clk_esw);
-+      clk_disable_unprepare(eth->clk_gp1);
-+      clk_disable_unprepare(eth->clk_gp2);
-+
-+      netif_napi_del(&eth->rx_napi);
-+      mtk_cleanup(eth);
-+      platform_set_drvdata(pdev, NULL);
-+
-+      return 0;
-+}
-+
-+const struct of_device_id of_mtk_match[] = {
-+      { .compatible = "mediatek,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 */
diff --git a/target/linux/mediatek/patches-4.4/0050-net-next-mediatek-add-Kconfig-and-Makefile.patch b/target/linux/mediatek/patches-4.4/0050-net-next-mediatek-add-Kconfig-and-Makefile.patch
deleted file mode 100644 (file)
index 0c7a89e..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-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
diff --git a/target/linux/mediatek/patches-4.4/0051-net-next-mediatek-add-an-entry-to-MAINTAINERS.patch b/target/linux/mediatek/patches-4.4/0051-net-next-mediatek-add-an-entry-to-MAINTAINERS.patch
deleted file mode 100644 (file)
index 10690b2..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-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
diff --git a/target/linux/mediatek/patches-4.4/0052-clk-dont-disable-unused-clocks.patch b/target/linux/mediatek/patches-4.4/0052-clk-dont-disable-unused-clocks.patch
deleted file mode 100644 (file)
index 87e4a54..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-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;
diff --git a/target/linux/mediatek/patches-4.4/0053-clk-mediatek-enable-critical-clocks.patch b/target/linux/mediatek/patches-4.4/0053-clk-mediatek-enable-critical-clocks.patch
deleted file mode 100644 (file)
index 3993900..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-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);
diff --git a/target/linux/mediatek/patches-4.4/0054-clk-mediatek-Export-CPU-mux-clocks-for-CPU-frequency.patch b/target/linux/mediatek/patches-4.4/0054-clk-mediatek-Export-CPU-mux-clocks-for-CPU-frequency.patch
deleted file mode 100644 (file)
index d5af5f0..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-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 */
diff --git a/target/linux/mediatek/patches-4.4/0055-cpufreq-mediatek-add-driver.patch b/target/linux/mediatek/patches-4.4/0055-cpufreq-mediatek-add-driver.patch
deleted file mode 100644 (file)
index 8b47636..0000000
+++ /dev/null
@@ -1,433 +0,0 @@
-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);
diff --git a/target/linux/mediatek/patches-4.4/0056-arm-mediatek-make-a7-timer-work-Signed-off-by-John-C.patch b/target/linux/mediatek/patches-4.4/0056-arm-mediatek-make-a7-timer-work-Signed-off-by-John-C.patch
deleted file mode 100644 (file)
index fe81b47..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-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 */
diff --git a/target/linux/mediatek/patches-4.4/0057-net-mediatek-checking-for-IS_ERR-instead-of-NULL.patch b/target/linux/mediatek/patches-4.4/0057-net-mediatek-checking-for-IS_ERR-instead-of-NULL.patch
deleted file mode 100644 (file)
index f00e968..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-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,
diff --git a/target/linux/mediatek/patches-4.4/0058-net-mediatek-unlock-on-error-in-mtk_tx_map.patch b/target/linux/mediatek/patches-4.4/0058-net-mediatek-unlock-on-error-in-mtk_tx_map.patch
deleted file mode 100644 (file)
index a3f861b..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-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(&eth->page_lock, flags);
-+
-       return -ENOMEM;
- }
diff --git a/target/linux/mediatek/patches-4.4/0059-net-mediatek-use-dma_addr_t-correctly.patch b/target/linux/mediatek/patches-4.4/0059-net-mediatek-use-dma_addr_t-correctly.patch
deleted file mode 100644 (file)
index 0dd5f2d..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-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;
diff --git a/target/linux/mediatek/patches-4.4/0060-net-mediatek-remove-incorrect-dma_mask-assignment.patch b/target/linux/mediatek/patches-4.4/0060-net-mediatek-remove-incorrect-dma_mask-assignment.patch
deleted file mode 100644 (file)
index d1df732..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-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);
diff --git a/target/linux/mediatek/patches-4.4/0061-net-mediatek-check-device_reset-return-code.patch b/target/linux/mediatek/patches-4.4/0061-net-mediatek-check-device_reset-return-code.patch
deleted file mode 100644 (file)
index ebc6d9b..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-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;
diff --git a/target/linux/mediatek/patches-4.4/0062-net-mediatek-watchdog_timeo-was-not-set.patch b/target/linux/mediatek/patches-4.4/0062-net-mediatek-watchdog_timeo-was-not-set.patch
deleted file mode 100644 (file)
index ca2e791..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-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 &
diff --git a/target/linux/mediatek/patches-4.4/0063-net-mediatek-mtk_cal_txd_req-returns-bad-value.patch b/target/linux/mediatek/patches-4.4/0063-net-mediatek-mtk_cal_txd_req-returns-bad-value.patch
deleted file mode 100644 (file)
index a81f165..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-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)
diff --git a/target/linux/mediatek/patches-4.4/0064-net-mediatek-remove-superflous-reset-call.patch b/target/linux/mediatek/patches-4.4/0064-net-mediatek-remove-superflous-reset-call.patch
deleted file mode 100644 (file)
index 434a6e3..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-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;
diff --git a/target/linux/mediatek/patches-4.4/0065-net-mediatek-fix-stop-and-wakeup-of-queue.patch b/target/linux/mediatek/patches-4.4/0065-net-mediatek-fix-stop-and-wakeup-of-queue.patch
deleted file mode 100644 (file)
index 1660e42..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-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;
- }
diff --git a/target/linux/mediatek/patches-4.4/0066-net-mediatek-fix-mtk_pending_work.patch b/target/linux/mediatek/patches-4.4/0066-net-mediatek-fix-mtk_pending_work.patch
deleted file mode 100644 (file)
index b233578..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-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();
- }
diff --git a/target/linux/mediatek/patches-4.4/0067-net-mediatek-fix-TX-locking.patch b/target/linux/mediatek/patches-4.4/0067-net-mediatek-fix-TX-locking.patch
deleted file mode 100644 (file)
index d750de6..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-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(&eth->page_lock, flags);
-       WRITE_ONCE(itxd->txd1, mapped_addr);
-       tx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
-       dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr);
-@@ -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(&eth->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(&eth->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 = &eth->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(&eth->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(&eth->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(&eth->page_lock, flags);
-       return NETDEV_TX_OK;
- drop:
-+      spin_unlock_irqrestore(&eth->page_lock, flags);
-       stats->tx_dropped++;
-       dev_kfree_skb(skb);
-       return NETDEV_TX_OK;
diff --git a/target/linux/mediatek/patches-4.4/0068-net-mediatek-move-the-pending_work-struct-to-the-dev.patch b/target/linux/mediatek/patches-4.4/0068-net-mediatek-move-the-pending_work-struct-to-the-dev.patch
deleted file mode 100644 (file)
index 4973091..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-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(&eth->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(&eth->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(&eth->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 */
diff --git a/target/linux/mediatek/patches-4.4/0069-net-mediatek-do-not-set-the-QID-field-in-the-TX-DMA-.patch b/target/linux/mediatek/patches-4.4/0069-net-mediatek-do-not-set-the-QID-field-in-the-TX-DMA-.patch
deleted file mode 100644 (file)
index 72f96e2..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-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;
diff --git a/target/linux/mediatek/patches-4.4/0070-net-mediatek-update-the-IRQ-part-of-the-binding-docu.patch b/target/linux/mediatek/patches-4.4/0070-net-mediatek-update-the-IRQ-part-of-the-binding-docu.patch
deleted file mode 100644 (file)
index afb0174..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-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 {
-                <&ethsys CLK_ETHSYS_GP2>,
-                <&ethsys 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 = <&ethsys MT2701_ETHSYS_ETH_RST>;
-       reset-names = "eth";
diff --git a/target/linux/mediatek/patches-4.4/0071-pwm-add-pwm-mediatek.patch b/target/linux/mediatek/patches-4.4/0071-pwm-add-pwm-mediatek.patch
deleted file mode 100644 (file)
index 8ca6c49..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-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");
diff --git a/target/linux/mediatek/patches-4.4/0072-mtd-backport-v4.7-0day-patches-from-Boris.patch b/target/linux/mediatek/patches-4.4/0072-mtd-backport-v4.7-0day-patches-from-Boris.patch
deleted file mode 100644 (file)
index b45d3aa..0000000
+++ /dev/null
@@ -1,5286 +0,0 @@
-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, &section, &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, &section,
-+                                      &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, &section,
-+                                      &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, &section, &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
diff --git a/target/linux/mediatek/patches-4.4/0073-of-mtd-prepare-helper-reading-NAND-ECC-algo-from-DT.patch b/target/linux/mediatek/patches-4.4/0073-of-mtd-prepare-helper-reading-NAND-ECC-algo-from-DT.patch
deleted file mode 100644 (file)
index aa45441..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-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)
- {
diff --git a/target/linux/mediatek/patches-4.4/0074-mtd-mediatek-device-tree-docs-for-MTK-Smart-Device-G.patch b/target/linux/mediatek/patches-4.4/0074-mtd-mediatek-device-tree-docs-for-MTK-Smart-Device-G.patch
deleted file mode 100644 (file)
index 5f260e3..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-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";
-+      };
diff --git a/target/linux/mediatek/patches-4.4/0075-mtd-mediatek-driver-for-MTK-Smart-Device-Gen1-NAND.patch b/target/linux/mediatek/patches-4.4/0075-mtd-mediatek-driver-for-MTK-Smart-Device-Gen1-NAND.patch
deleted file mode 100644 (file)
index e5312eb..0000000
+++ /dev/null
@@ -1,2064 +0,0 @@
-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");
diff --git a/target/linux/mediatek/patches-4.4/0076-mtd-nand-add-power-domains-to-the-mediatek-driver.patch b/target/linux/mediatek/patches-4.4/0076-mtd-nand-add-power-domains-to-the-mediatek-driver.patch
deleted file mode 100644 (file)
index 7702246..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-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;
- }
diff --git a/target/linux/mediatek/patches-4.4/0077-net-next-mediatek-use-mdiobus_free-in-favour-of-kfre.patch b/target/linux/mediatek/patches-4.4/0077-net-next-mediatek-use-mdiobus_free-in-favour-of-kfre.patch
deleted file mode 100644 (file)
index c2fe218..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-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)
diff --git a/target/linux/mediatek/patches-4.4/0078-net-next-mediatek-fix-gigabit-and-flow-control-adver.patch b/target/linux/mediatek/patches-4.4/0078-net-next-mediatek-fix-gigabit-and-flow-control-adver.patch
deleted file mode 100644 (file)
index 42adb9e..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-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);
diff --git a/target/linux/mediatek/patches-4.4/0079-net-next-mediatek-add-fixed-phy-support.patch b/target/linux/mediatek/patches-4.4/0079-net-next-mediatek-add-fixed-phy-support.patch
deleted file mode 100644 (file)
index 669febb..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-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 |
diff --git a/target/linux/mediatek/patches-4.4/0080-net-next-mediatek-properly-handle-RGMII-modes.patch b/target/linux/mediatek/patches-4.4/0080-net-next-mediatek-properly-handle-RGMII-modes.patch
deleted file mode 100644 (file)
index 1d176f2..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-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;
diff --git a/target/linux/mediatek/patches-4.4/0081-net-next-mediatek-fix-DQL-support.patch b/target/linux/mediatek/patches-4.4/0081-net-next-mediatek-fix-DQL-support.patch
deleted file mode 100644 (file)
index f1c7290..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-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 */
diff --git a/target/linux/mediatek/patches-4.4/0082-net-next-mediatek-add-missing-return-code-check.patch b/target/linux/mediatek/patches-4.4/0082-net-next-mediatek-add-missing-return-code-check.patch
deleted file mode 100644 (file)
index 19cdbf0..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-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);
diff --git a/target/linux/mediatek/patches-4.4/0083-net-next-mediatek-fix-missing-free-of-scratch-memory.patch b/target/linux/mediatek/patches-4.4/0083-net-next-mediatek-fix-missing-free-of-scratch-memory.patch
deleted file mode 100644 (file)
index 793875f..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-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,
-+                                             &eth->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;
diff --git a/target/linux/mediatek/patches-4.4/0084-net-next-mediatek-invalid-buffer-lookup-in-mtk_tx_ma.patch b/target/linux/mediatek/patches-4.4/0084-net-next-mediatek-invalid-buffer-lookup-in-mtk_tx_ma.patch
deleted file mode 100644 (file)
index eb44af6..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-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);
diff --git a/target/linux/mediatek/patches-4.4/0085-net-next-mediatek-dropped-rx-packets-are-not-being-c.patch b/target/linux/mediatek/patches-4.4/0085-net-next-mediatek-dropped-rx-packets-are-not-being-c.patch
deleted file mode 100644 (file)
index 2b2a011..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-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);
diff --git a/target/linux/mediatek/patches-4.4/0086-net-next-mediatek-add-next-data-pointer-coherency-pr.patch b/target/linux/mediatek/patches-4.4/0086-net-next-mediatek-add-next-data-pointer-coherency-pr.patch
deleted file mode 100644 (file)
index cd4bdf8..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-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)
diff --git a/target/linux/mediatek/patches-4.4/0087-net-next-mediatek-disable-all-interrupts-during-prob.patch b/target/linux/mediatek/patches-4.4/0087-net-next-mediatek-disable-all-interrupts-during-prob.patch
deleted file mode 100644 (file)
index 6e809b9..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-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);
diff --git a/target/linux/mediatek/patches-4.4/0088-net-next-mediatek-fix-threshold-value.patch b/target/linux/mediatek/patches-4.4/0088-net-next-mediatek-fix-threshold-value.patch
deleted file mode 100644 (file)
index c35975b..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-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
diff --git a/target/linux/mediatek/patches-4.4/0089-net-next-mediatek-increase-watchdog_timeo.patch b/target/linux/mediatek/patches-4.4/0089-net-next-mediatek-increase-watchdog_timeo.patch
deleted file mode 100644 (file)
index 96928d2..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-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 &
diff --git a/target/linux/mediatek/patches-4.4/0090-net-next-mediatek-fix-off-by-one-in-the-TX-ring-allo.patch b/target/linux/mediatek/patches-4.4/0090-net-next-mediatek-fix-off-by-one-in-the-TX-ring-allo.patch
deleted file mode 100644 (file)
index b6f32fc..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-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
diff --git a/target/linux/mediatek/patches-4.4/0091-net-next-mediatek-only-wake-the-queue-if-it-is-stopp.patch b/target/linux/mediatek/patches-4.4/0091-net-next-mediatek-only-wake-the-queue-if-it-is-stopp.patch
deleted file mode 100644 (file)
index 257634c..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-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;
diff --git a/target/linux/mediatek/patches-4.4/0092-net-next-mediatek-remove-superfluous-queue-wake-up-c.patch b/target/linux/mediatek/patches-4.4/0092-net-next-mediatek-remove-superfluous-queue-wake-up-c.patch
deleted file mode 100644 (file)
index fe08958..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-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(&eth->page_lock, flags);
-       return NETDEV_TX_OK;
diff --git a/target/linux/mediatek/patches-4.4/0093-net-next-mediatek-remove-superfluous-register-reads.patch b/target/linux/mediatek/patches-4.4/0093-net-next-mediatek-remove-superfluous-register-reads.patch
deleted file mode 100644 (file)
index 3ddbbc6..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-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)
diff --git a/target/linux/mediatek/patches-4.4/0094-net-next-mediatek-don-t-use-intermediate-variables-t.patch b/target/linux/mediatek/patches-4.4/0094-net-next-mediatek-don-t-use-intermediate-variables-t.patch
deleted file mode 100644 (file)
index 983d0c2..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-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 = &eth->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;
- }
diff --git a/target/linux/mediatek/patches-4.4/0095-net-next-mediatek-add-IRQ-locking.patch b/target/linux/mediatek/patches-4.4/0095-net-next-mediatek-add-IRQ-locking.patch
deleted file mode 100644 (file)
index bf27aac..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-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(&eth->irq_lock, flags);
-       val = mtk_r32(eth, MTK_QDMA_INT_MASK);
-       mtk_w32(eth, val & ~mask, MTK_QDMA_INT_MASK);
-+      spin_unlock_irqrestore(&eth->irq_lock, flags);
- }
- static inline void mtk_irq_enable(struct mtk_eth *eth, u32 mask)
- {
-+      unsigned long flags;
-       u32 val;
-+      spin_lock_irqsave(&eth->irq_lock, flags);
-       val = mtk_r32(eth, MTK_QDMA_INT_MASK);
-       mtk_w32(eth, val | mask, MTK_QDMA_INT_MASK);
-+      spin_unlock_irqrestore(&eth->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(&eth->page_lock);
-+      spin_lock_init(&eth->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];
diff --git a/target/linux/mediatek/patches-4.4/0096-net-next-mediatek-add-support-for-IRQ-grouping.patch b/target/linux/mediatek/patches-4.4/0096-net-next-mediatek-add-support-for-IRQ-grouping.patch
deleted file mode 100644 (file)
index 727073e..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-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 = &eth->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(&eth->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(&eth->rx_napi))) {
-+              __napi_schedule(&eth->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(&eth->rx_napi)))
--                      __napi_schedule(&eth->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(&eth->tx_napi))) {
-+              __napi_schedule(&eth->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(&eth->tx_napi);
-               napi_enable(&eth->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(&eth->tx_napi);
-       napi_disable(&eth->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(&eth->dummy_dev);
--      netif_napi_add(&eth->dummy_dev, &eth->rx_napi, mtk_poll,
-+      netif_napi_add(&eth->dummy_dev, &eth->tx_napi, mtk_napi_tx,
-+                     MTK_NAPI_WEIGHT);
-+      netif_napi_add(&eth->dummy_dev, &eth->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(&eth->tx_napi);
-       netif_napi_del(&eth->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;
diff --git a/target/linux/mediatek/patches-4.4/0097-net-next-mediatek-change-my-email-address.patch b/target/linux/mediatek/patches-4.4/0097-net-next-mediatek-change-my-email-address.patch
deleted file mode 100644 (file)
index 472d58b..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-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");
diff --git a/target/linux/mediatek/patches-4.4/0098-net-next-mediatek-only-trigger-the-tx-watchdog-reset.patch b/target/linux/mediatek/patches-4.4/0098-net-next-mediatek-only-trigger-the-tx-watchdog-reset.patch
deleted file mode 100644 (file)
index cc18be5..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-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(&eth->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(&eth->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
diff --git a/target/linux/mediatek/patches-4.4/0099-MAINTAINERS-change-my-email-address.patch b/target/linux/mediatek/patches-4.4/0099-MAINTAINERS-change-my-email-address.patch
deleted file mode 100644 (file)
index 1bad613..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-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/
diff --git a/target/linux/mediatek/patches-4.4/0100-MAINTAINERS-add-Sean-as-mediatek-ethernet-maintainer.patch b/target/linux/mediatek/patches-4.4/0100-MAINTAINERS-add-Sean-as-mediatek-ethernet-maintainer.patch
deleted file mode 100644 (file)
index 145868c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-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/
diff --git a/target/linux/mediatek/patches-4.4/0101-net-mediatek-add-gsw-mt7530-driver.patch b/target/linux/mediatek/patches-4.4/0101-net-mediatek-add-gsw-mt7530-driver.patch
deleted file mode 100644 (file)
index 4d931fc..0000000
+++ /dev/null
@@ -1,2360 +0,0 @@
-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(&eth->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 */
diff --git a/target/linux/mediatek/patches-4.4/0102-net-mediatek-v4.4-backports.patch b/target/linux/mediatek/patches-4.4/0102-net-mediatek-v4.4-backports.patch
deleted file mode 100644 (file)
index 3561b40..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-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);
diff --git a/target/linux/mediatek/patches-4.4/0103-nand_fixes.patch b/target/linux/mediatek/patches-4.4/0103-nand_fixes.patch
deleted file mode 100644 (file)
index 92f34c5..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
---- 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,
diff --git a/target/linux/mediatek/patches-4.4/0200-devicetree.patch b/target/linux/mediatek/patches-4.4/0200-devicetree.patch
deleted file mode 100644 (file)
index eb743c7..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- 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
diff --git a/target/linux/mediatek/patches-4.4/0201-block2mtd.patch b/target/linux/mediatek/patches-4.4/0201-block2mtd.patch
deleted file mode 100644 (file)
index 395884b..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
---- 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;
-       }
diff --git a/target/linux/mediatek/patches-4.9/0000-pinctrl-esw.patch b/target/linux/mediatek/patches-4.9/0000-pinctrl-esw.patch
new file mode 100644 (file)
index 0000000..2fedae7
--- /dev/null
@@ -0,0 +1,12 @@
+--- 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)
diff --git a/target/linux/mediatek/patches-4.9/0001-NET-multi-phy-support.patch b/target/linux/mediatek/patches-4.9/0001-NET-multi-phy-support.patch
new file mode 100644 (file)
index 0000000..b60eac0
--- /dev/null
@@ -0,0 +1,53 @@
+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;
diff --git a/target/linux/mediatek/patches-4.9/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch b/target/linux/mediatek/patches-4.9/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch
new file mode 100644 (file)
index 0000000..132d6c8
--- /dev/null
@@ -0,0 +1,44 @@
+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 */
diff --git a/target/linux/mediatek/patches-4.9/0009-clk-mediatek-Add-MT2701-clock-support.patch b/target/linux/mediatek/patches-4.9/0009-clk-mediatek-Add-MT2701-clock-support.patch
new file mode 100644 (file)
index 0000000..552b46e
--- /dev/null
@@ -0,0 +1,1431 @@
+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 = &eth_cg_regs,                   \
++              .shift = _shift,                        \
++              .ops = &mtk_clk_gate_ops_no_setclr_inv, \
++      }
++
++static const struct mtk_gate eth_clks[] __initconst = {
++      GATE_HIF(CLK_ETHSYS_HSDMA, "hsdma_clk", "ethif_sel", 5),
++      GATE_HIF(CLK_ETHSYS_ESW, "esw_clk", "ethpll_500m_ck", 6),
++      GATE_HIF(CLK_ETHSYS_GP2, "gp2_clk", "trgpll", 7),
++      GATE_HIF(CLK_ETHSYS_GP1, "gp1_clk", "ethpll_500m_ck", 8),
++      GATE_HIF(CLK_ETHSYS_PCM, "pcm_clk", "ethif_sel", 11),
++      GATE_HIF(CLK_ETHSYS_GDMA, "gdma_clk", "ethif_sel", 14),
++      GATE_HIF(CLK_ETHSYS_I2S, "i2s_clk", "ethif_sel", 17),
++      GATE_HIF(CLK_ETHSYS_CRYPTO, "crypto_clk", "ethif_sel", 29),
++};
++
++static void __init mtk_ethsys_init(struct device_node *node)
++{
++      struct clk_onecell_data *clk_data;
++      int r;
++
++      clk_data = mtk_alloc_clk_data(CLK_ETHSYS_NR);
++
++      mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks),
++                                              clk_data);
++
++      r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++      if (r)
++              pr_err("%s(): could not register clock provider: %d\n",
++                      __func__, r);
++}
++CLK_OF_DECLARE(mtk_ethsys, "mediatek,mt2701-ethsys", mtk_ethsys_init);
++
++static const struct mtk_gate_regs bdp0_cg_regs __initconst = {
++      .set_ofs = 0x0104,
++      .clr_ofs = 0x0108,
++      .sta_ofs = 0x0100,
++};
++
++static const struct mtk_gate_regs bdp1_cg_regs __initconst = {
++      .set_ofs = 0x0114,
++      .clr_ofs = 0x0118,
++      .sta_ofs = 0x0110,
++};
++
++#define GATE_BDP0(_id, _name, _parent, _shift) {      \
++              .id = _id,                              \
++              .name = _name,                          \
++              .parent_name = _parent,                 \
++              .regs = &bdp0_cg_regs,                  \
++              .shift = _shift,                        \
++              .ops = &mtk_clk_gate_ops_setclr_inv,    \
++      }
++
++#define GATE_BDP1(_id, _name, _parent, _shift) {      \
++              .id = _id,                              \
++              .name = _name,                          \
++              .parent_name = _parent,                 \
++              .regs = &bdp1_cg_regs,                  \
++              .shift = _shift,                        \
++              .ops = &mtk_clk_gate_ops_setclr_inv,    \
++      }
++
++static const struct mtk_gate bdp_clks[] __initconst = {
++      GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0),
++      GATE_BDP0(CLK_BDP_BRG_DRAM, "brg_dram", "mm_sel", 1),
++      GATE_BDP0(CLK_BDP_LARB_DRAM, "larb_dram", "mm_sel", 2),
++      GATE_BDP0(CLK_BDP_WR_VDI_PXL, "wr_vdi_pxl", "hdmi_0_deep340m", 3),
++      GATE_BDP0(CLK_BDP_WR_VDI_DRAM, "wr_vdi_dram", "mm_sel", 4),
++      GATE_BDP0(CLK_BDP_WR_B, "wr_bclk", "mm_sel", 5),
++      GATE_BDP0(CLK_BDP_DGI_IN, "dgi_in", "dpi1_sel", 6),
++      GATE_BDP0(CLK_BDP_DGI_OUT, "dgi_out", "dpi_sel", 7),
++      GATE_BDP0(CLK_BDP_FMT_MAST_27, "fmt_mast_27", "dpi1_sel", 8),
++      GATE_BDP0(CLK_BDP_FMT_B, "fmt_bclk", "mm_sel", 9),
++      GATE_BDP0(CLK_BDP_OSD_B, "osd_bclk", "mm_sel", 10),
++      GATE_BDP0(CLK_BDP_OSD_DRAM, "osd_dram", "mm_sel", 11),
++      GATE_BDP0(CLK_BDP_OSD_AGENT, "osd_agent", "osd_sel", 12),
++      GATE_BDP0(CLK_BDP_OSD_PXL, "osd_pxl", "dpi1_sel", 13),
++      GATE_BDP0(CLK_BDP_RLE_B, "rle_bclk", "mm_sel", 14),
++      GATE_BDP0(CLK_BDP_RLE_AGENT, "rle_agent", "mm_sel", 15),
++      GATE_BDP0(CLK_BDP_RLE_DRAM, "rle_dram", "mm_sel", 16),
++      GATE_BDP0(CLK_BDP_F27M, "f27m", "di_sel", 17),
++      GATE_BDP0(CLK_BDP_F27M_VDOUT, "f27m_vdout", "di_sel", 18),
++      GATE_BDP0(CLK_BDP_F27_74_74, "f27_74_74", "di_sel", 19),
++      GATE_BDP0(CLK_BDP_F2FS, "f2fs", "di_sel", 20),
++      GATE_BDP0(CLK_BDP_F2FS74_148, "f2fs74_148", "di_sel", 21),
++      GATE_BDP0(CLK_BDP_FB, "fbclk", "mm_sel", 22),
++      GATE_BDP0(CLK_BDP_VDO_DRAM, "vdo_dram", "mm_sel", 23),
++      GATE_BDP0(CLK_BDP_VDO_2FS, "vdo_2fs", "di_sel", 24),
++      GATE_BDP0(CLK_BDP_VDO_B, "vdo_bclk", "mm_sel", 25),
++      GATE_BDP0(CLK_BDP_WR_DI_PXL, "wr_di_pxl", "di_sel", 26),
++      GATE_BDP0(CLK_BDP_WR_DI_DRAM, "wr_di_dram", "mm_sel", 27),
++      GATE_BDP0(CLK_BDP_WR_DI_B, "wr_di_bclk", "mm_sel", 28),
++      GATE_BDP0(CLK_BDP_NR_PXL, "nr_pxl", "nr_sel", 29),
++      GATE_BDP0(CLK_BDP_NR_DRAM, "nr_dram", "mm_sel", 30),
++      GATE_BDP0(CLK_BDP_NR_B, "nr_bclk", "mm_sel", 31),
++      GATE_BDP1(CLK_BDP_RX_F, "rx_fclk", "hadds2_fbclk", 0),
++      GATE_BDP1(CLK_BDP_RX_X, "rx_xclk", "clk26m", 1),
++      GATE_BDP1(CLK_BDP_RXPDT, "rxpdtclk", "hdmi_0_pix340m", 2),
++      GATE_BDP1(CLK_BDP_RX_CSCL_N, "rx_cscl_n", "clk26m", 3),
++      GATE_BDP1(CLK_BDP_RX_CSCL, "rx_cscl", "clk26m", 4),
++      GATE_BDP1(CLK_BDP_RX_DDCSCL_N, "rx_ddcscl_n", "hdmi_scl_rx", 5),
++      GATE_BDP1(CLK_BDP_RX_DDCSCL, "rx_ddcscl", "hdmi_scl_rx", 6),
++      GATE_BDP1(CLK_BDP_RX_VCO, "rx_vcoclk", "hadds2pll_294m", 7),
++      GATE_BDP1(CLK_BDP_RX_DP, "rx_dpclk", "hdmi_0_pll340m", 8),
++      GATE_BDP1(CLK_BDP_RX_P, "rx_pclk", "hdmi_0_pll340m", 9),
++      GATE_BDP1(CLK_BDP_RX_M, "rx_mclk", "hadds2pll_294m", 10),
++      GATE_BDP1(CLK_BDP_RX_PLL, "rx_pllclk", "hdmi_0_pix340m", 11),
++      GATE_BDP1(CLK_BDP_BRG_RT_B, "brg_rt_bclk", "mm_sel", 12),
++      GATE_BDP1(CLK_BDP_BRG_RT_DRAM, "brg_rt_dram", "mm_sel", 13),
++      GATE_BDP1(CLK_BDP_LARBRT_DRAM, "larbrt_dram", "mm_sel", 14),
++      GATE_BDP1(CLK_BDP_TMDS_SYN, "tmds_syn", "hdmi_0_pll340m", 15),
++      GATE_BDP1(CLK_BDP_HDMI_MON, "hdmi_mon", "hdmi_0_mon", 16),
++};
++
++static void __init mtk_bdpsys_init(struct device_node *node)
++{
++      struct clk_onecell_data *clk_data;
++      int r;
++
++      clk_data = mtk_alloc_clk_data(CLK_BDP_NR);
++
++      mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks),
++                                              clk_data);
++
++      r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++      if (r)
++              pr_err("%s(): could not register clock provider: %d\n",
++                      __func__, r);
++}
++CLK_OF_DECLARE(mtk_bdpsys, "mediatek,mt2701-bdpsys", mtk_bdpsys_init);
++
++#define MT8590_PLL_FMAX               (2000 * MHZ)
++#define CON0_MT8590_RST_BAR   BIT(27)
++
++#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \
++                      _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) {  \
++              .id = _id,                                              \
++              .name = _name,                                          \
++              .reg = _reg,                                            \
++              .pwr_reg = _pwr_reg,                                    \
++              .en_mask = _en_mask,                                    \
++              .flags = _flags,                                        \
++              .rst_bar_mask = CON0_MT8590_RST_BAR,                    \
++              .fmax = MT8590_PLL_FMAX,                                \
++              .pcwbits = _pcwbits,                                    \
++              .pd_reg = _pd_reg,                                      \
++              .pd_shift = _pd_shift,                                  \
++              .tuner_reg = _tuner_reg,                                \
++              .pcw_reg = _pcw_reg,                                    \
++              .pcw_shift = _pcw_shift,                                \
++      }
++
++static const struct mtk_pll_data apmixed_plls[] = {
++      PLL(CLK_APMIXED_ARMPLL, "armpll", 0x200, 0x20c, 0x80000001, 0,
++                              21, 0x204, 24, 0x0, 0x204, 0),
++      PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x210, 0x21c, 0xf0000001,
++                HAVE_RST_BAR, 21, 0x210, 4, 0x0, 0x214, 0),
++      PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x220, 0x22c, 0xf3000001,
++                HAVE_RST_BAR, 7, 0x220, 4, 0x0, 0x224, 14),
++      PLL(CLK_APMIXED_MMPLL, "mmpll", 0x230, 0x23c, 0x00000001, 0,
++                              21, 0x230, 4, 0x0, 0x234, 0),
++      PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x240, 0x24c, 0x00000001, 0,
++                              21, 0x240, 4, 0x0, 0x244, 0),
++      PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x250, 0x25c, 0x00000001, 0,
++                              21, 0x250, 4, 0x0, 0x254, 0),
++      PLL(CLK_APMIXED_AUD1PLL, "aud1pll", 0x270, 0x27c, 0x00000001, 0,
++                              31, 0x270, 4, 0x0, 0x274, 0),
++      PLL(CLK_APMIXED_TRGPLL, "trgpll", 0x280, 0x28c, 0x00000001, 0,
++                              31, 0x280, 4, 0x0, 0x284, 0),
++      PLL(CLK_APMIXED_ETHPLL, "ethpll", 0x290, 0x29c, 0x00000001, 0,
++                              31, 0x290, 4, 0x0, 0x294, 0),
++      PLL(CLK_APMIXED_VDECPLL, "vdecpll", 0x2a0, 0x2ac, 0x00000001, 0,
++                              31, 0x2a0, 4, 0x0, 0x2a4, 0),
++      PLL(CLK_APMIXED_HADDS2PLL, "hadds2pll", 0x2b0, 0x2bc, 0x00000001, 0,
++                              31, 0x2b0, 4, 0x0, 0x2b4, 0),
++      PLL(CLK_APMIXED_AUD2PLL, "aud2pll", 0x2c0, 0x2cc, 0x00000001, 0,
++                              31, 0x2c0, 4, 0x0, 0x2c4, 0),
++      PLL(CLK_APMIXED_TVD2PLL, "tvd2pll", 0x2d0, 0x2dc, 0x00000001, 0,
++                              21, 0x2d0, 4, 0x0, 0x2d4, 0),
++};
++
++static void __init mtk_apmixedsys_init(struct device_node *node)
++{
++      struct clk_onecell_data *clk_data;
++      int r;
++
++      clk_data = mtk_alloc_clk_data(ARRAY_SIZE(apmixed_plls));
++      if (!clk_data)
++              return;
++
++      mtk_clk_register_plls(node, apmixed_plls, ARRAY_SIZE(apmixed_plls),
++                                                              clk_data);
++
++      r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
++      if (r)
++              pr_err("%s(): could not register clock provider: %d\n",
++                      __func__, r);
++}
++CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt2701-apmixedsys",
++                                                      mtk_apmixedsys_init);
+--- 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);
diff --git a/target/linux/mediatek/patches-4.9/0011-reset-mediatek-mt2701-reset-driver.patch b/target/linux/mediatek/patches-4.9/0011-reset-mediatek-mt2701-reset-driver.patch
new file mode 100644 (file)
index 0000000..18d4fbf
--- /dev/null
@@ -0,0 +1,36 @@
+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);
diff --git a/target/linux/mediatek/patches-4.9/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch b/target/linux/mediatek/patches-4.9/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch
new file mode 100644 (file)
index 0000000..696dea6
--- /dev/null
@@ -0,0 +1,29 @@
+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
diff --git a/target/linux/mediatek/patches-4.9/0017-clk-add-hifsys-reset.patch b/target/linux/mediatek/patches-4.9/0017-clk-add-hifsys-reset.patch
new file mode 100644 (file)
index 0000000..60940f3
--- /dev/null
@@ -0,0 +1,31 @@
+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);
diff --git a/target/linux/mediatek/patches-4.9/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch b/target/linux/mediatek/patches-4.9/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch
new file mode 100644 (file)
index 0000000..d6fe977
--- /dev/null
@@ -0,0 +1,154 @@
+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";
++              };
++      };
diff --git a/target/linux/mediatek/patches-4.9/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch b/target/linux/mediatek/patches-4.9/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch
new file mode 100644 (file)
index 0000000..71081fb
--- /dev/null
@@ -0,0 +1,698 @@
+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);
diff --git a/target/linux/mediatek/patches-4.9/0026-scpsys-various-fixes.patch b/target/linux/mediatek/patches-4.9/0026-scpsys-various-fixes.patch
new file mode 100644 (file)
index 0000000..b5047f7
--- /dev/null
@@ -0,0 +1,22 @@
+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);
diff --git a/target/linux/mediatek/patches-4.9/0052-clk-dont-disable-unused-clocks.patch b/target/linux/mediatek/patches-4.9/0052-clk-dont-disable-unused-clocks.patch
new file mode 100644 (file)
index 0000000..87e4a54
--- /dev/null
@@ -0,0 +1,21 @@
+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;
diff --git a/target/linux/mediatek/patches-4.9/0053-clk-mediatek-enable-critical-clocks.patch b/target/linux/mediatek/patches-4.9/0053-clk-mediatek-enable-critical-clocks.patch
new file mode 100644 (file)
index 0000000..3993900
--- /dev/null
@@ -0,0 +1,69 @@
+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);
diff --git a/target/linux/mediatek/patches-4.9/0054-clk-mediatek-Export-CPU-mux-clocks-for-CPU-frequency.patch b/target/linux/mediatek/patches-4.9/0054-clk-mediatek-Export-CPU-mux-clocks-for-CPU-frequency.patch
new file mode 100644 (file)
index 0000000..2ff6990
--- /dev/null
@@ -0,0 +1,287 @@
+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 */
diff --git a/target/linux/mediatek/patches-4.9/0055-cpufreq-mediatek-add-driver.patch b/target/linux/mediatek/patches-4.9/0055-cpufreq-mediatek-add-driver.patch
new file mode 100644 (file)
index 0000000..8b47636
--- /dev/null
@@ -0,0 +1,433 @@
+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);
diff --git a/target/linux/mediatek/patches-4.9/0071-pwm-add-pwm-mediatek.patch b/target/linux/mediatek/patches-4.9/0071-pwm-add-pwm-mediatek.patch
new file mode 100644 (file)
index 0000000..75796ab
--- /dev/null
@@ -0,0 +1,304 @@
+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");
diff --git a/target/linux/mediatek/patches-4.9/0101-net-mediatek-add-gsw-mt7530-driver.patch b/target/linux/mediatek/patches-4.9/0101-net-mediatek-add-gsw-mt7530-driver.patch
new file mode 100644 (file)
index 0000000..a90f490
--- /dev/null
@@ -0,0 +1,2322 @@
+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 */
diff --git a/target/linux/mediatek/patches-4.9/0103-nand_fixes.patch b/target/linux/mediatek/patches-4.9/0103-nand_fixes.patch
new file mode 100644 (file)
index 0000000..92f34c5
--- /dev/null
@@ -0,0 +1,22 @@
+--- 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,
diff --git a/target/linux/mediatek/patches-4.9/0200-devicetree.patch b/target/linux/mediatek/patches-4.9/0200-devicetree.patch
new file mode 100644 (file)
index 0000000..eb743c7
--- /dev/null
@@ -0,0 +1,11 @@
+--- 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
diff --git a/target/linux/mediatek/patches-4.9/0201-block2mtd.patch b/target/linux/mediatek/patches-4.9/0201-block2mtd.patch
new file mode 100644 (file)
index 0000000..395884b
--- /dev/null
@@ -0,0 +1,32 @@
+--- 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;
+       }