From: John Crispin Date: Thu, 16 Feb 2017 08:53:03 +0000 (+0100) Subject: mediatek: bump to v4.9 X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fstaging%2Fflorian.git;a=commitdiff_plain;h=53f5d59fa17049d94a3992d1067ded1fa90f61f8 mediatek: bump to v4.9 Signed-off-by: John Crispin --- diff --git a/target/linux/mediatek/Makefile b/target/linux/mediatek/Makefile index e3eecd5886..0b495ef70e 100644 --- a/target/linux/mediatek/Makefile +++ b/target/linux/mediatek/Makefile @@ -10,7 +10,7 @@ CPU_TYPE:=cortex-a7 CPU_SUBTYPE:=neon-vfpv4 MAINTAINER:=John Crispin -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 index 56e721bdb6..0000000000 --- a/target/linux/mediatek/config-4.4 +++ /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 diff --git a/target/linux/mediatek/files/arch/arm/boot/dts/_mt7623.dtsi b/target/linux/mediatek/files/arch/arm/boot/dts/_mt7623.dtsi index 87be1b8092..0f91194e8a 100644 --- a/target/linux/mediatek/files/arch/arm/boot/dts/_mt7623.dtsi +++ b/target/linux/mediatek/files/arch/arm/boot/dts/_mt7623.dtsi @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #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 index b60eac0efc..0000000000 --- a/target/linux/mediatek/patches-4.4/0001-NET-multi-phy-support.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 1e021917e634b173d466bf0dd3d2ae84e51a77ff Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Sun, 27 Jul 2014 09:38:50 +0100 -Subject: [PATCH 001/102] NET: multi phy support - -Signed-off-by: John Crispin ---- - 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 index 194e66970e..0000000000 --- a/target/linux/mediatek/patches-4.4/0002-soc-mediatek-Separate-scpsys-driver-common-code.patch +++ /dev/null @@ -1,665 +0,0 @@ -From 1892fcf687116720d07135c83d489a23ec56a166 Mon Sep 17 00:00:00 2001 -From: James Liao -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 ---- - 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 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+ -+#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 --#include - #include --#include - #include --#include --#include - #include - #include --#include - #include --#include - --#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 index 46af96450b..0000000000 --- a/target/linux/mediatek/patches-4.4/0003-soc-mediatek-Init-MT8173-scpsys-driver-earlier.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 6f87948c3a58f02f6a64eadda719317016739d5e Mon Sep 17 00:00:00 2001 -From: James Liao -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 ---- - 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 index 132d6c89c8..0000000000 --- a/target/linux/mediatek/patches-4.4/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 7c5b29de78f1b15c5bde40a6ca4510fc09588457 Mon Sep 17 00:00:00 2001 -From: Shunli Wang -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 -Signed-off-by: James Liao ---- - 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 index 2f2337a8e3..0000000000 --- a/target/linux/mediatek/patches-4.4/0005-soc-mediatek-Add-MT2701-MT7623-scpsys-driver.patch +++ /dev/null @@ -1,204 +0,0 @@ -From 8aa49d107d8a22fd6cbf37174614baf32d0976e2 Mon Sep 17 00:00:00 2001 -From: Shunli Wang -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 -Signed-off-by: James Liao ---- - 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 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+ -+#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 index d4bac233b9..0000000000 --- a/target/linux/mediatek/patches-4.4/0006-clk-mediatek-Refine-the-makefile-to-support-multiple.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 69d4e250847f82a5896c41bcb5f1e793c5a8fbac Mon Sep 17 00:00:00 2001 -From: James Liao -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 -Signed-off-by: James Liao ---- - 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 index fd21c0b788..0000000000 --- a/target/linux/mediatek/patches-4.4/0007-dt-bindings-ARM-Mediatek-Document-bindings-for-MT270.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 7c98b20fa68a2a64bca69822eb7be4fa9b668fab Mon Sep 17 00:00:00 2001 -From: James Liao -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 ---- - .../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 index 422a5bec3a..0000000000 --- a/target/linux/mediatek/patches-4.4/0008-clk-mediatek-Add-dt-bindings-for-MT2701-clocks.patch +++ /dev/null @@ -1,499 +0,0 @@ -From 190696e3995be38fa01490e4ab88ea2c859829c9 Mon Sep 17 00:00:00 2001 -From: Shunli Wang -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 -Signed-off-by: James Liao ---- - 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 -+ * -+ * 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 index 6f8f68a300..0000000000 --- a/target/linux/mediatek/patches-4.4/0009-clk-mediatek-Add-MT2701-clock-support.patch +++ /dev/null @@ -1,1431 +0,0 @@ -From a4c507d052390b42d7e8c59241e3c336796f730f Mon Sep 17 00:00:00 2001 -From: Shunli Wang -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 -Signed-off-by: James Liao ---- - 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 -+ * -+ * 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 -+#include -+#include -+ -+#include "clk-mtk.h" -+#include "clk-gate.h" -+ -+#include -+ -+static DEFINE_SPINLOCK(lock); -+ -+static const struct mtk_fixed_clk top_fixed_clks[] __initconst = { -+ FIXED_CLK(CLK_TOP_DPI, "dpi_ck", "clk26m", 108 * MHZ), -+ FIXED_CLK(CLK_TOP_DMPLL, "dmpll_ck", "clk26m", 400 * MHZ), -+ FIXED_CLK(CLK_TOP_VENCPLL, "vencpll_ck", "clk26m", 295750000), -+ FIXED_CLK(CLK_TOP_HDMI_0_PIX340M, "hdmi_0_pix340m", "clk26m", 340 * MHZ), -+ FIXED_CLK(CLK_TOP_HDMI_0_DEEP340M, "hdmi_0_deep340m", "clk26m", 340 * MHZ), -+ FIXED_CLK(CLK_TOP_HDMI_0_PLL340M, "hdmi_0_pll340m", "clk26m", 340 * MHZ), -+ FIXED_CLK(CLK_TOP_HDMITX_CLKDIG_CTS, "hdmitx_dig_cts", "clk26m", 300 * MHZ), -+ FIXED_CLK(CLK_TOP_HADDS2_FB, "hadds2_fbclk", "clk26m", 27 * MHZ), -+ FIXED_CLK(CLK_TOP_WBG_DIG_416M, "wbg_dig_ck_416m", "clk26m", 416 * MHZ), -+}; -+ -+static const struct mtk_fixed_factor top_fixed_divs[] __initconst = { -+ FACTOR(CLK_TOP_SYSPLL, "syspll_ck", "mainpll", 1, 1), -+ FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2), -+ FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1, 3), -+ FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5), -+ FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll", 1, 7), -+ FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "syspll_d2", 1, 2), -+ FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "syspll_d2", 1, 4), -+ FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "syspll_d2", 1, 8), -+ FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "syspll_d2", 1, 16), -+ FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "syspll_d3", 1, 2), -+ FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "syspll_d3", 1, 4), -+ FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "syspll_d3", 1, 8), -+ FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "syspll_d5", 1, 2), -+ FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "syspll_d5", 1, 4), -+ FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "syspll_d7", 1, 2), -+ FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "syspll_d7", 1, 4), -+ -+ FACTOR(CLK_TOP_UNIVPLL, "univpll_ck", "univpll", 1, 1), -+ FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2), -+ FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3), -+ FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5), -+ FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7), -+ FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll", 1, 26), -+ FACTOR(CLK_TOP_UNIVPLL_D52, "univpll_d52", "univpll", 1, 52), -+ FACTOR(CLK_TOP_UNIVPLL_D108, "univpll_d108", "univpll", 1, 108), -+ FACTOR(CLK_TOP_USB_PHY48M, "USB_PHY48M_CK", "univpll", 1, 26), -+ FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_d2", 1, 2), -+ FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_d2", 1, 4), -+ FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_d2", 1, 8), -+ FACTOR(CLK_TOP_8BDAC, "8bdac_ck", "univpll_d2", 1, 1), -+ FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_d3", 1, 2), -+ FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_d3", 1, 4), -+ FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_d3", 1, 8), -+ FACTOR(CLK_TOP_UNIVPLL2_D16, "univpll2_d16", "univpll_d3", 1, 16), -+ FACTOR(CLK_TOP_UNIVPLL2_D32, "univpll2_d32", "univpll_d3", 1, 32), -+ FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll_d5", 1, 2), -+ FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll_d5", 1, 4), -+ FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univpll_d5", 1, 8), -+ -+ FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1), -+ FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2), -+ FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4), -+ FACTOR(CLK_TOP_MSDCPLL_D8, "msdcpll_d8", "msdcpll", 1, 8), -+ -+ FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1, 1), -+ FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2), -+ -+ FACTOR(CLK_TOP_DMPLL_D2, "dmpll_d2", "dmpll_ck", 1, 2), -+ FACTOR(CLK_TOP_DMPLL_D4, "dmpll_d4", "dmpll_ck", 1, 4), -+ FACTOR(CLK_TOP_DMPLL_X2, "dmpll_x2", "dmpll_ck", 1, 1), -+ -+ FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll", 1, 1), -+ FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll", 1, 2), -+ FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4), -+ -+ FACTOR(CLK_TOP_VDECPLL, "vdecpll_ck", "vdecpll", 1, 1), -+ FACTOR(CLK_TOP_TVD2PLL, "tvd2pll_ck", "tvd2pll", 1, 1), -+ FACTOR(CLK_TOP_TVD2PLL_D2, "tvd2pll_d2", "tvd2pll", 1, 2), -+ -+ FACTOR(CLK_TOP_MIPIPLL, "mipipll", "dpi_ck", 1, 1), -+ FACTOR(CLK_TOP_MIPIPLL_D2, "mipipll_d2", "dpi_ck", 1, 2), -+ FACTOR(CLK_TOP_MIPIPLL_D4, "mipipll_d4", "dpi_ck", 1, 4), -+ -+ FACTOR(CLK_TOP_HDMIPLL, "hdmipll_ck", "hdmitx_dig_cts", 1, 1), -+ FACTOR(CLK_TOP_HDMIPLL_D2, "hdmipll_d2", "hdmitx_dig_cts", 1, 2), -+ FACTOR(CLK_TOP_HDMIPLL_D3, "hdmipll_d3", "hdmitx_dig_cts", 1, 3), -+ -+ FACTOR(CLK_TOP_ARMPLL_1P3G, "armpll_1p3g_ck", "armpll", 1, 1), -+ -+ FACTOR(CLK_TOP_AUDPLL, "audpll", "audpll_sel", 1, 1), -+ FACTOR(CLK_TOP_AUDPLL_D4, "audpll_d4", "audpll_sel", 1, 4), -+ FACTOR(CLK_TOP_AUDPLL_D8, "audpll_d8", "audpll_sel", 1, 8), -+ FACTOR(CLK_TOP_AUDPLL_D16, "audpll_d16", "audpll_sel", 1, 16), -+ FACTOR(CLK_TOP_AUDPLL_D24, "audpll_d24", "audpll_sel", 1, 24), -+ -+ FACTOR(CLK_TOP_AUD1PLL_98M, "aud1pll_98m_ck", "aud1pll", 1, 3), -+ FACTOR(CLK_TOP_AUD2PLL_90M, "aud2pll_90m_ck", "aud2pll", 1, 3), -+ FACTOR(CLK_TOP_HADDS2PLL_98M, "hadds2pll_98m", "hadds2pll", 1, 3), -+ FACTOR(CLK_TOP_HADDS2PLL_294M, "hadds2pll_294m", "hadds2pll", 1, 1), -+ FACTOR(CLK_TOP_ETHPLL_500M, "ethpll_500m_ck", "ethpll", 1, 1), -+ FACTOR(CLK_TOP_CLK26M_D8, "clk26m_d8", "clk26m", 1, 8), -+ FACTOR(CLK_TOP_32K_INTERNAL, "32k_internal", "clk26m", 1, 793), -+ FACTOR(CLK_TOP_32K_EXTERNAL, "32k_external", "rtc32k", 1, 1), -+}; -+ -+static const char * const axi_parents[] __initconst = { -+ "clk26m", -+ "syspll1_d2", -+ "syspll_d5", -+ "syspll1_d4", -+ "univpll_d5", -+ "univpll2_d2", -+ "mmpll_d2", -+ "dmpll_d2" -+}; -+ -+static const char * const mem_parents[] __initconst = { -+ "clk26m", -+ "dmpll_ck" -+}; -+ -+static const char * const ddrphycfg_parents[] __initconst = { -+ "clk26m", -+ "syspll1_d8" -+}; -+ -+static const char * const mm_parents[] __initconst = { -+ "clk26m", -+ "vencpll_ck", -+ "syspll1_d2", -+ "syspll1_d4", -+ "univpll_d5", -+ "univpll1_d2", -+ "univpll2_d2", -+ "dmpll_ck" -+}; -+ -+static const char * const pwm_parents[] __initconst = { -+ "clk26m", -+ "univpll2_d4", -+ "univpll3_d2", -+ "univpll1_d4", -+}; -+ -+static const char * const vdec_parents[] __initconst = { -+ "clk26m", -+ "vdecpll_ck", -+ "syspll_d5", -+ "syspll1_d4", -+ "univpll_d5", -+ "univpll2_d2", -+ "vencpll_ck", -+ "msdcpll_d2", -+ "mmpll_d2" -+}; -+ -+static const char * const mfg_parents[] __initconst = { -+ "clk26m", -+ "mmpll_ck", -+ "dmpll_x2_ck", -+ "msdcpll_ck", -+ "clk26m", -+ "syspll_d3", -+ "univpll_d3", -+ "univpll1_d2" -+}; -+ -+static const char * const camtg_parents[] __initconst = { -+ "clk26m", -+ "univpll_d26", -+ "univpll2_d2", -+ "syspll3_d2", -+ "syspll3_d4", -+ "msdcpll_d2", -+ "mmpll_d2" -+}; -+ -+static const char * const uart_parents[] __initconst = { -+ "clk26m", -+ "univpll2_d8" -+}; -+ -+static const char * const spi_parents[] __initconst = { -+ "clk26m", -+ "syspll3_d2", -+ "syspll4_d2", -+ "univpll2_d4", -+ "univpll1_d8" -+}; -+ -+static const char * const usb20_parents[] __initconst = { -+ "clk26m", -+ "univpll1_d8", -+ "univpll3_d4" -+}; -+ -+static const char * const msdc30_parents[] __initconst = { -+ "clk26m", -+ "msdcpll_d2", -+ "syspll2_d2", -+ "syspll1_d4", -+ "univpll1_d4", -+ "univpll2_d4" -+}; -+ -+static const char * const audio_parents[] __initconst = { -+ "clk26m", -+ "syspll1_d16" -+}; -+ -+static const char * const aud_intbus_parents[] __initconst = { -+ "clk26m", -+ "syspll1_d4", -+ "syspll3_d2", -+ "syspll4_d2", -+ "univpll3_d2", -+ "univpll2_d4" -+}; -+ -+static const char * const pmicspi_parents[] __initconst = { -+ "clk26m", -+ "syspll1_d8", -+ "syspll2_d4", -+ "syspll4_d2", -+ "syspll3_d4", -+ "syspll2_d8", -+ "syspll1_d16", -+ "univpll3_d4", -+ "univpll_d26", -+ "dmpll_d2", -+ "dmpll_d4" -+}; -+ -+static const char * const scp_parents[] __initconst = { -+ "clk26m", -+ "syspll1_d8", -+ "dmpll_d2", -+ "dmpll_d4" -+}; -+ -+static const char * const dpi0_parents[] __initconst = { -+ "clk26m", -+ "mipipll", -+ "mipipll_d2", -+ "mipipll_d4", -+ "clk26m", -+ "tvdpll_ck", -+ "tvdpll_d2", -+ "tvdpll_d4" -+}; -+ -+static const char * const dpi1_parents[] __initconst = { -+ "clk26m", -+ "tvdpll_ck", -+ "tvdpll_d2", -+ "tvdpll_d4" -+}; -+ -+static const char * const tve_parents[] __initconst = { -+ "clk26m", -+ "mipipll", -+ "mipipll_d2", -+ "mipipll_d4", -+ "clk26m", -+ "tvdpll_ck", -+ "tvdpll_d2", -+ "tvdpll_d4" -+}; -+ -+static const char * const hdmi_parents[] __initconst = { -+ "clk26m", -+ "hdmipll_ck", -+ "hdmipll_d2", -+ "hdmipll_d3" -+}; -+ -+static const char * const apll_parents[] __initconst = { -+ "clk26m", -+ "audpll", -+ "audpll_d4", -+ "audpll_d8", -+ "audpll_d16", -+ "audpll_d24", -+ "clk26m", -+ "clk26m" -+}; -+ -+static const char * const rtc_parents[] __initconst = { -+ "32k_internal", -+ "32k_external", -+ "clk26m", -+ "univpll3_d8" -+}; -+ -+static const char * const nfi2x_parents[] __initconst = { -+ "clk26m", -+ "syspll2_d2", -+ "syspll_d7", -+ "univpll3_d2", -+ "syspll2_d4", -+ "univpll3_d4", -+ "syspll4_d4", -+ "clk26m" -+}; -+ -+static const char * const emmc_hclk_parents[] __initconst = { -+ "clk26m", -+ "syspll1_d2", -+ "syspll1_d4", -+ "syspll2_d2" -+}; -+ -+static const char * const flash_parents[] __initconst = { -+ "clk26m_d8", -+ "clk26m", -+ "syspll2_d8", -+ "syspll3_d4", -+ "univpll3_d4", -+ "syspll4_d2", -+ "syspll2_d4", -+ "univpll2_d4" -+}; -+ -+static const char * const di_parents[] __initconst = { -+ "clk26m", -+ "tvd2pll_ck", -+ "tvd2pll_d2", -+ "clk26m" -+}; -+ -+static const char * const nr_osd_parents[] __initconst = { -+ "clk26m", -+ "vencpll_ck", -+ "syspll1_d2", -+ "syspll1_d4", -+ "univpll_d5", -+ "univpll1_d2", -+ "univpll2_d2", -+ "dmpll_ck" -+}; -+ -+static const char * const hdmirx_bist_parents[] __initconst = { -+ "clk26m", -+ "syspll_d3", -+ "clk26m", -+ "syspll1_d16", -+ "syspll4_d2", -+ "syspll1_d4", -+ "vencpll_ck", -+ "clk26m" -+}; -+ -+static const char * const intdir_parents[] __initconst = { -+ "clk26m", -+ "mmpll_ck", -+ "syspll_d2", -+ "univpll_d2" -+}; -+ -+static const char * const asm_parents[] __initconst = { -+ "clk26m", -+ "univpll2_d4", -+ "univpll2_d2", -+ "syspll_d5" -+}; -+ -+static const char * const ms_card_parents[] __initconst = { -+ "clk26m", -+ "univpll3_d8", -+ "syspll4_d4" -+}; -+ -+static const char * const ethif_parents[] __initconst = { -+ "clk26m", -+ "syspll1_d2", -+ "syspll_d5", -+ "syspll1_d4", -+ "univpll_d5", -+ "univpll1_d2", -+ "dmpll_ck", -+ "dmpll_d2" -+}; -+ -+static const char * const hdmirx_parents[] __initconst = { -+ "clk26m", -+ "univpll_d52" -+}; -+ -+static const char * const cmsys_parents[] __initconst = { -+ "clk26m", -+ "syspll1_d2", -+ "univpll1_d2", -+ "univpll_d5", -+ "syspll_d5", -+ "syspll2_d2", -+ "syspll1_d4", -+ "syspll3_d2", -+ "syspll2_d4", -+ "syspll1_d8", -+ "clk26m", -+ "clk26m", -+ "clk26m", -+ "clk26m", -+ "clk26m" -+}; -+ -+static const char * const clk_8bdac_parents[] __initconst = { -+ "clkrtc_int", -+ "8bdac_ck_pre", -+ "clk26m", -+ "clk26m" -+}; -+ -+static const char * const aud2dvd_parents[] __initconst = { -+ "a1sys_hp_ck", -+ "a2sys_hp_ck" -+}; -+ -+static const char * const padmclk_parents[] __initconst = { -+ "clk26m", -+ "univpll_d26", -+ "univpll_d52", -+ "univpll_d108", -+ "univpll2_d8", -+ "univpll2_d16", -+ "univpll2_d32" -+}; -+ -+static const char * const aud_mux_parents[] __initconst = { -+ "clk26m", -+ "aud1pll_98m_ck", -+ "aud2pll_90m_ck", -+ "hadds2pll_98m", -+ "audio_ext1_ck", -+ "audio_ext2_ck" -+}; -+ -+static const char * const aud_src_parents[] __initconst = { -+ "aud_mux1_sel", -+ "aud_mux2_sel" -+}; -+ -+static const char * const cpu_parents[] __initconst = { -+ "clk26m", -+ "armpll", -+ "mainpll", -+ "mmpll" -+}; -+ -+static const struct mtk_composite top_muxes[] __initconst = { -+ MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, -+ 0x0040, 0, 3, INVALID_MUX_GATE_BIT), -+ MUX_GATE(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x0040, 8, 1, 15), -+ MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents, 0x0040, 16, 1, 23), -+ MUX_GATE(CLK_TOP_MM_SEL, "mm_sel", mm_parents, 0x0040, 24, 3, 31), -+ -+ MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x0050, 0, 2, 7), -+ MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x0050, 8, 4, 15), -+ MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0050, 16, 3, 23), -+ MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x0050, 24, 3, 31), -+ MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x0060, 0, 1, 7), -+ -+ MUX_GATE(CLK_TOP_SPI0_SEL, "spi0_sel", spi_parents, 0x0060, 8, 3, 15), -+ MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x0060, 16, 2, 23), -+ MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_parents, 0x0060, 24, 3, 31), -+ -+ MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_parents, 0x0070, 0, 3, 7), -+ MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_parents, 0x0070, 8, 3, 15), -+ MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", msdc30_parents, 0x0070, 16, 1, 23), -+ MUX_GATE(CLK_TOP_AUDINTBUS_SEL, "aud_intbus_sel", aud_intbus_parents, 0x0070, 24, 3, 31), -+ -+ MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x0080, 0, 4, 7), -+ MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, 0x0080, 8, 2, 15), -+ MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents, 0x0080, 16, 3, 23), -+ MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0080, 24, 2, 31), -+ -+ MUX_GATE(CLK_TOP_TVE_SEL, "tve_sel", tve_parents, 0x0090, 0, 3, 7), -+ MUX_GATE(CLK_TOP_HDMI_SEL, "hdmi_sel", hdmi_parents, 0x0090, 8, 2, 15), -+ MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", apll_parents, 0x0090, 16, 3, 23), -+ -+ MUX_GATE(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents, 0x00A0, 0, 2, 7), -+ MUX_GATE(CLK_TOP_NFI2X_SEL, "nfi2x_sel", nfi2x_parents, 0x00A0, 8, 3, 15), -+ MUX_GATE(CLK_TOP_EMMC_HCLK_SEL, "emmc_hclk_sel", emmc_hclk_parents, 0x00A0, 24, 2, 31), -+ -+ MUX_GATE(CLK_TOP_FLASH_SEL, "flash_sel", flash_parents, 0x00B0, 0, 3, 7), -+ MUX_GATE(CLK_TOP_DI_SEL, "di_sel", di_parents, 0x00B0, 8, 2, 15), -+ MUX_GATE(CLK_TOP_NR_SEL, "nr_sel", nr_osd_parents, 0x00B0, 16, 3, 23), -+ MUX_GATE(CLK_TOP_OSD_SEL, "osd_sel", nr_osd_parents, 0x00B0, 24, 3, 31), -+ -+ MUX_GATE(CLK_TOP_HDMIRX_BIST_SEL, "hdmirx_bist_sel", hdmirx_bist_parents, 0x00C0, 0, 3, 7), -+ MUX_GATE(CLK_TOP_INTDIR_SEL, "intdir_sel", intdir_parents, 0x00C0, 8, 2, 15), -+ MUX_GATE(CLK_TOP_ASM_I_SEL, "asm_i_sel", asm_parents, 0x00C0, 16, 2, 23), -+ MUX_GATE(CLK_TOP_ASM_M_SEL, "asm_m_sel", asm_parents, 0x00C0, 24, 3, 31), -+ -+ MUX_GATE(CLK_TOP_ASM_H_SEL, "asm_h_sel", asm_parents, 0x00D0, 0, 2, 7), -+ MUX_GATE(CLK_TOP_MS_CARD_SEL, "ms_card_sel", ms_card_parents, 0x00D0, 16, 2, 23), -+ MUX_GATE(CLK_TOP_ETHIF_SEL, "ethif_sel", ethif_parents, 0x00D0, 24, 3, 31), -+ -+ MUX_GATE(CLK_TOP_HDMIRX26_24_SEL, "hdmirx26_24_sel", hdmirx_parents, 0x00E0, 0, 1, 7), -+ MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_parents, 0x00E0, 8, 3, 15), -+ MUX_GATE(CLK_TOP_CMSYS_SEL, "cmsys_sel", cmsys_parents, 0x00E0, 16, 4, 23), -+ -+ MUX_GATE(CLK_TOP_SPI1_SEL, "spi2_sel", spi_parents, 0x00E0, 24, 3, 31), -+ MUX_GATE(CLK_TOP_SPI2_SEL, "spi1_sel", spi_parents, 0x00F0, 0, 3, 7), -+ MUX_GATE(CLK_TOP_8BDAC_SEL, "8bdac_sel", clk_8bdac_parents, 0x00F0, 8, 2, 15), -+ MUX_GATE(CLK_TOP_AUD2DVD_SEL, "aud2dvd_sel", aud2dvd_parents, 0x00F0, 16, 1, 23), -+ -+ MUX(CLK_TOP_PADMCLK_SEL, "padmclk_sel", padmclk_parents, 0x0100, 0, 3), -+ -+ MUX(CLK_TOP_AUD_MUX1_SEL, "aud_mux1_sel", aud_mux_parents, 0x012c, 0, 3), -+ MUX(CLK_TOP_AUD_MUX2_SEL, "aud_mux2_sel", aud_mux_parents, 0x012c, 3, 3), -+ MUX(CLK_TOP_AUDPLL_MUX_SEL, "audpll_sel", aud_mux_parents, 0x012c, 6, 3), -+ MUX_GATE(CLK_TOP_AUD_K1_SRC_SEL, "aud_k1_src_sel", aud_src_parents, 0x012c, 15, 1, 23), -+ MUX_GATE(CLK_TOP_AUD_K2_SRC_SEL, "aud_k2_src_sel", aud_src_parents, 0x012c, 16, 1, 24), -+ MUX_GATE(CLK_TOP_AUD_K3_SRC_SEL, "aud_k3_src_sel", aud_src_parents, 0x012c, 17, 1, 25), -+ MUX_GATE(CLK_TOP_AUD_K4_SRC_SEL, "aud_k4_src_sel", aud_src_parents, 0x012c, 18, 1, 26), -+ MUX_GATE(CLK_TOP_AUD_K5_SRC_SEL, "aud_k5_src_sel", aud_src_parents, 0x012c, 19, 1, 27), -+ MUX_GATE(CLK_TOP_AUD_K6_SRC_SEL, "aud_k6_src_sel", aud_src_parents, 0x012c, 20, 1, 28), -+}; -+ -+static const struct mtk_clk_divider top_adj_divs[] __initconst = { -+ DIV_ADJ(CLK_TOP_AUD_EXTCK1_DIV, "audio_ext1_ck", "aud_ext_ck1", 0x0120, 0, 8), -+ DIV_ADJ(CLK_TOP_AUD_EXTCK2_DIV, "audio_ext2_ck", "aud_ext_ck2", 0x0120, 8, 8), -+ DIV_ADJ(CLK_TOP_AUD_MUX1_DIV, "aud_mux1_div", "aud_mux1_sel", 0x0120, 16, 8), -+ DIV_ADJ(CLK_TOP_AUD_MUX2_DIV, "aud_mux2_div", "aud_mux2_sel", 0x0120, 24, 8), -+ DIV_ADJ(CLK_TOP_AUD_K1_SRC_DIV, "aud_k1_src_div", "aud_k1_src_sel", 0x0124, 0, 8), -+ DIV_ADJ(CLK_TOP_AUD_K2_SRC_DIV, "aud_k2_src_div", "aud_k2_src_sel", 0x0124, 8, 8), -+ DIV_ADJ(CLK_TOP_AUD_K3_SRC_DIV, "aud_k3_src_div", "aud_k3_src_sel", 0x0124, 16, 8), -+ DIV_ADJ(CLK_TOP_AUD_K4_SRC_DIV, "aud_k4_src_div", "aud_k4_src_sel", 0x0124, 24, 8), -+ DIV_ADJ(CLK_TOP_AUD_K5_SRC_DIV, "aud_k5_src_div", "aud_k5_src_sel", 0x0128, 0, 8), -+ DIV_ADJ(CLK_TOP_AUD_K6_SRC_DIV, "aud_k6_src_div", "aud_k6_src_sel", 0x0128, 8, 8), -+}; -+ -+static const struct mtk_gate_regs top_aud_cg_regs __initconst = { -+ .sta_ofs = 0x012C, -+}; -+ -+#define GATE_TOP_AUD(_id, _name, _parent, _shift) { \ -+ .id = _id, \ -+ .name = _name, \ -+ .parent_name = _parent, \ -+ .regs = &top_aud_cg_regs, \ -+ .shift = _shift, \ -+ .ops = &mtk_clk_gate_ops_no_setclr, \ -+ } -+ -+static const struct mtk_gate top_clks[] __initconst = { -+ GATE_TOP_AUD(CLK_TOP_AUD_48K_TIMING, "a1sys_hp_ck", "aud_mux1_div", 21), -+ GATE_TOP_AUD(CLK_TOP_AUD_44K_TIMING, "a2sys_hp_ck", "aud_mux2_div", 22), -+ GATE_TOP_AUD(CLK_TOP_AUD_I2S1_MCLK, "aud_i2s1_mclk", "aud_k1_src_div", 23), -+ GATE_TOP_AUD(CLK_TOP_AUD_I2S2_MCLK, "aud_i2s2_mclk", "aud_k2_src_div", 24), -+ GATE_TOP_AUD(CLK_TOP_AUD_I2S3_MCLK, "aud_i2s3_mclk", "aud_k3_src_div", 25), -+ GATE_TOP_AUD(CLK_TOP_AUD_I2S4_MCLK, "aud_i2s4_mclk", "aud_k4_src_div", 26), -+ GATE_TOP_AUD(CLK_TOP_AUD_I2S5_MCLK, "aud_i2s5_mclk", "aud_k5_src_div", 27), -+ GATE_TOP_AUD(CLK_TOP_AUD_I2S6_MCLK, "aud_i2s6_mclk", "aud_k6_src_div", 28), -+}; -+ -+static void __init mtk_topckgen_init(struct device_node *node) -+{ -+ struct clk_onecell_data *clk_data; -+ void __iomem *base; -+ int r; -+ -+ base = of_iomap(node, 0); -+ if (!base) { -+ pr_err("%s(): ioremap failed\n", __func__); -+ return; -+ } -+ -+ clk_data = mtk_alloc_clk_data(CLK_TOP_NR); -+ -+ mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), -+ clk_data); -+ -+ mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs), -+ clk_data); -+ -+ mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), -+ base, &lock, clk_data); -+ -+ mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs), -+ base, &lock, clk_data); -+ -+ mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), -+ clk_data); -+ -+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); -+ if (r) -+ pr_err("%s(): could not register clock provider: %d\n", -+ __func__, r); -+} -+CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt2701-topckgen", mtk_topckgen_init); -+ -+static const struct mtk_gate_regs infra_cg_regs __initconst = { -+ .set_ofs = 0x0040, -+ .clr_ofs = 0x0044, -+ .sta_ofs = 0x0048, -+}; -+ -+#define GATE_ICG(_id, _name, _parent, _shift) { \ -+ .id = _id, \ -+ .name = _name, \ -+ .parent_name = _parent, \ -+ .regs = &infra_cg_regs, \ -+ .shift = _shift, \ -+ .ops = &mtk_clk_gate_ops_setclr, \ -+ } -+ -+static const struct mtk_gate infra_clks[] __initconst = { -+ GATE_ICG(CLK_INFRA_DBG, "dbgclk", "axi_sel", 0), -+ GATE_ICG(CLK_INFRA_SMI, "smi_ck", "mm_sel", 1), -+ GATE_ICG(CLK_INFRA_QAXI_CM4, "cm4_ck", "axi_sel", 2), -+ GATE_ICG(CLK_INFRA_AUD_SPLIN_B, "audio_splin_bck", "hadds2_294m_ck", 4), -+ GATE_ICG(CLK_INFRA_AUDIO, "audio_ck", "clk_null", 5), -+ GATE_ICG(CLK_INFRA_EFUSE, "efuse_ck", "clk26m", 6), -+ GATE_ICG(CLK_INFRA_L2C_SRAM, "l2c_sram_ck", "mm_sel", 7), -+ GATE_ICG(CLK_INFRA_M4U, "m4u_ck", "mem_sel", 8), -+ GATE_ICG(CLK_INFRA_CONNMCU, "connsys_bus", "wbg_dig_ck_416m", 12), -+ GATE_ICG(CLK_INFRA_TRNG, "trng_ck", "axi_sel", 13), -+ GATE_ICG(CLK_INFRA_RAMBUFIF, "rambufif_ck", "mem_sel", 14), -+ GATE_ICG(CLK_INFRA_CPUM, "cpum_ck", "mem_sel", 15), -+ GATE_ICG(CLK_INFRA_KP, "kp_ck", "axi_sel", 16), -+ GATE_ICG(CLK_INFRA_CEC, "cec_ck", "rtc_sel", 18), -+ GATE_ICG(CLK_INFRA_IRRX, "irrx_ck", "axi_sel", 19), -+ GATE_ICG(CLK_INFRA_PMICSPI, "pmicspi_ck", "pmicspi_sel", 22), -+ GATE_ICG(CLK_INFRA_PMICWRAP, "pmicwrap_ck", "axi_sel", 23), -+ GATE_ICG(CLK_INFRA_DDCCI, "ddcci_ck", "axi_sel", 24), -+}; -+ -+static const struct mtk_fixed_factor infra_fixed_divs[] __initconst = { -+ FACTOR(CLK_INFRA_CLK_13M, "clk13m", "clk26m", 1, 2), -+}; -+ -+static void __init mtk_infrasys_init(struct device_node *node) -+{ -+ struct clk_onecell_data *clk_data; -+ int r; -+ -+ clk_data = mtk_alloc_clk_data(CLK_INFRA_NR); -+ -+ mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), -+ clk_data); -+ mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs), -+ clk_data); -+ -+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); -+ if (r) -+ pr_err("%s(): could not register clock provider: %d\n", -+ __func__, r); -+} -+CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt2701-infracfg", mtk_infrasys_init); -+ -+static const struct mtk_gate_regs peri0_cg_regs __initconst = { -+ .set_ofs = 0x0008, -+ .clr_ofs = 0x0010, -+ .sta_ofs = 0x0018, -+}; -+ -+static const struct mtk_gate_regs peri1_cg_regs __initconst = { -+ .set_ofs = 0x000c, -+ .clr_ofs = 0x0014, -+ .sta_ofs = 0x001c, -+}; -+ -+#define GATE_PERI0(_id, _name, _parent, _shift) { \ -+ .id = _id, \ -+ .name = _name, \ -+ .parent_name = _parent, \ -+ .regs = &peri0_cg_regs, \ -+ .shift = _shift, \ -+ .ops = &mtk_clk_gate_ops_setclr, \ -+ } -+ -+#define GATE_PERI1(_id, _name, _parent, _shift) { \ -+ .id = _id, \ -+ .name = _name, \ -+ .parent_name = _parent, \ -+ .regs = &peri1_cg_regs, \ -+ .shift = _shift, \ -+ .ops = &mtk_clk_gate_ops_setclr, \ -+ } -+ -+static const struct mtk_gate peri_clks[] __initconst = { -+ GATE_PERI1(CLK_PERI_USB0_MCU, "usb0_mcu_ck", "axi_sel", 31), -+ GATE_PERI1(CLK_PERI_ETH, "eth_ck", "clk26m", 30), -+ GATE_PERI1(CLK_PERI_SPI0, "spi0_ck", "spi0_sel", 29), -+ GATE_PERI1(CLK_PERI_AUXADC, "auxadc_ck", "clk26m", 28), -+ GATE_PERI0(CLK_PERI_I2C3, "i2c3_ck", "clk26m", 27), -+ GATE_PERI0(CLK_PERI_I2C2, "i2c2_ck", "axi_sel", 26), -+ GATE_PERI0(CLK_PERI_I2C1, "i2c1_ck", "axi_sel", 25), -+ GATE_PERI0(CLK_PERI_I2C0, "i2c0_ck", "axi_sel", 24), -+ GATE_PERI0(CLK_PERI_BTIF, "bitif_ck", "axi_sel", 23), -+ GATE_PERI0(CLK_PERI_UART3, "uart3_ck", "axi_sel", 22), -+ GATE_PERI0(CLK_PERI_UART2, "uart2_ck", "axi_sel", 21), -+ GATE_PERI0(CLK_PERI_UART1, "uart1_ck", "axi_sel", 20), -+ GATE_PERI0(CLK_PERI_UART0, "uart0_ck", "axi_sel", 19), -+ GATE_PERI0(CLK_PERI_NLI, "nli_ck", "axi_sel", 18), -+ GATE_PERI0(CLK_PERI_MSDC50_3, "msdc50_3_ck", "emmc_hclk_sel", 17), -+ GATE_PERI0(CLK_PERI_MSDC30_3, "msdc30_3_ck", "msdc30_3_sel", 16), -+ GATE_PERI0(CLK_PERI_MSDC30_2, "msdc30_2_ck", "msdc30_2_sel", 15), -+ GATE_PERI0(CLK_PERI_MSDC30_1, "msdc30_1_ck", "msdc30_1_sel", 14), -+ GATE_PERI0(CLK_PERI_MSDC30_0, "msdc30_0_ck", "msdc30_0_sel", 13), -+ GATE_PERI0(CLK_PERI_AP_DMA, "ap_dma_ck", "axi_sel", 12), -+ GATE_PERI0(CLK_PERI_USB1, "usb1_ck", "usb20_sel", 11), -+ GATE_PERI0(CLK_PERI_USB0, "usb0_ck", "usb20_sel", 10), -+ GATE_PERI0(CLK_PERI_PWM, "pwm_ck", "axi_sel", 9), -+ GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axi_sel", 8), -+ GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axi_sel", 7), -+ GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axi_sel", 6), -+ GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axi_sel", 5), -+ GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axi_sel", 4), -+ GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axi_sel", 3), -+ GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axi_sel", 2), -+ GATE_PERI0(CLK_PERI_THERM, "therm_ck", "axi_sel", 1), -+ GATE_PERI0(CLK_PERI_NFI, "nfi_ck", "nfi2x_sel", 0), -+ -+ GATE_PERI1(CLK_PERI_FCI, "fci_ck", "ms_card", 11), -+ GATE_PERI1(CLK_PERI_SPI2, "spi2_ck", "spi2_sel", 10), -+ GATE_PERI1(CLK_PERI_SPI1, "spi1_ck", "spi1_sel", 9), -+ GATE_PERI1(CLK_PERI_HOST89_DVD, "host89_dvd_ck", "aud2dvd_sel", 8), -+ GATE_PERI1(CLK_PERI_HOST89_SPI, "host89_spi_ck", "spi0_sel", 7), -+ GATE_PERI1(CLK_PERI_HOST89_INT, "host89_int_ck", "axi_sel", 6), -+ GATE_PERI1(CLK_PERI_FLASH, "flash_ck", "nfi2x_sel", 5), -+ GATE_PERI1(CLK_PERI_NFI_PAD, "nfi_pad_ck", "nfi_sel", 4), -+ GATE_PERI1(CLK_PERI_NFI_ECC, "nfi_ecc_ck", "nfi_sel", 3), -+ GATE_PERI1(CLK_PERI_GCPU, "gcpu_ck", "axi_sel", 2), -+ GATE_PERI1(CLK_PERI_USB_SLV, "usbslv_ck", "axi_sel", 1), -+ GATE_PERI1(CLK_PERI_USB1_MCU, "usb1_mcu_ck", "axi_sel", 0), -+}; -+ -+static const char * const uart_ck_sel_parents[] __initconst = { -+ "clk26m", -+ "uart_sel", -+}; -+ -+static const struct mtk_composite peri_muxs[] __initconst = { -+ MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents, 0x40c, 0, 1), -+ MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents, 0x40c, 1, 1), -+ MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents, 0x40c, 2, 1), -+ MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1), -+}; -+ -+static void __init mtk_pericfg_init(struct device_node *node) -+{ -+ struct clk_onecell_data *clk_data; -+ void __iomem *base; -+ int r; -+ -+ base = of_iomap(node, 0); -+ if (!base) { -+ pr_err("%s(): ioremap failed\n", __func__); -+ return; -+ } -+ -+ clk_data = mtk_alloc_clk_data(CLK_PERI_NR); -+ -+ mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks), -+ clk_data); -+ -+ mtk_clk_register_composites(peri_muxs, ARRAY_SIZE(peri_muxs), base, -+ &lock, clk_data); -+ -+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); -+ if (r) -+ pr_err("%s(): could not register clock provider: %d\n", -+ __func__, r); -+} -+CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt2701-pericfg", mtk_pericfg_init); -+ -+static const struct mtk_gate_regs disp0_cg_regs __initconst = { -+ .set_ofs = 0x0104, -+ .clr_ofs = 0x0108, -+ .sta_ofs = 0x0100, -+}; -+ -+static const struct mtk_gate_regs disp1_cg_regs __initconst = { -+ .set_ofs = 0x0114, -+ .clr_ofs = 0x0118, -+ .sta_ofs = 0x0110, -+}; -+ -+#define GATE_DISP0(_id, _name, _parent, _shift) { \ -+ .id = _id, \ -+ .name = _name, \ -+ .parent_name = _parent, \ -+ .regs = &disp0_cg_regs, \ -+ .shift = _shift, \ -+ .ops = &mtk_clk_gate_ops_setclr, \ -+ } -+ -+#define GATE_DISP1(_id, _name, _parent, _shift) { \ -+ .id = _id, \ -+ .name = _name, \ -+ .parent_name = _parent, \ -+ .regs = &disp1_cg_regs, \ -+ .shift = _shift, \ -+ .ops = &mtk_clk_gate_ops_setclr, \ -+ } -+ -+static const struct mtk_gate mm_clks[] __initconst = { -+ GATE_DISP0(CLK_MM_SMI_COMMON, "mm_smi_comm", "mm_sel", 0), -+ GATE_DISP0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1), -+ GATE_DISP0(CLK_MM_CMDQ, "mm_cmdq", "mm_sel", 2), -+ GATE_DISP0(CLK_MM_MUTEX, "mm_mutex", "mm_sel", 3), -+ GATE_DISP0(CLK_MM_DISP_COLOR, "mm_disp_color", "mm_sel", 4), -+ GATE_DISP0(CLK_MM_DISP_BLS, "mm_disp_bls", "mm_sel", 5), -+ GATE_DISP0(CLK_MM_DISP_WDMA, "mm_disp_wdma", "mm_sel", 6), -+ GATE_DISP0(CLK_MM_DISP_RDMA, "mm_disp_rdma", "mm_sel", 7), -+ GATE_DISP0(CLK_MM_DISP_OVL, "mm_disp_ovl", "mm_sel", 8), -+ GATE_DISP0(CLK_MM_MDP_TDSHP, "mm_mdp_tdshp", "mm_sel", 9), -+ GATE_DISP0(CLK_MM_MDP_WROT, "mm_mdp_wrot", "mm_sel", 10), -+ GATE_DISP0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11), -+ GATE_DISP0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 12), -+ GATE_DISP0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 13), -+ GATE_DISP0(CLK_MM_MDP_RDMA, "mm_mdp_rdma", "mm_sel", 14), -+ GATE_DISP0(CLK_MM_MDP_BLS_26M, "mm_mdp_bls_26m", "clk26m", 15), -+ GATE_DISP0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 16), -+ GATE_DISP0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 17), -+ GATE_DISP0(CLK_MM_MUTEX_32K, "mm_mutex_32k", "rtc_sel", 18), -+ GATE_DISP0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 19), -+ GATE_DISP0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 20), -+ GATE_DISP1(CLK_MM_DSI_ENGINE, "mm_dsi_eng", "mm_sel", 0), -+ GATE_DISP1(CLK_MM_DSI_DIG, "mm_dsi_dig", "dsio_lntc_dsiclk", 1), -+ GATE_DISP1(CLK_MM_DPI_DIGL, "mm_dpi_digl", "dpi0_sel", 2), -+ GATE_DISP1(CLK_MM_DPI_ENGINE, "mm_dpi_eng", "mm_sel", 3), -+ GATE_DISP1(CLK_MM_DPI1_DIGL, "mm_dpi1_digl", "dpi1_sel", 4), -+ GATE_DISP1(CLK_MM_DPI1_ENGINE, "mm_dpi1_eng", "mm_sel", 5), -+ GATE_DISP1(CLK_MM_TVE_OUTPUT, "mm_tve_output", "tve_sel", 6), -+ GATE_DISP1(CLK_MM_TVE_INPUT, "mm_tve_input", "dpi0_sel", 7), -+ GATE_DISP1(CLK_MM_HDMI_PIXEL, "mm_hdmi_pixel", "dpi1_sel", 8), -+ GATE_DISP1(CLK_MM_HDMI_PLL, "mm_hdmi_pll", "hdmi_sel", 9), -+ GATE_DISP1(CLK_MM_HDMI_AUDIO, "mm_hdmi_audio", "apll_sel", 10), -+ GATE_DISP1(CLK_MM_HDMI_SPDIF, "mm_hdmi_spdif", "apll_sel", 11), -+ GATE_DISP1(CLK_MM_TVE_FMM, "mm_tve_fmm", "mm_sel", 14), -+}; -+ -+static void __init mtk_mmsys_init(struct device_node *node) -+{ -+ struct clk_onecell_data *clk_data; -+ int r; -+ -+ clk_data = mtk_alloc_clk_data(CLK_MM_NR); -+ -+ mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks), -+ clk_data); -+ -+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); -+ if (r) -+ pr_err("%s(): could not register clock provider: %d\n", -+ __func__, r); -+} -+CLK_OF_DECLARE(mtk_mmsys, "mediatek,mt2701-mmsys", mtk_mmsys_init); -+ -+static const struct mtk_gate_regs img_cg_regs __initconst = { -+ .set_ofs = 0x0004, -+ .clr_ofs = 0x0008, -+ .sta_ofs = 0x0000, -+}; -+ -+#define GATE_IMG(_id, _name, _parent, _shift) { \ -+ .id = _id, \ -+ .name = _name, \ -+ .parent_name = _parent, \ -+ .regs = &img_cg_regs, \ -+ .shift = _shift, \ -+ .ops = &mtk_clk_gate_ops_setclr, \ -+ } -+ -+static const struct mtk_gate img_clks[] __initconst = { -+ GATE_IMG(CLK_IMG_SMI_COMM, "img_smi_comm", "mm_sel", 0), -+ GATE_IMG(CLK_IMG_RESZ, "img_resz", "mm_sel", 1), -+ GATE_IMG(CLK_IMG_JPGDEC, "img_jpgdec", "mm_sel", 5), -+ GATE_IMG(CLK_IMG_VENC_LT, "img_venc_lt", "mm_sel", 8), -+ GATE_IMG(CLK_IMG_VENC, "img_venc", "mm_sel", 9), -+}; -+ -+static void __init mtk_imgsys_init(struct device_node *node) -+{ -+ struct clk_onecell_data *clk_data; -+ int r; -+ -+ clk_data = mtk_alloc_clk_data(CLK_IMG_NR); -+ -+ mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks), -+ clk_data); -+ -+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); -+ if (r) -+ pr_err("%s(): could not register clock provider: %d\n", -+ __func__, r); -+} -+CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt2701-imgsys", mtk_imgsys_init); -+ -+static const struct mtk_gate_regs vdec0_cg_regs __initconst = { -+ .set_ofs = 0x0000, -+ .clr_ofs = 0x0004, -+ .sta_ofs = 0x0000, -+}; -+ -+static const struct mtk_gate_regs vdec1_cg_regs __initconst = { -+ .set_ofs = 0x0008, -+ .clr_ofs = 0x000c, -+ .sta_ofs = 0x0008, -+}; -+ -+#define GATE_VDEC0(_id, _name, _parent, _shift) { \ -+ .id = _id, \ -+ .name = _name, \ -+ .parent_name = _parent, \ -+ .regs = &vdec0_cg_regs, \ -+ .shift = _shift, \ -+ .ops = &mtk_clk_gate_ops_setclr_inv, \ -+ } -+ -+#define GATE_VDEC1(_id, _name, _parent, _shift) { \ -+ .id = _id, \ -+ .name = _name, \ -+ .parent_name = _parent, \ -+ .regs = &vdec1_cg_regs, \ -+ .shift = _shift, \ -+ .ops = &mtk_clk_gate_ops_setclr_inv, \ -+ } -+ -+static const struct mtk_gate vdec_clks[] __initconst = { -+ GATE_VDEC0(CLK_VDEC_CKGEN, "vdec_cken", "vdec_sel", 0), -+ GATE_VDEC1(CLK_VDEC_LARB, "vdec_larb_cken", "mm_sel", 0), -+}; -+ -+static void __init mtk_vdecsys_init(struct device_node *node) -+{ -+ struct clk_onecell_data *clk_data; -+ int r; -+ -+ clk_data = mtk_alloc_clk_data(CLK_VDEC_NR); -+ -+ mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks), -+ clk_data); -+ -+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); -+ if (r) -+ pr_err("%s(): could not register clock provider: %d\n", -+ __func__, r); -+} -+CLK_OF_DECLARE(mtk_vdecsys, "mediatek,mt2701-vdecsys", mtk_vdecsys_init); -+ -+static const struct mtk_gate_regs hif_cg_regs __initconst = { -+ .sta_ofs = 0x0008, -+}; -+ -+#define GATE_HIF(_id, _name, _parent, _shift) { \ -+ .id = _id, \ -+ .name = _name, \ -+ .parent_name = _parent, \ -+ .regs = &hif_cg_regs, \ -+ .shift = _shift, \ -+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \ -+ } -+ -+static const struct mtk_gate hif_clks[] __initconst = { -+ GATE_HIF(CLK_HIFSYS_USB0PHY, "usb0_phy_clk", "ethpll_500m_ck", 21), -+ GATE_HIF(CLK_HIFSYS_USB1PHY, "usb1_phy_clk", "ethpll_500m_ck", 22), -+ GATE_HIF(CLK_HIFSYS_PCIE0, "pcie0_clk", "ethpll_500m_ck", 24), -+ GATE_HIF(CLK_HIFSYS_PCIE1, "pcie1_clk", "ethpll_500m_ck", 25), -+ GATE_HIF(CLK_HIFSYS_PCIE2, "pcie2_clk", "ethpll_500m_ck", 26), -+}; -+ -+static void __init mtk_hifsys_init(struct device_node *node) -+{ -+ struct clk_onecell_data *clk_data; -+ int r; -+ -+ clk_data = mtk_alloc_clk_data(CLK_HIFSYS_NR); -+ -+ mtk_clk_register_gates(node, hif_clks, ARRAY_SIZE(hif_clks), -+ clk_data); -+ -+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); -+ if (r) -+ pr_err("%s(): could not register clock provider: %d\n", -+ __func__, r); -+} -+CLK_OF_DECLARE(mtk_hifsys, "mediatek,mt2701-hifsys", mtk_hifsys_init); -+ -+static const struct mtk_gate_regs eth_cg_regs __initconst = { -+ .sta_ofs = 0x0030, -+}; -+ -+#define GATE_eth(_id, _name, _parent, _shift) { \ -+ .id = _id, \ -+ .name = _name, \ -+ .parent_name = _parent, \ -+ .regs = ð_cg_regs, \ -+ .shift = _shift, \ -+ .ops = &mtk_clk_gate_ops_no_setclr_inv, \ -+ } -+ -+static const struct mtk_gate eth_clks[] __initconst = { -+ GATE_HIF(CLK_ETHSYS_HSDMA, "hsdma_clk", "ethif_sel", 5), -+ GATE_HIF(CLK_ETHSYS_ESW, "esw_clk", "ethpll_500m_ck", 6), -+ GATE_HIF(CLK_ETHSYS_GP2, "gp2_clk", "trgpll", 7), -+ GATE_HIF(CLK_ETHSYS_GP1, "gp1_clk", "ethpll_500m_ck", 8), -+ GATE_HIF(CLK_ETHSYS_PCM, "pcm_clk", "ethif_sel", 11), -+ GATE_HIF(CLK_ETHSYS_GDMA, "gdma_clk", "ethif_sel", 14), -+ GATE_HIF(CLK_ETHSYS_I2S, "i2s_clk", "ethif_sel", 17), -+ GATE_HIF(CLK_ETHSYS_CRYPTO, "crypto_clk", "ethif_sel", 29), -+}; -+ -+static void __init mtk_ethsys_init(struct device_node *node) -+{ -+ struct clk_onecell_data *clk_data; -+ int r; -+ -+ clk_data = mtk_alloc_clk_data(CLK_ETHSYS_NR); -+ -+ mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks), -+ clk_data); -+ -+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); -+ if (r) -+ pr_err("%s(): could not register clock provider: %d\n", -+ __func__, r); -+} -+CLK_OF_DECLARE(mtk_ethsys, "mediatek,mt2701-ethsys", mtk_ethsys_init); -+ -+static const struct mtk_gate_regs bdp0_cg_regs __initconst = { -+ .set_ofs = 0x0104, -+ .clr_ofs = 0x0108, -+ .sta_ofs = 0x0100, -+}; -+ -+static const struct mtk_gate_regs bdp1_cg_regs __initconst = { -+ .set_ofs = 0x0114, -+ .clr_ofs = 0x0118, -+ .sta_ofs = 0x0110, -+}; -+ -+#define GATE_BDP0(_id, _name, _parent, _shift) { \ -+ .id = _id, \ -+ .name = _name, \ -+ .parent_name = _parent, \ -+ .regs = &bdp0_cg_regs, \ -+ .shift = _shift, \ -+ .ops = &mtk_clk_gate_ops_setclr_inv, \ -+ } -+ -+#define GATE_BDP1(_id, _name, _parent, _shift) { \ -+ .id = _id, \ -+ .name = _name, \ -+ .parent_name = _parent, \ -+ .regs = &bdp1_cg_regs, \ -+ .shift = _shift, \ -+ .ops = &mtk_clk_gate_ops_setclr_inv, \ -+ } -+ -+static const struct mtk_gate bdp_clks[] __initconst = { -+ GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0), -+ GATE_BDP0(CLK_BDP_BRG_DRAM, "brg_dram", "mm_sel", 1), -+ GATE_BDP0(CLK_BDP_LARB_DRAM, "larb_dram", "mm_sel", 2), -+ GATE_BDP0(CLK_BDP_WR_VDI_PXL, "wr_vdi_pxl", "hdmi_0_deep340m", 3), -+ GATE_BDP0(CLK_BDP_WR_VDI_DRAM, "wr_vdi_dram", "mm_sel", 4), -+ GATE_BDP0(CLK_BDP_WR_B, "wr_bclk", "mm_sel", 5), -+ GATE_BDP0(CLK_BDP_DGI_IN, "dgi_in", "dpi1_sel", 6), -+ GATE_BDP0(CLK_BDP_DGI_OUT, "dgi_out", "dpi_sel", 7), -+ GATE_BDP0(CLK_BDP_FMT_MAST_27, "fmt_mast_27", "dpi1_sel", 8), -+ GATE_BDP0(CLK_BDP_FMT_B, "fmt_bclk", "mm_sel", 9), -+ GATE_BDP0(CLK_BDP_OSD_B, "osd_bclk", "mm_sel", 10), -+ GATE_BDP0(CLK_BDP_OSD_DRAM, "osd_dram", "mm_sel", 11), -+ GATE_BDP0(CLK_BDP_OSD_AGENT, "osd_agent", "osd_sel", 12), -+ GATE_BDP0(CLK_BDP_OSD_PXL, "osd_pxl", "dpi1_sel", 13), -+ GATE_BDP0(CLK_BDP_RLE_B, "rle_bclk", "mm_sel", 14), -+ GATE_BDP0(CLK_BDP_RLE_AGENT, "rle_agent", "mm_sel", 15), -+ GATE_BDP0(CLK_BDP_RLE_DRAM, "rle_dram", "mm_sel", 16), -+ GATE_BDP0(CLK_BDP_F27M, "f27m", "di_sel", 17), -+ GATE_BDP0(CLK_BDP_F27M_VDOUT, "f27m_vdout", "di_sel", 18), -+ GATE_BDP0(CLK_BDP_F27_74_74, "f27_74_74", "di_sel", 19), -+ GATE_BDP0(CLK_BDP_F2FS, "f2fs", "di_sel", 20), -+ GATE_BDP0(CLK_BDP_F2FS74_148, "f2fs74_148", "di_sel", 21), -+ GATE_BDP0(CLK_BDP_FB, "fbclk", "mm_sel", 22), -+ GATE_BDP0(CLK_BDP_VDO_DRAM, "vdo_dram", "mm_sel", 23), -+ GATE_BDP0(CLK_BDP_VDO_2FS, "vdo_2fs", "di_sel", 24), -+ GATE_BDP0(CLK_BDP_VDO_B, "vdo_bclk", "mm_sel", 25), -+ GATE_BDP0(CLK_BDP_WR_DI_PXL, "wr_di_pxl", "di_sel", 26), -+ GATE_BDP0(CLK_BDP_WR_DI_DRAM, "wr_di_dram", "mm_sel", 27), -+ GATE_BDP0(CLK_BDP_WR_DI_B, "wr_di_bclk", "mm_sel", 28), -+ GATE_BDP0(CLK_BDP_NR_PXL, "nr_pxl", "nr_sel", 29), -+ GATE_BDP0(CLK_BDP_NR_DRAM, "nr_dram", "mm_sel", 30), -+ GATE_BDP0(CLK_BDP_NR_B, "nr_bclk", "mm_sel", 31), -+ GATE_BDP1(CLK_BDP_RX_F, "rx_fclk", "hadds2_fbclk", 0), -+ GATE_BDP1(CLK_BDP_RX_X, "rx_xclk", "clk26m", 1), -+ GATE_BDP1(CLK_BDP_RXPDT, "rxpdtclk", "hdmi_0_pix340m", 2), -+ GATE_BDP1(CLK_BDP_RX_CSCL_N, "rx_cscl_n", "clk26m", 3), -+ GATE_BDP1(CLK_BDP_RX_CSCL, "rx_cscl", "clk26m", 4), -+ GATE_BDP1(CLK_BDP_RX_DDCSCL_N, "rx_ddcscl_n", "hdmi_scl_rx", 5), -+ GATE_BDP1(CLK_BDP_RX_DDCSCL, "rx_ddcscl", "hdmi_scl_rx", 6), -+ GATE_BDP1(CLK_BDP_RX_VCO, "rx_vcoclk", "hadds2pll_294m", 7), -+ GATE_BDP1(CLK_BDP_RX_DP, "rx_dpclk", "hdmi_0_pll340m", 8), -+ GATE_BDP1(CLK_BDP_RX_P, "rx_pclk", "hdmi_0_pll340m", 9), -+ GATE_BDP1(CLK_BDP_RX_M, "rx_mclk", "hadds2pll_294m", 10), -+ GATE_BDP1(CLK_BDP_RX_PLL, "rx_pllclk", "hdmi_0_pix340m", 11), -+ GATE_BDP1(CLK_BDP_BRG_RT_B, "brg_rt_bclk", "mm_sel", 12), -+ GATE_BDP1(CLK_BDP_BRG_RT_DRAM, "brg_rt_dram", "mm_sel", 13), -+ GATE_BDP1(CLK_BDP_LARBRT_DRAM, "larbrt_dram", "mm_sel", 14), -+ GATE_BDP1(CLK_BDP_TMDS_SYN, "tmds_syn", "hdmi_0_pll340m", 15), -+ GATE_BDP1(CLK_BDP_HDMI_MON, "hdmi_mon", "hdmi_0_mon", 16), -+}; -+ -+static void __init mtk_bdpsys_init(struct device_node *node) -+{ -+ struct clk_onecell_data *clk_data; -+ int r; -+ -+ clk_data = mtk_alloc_clk_data(CLK_BDP_NR); -+ -+ mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks), -+ clk_data); -+ -+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); -+ if (r) -+ pr_err("%s(): could not register clock provider: %d\n", -+ __func__, r); -+} -+CLK_OF_DECLARE(mtk_bdpsys, "mediatek,mt2701-bdpsys", mtk_bdpsys_init); -+ -+#define MT8590_PLL_FMAX (2000 * MHZ) -+#define CON0_MT8590_RST_BAR BIT(27) -+ -+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \ -+ _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \ -+ .id = _id, \ -+ .name = _name, \ -+ .reg = _reg, \ -+ .pwr_reg = _pwr_reg, \ -+ .en_mask = _en_mask, \ -+ .flags = _flags, \ -+ .rst_bar_mask = CON0_MT8590_RST_BAR, \ -+ .fmax = MT8590_PLL_FMAX, \ -+ .pcwbits = _pcwbits, \ -+ .pd_reg = _pd_reg, \ -+ .pd_shift = _pd_shift, \ -+ .tuner_reg = _tuner_reg, \ -+ .pcw_reg = _pcw_reg, \ -+ .pcw_shift = _pcw_shift, \ -+ } -+ -+static const struct mtk_pll_data apmixed_plls[] = { -+ PLL(CLK_APMIXED_ARMPLL, "armpll", 0x200, 0x20c, 0x80000001, 0, -+ 21, 0x204, 24, 0x0, 0x204, 0), -+ PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x210, 0x21c, 0xf0000001, -+ HAVE_RST_BAR, 21, 0x210, 4, 0x0, 0x214, 0), -+ PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x220, 0x22c, 0xf3000001, -+ HAVE_RST_BAR, 7, 0x220, 4, 0x0, 0x224, 14), -+ PLL(CLK_APMIXED_MMPLL, "mmpll", 0x230, 0x23c, 0x00000001, 0, -+ 21, 0x230, 4, 0x0, 0x234, 0), -+ PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x240, 0x24c, 0x00000001, 0, -+ 21, 0x240, 4, 0x0, 0x244, 0), -+ PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x250, 0x25c, 0x00000001, 0, -+ 21, 0x250, 4, 0x0, 0x254, 0), -+ PLL(CLK_APMIXED_AUD1PLL, "aud1pll", 0x270, 0x27c, 0x00000001, 0, -+ 31, 0x270, 4, 0x0, 0x274, 0), -+ PLL(CLK_APMIXED_TRGPLL, "trgpll", 0x280, 0x28c, 0x00000001, 0, -+ 31, 0x280, 4, 0x0, 0x284, 0), -+ PLL(CLK_APMIXED_ETHPLL, "ethpll", 0x290, 0x29c, 0x00000001, 0, -+ 31, 0x290, 4, 0x0, 0x294, 0), -+ PLL(CLK_APMIXED_VDECPLL, "vdecpll", 0x2a0, 0x2ac, 0x00000001, 0, -+ 31, 0x2a0, 4, 0x0, 0x2a4, 0), -+ PLL(CLK_APMIXED_HADDS2PLL, "hadds2pll", 0x2b0, 0x2bc, 0x00000001, 0, -+ 31, 0x2b0, 4, 0x0, 0x2b4, 0), -+ PLL(CLK_APMIXED_AUD2PLL, "aud2pll", 0x2c0, 0x2cc, 0x00000001, 0, -+ 31, 0x2c0, 4, 0x0, 0x2c4, 0), -+ PLL(CLK_APMIXED_TVD2PLL, "tvd2pll", 0x2d0, 0x2dc, 0x00000001, 0, -+ 21, 0x2d0, 4, 0x0, 0x2d4, 0), -+}; -+ -+static void __init mtk_apmixedsys_init(struct device_node *node) -+{ -+ struct clk_onecell_data *clk_data; -+ int r; -+ -+ clk_data = mtk_alloc_clk_data(ARRAY_SIZE(apmixed_plls)); -+ if (!clk_data) -+ return; -+ -+ mtk_clk_register_plls(node, apmixed_plls, ARRAY_SIZE(apmixed_plls), -+ clk_data); -+ -+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); -+ if (r) -+ pr_err("%s(): could not register clock provider: %d\n", -+ __func__, r); -+} -+CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt2701-apmixedsys", -+ mtk_apmixedsys_init); ---- a/drivers/clk/mediatek/clk-mtk.c -+++ b/drivers/clk/mediatek/clk-mtk.c -@@ -242,3 +242,28 @@ void __init mtk_clk_register_composites( - clk_data->clks[mc->id] = clk; - } - } -+ -+void __init mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, -+ int num, void __iomem *base, spinlock_t *lock, -+ struct clk_onecell_data *clk_data) -+{ -+ struct clk *clk; -+ int i; -+ -+ for (i = 0; i < num; i++) { -+ const struct mtk_clk_divider *mcd = &mcds[i]; -+ -+ clk = clk_register_divider(NULL, mcd->name, mcd->parent_name, -+ mcd->flags, base + mcd->div_reg, mcd->div_shift, -+ mcd->div_width, mcd->clk_divider_flags, lock); -+ -+ if (IS_ERR(clk)) { -+ pr_err("Failed to register clk %s: %ld\n", -+ mcd->name, PTR_ERR(clk)); -+ continue; -+ } -+ -+ if (clk_data) -+ clk_data->clks[mcd->id] = clk; -+ } -+} ---- a/drivers/clk/mediatek/clk-mtk.h -+++ b/drivers/clk/mediatek/clk-mtk.h -@@ -110,7 +110,8 @@ struct mtk_composite { - .flags = CLK_SET_RATE_PARENT, \ - } - --#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, _div_width, _div_shift) { \ -+#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, \ -+ _div_width, _div_shift) { \ - .id = _id, \ - .parent = _parent, \ - .name = _name, \ -@@ -145,8 +146,36 @@ struct mtk_gate { - const struct clk_ops *ops; - }; - --int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks, -- int num, struct clk_onecell_data *clk_data); -+int mtk_clk_register_gates(struct device_node *node, -+ const struct mtk_gate *clks, int num, -+ struct clk_onecell_data *clk_data); -+ -+struct mtk_clk_divider { -+ int id; -+ const char *name; -+ const char *parent_name; -+ unsigned long flags; -+ -+ uint32_t div_reg; -+ unsigned char div_shift; -+ unsigned char div_width; -+ unsigned char clk_divider_flags; -+ const struct clk_div_table *clk_div_table; -+}; -+ -+#define DIV_ADJ(_id, _name, _parent, _reg, _shift, _width) { \ -+ .id = _id, \ -+ .name = _name, \ -+ .parent_name = _parent, \ -+ .flags = CLK_SET_RATE_PARENT, \ -+ .div_reg = _reg, \ -+ .div_shift = _shift, \ -+ .div_width = _width, \ -+} -+ -+void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, -+ int num, void __iomem *base, spinlock_t *lock, -+ struct clk_onecell_data *clk_data); - - struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num); - 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 index b5b10e7b0b..0000000000 --- a/target/linux/mediatek/patches-4.4/0010-reset-mediatek-mt2701-reset-controller-dt-binding-fi.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 8bf0f2a1e8ff082de3f650211abd985ef68abe1b Mon Sep 17 00:00:00 2001 -From: Shunli Wang -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 ---- - .../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 -+ * -+ * 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 index 18d4fbf252..0000000000 --- a/target/linux/mediatek/patches-4.4/0011-reset-mediatek-mt2701-reset-driver.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 3ba0020ea70ffb5503eff1823be7fa5ceda38286 Mon Sep 17 00:00:00 2001 -From: Shunli Wang -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 -Acked-by: Philipp Zabel ---- - 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 index 479334a92d..0000000000 --- a/target/linux/mediatek/patches-4.4/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 32fa899c6ab79953e4f470fb23c38bcc40edc5c8 Mon Sep 17 00:00:00 2001 -From: Erin Lo -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 -Acked-by: Linus Walleij ---- - 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 index af1ad668f5..0000000000 --- a/target/linux/mediatek/patches-4.4/0013-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt2.patch +++ /dev/null @@ -1,31 +0,0 @@ -From afcbed6f51e8c3a9195952b27c8aad047c314ed0 Mon Sep 17 00:00:00 2001 -From: Biao Huang -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 -Acked-by: Rob Herring -Reviewed-by: Mathias Brugger ---- - 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 index 0df6d186ba..0000000000 --- a/target/linux/mediatek/patches-4.4/0014-pinctrl-dt-bindings-Add-pinfunc-header-file-for-mt27.patch +++ /dev/null @@ -1,3792 +0,0 @@ -From 124894a4d1635915ff95c447767677b60fd27e9c Mon Sep 17 00:00:00 2001 -From: Biao Huang -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 -Acked-by: Linus Walleij ---- - 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 -+ * -+ * 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 -+ -+#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 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "pinctrl-mtk-common.h" -+#include "pinctrl-mtk-mt2701.h" -+ -+/** -+ * struct mtk_spec_pinmux_set -+ * - For special pins' mode setting -+ * @pin: The pin number. -+ * @offset: The offset of extra setting register. -+ * @bit: The bit of extra setting register. -+ */ -+struct mtk_spec_pinmux_set { -+ unsigned short pin; -+ unsigned short offset; -+ unsigned char bit; -+}; -+ -+#define MTK_PINMUX_SPEC(_pin, _offset, _bit) \ -+ { \ -+ .pin = _pin, \ -+ .offset = _offset, \ -+ .bit = _bit, \ -+ } -+ -+static const struct mtk_drv_group_desc mt2701_drv_grp[] = { -+ /* 0E4E8SR 4/8/12/16 */ -+ MTK_DRV_GRP(4, 16, 1, 2, 4), -+ /* 0E2E4SR 2/4/6/8 */ -+ MTK_DRV_GRP(2, 8, 1, 2, 2), -+ /* E8E4E2 2/4/6/8/10/12/14/16 */ -+ MTK_DRV_GRP(2, 16, 0, 2, 2) -+}; -+ -+static const struct mtk_pin_drv_grp mt2701_pin_drv[] = { -+ MTK_PIN_DRV_GRP(0, 0xf50, 0, 1), -+ MTK_PIN_DRV_GRP(1, 0xf50, 0, 1), -+ MTK_PIN_DRV_GRP(2, 0xf50, 0, 1), -+ MTK_PIN_DRV_GRP(3, 0xf50, 0, 1), -+ MTK_PIN_DRV_GRP(4, 0xf50, 0, 1), -+ MTK_PIN_DRV_GRP(5, 0xf50, 0, 1), -+ MTK_PIN_DRV_GRP(6, 0xf50, 0, 1), -+ MTK_PIN_DRV_GRP(7, 0xf50, 4, 1), -+ MTK_PIN_DRV_GRP(8, 0xf50, 4, 1), -+ MTK_PIN_DRV_GRP(9, 0xf50, 4, 1), -+ MTK_PIN_DRV_GRP(10, 0xf50, 8, 1), -+ MTK_PIN_DRV_GRP(11, 0xf50, 8, 1), -+ MTK_PIN_DRV_GRP(12, 0xf50, 8, 1), -+ MTK_PIN_DRV_GRP(13, 0xf50, 8, 1), -+ MTK_PIN_DRV_GRP(14, 0xf50, 12, 0), -+ MTK_PIN_DRV_GRP(15, 0xf50, 12, 0), -+ MTK_PIN_DRV_GRP(16, 0xf60, 0, 0), -+ MTK_PIN_DRV_GRP(17, 0xf60, 0, 0), -+ MTK_PIN_DRV_GRP(18, 0xf60, 4, 0), -+ MTK_PIN_DRV_GRP(19, 0xf60, 4, 0), -+ MTK_PIN_DRV_GRP(20, 0xf60, 4, 0), -+ MTK_PIN_DRV_GRP(21, 0xf60, 4, 0), -+ MTK_PIN_DRV_GRP(22, 0xf60, 8, 0), -+ MTK_PIN_DRV_GRP(23, 0xf60, 8, 0), -+ MTK_PIN_DRV_GRP(24, 0xf60, 8, 0), -+ MTK_PIN_DRV_GRP(25, 0xf60, 8, 0), -+ MTK_PIN_DRV_GRP(26, 0xf60, 8, 0), -+ MTK_PIN_DRV_GRP(27, 0xf60, 12, 0), -+ MTK_PIN_DRV_GRP(28, 0xf60, 12, 0), -+ MTK_PIN_DRV_GRP(29, 0xf60, 12, 0), -+ MTK_PIN_DRV_GRP(30, 0xf60, 0, 0), -+ MTK_PIN_DRV_GRP(31, 0xf60, 0, 0), -+ MTK_PIN_DRV_GRP(32, 0xf60, 0, 0), -+ MTK_PIN_DRV_GRP(33, 0xf70, 0, 0), -+ MTK_PIN_DRV_GRP(34, 0xf70, 0, 0), -+ MTK_PIN_DRV_GRP(35, 0xf70, 0, 0), -+ MTK_PIN_DRV_GRP(36, 0xf70, 0, 0), -+ MTK_PIN_DRV_GRP(37, 0xf70, 0, 0), -+ MTK_PIN_DRV_GRP(38, 0xf70, 4, 0), -+ MTK_PIN_DRV_GRP(39, 0xf70, 8, 1), -+ MTK_PIN_DRV_GRP(40, 0xf70, 8, 1), -+ MTK_PIN_DRV_GRP(41, 0xf70, 8, 1), -+ MTK_PIN_DRV_GRP(42, 0xf70, 8, 1), -+ MTK_PIN_DRV_GRP(43, 0xf70, 12, 0), -+ MTK_PIN_DRV_GRP(44, 0xf70, 12, 0), -+ MTK_PIN_DRV_GRP(45, 0xf70, 12, 0), -+ MTK_PIN_DRV_GRP(47, 0xf80, 0, 0), -+ MTK_PIN_DRV_GRP(48, 0xf80, 0, 0), -+ MTK_PIN_DRV_GRP(49, 0xf80, 4, 0), -+ MTK_PIN_DRV_GRP(50, 0xf70, 4, 0), -+ MTK_PIN_DRV_GRP(51, 0xf70, 4, 0), -+ MTK_PIN_DRV_GRP(52, 0xf70, 4, 0), -+ MTK_PIN_DRV_GRP(53, 0xf80, 12, 0), -+ MTK_PIN_DRV_GRP(54, 0xf80, 12, 0), -+ MTK_PIN_DRV_GRP(55, 0xf80, 12, 0), -+ MTK_PIN_DRV_GRP(56, 0xf80, 12, 0), -+ MTK_PIN_DRV_GRP(60, 0xf90, 8, 1), -+ MTK_PIN_DRV_GRP(61, 0xf90, 8, 1), -+ MTK_PIN_DRV_GRP(62, 0xf90, 8, 1), -+ MTK_PIN_DRV_GRP(63, 0xf90, 12, 1), -+ MTK_PIN_DRV_GRP(64, 0xf90, 12, 1), -+ MTK_PIN_DRV_GRP(65, 0xf90, 12, 1), -+ MTK_PIN_DRV_GRP(66, 0xfa0, 0, 1), -+ MTK_PIN_DRV_GRP(67, 0xfa0, 0, 1), -+ MTK_PIN_DRV_GRP(68, 0xfa0, 0, 1), -+ MTK_PIN_DRV_GRP(69, 0xfa0, 0, 1), -+ MTK_PIN_DRV_GRP(70, 0xfa0, 0, 1), -+ MTK_PIN_DRV_GRP(71, 0xfa0, 0, 1), -+ MTK_PIN_DRV_GRP(72, 0xf80, 4, 0), -+ MTK_PIN_DRV_GRP(73, 0xf80, 4, 0), -+ MTK_PIN_DRV_GRP(74, 0xf80, 4, 0), -+ MTK_PIN_DRV_GRP(85, 0xda0, 0, 2), -+ MTK_PIN_DRV_GRP(86, 0xd90, 0, 2), -+ MTK_PIN_DRV_GRP(87, 0xdb0, 0, 2), -+ MTK_PIN_DRV_GRP(88, 0xdb0, 0, 2), -+ MTK_PIN_DRV_GRP(89, 0xdb0, 0, 2), -+ MTK_PIN_DRV_GRP(90, 0xdb0, 0, 2), -+ MTK_PIN_DRV_GRP(105, 0xd40, 0, 2), -+ MTK_PIN_DRV_GRP(106, 0xd30, 0, 2), -+ MTK_PIN_DRV_GRP(107, 0xd50, 0, 2), -+ MTK_PIN_DRV_GRP(108, 0xd50, 0, 2), -+ MTK_PIN_DRV_GRP(109, 0xd50, 0, 2), -+ MTK_PIN_DRV_GRP(110, 0xd50, 0, 2), -+ MTK_PIN_DRV_GRP(111, 0xce0, 0, 2), -+ MTK_PIN_DRV_GRP(112, 0xce0, 0, 2), -+ MTK_PIN_DRV_GRP(113, 0xce0, 0, 2), -+ MTK_PIN_DRV_GRP(114, 0xce0, 0, 2), -+ MTK_PIN_DRV_GRP(115, 0xce0, 0, 2), -+ MTK_PIN_DRV_GRP(116, 0xcd0, 0, 2), -+ MTK_PIN_DRV_GRP(117, 0xcc0, 0, 2), -+ MTK_PIN_DRV_GRP(118, 0xce0, 0, 2), -+ MTK_PIN_DRV_GRP(119, 0xce0, 0, 2), -+ MTK_PIN_DRV_GRP(120, 0xce0, 0, 2), -+ MTK_PIN_DRV_GRP(121, 0xce0, 0, 2), -+ MTK_PIN_DRV_GRP(126, 0xf80, 4, 0), -+ MTK_PIN_DRV_GRP(188, 0xf70, 4, 0), -+ MTK_PIN_DRV_GRP(189, 0xfe0, 8, 0), -+ MTK_PIN_DRV_GRP(190, 0xfe0, 8, 0), -+ MTK_PIN_DRV_GRP(191, 0xfe0, 8, 0), -+ MTK_PIN_DRV_GRP(192, 0xfe0, 8, 0), -+ MTK_PIN_DRV_GRP(193, 0xfe0, 8, 0), -+ MTK_PIN_DRV_GRP(194, 0xfe0, 12, 0), -+ MTK_PIN_DRV_GRP(195, 0xfe0, 12, 0), -+ MTK_PIN_DRV_GRP(196, 0xfe0, 12, 0), -+ MTK_PIN_DRV_GRP(197, 0xfe0, 12, 0), -+ MTK_PIN_DRV_GRP(198, 0xfe0, 12, 0), -+ MTK_PIN_DRV_GRP(199, 0xf50, 4, 1), -+ MTK_PIN_DRV_GRP(200, 0xfd0, 0, 0), -+ MTK_PIN_DRV_GRP(201, 0xfd0, 0, 0), -+ MTK_PIN_DRV_GRP(202, 0xfd0, 0, 0), -+ MTK_PIN_DRV_GRP(203, 0xfd0, 4, 0), -+ MTK_PIN_DRV_GRP(204, 0xfd0, 4, 0), -+ MTK_PIN_DRV_GRP(205, 0xfd0, 4, 0), -+ MTK_PIN_DRV_GRP(206, 0xfd0, 4, 0), -+ MTK_PIN_DRV_GRP(207, 0xfd0, 4, 0), -+ MTK_PIN_DRV_GRP(208, 0xfd0, 8, 0), -+ MTK_PIN_DRV_GRP(209, 0xfd0, 8, 0), -+ MTK_PIN_DRV_GRP(210, 0xfd0, 12, 1), -+ MTK_PIN_DRV_GRP(211, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(212, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(213, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(214, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(215, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(216, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(217, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(218, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(219, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(220, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(221, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(222, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(223, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(224, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(225, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(226, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(227, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(228, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(229, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(230, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(231, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(232, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(233, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(234, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(235, 0xff0, 0, 1), -+ MTK_PIN_DRV_GRP(236, 0xff0, 4, 0), -+ MTK_PIN_DRV_GRP(237, 0xff0, 4, 0), -+ MTK_PIN_DRV_GRP(238, 0xff0, 4, 0), -+ MTK_PIN_DRV_GRP(239, 0xff0, 4, 0), -+ MTK_PIN_DRV_GRP(240, 0xff0, 4, 0), -+ MTK_PIN_DRV_GRP(241, 0xff0, 4, 0), -+ MTK_PIN_DRV_GRP(242, 0xff0, 8, 0), -+ MTK_PIN_DRV_GRP(243, 0xff0, 8, 0), -+ MTK_PIN_DRV_GRP(248, 0xf00, 0, 0), -+ MTK_PIN_DRV_GRP(249, 0xfc0, 0, 2), -+ MTK_PIN_DRV_GRP(250, 0xfc0, 0, 2), -+ MTK_PIN_DRV_GRP(251, 0xfc0, 0, 2), -+ MTK_PIN_DRV_GRP(252, 0xfc0, 0, 2), -+ MTK_PIN_DRV_GRP(253, 0xfc0, 0, 2), -+ MTK_PIN_DRV_GRP(254, 0xfc0, 0, 2), -+ MTK_PIN_DRV_GRP(255, 0xfc0, 0, 2), -+ MTK_PIN_DRV_GRP(256, 0xfc0, 0, 2), -+ MTK_PIN_DRV_GRP(257, 0xce0, 0, 2), -+ MTK_PIN_DRV_GRP(258, 0xcb0, 0, 2), -+ MTK_PIN_DRV_GRP(259, 0xc90, 0, 2), -+ MTK_PIN_DRV_GRP(260, 0x3a0, 0, 2), -+ MTK_PIN_DRV_GRP(261, 0xd50, 0, 2), -+ MTK_PIN_DRV_GRP(262, 0xf00, 8, 0), -+ MTK_PIN_DRV_GRP(263, 0xf00, 8, 0), -+ MTK_PIN_DRV_GRP(264, 0xf00, 8, 0), -+ MTK_PIN_DRV_GRP(265, 0xf00, 8, 0), -+ MTK_PIN_DRV_GRP(266, 0xf00, 8, 0), -+ MTK_PIN_DRV_GRP(267, 0xf00, 8, 0), -+ MTK_PIN_DRV_GRP(268, 0xf00, 8, 0), -+ MTK_PIN_DRV_GRP(269, 0xf00, 8, 0), -+ MTK_PIN_DRV_GRP(270, 0xf00, 8, 0), -+ MTK_PIN_DRV_GRP(271, 0xf00, 8, 0), -+ MTK_PIN_DRV_GRP(272, 0xf00, 8, 0), -+ MTK_PIN_DRV_GRP(273, 0xf00, 8, 0), -+ MTK_PIN_DRV_GRP(274, 0xf00, 8, 0), -+ MTK_PIN_DRV_GRP(275, 0xf00, 8, 0), -+ MTK_PIN_DRV_GRP(276, 0xf00, 8, 0), -+ MTK_PIN_DRV_GRP(277, 0xf00, 8, 0), -+ MTK_PIN_DRV_GRP(278, 0xf70, 8, 1), -+}; -+ -+static const struct mtk_pin_spec_pupd_set_samereg mt2701_spec_pupd[] = { -+ MTK_PIN_PUPD_SPEC_SR(111, 0xd00, 12, 13, 14), /* ms0 data7 */ -+ MTK_PIN_PUPD_SPEC_SR(112, 0xd00, 8, 9, 10), /* ms0 data6 */ -+ MTK_PIN_PUPD_SPEC_SR(113, 0xd00, 4, 5, 6), /* ms0 data5 */ -+ MTK_PIN_PUPD_SPEC_SR(114, 0xd00, 0, 1, 2), /* ms0 data4 */ -+ MTK_PIN_PUPD_SPEC_SR(115, 0xd10, 0, 1, 2), /* ms0 rstb */ -+ MTK_PIN_PUPD_SPEC_SR(116, 0xcd0, 8, 9, 10), /* ms0 cmd */ -+ MTK_PIN_PUPD_SPEC_SR(117, 0xcc0, 8, 9, 10), /* ms0 clk */ -+ MTK_PIN_PUPD_SPEC_SR(118, 0xcf0, 12, 13, 14), /* ms0 data3 */ -+ MTK_PIN_PUPD_SPEC_SR(119, 0xcf0, 8, 9, 10), /* ms0 data2 */ -+ MTK_PIN_PUPD_SPEC_SR(120, 0xcf0, 4, 5, 6), /* ms0 data1 */ -+ MTK_PIN_PUPD_SPEC_SR(121, 0xcf0, 0, 1, 2), /* ms0 data0 */ -+ -+ MTK_PIN_PUPD_SPEC_SR(105, 0xd40, 8, 9, 10), /* ms1 cmd */ -+ MTK_PIN_PUPD_SPEC_SR(106, 0xd30, 8, 9, 10), /* ms1 clk */ -+ MTK_PIN_PUPD_SPEC_SR(107, 0xd60, 0, 1, 2), /* ms1 dat0 */ -+ MTK_PIN_PUPD_SPEC_SR(108, 0xd60, 10, 9, 8), /* ms1 dat1 */ -+ MTK_PIN_PUPD_SPEC_SR(109, 0xd60, 4, 5, 6), /* ms1 dat2 */ -+ MTK_PIN_PUPD_SPEC_SR(110, 0xc60, 12, 13, 14), /* ms1 dat3 */ -+ -+ MTK_PIN_PUPD_SPEC_SR(85, 0xda0, 8, 9, 10), /* ms2 cmd */ -+ MTK_PIN_PUPD_SPEC_SR(86, 0xd90, 8, 9, 10), /* ms2 clk */ -+ MTK_PIN_PUPD_SPEC_SR(87, 0xdc0, 0, 1, 2), /* ms2 dat0 */ -+ MTK_PIN_PUPD_SPEC_SR(88, 0xdc0, 10, 9, 8), /* ms2 dat1 */ -+ MTK_PIN_PUPD_SPEC_SR(89, 0xdc0, 4, 5, 6), /* ms2 dat2 */ -+ MTK_PIN_PUPD_SPEC_SR(90, 0xdc0, 12, 13, 14), /* ms2 dat3 */ -+ -+ MTK_PIN_PUPD_SPEC_SR(249, 0x140, 0, 1, 2), /* ms0e rstb */ -+ MTK_PIN_PUPD_SPEC_SR(250, 0x130, 12, 13, 14), /* ms0e dat7 */ -+ MTK_PIN_PUPD_SPEC_SR(251, 0x130, 8, 9, 10), /* ms0e dat6 */ -+ MTK_PIN_PUPD_SPEC_SR(252, 0x130, 4, 5, 6), /* ms0e dat5 */ -+ MTK_PIN_PUPD_SPEC_SR(253, 0x130, 0, 1, 2), /* ms0e dat4 */ -+ MTK_PIN_PUPD_SPEC_SR(254, 0xf40, 12, 13, 14), /* ms0e dat3 */ -+ MTK_PIN_PUPD_SPEC_SR(255, 0xf40, 8, 9, 10), /* ms0e dat2 */ -+ MTK_PIN_PUPD_SPEC_SR(256, 0xf40, 4, 5, 6), /* ms0e dat1 */ -+ MTK_PIN_PUPD_SPEC_SR(257, 0xf40, 0, 1, 2), /* ms0e dat0 */ -+ MTK_PIN_PUPD_SPEC_SR(258, 0xcb0, 8, 9, 10), /* ms0e cmd */ -+ MTK_PIN_PUPD_SPEC_SR(259, 0xc90, 8, 9, 10), /* ms0e clk */ -+ MTK_PIN_PUPD_SPEC_SR(261, 0x140, 8, 9, 10), /* ms1 ins */ -+}; -+ -+static int mt2701_spec_pull_set(struct regmap *regmap, unsigned int pin, -+ unsigned char align, bool isup, unsigned int r1r0) -+{ -+ return mtk_pctrl_spec_pull_set_samereg(regmap, mt2701_spec_pupd, -+ ARRAY_SIZE(mt2701_spec_pupd), pin, align, isup, r1r0); -+} -+ -+static const struct mtk_pin_ies_smt_set mt2701_ies_set[] = { -+ MTK_PIN_IES_SMT_SPEC(0, 6, 0xb20, 0), -+ MTK_PIN_IES_SMT_SPEC(7, 9, 0xb20, 1), -+ MTK_PIN_IES_SMT_SPEC(10, 13, 0xb30, 3), -+ MTK_PIN_IES_SMT_SPEC(14, 15, 0xb30, 13), -+ MTK_PIN_IES_SMT_SPEC(16, 17, 0xb40, 7), -+ MTK_PIN_IES_SMT_SPEC(18, 21, 0xb40, 13), -+ MTK_PIN_IES_SMT_SPEC(22, 26, 0xb40, 13), -+ MTK_PIN_IES_SMT_SPEC(27, 29, 0xb40, 13), -+ MTK_PIN_IES_SMT_SPEC(30, 32, 0xb40, 7), -+ MTK_PIN_IES_SMT_SPEC(33, 37, 0xb40, 13), -+ MTK_PIN_IES_SMT_SPEC(38, 38, 0xb20, 13), -+ MTK_PIN_IES_SMT_SPEC(39, 42, 0xb40, 13), -+ MTK_PIN_IES_SMT_SPEC(43, 45, 0xb20, 10), -+ MTK_PIN_IES_SMT_SPEC(47, 48, 0xb20, 11), -+ MTK_PIN_IES_SMT_SPEC(49, 49, 0xb20, 12), -+ MTK_PIN_IES_SMT_SPEC(50, 52, 0xb20, 13), -+ MTK_PIN_IES_SMT_SPEC(53, 56, 0xb20, 14), -+ MTK_PIN_IES_SMT_SPEC(57, 58, 0xb20, 15), -+ MTK_PIN_IES_SMT_SPEC(59, 59, 0xb30, 10), -+ MTK_PIN_IES_SMT_SPEC(60, 62, 0xb30, 0), -+ MTK_PIN_IES_SMT_SPEC(63, 65, 0xb30, 1), -+ MTK_PIN_IES_SMT_SPEC(66, 71, 0xb30, 2), -+ MTK_PIN_IES_SMT_SPEC(72, 74, 0xb20, 12), -+ MTK_PIN_IES_SMT_SPEC(75, 76, 0xb30, 3), -+ MTK_PIN_IES_SMT_SPEC(77, 78, 0xb30, 4), -+ MTK_PIN_IES_SMT_SPEC(79, 82, 0xb30, 5), -+ MTK_PIN_IES_SMT_SPEC(83, 84, 0xb30, 2), -+ MTK_PIN_IES_SMT_SPEC(85, 85, 0xda0, 4), -+ MTK_PIN_IES_SMT_SPEC(86, 86, 0xd90, 4), -+ MTK_PIN_IES_SMT_SPEC(87, 90, 0xdb0, 4), -+ MTK_PIN_IES_SMT_SPEC(101, 104, 0xb30, 6), -+ MTK_PIN_IES_SMT_SPEC(105, 105, 0xd40, 4), -+ MTK_PIN_IES_SMT_SPEC(106, 106, 0xd30, 4), -+ MTK_PIN_IES_SMT_SPEC(107, 110, 0xd50, 4), -+ MTK_PIN_IES_SMT_SPEC(111, 115, 0xce0, 4), -+ MTK_PIN_IES_SMT_SPEC(116, 116, 0xcd0, 4), -+ MTK_PIN_IES_SMT_SPEC(117, 117, 0xcc0, 4), -+ MTK_PIN_IES_SMT_SPEC(118, 121, 0xce0, 4), -+ MTK_PIN_IES_SMT_SPEC(122, 125, 0xb30, 7), -+ MTK_PIN_IES_SMT_SPEC(126, 126, 0xb20, 12), -+ MTK_PIN_IES_SMT_SPEC(127, 142, 0xb30, 9), -+ MTK_PIN_IES_SMT_SPEC(143, 160, 0xb30, 10), -+ MTK_PIN_IES_SMT_SPEC(161, 168, 0xb30, 12), -+ MTK_PIN_IES_SMT_SPEC(169, 183, 0xb30, 10), -+ MTK_PIN_IES_SMT_SPEC(184, 186, 0xb30, 9), -+ MTK_PIN_IES_SMT_SPEC(187, 187, 0xb30, 14), -+ MTK_PIN_IES_SMT_SPEC(188, 188, 0xb20, 13), -+ MTK_PIN_IES_SMT_SPEC(189, 193, 0xb30, 15), -+ MTK_PIN_IES_SMT_SPEC(194, 198, 0xb40, 0), -+ MTK_PIN_IES_SMT_SPEC(199, 199, 0xb20, 1), -+ MTK_PIN_IES_SMT_SPEC(200, 202, 0xb40, 1), -+ MTK_PIN_IES_SMT_SPEC(203, 207, 0xb40, 2), -+ MTK_PIN_IES_SMT_SPEC(208, 209, 0xb40, 3), -+ MTK_PIN_IES_SMT_SPEC(210, 210, 0xb40, 4), -+ MTK_PIN_IES_SMT_SPEC(211, 235, 0xb40, 5), -+ MTK_PIN_IES_SMT_SPEC(236, 241, 0xb40, 6), -+ MTK_PIN_IES_SMT_SPEC(242, 243, 0xb40, 7), -+ MTK_PIN_IES_SMT_SPEC(244, 247, 0xb40, 8), -+ MTK_PIN_IES_SMT_SPEC(248, 248, 0xb40, 9), -+ MTK_PIN_IES_SMT_SPEC(249, 257, 0xfc0, 4), -+ MTK_PIN_IES_SMT_SPEC(258, 258, 0xcb0, 4), -+ MTK_PIN_IES_SMT_SPEC(259, 259, 0xc90, 4), -+ MTK_PIN_IES_SMT_SPEC(260, 260, 0x3a0, 4), -+ MTK_PIN_IES_SMT_SPEC(261, 261, 0xd50, 4), -+ MTK_PIN_IES_SMT_SPEC(262, 277, 0xb40, 12), -+ MTK_PIN_IES_SMT_SPEC(278, 278, 0xb40, 13), -+}; -+ -+static const struct mtk_pin_ies_smt_set mt2701_smt_set[] = { -+ MTK_PIN_IES_SMT_SPEC(0, 6, 0xb50, 0), -+ MTK_PIN_IES_SMT_SPEC(7, 9, 0xb50, 1), -+ MTK_PIN_IES_SMT_SPEC(10, 13, 0xb60, 3), -+ MTK_PIN_IES_SMT_SPEC(14, 15, 0xb60, 13), -+ MTK_PIN_IES_SMT_SPEC(16, 17, 0xb70, 7), -+ MTK_PIN_IES_SMT_SPEC(18, 21, 0xb70, 13), -+ MTK_PIN_IES_SMT_SPEC(22, 26, 0xb70, 13), -+ MTK_PIN_IES_SMT_SPEC(27, 29, 0xb70, 13), -+ MTK_PIN_IES_SMT_SPEC(30, 32, 0xb70, 7), -+ MTK_PIN_IES_SMT_SPEC(33, 37, 0xb70, 13), -+ MTK_PIN_IES_SMT_SPEC(38, 38, 0xb50, 13), -+ MTK_PIN_IES_SMT_SPEC(39, 42, 0xb70, 13), -+ MTK_PIN_IES_SMT_SPEC(43, 45, 0xb50, 10), -+ MTK_PIN_IES_SMT_SPEC(47, 48, 0xb50, 11), -+ MTK_PIN_IES_SMT_SPEC(49, 49, 0xb50, 12), -+ MTK_PIN_IES_SMT_SPEC(50, 52, 0xb50, 13), -+ MTK_PIN_IES_SMT_SPEC(53, 56, 0xb50, 14), -+ MTK_PIN_IES_SMT_SPEC(57, 58, 0xb50, 15), -+ MTK_PIN_IES_SMT_SPEC(59, 59, 0xb60, 10), -+ MTK_PIN_IES_SMT_SPEC(60, 62, 0xb60, 0), -+ MTK_PIN_IES_SMT_SPEC(63, 65, 0xb60, 1), -+ MTK_PIN_IES_SMT_SPEC(66, 71, 0xb60, 2), -+ MTK_PIN_IES_SMT_SPEC(72, 74, 0xb50, 12), -+ MTK_PIN_IES_SMT_SPEC(75, 76, 0xb60, 3), -+ MTK_PIN_IES_SMT_SPEC(77, 78, 0xb60, 4), -+ MTK_PIN_IES_SMT_SPEC(79, 82, 0xb60, 5), -+ MTK_PIN_IES_SMT_SPEC(83, 84, 0xb60, 2), -+ MTK_PIN_IES_SMT_SPEC(85, 85, 0xda0, 11), -+ MTK_PIN_IES_SMT_SPEC(86, 86, 0xd90, 11), -+ MTK_PIN_IES_SMT_SPEC(87, 87, 0xdc0, 3), -+ MTK_PIN_IES_SMT_SPEC(88, 88, 0xdc0, 7), -+ MTK_PIN_IES_SMT_SPEC(89, 89, 0xdc0, 11), -+ MTK_PIN_IES_SMT_SPEC(90, 90, 0xdc0, 15), -+ MTK_PIN_IES_SMT_SPEC(101, 104, 0xb60, 6), -+ MTK_PIN_IES_SMT_SPEC(105, 105, 0xd40, 11), -+ MTK_PIN_IES_SMT_SPEC(106, 106, 0xd30, 11), -+ MTK_PIN_IES_SMT_SPEC(107, 107, 0xd60, 3), -+ MTK_PIN_IES_SMT_SPEC(108, 108, 0xd60, 7), -+ MTK_PIN_IES_SMT_SPEC(109, 109, 0xd60, 11), -+ MTK_PIN_IES_SMT_SPEC(110, 110, 0xd60, 15), -+ MTK_PIN_IES_SMT_SPEC(111, 111, 0xd00, 15), -+ MTK_PIN_IES_SMT_SPEC(112, 112, 0xd00, 11), -+ MTK_PIN_IES_SMT_SPEC(113, 113, 0xd00, 7), -+ MTK_PIN_IES_SMT_SPEC(114, 114, 0xd00, 3), -+ MTK_PIN_IES_SMT_SPEC(115, 115, 0xd10, 3), -+ MTK_PIN_IES_SMT_SPEC(116, 116, 0xcd0, 11), -+ MTK_PIN_IES_SMT_SPEC(117, 117, 0xcc0, 11), -+ MTK_PIN_IES_SMT_SPEC(118, 118, 0xcf0, 15), -+ MTK_PIN_IES_SMT_SPEC(119, 119, 0xcf0, 11), -+ MTK_PIN_IES_SMT_SPEC(120, 120, 0xcf0, 7), -+ MTK_PIN_IES_SMT_SPEC(121, 121, 0xcf0, 3), -+ MTK_PIN_IES_SMT_SPEC(122, 125, 0xb60, 7), -+ MTK_PIN_IES_SMT_SPEC(126, 126, 0xb50, 12), -+ MTK_PIN_IES_SMT_SPEC(127, 142, 0xb60, 9), -+ MTK_PIN_IES_SMT_SPEC(143, 160, 0xb60, 10), -+ MTK_PIN_IES_SMT_SPEC(161, 168, 0xb60, 12), -+ MTK_PIN_IES_SMT_SPEC(169, 183, 0xb60, 10), -+ MTK_PIN_IES_SMT_SPEC(184, 186, 0xb60, 9), -+ MTK_PIN_IES_SMT_SPEC(187, 187, 0xb60, 14), -+ MTK_PIN_IES_SMT_SPEC(188, 188, 0xb50, 13), -+ MTK_PIN_IES_SMT_SPEC(189, 193, 0xb60, 15), -+ MTK_PIN_IES_SMT_SPEC(194, 198, 0xb70, 0), -+ MTK_PIN_IES_SMT_SPEC(199, 199, 0xb50, 1), -+ MTK_PIN_IES_SMT_SPEC(200, 202, 0xb70, 1), -+ MTK_PIN_IES_SMT_SPEC(203, 207, 0xb70, 2), -+ MTK_PIN_IES_SMT_SPEC(208, 209, 0xb70, 3), -+ MTK_PIN_IES_SMT_SPEC(210, 210, 0xb70, 4), -+ MTK_PIN_IES_SMT_SPEC(211, 235, 0xb70, 5), -+ MTK_PIN_IES_SMT_SPEC(236, 241, 0xb70, 6), -+ MTK_PIN_IES_SMT_SPEC(242, 243, 0xb70, 7), -+ MTK_PIN_IES_SMT_SPEC(244, 247, 0xb70, 8), -+ MTK_PIN_IES_SMT_SPEC(248, 248, 0xb70, 9), -+ MTK_PIN_IES_SMT_SPEC(249, 249, 0x140, 3), -+ MTK_PIN_IES_SMT_SPEC(250, 250, 0x130, 15), -+ MTK_PIN_IES_SMT_SPEC(251, 251, 0x130, 11), -+ MTK_PIN_IES_SMT_SPEC(252, 252, 0x130, 7), -+ MTK_PIN_IES_SMT_SPEC(253, 253, 0x130, 3), -+ MTK_PIN_IES_SMT_SPEC(254, 254, 0xf40, 15), -+ MTK_PIN_IES_SMT_SPEC(255, 255, 0xf40, 11), -+ MTK_PIN_IES_SMT_SPEC(256, 256, 0xf40, 7), -+ MTK_PIN_IES_SMT_SPEC(257, 257, 0xf40, 3), -+ MTK_PIN_IES_SMT_SPEC(258, 258, 0xcb0, 11), -+ MTK_PIN_IES_SMT_SPEC(259, 259, 0xc90, 11), -+ MTK_PIN_IES_SMT_SPEC(260, 260, 0x3a0, 11), -+ MTK_PIN_IES_SMT_SPEC(261, 261, 0x0b0, 3), -+ MTK_PIN_IES_SMT_SPEC(262, 277, 0xb70, 12), -+ MTK_PIN_IES_SMT_SPEC(278, 278, 0xb70, 13), -+}; -+ -+static int mt2701_ies_smt_set(struct regmap *regmap, unsigned int pin, -+ unsigned char align, int value, enum pin_config_param arg) -+{ -+ if (arg == PIN_CONFIG_INPUT_ENABLE) -+ return mtk_pconf_spec_set_ies_smt_range(regmap, mt2701_ies_set, -+ ARRAY_SIZE(mt2701_ies_set), pin, align, value); -+ else if (arg == PIN_CONFIG_INPUT_SCHMITT_ENABLE) -+ return mtk_pconf_spec_set_ies_smt_range(regmap, mt2701_smt_set, -+ ARRAY_SIZE(mt2701_smt_set), pin, align, value); -+ return -EINVAL; -+} -+ -+static const struct mtk_spec_pinmux_set mt2701_spec_pinmux[] = { -+ MTK_PINMUX_SPEC(22, 0xb10, 3), -+ MTK_PINMUX_SPEC(23, 0xb10, 4), -+ MTK_PINMUX_SPEC(24, 0xb10, 5), -+ MTK_PINMUX_SPEC(29, 0xb10, 9), -+ MTK_PINMUX_SPEC(208, 0xb10, 7), -+ MTK_PINMUX_SPEC(209, 0xb10, 8), -+ MTK_PINMUX_SPEC(203, 0xf20, 0), -+ MTK_PINMUX_SPEC(204, 0xf20, 1), -+ MTK_PINMUX_SPEC(249, 0xef0, 0), -+ MTK_PINMUX_SPEC(250, 0xef0, 0), -+ MTK_PINMUX_SPEC(251, 0xef0, 0), -+ MTK_PINMUX_SPEC(252, 0xef0, 0), -+ MTK_PINMUX_SPEC(253, 0xef0, 0), -+ MTK_PINMUX_SPEC(254, 0xef0, 0), -+ MTK_PINMUX_SPEC(255, 0xef0, 0), -+ MTK_PINMUX_SPEC(256, 0xef0, 0), -+ MTK_PINMUX_SPEC(257, 0xef0, 0), -+ MTK_PINMUX_SPEC(258, 0xef0, 0), -+ MTK_PINMUX_SPEC(259, 0xef0, 0), -+ MTK_PINMUX_SPEC(260, 0xef0, 0), -+}; -+ -+static void mt2701_spec_pinmux_set(struct regmap *reg, unsigned int pin, -+ unsigned int mode) -+{ -+ unsigned int i, value, mask; -+ unsigned int info_num = ARRAY_SIZE(mt2701_spec_pinmux); -+ unsigned int spec_flag; -+ -+ for (i = 0; i < info_num; i++) { -+ if (pin == mt2701_spec_pinmux[i].pin) -+ break; -+ } -+ -+ if (i == info_num) -+ return; -+ -+ spec_flag = (mode >> 3); -+ mask = BIT(mt2701_spec_pinmux[i].bit); -+ if (!spec_flag) -+ value = mask; -+ else -+ value = 0; -+ regmap_update_bits(reg, mt2701_spec_pinmux[i].offset, mask, value); -+} -+ -+static void mt2701_spec_dir_set(unsigned int *reg_addr, unsigned int pin) -+{ -+ if (pin > 175) -+ *reg_addr += 0x10; -+} -+ -+static const struct mtk_pinctrl_devdata mt2701_pinctrl_data = { -+ .pins = mtk_pins_mt2701, -+ .npins = ARRAY_SIZE(mtk_pins_mt2701), -+ .grp_desc = mt2701_drv_grp, -+ .n_grp_cls = ARRAY_SIZE(mt2701_drv_grp), -+ .pin_drv_grp = mt2701_pin_drv, -+ .n_pin_drv_grps = ARRAY_SIZE(mt2701_pin_drv), -+ .spec_pull_set = mt2701_spec_pull_set, -+ .spec_ies_smt_set = mt2701_ies_smt_set, -+ .spec_pinmux_set = mt2701_spec_pinmux_set, -+ .spec_dir_set = mt2701_spec_dir_set, -+ .dir_offset = 0x0000, -+ .pullen_offset = 0x0150, -+ .pullsel_offset = 0x0280, -+ .dout_offset = 0x0500, -+ .din_offset = 0x0630, -+ .pinmux_offset = 0x0760, -+ .type1_start = 280, -+ .type1_end = 280, -+ .port_shf = 4, -+ .port_mask = 0x1f, -+ .port_align = 4, -+ .eint_offsets = { -+ .name = "mt2701_eint", -+ .stat = 0x000, -+ .ack = 0x040, -+ .mask = 0x080, -+ .mask_set = 0x0c0, -+ .mask_clr = 0x100, -+ .sens = 0x140, -+ .sens_set = 0x180, -+ .sens_clr = 0x1c0, -+ .soft = 0x200, -+ .soft_set = 0x240, -+ .soft_clr = 0x280, -+ .pol = 0x300, -+ .pol_set = 0x340, -+ .pol_clr = 0x380, -+ .dom_en = 0x400, -+ .dbnc_ctrl = 0x500, -+ .dbnc_set = 0x600, -+ .dbnc_clr = 0x700, -+ .port_mask = 6, -+ .ports = 6, -+ }, -+ .ap_num = 169, -+ .db_cnt = 16, -+}; -+ -+static int mt2701_pinctrl_probe(struct platform_device *pdev) -+{ -+ return mtk_pctrl_init(pdev, &mt2701_pinctrl_data, NULL); -+} -+ -+static const struct of_device_id mt2701_pctrl_match[] = { -+ { .compatible = "mediatek,mt2701-pinctrl", }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, mt2701_pctrl_match); -+ -+static struct platform_driver mtk_pinctrl_driver = { -+ .probe = mt2701_pinctrl_probe, -+ .driver = { -+ .name = "mediatek-mt2701-pinctrl", -+ .owner = THIS_MODULE, -+ .of_match_table = mt2701_pctrl_match, -+ }, -+}; -+ -+static int __init mtk_pinctrl_init(void) -+{ -+ return platform_driver_register(&mtk_pinctrl_driver); -+} -+ -+arch_initcall(mtk_pinctrl_init); ---- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c -+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c -@@ -47,6 +47,8 @@ - static const char * const mtk_gpio_functions[] = { - "func0", "func1", "func2", "func3", - "func4", "func5", "func6", "func7", -+ "func8", "func9", "func10", "func11", -+ "func12", "func13", "func14", "func15", - }; - - /* -@@ -81,6 +83,9 @@ static int mtk_pmx_gpio_set_direction(st - reg_addr = mtk_get_port(pctl, offset) + pctl->devdata->dir_offset; - bit = BIT(offset & 0xf); - -+ if (pctl->devdata->spec_dir_set) -+ pctl->devdata->spec_dir_set(®_addr, offset); -+ - if (input) - /* Different SoC has different alignment offset. */ - reg_addr = CLR_ADDR(reg_addr, pctl); -@@ -347,6 +352,7 @@ static int mtk_pconf_parse_conf(struct p - ret = mtk_pconf_set_pull_select(pctl, pin, true, false, arg); - break; - case PIN_CONFIG_INPUT_ENABLE: -+ mtk_pmx_gpio_set_direction(pctldev, NULL, pin, true); - ret = mtk_pconf_set_ies_smt(pctl, pin, arg, param); - break; - case PIN_CONFIG_OUTPUT: -@@ -354,6 +360,7 @@ static int mtk_pconf_parse_conf(struct p - ret = mtk_pmx_gpio_set_direction(pctldev, NULL, pin, false); - break; - case PIN_CONFIG_INPUT_SCHMITT_ENABLE: -+ mtk_pmx_gpio_set_direction(pctldev, NULL, pin, true); - ret = mtk_pconf_set_ies_smt(pctl, pin, arg, param); - break; - case PIN_CONFIG_DRIVE_STRENGTH: -@@ -667,9 +674,14 @@ static int mtk_pmx_set_mode(struct pinct - unsigned int mask = (1L << GPIO_MODE_BITS) - 1; - struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - -+ if (pctl->devdata->spec_pinmux_set) -+ pctl->devdata->spec_pinmux_set(mtk_get_regmap(pctl, pin), -+ pin, mode); -+ - reg_addr = ((pin / MAX_GPIO_MODE_PER_REG) << pctl->devdata->port_shf) - + pctl->devdata->pinmux_offset; - -+ mode &= mask; - bit = pin % MAX_GPIO_MODE_PER_REG; - mask <<= (GPIO_MODE_BITS * bit); - val = (mode << (GPIO_MODE_BITS * bit)); -@@ -746,6 +758,10 @@ static int mtk_gpio_get_direction(struct - - reg_addr = mtk_get_port(pctl, offset) + pctl->devdata->dir_offset; - bit = BIT(offset & 0xf); -+ -+ if (pctl->devdata->spec_dir_set) -+ pctl->devdata->spec_dir_set(®_addr, offset); -+ - regmap_read(pctl->regmap1, reg_addr, &read_val); - return !(read_val & bit); - } ---- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h -+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h -@@ -209,7 +209,14 @@ struct mtk_eint_offsets { - * means when user set smt, input enable is set at the same time. So they - * also need special control. If special control is success, this should - * return 0, otherwise return non-zero value. -- * -+ * @spec_pinmux_set: In some cases, there are two pinmux functions share -+ * the same value in the same segment of pinmux control register. If user -+ * want to use one of the two functions, they need an extra bit setting to -+ * select the right one. -+ * @spec_dir_set: In very few SoCs, direction control registers are not -+ * arranged continuously, they may be cut to parts. So they need special -+ * dir setting. -+ - * @dir_offset: The direction register offset. - * @pullen_offset: The pull-up/pull-down enable register offset. - * @pinmux_offset: The pinmux register offset. -@@ -234,6 +241,9 @@ struct mtk_pinctrl_devdata { - unsigned char align, bool isup, unsigned int arg); - int (*spec_ies_smt_set)(struct regmap *reg, unsigned int pin, - unsigned char align, int value, enum pin_config_param arg); -+ void (*spec_pinmux_set)(struct regmap *reg, unsigned int pin, -+ unsigned int mode); -+ void (*spec_dir_set)(unsigned int *reg_addr, unsigned int pin); - unsigned int dir_offset; - unsigned int ies_offset; - unsigned int smt_offset; ---- /dev/null -+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-mt2701.h -@@ -0,0 +1,2323 @@ -+/* -+ * Copyright (c) 2015 MediaTek Inc. -+ * Author: Biao Huang -+ * -+ * 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 -+#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 index fcd39c487d..0000000000 --- a/target/linux/mediatek/patches-4.4/0015-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt7.patch +++ /dev/null @@ -1,547 +0,0 @@ -From 3800e5c33e5becbb56c6694008d1f3435fd78707 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - .../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 -+ -+#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 index 3428fce39c..0000000000 --- a/target/linux/mediatek/patches-4.4/0016-pinctrl-dt-bindings-Add-pinctrl-file-for-mt7623.patch +++ /dev/null @@ -1,2379 +0,0 @@ -From 641ccb565a934ffaa30b828f2361e6f57325c70a Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 -+ * -+ * 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 -+#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 index d7d151cedb..0000000000 --- a/target/linux/mediatek/patches-4.4/0017-clk-add-hifsys-reset.patch +++ /dev/null @@ -1,47 +0,0 @@ -From f7121d2b19ddad33a09408a2c5923bfd95da8533 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index 9c178f2918..0000000000 --- a/target/linux/mediatek/patches-4.4/0018-dt-bindings-Add-a-binding-for-Mediatek-xHCI-host-con.patch +++ /dev/null @@ -1,69 +0,0 @@ -From ba126a519da8a036dae0032e9d5a89e47570e5fb Mon Sep 17 00:00:00 2001 -From: "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 ---- - .../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 = ; -+ 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 index f081439f6e..0000000000 --- a/target/linux/mediatek/patches-4.4/0019-xhci-mediatek-support-MTK-xHCI-host-controller.patch +++ /dev/null @@ -1,1525 +0,0 @@ -From 8b8185586a13ebbd760e80bbe5f22f9417b50fd2 Mon Sep 17 00:00:00 2001 -From: "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 -Tested-by: Daniel Thompson -Reviewed-by: Daniel Thompson ---- - 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 -+ * Chunfeng.Yun -+ * -+ * 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 -+#include -+#include -+ -+#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 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 "); -+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 -+ * Chunfeng.Yun -+ * -+ * 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 - #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 index 50c03ee892..0000000000 --- a/target/linux/mediatek/patches-4.4/0020-arm64-dts-mediatek-add-xHCI-usb-phy-for-mt8173.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 645465d4c6dd46c5e6c9ac25cd42608b4201fde0 Mon Sep 17 00:00:00 2001 -From: "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 ---- - 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 - #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 - #include - #include -+#include - #include - #include - #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 = ; -+ 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 index 223c2263f3..0000000000 --- a/target/linux/mediatek/patches-4.4/0021-Document-DT-Add-bindings-for-mediatek-MT7623-SoC-Pla.patch +++ /dev/null @@ -1,55 +0,0 @@ -From e111a35542ac14712026fe1a55236f76c7fc9048 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index 453b61288a..0000000000 --- a/target/linux/mediatek/patches-4.4/0022-soc-mediatek-add-compat-string-for-mt7623-to-scpsys.patch +++ /dev/null @@ -1,22 +0,0 @@ -From f232c3b36355974bf3442de3a4726d2e499ed3fe Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index c1f2690391..0000000000 --- a/target/linux/mediatek/patches-4.4/0023-ARM-dts-mediatek-add-MT7623-basic-support.patch +++ /dev/null @@ -1,1079 +0,0 @@ -From 51d5ca9e151eb323bd965e72ad1e1dc93fcf7b13 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 -+ * -+ * 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 -+ -+/ { -+ 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 = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ input-enable; -+ drive-strength = ; -+ bias-pull-up; -+ }; -+ -+ pins_we { -+ pinmux = ; -+ drive-strength = ; -+ bias-pull-up = ; -+ }; -+ -+ pins_ale { -+ pinmux = ; -+ drive-strength = ; -+ bias-pull-down = ; -+ }; -+ }; -+ -+ eth_default: eth { -+ pins_eth { -+ pinmux = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ }; -+ -+ pins_eth_rst { -+ pinmux = ; -+ output-low; -+ }; -+ }; -+}; -+ -+&nandc { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&nand_pins_default>; -+ nand@0 { -+ reg = <0>; -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@C0000 { -+ label = "uboot-env"; -+ reg = <0xC0000 0x40000>; -+ }; -+ -+ partition@100000 { -+ label = "factory"; -+ reg = <0x100000 0x40000>; -+ }; -+ -+ partition@140000 { -+ label = "kernel"; -+ reg = <0x140000 0x2000000>; -+ }; -+ -+ partition@2140000 { -+ label = "recovery"; -+ reg = <0x2140000 0x2000000>; -+ }; -+ -+ partition@4140000 { -+ label = "rootfs"; -+ reg = <0x4140000 0x1000000>; -+ }; -+ }; -+ }; -+}; -+&bch { -+ status = "okay"; -+}; -+ -+&usb1 { -+ vusb33-supply = <&mt6323_vusb_reg>; -+ vbus-supply = <&usb_p1_vbus>; -+ status = "okay"; -+}; -+ -+&u3phy1 { -+ status = "okay"; -+}; -+ -+&pcie { -+ status = "okay"; -+}; -+ -+ð { -+ status = "okay"; -+}; -+ -+&gmac1 { -+ mac-address = [00 11 22 33 44 56]; -+ status = "okay"; -+}; -+ -+&gmac2 { -+ mac-address = [00 11 22 33 44 55]; -+ status = "okay"; -+}; -+ -+&gsw { -+ pinctrl-names = "default"; -+ pinctrl-0 = <ð_default>; -+ mediatek,reset-pin = <&pio 15 0>; -+ status = "okay"; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/mt7623.dtsi -@@ -0,0 +1,601 @@ -+/* -+ * Copyright (c) 2016 MediaTek Inc. -+ * Author: John Crispin -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#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 = , -+ , -+ , -+ ; -+ 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 = , -+ ; -+ }; -+ -+ 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 = ; -+ 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 = ; -+ 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 = ; -+ 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 = ; -+ 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 = ; -+ 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 = ; -+ 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 = ; -+ 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 = ; -+ 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 = ; -+ 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 = ; -+ clocks = <&pericfg CLK_PERI_SPI0>; -+ clock-names = "main"; -+ -+ status = "disabled"; -+ }; -+ -+ nandc: nfi@1100d000 { -+ compatible = "mediatek,mt2701-nfc"; -+ reg = <0 0x1100d000 0 0x1000>; -+ interrupts = ; -+ 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 = ; -+ 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 = ; -+ 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 = ; -+ 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 = ; -+ 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 = ; -+ 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 = , -+ , -+ ; -+ interrupt-names = "pcie0", "pcie1", "pcie2"; -+ clocks = <&topckgen CLK_TOP_ETHIF_SEL>; -+ clock-names = "pcie"; -+ power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; -+ resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>, -+ <&hifsys MT2701_HIFSYS_PCIE1_RST>, -+ <&hifsys MT2701_HIFSYS_PCIE2_RST>; -+ reset-names = "pcie0", "pcie1", "pcie2"; -+ -+ mediatek,hifsys = <&hifsys>; -+ -+ bus-range = <0x00 0xff>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ -+ ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000 /* io space */ -+ 0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* pci memory */ -+ -+ status = "disabled"; -+ -+ pcie@1,0 { -+ device_type = "pci"; -+ reg = <0x0800 0 0 0 0>; -+ -+ #address-cells = <3>; -+ #size-cells = <2>; -+ ranges; -+ }; -+ -+ pcie@2,0{ -+ device_type = "pci"; -+ reg = <0x1000 0 0 0 0>; -+ -+ #address-cells = <3>; -+ #size-cells = <2>; -+ ranges; -+ }; -+ -+ pcie@3,0{ -+ device_type = "pci"; -+ reg = <0x1800 0 0 0 0>; -+ -+ #address-cells = <3>; -+ #size-cells = <2>; -+ ranges; -+ }; -+ }; -+ -+ ethsys: syscon@1b000000 { -+ compatible = "mediatek,mt2701-ethsys", "syscon"; -+ reg = <0 0x1b000000 0 0x1000>; -+ #reset-cells = <1>; -+ #clock-cells = <1>; -+ }; -+ -+ eth: ethernet@1b100000 { -+ compatible = "mediatek,mt2701-eth"; -+ reg = <0 0x1b100000 0 0x20000>; -+ -+ clocks = <&topckgen CLK_TOP_ETHIF_SEL>, -+ <ðsys CLK_ETHSYS_ESW>, -+ <ðsys CLK_ETHSYS_GP2>, -+ <ðsys CLK_ETHSYS_GP1>; -+ clock-names = "ethif", "esw", "gp2", "gp1"; -+ interrupts = ; -+ power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; -+ -+ resets = <ðsys 6>; -+ reset-names = "eth"; -+ -+ mediatek,ethsys = <ðsys>; -+ mediatek,pctl = <&syscfg_pctl_a>; -+ -+ mediatek,switch = <&gsw>; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ status = "disabled"; -+ -+ gmac1: mac@0 { -+ compatible = "mediatek,eth-mac"; -+ reg = <0>; -+ -+ status = "disabled"; -+ -+ phy-mode = "rgmii"; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ pause; -+ }; -+ }; -+ -+ gmac2: mac@1 { -+ compatible = "mediatek,eth-mac"; -+ reg = <1>; -+ -+ status = "disabled"; -+ -+ phy-mode = "rgmii"; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ pause; -+ }; -+ }; -+ -+ mdio-bus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ phy5: ethernet-phy@5 { -+ reg = <5>; -+ phy-mode = "rgmii-rxid"; -+ }; -+ -+ phy1f: ethernet-phy@1f { -+ reg = <0x1f>; -+ phy-mode = "rgmii"; -+ }; -+ }; -+ }; -+ -+ gsw: switch@1b100000 { -+ compatible = "mediatek,mt7623-gsw"; -+ interrupt-parent = <&pio>; -+ interrupts = <168 IRQ_TYPE_EDGE_RISING>; -+ resets = <ðsys 2>; -+ reset-names = "eth"; -+ clocks = <&apmixedsys CLK_APMIXED_TRGPLL>; -+ clock-names = "trgpll"; -+ mt7530-supply = <&mt6323_vpa_reg>; -+ mediatek,pctl-regmap = <&syscfg_pctl_a>; -+ mediatek,ethsys = <ðsys>; -+ status = "disabled"; -+ }; -+}; ---- a/arch/arm/mach-mediatek/Kconfig -+++ b/arch/arm/mach-mediatek/Kconfig -@@ -21,6 +21,10 @@ config MACH_MT6592 - bool "MediaTek MT6592 SoCs support" - default ARCH_MEDIATEK - -+config MACH_MT7623 -+ bool "MediaTek MT7623 SoCs support" -+ default ARCH_MEDIATEK -+ - config MACH_MT8127 - bool "MediaTek MT8127 SoCs support" - default ARCH_MEDIATEK ---- a/arch/arm/mach-mediatek/mediatek.c -+++ b/arch/arm/mach-mediatek/mediatek.c -@@ -46,6 +46,7 @@ static void __init mediatek_timer_init(v - static const char * const mediatek_board_dt_compat[] = { - "mediatek,mt6589", - "mediatek,mt6592", -+ "mediatek,mt7623", - "mediatek,mt8127", - "mediatek,mt8135", - NULL, 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 index d6fe977793..0000000000 --- a/target/linux/mediatek/patches-4.4/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 05be818061b9f2a0fa5ad0cde6881917ff14a2f2 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - .../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 = , -+ , -+ ; -+ 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 index bcb109d6a9..0000000000 --- a/target/linux/mediatek/patches-4.4/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch +++ /dev/null @@ -1,698 +0,0 @@ -From 8ab1d4e0a9a68e03f472dee1c036a01d0198c20c Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 -+ * Copyright (C) 2015 John Crispin -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 index 7ec3033463..0000000000 --- a/target/linux/mediatek/patches-4.4/0026-scpsys-various-fixes.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 59aafd667d2880c90776931b6102b8252214d93c Mon Sep 17 00:00:00 2001 -From: John Crispin -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 index 964373bf49..0000000000 --- a/target/linux/mediatek/patches-4.4/0027-soc-mediatek-PMIC-wrap-Clear-the-vldclr-if-state-mac.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 55231d8299d3dccde8588ed2e86c2bc0ef2e12ce Mon Sep 17 00:00:00 2001 -From: Henry Chen -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 -Tested-by: Ricky Liang -Signed-off-by: Matthias Brugger ---- - 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 index 4aacd26a1f..0000000000 --- a/target/linux/mediatek/patches-4.4/0028-ARM-mediatek-add-MT7623-smp-bringup-code.patch +++ /dev/null @@ -1,36 +0,0 @@ -From d088a94afc768683a881b627b6737442158e7db6 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Signed-off-by: Matthias Brugger ---- - 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 index eb936a789b..0000000000 --- a/target/linux/mediatek/patches-4.4/0029-soc-mediatek-PMIC-wrap-clear-the-STAUPD_TRIG-bit-of-.patch +++ /dev/null @@ -1,58 +0,0 @@ -From b92861fbc79b3a7a9bc1c51e2dbfa2c191cc27ea Mon Sep 17 00:00:00 2001 -From: Henry Chen -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 -Reviewed-by: Daniel Kurtz -Signed-off-by: Matthias Brugger ---- - 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 index 790ccca1ff..0000000000 --- a/target/linux/mediatek/patches-4.4/0030-ARM-mediatek-add-mt2701-smp-bringup-code.patch +++ /dev/null @@ -1,23 +0,0 @@ -From f88ec31c6ba3a006d0be87ff1d99145f8cc85bee Mon Sep 17 00:00:00 2001 -From: Louis Yu -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 -Signed-off-by: Matthias Brugger ---- - 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 index 186b2f4e34..0000000000 --- a/target/linux/mediatek/patches-4.4/0031-dt-bindings-ARM-Mediatek-add-MT2701-7623-string-to-t.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 15f4d895578f02cbaed10b0f5f6853b873aba10b Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Acked-by: Rob Herring -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 index 8092e96d71..0000000000 --- a/target/linux/mediatek/patches-4.4/0032-soc-mediatek-PMIC-wrap-don-t-duplicate-the-wrapper-d.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 64e8091be39c3f0a7bf4651bd2045b8c86429d55 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index 9368a85f82..0000000000 --- a/target/linux/mediatek/patches-4.4/0033-soc-mediatek-PMIC-wrap-add-wrapper-callbacks-for-ini.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 756b919b7874cc241a276b4fc5bbec5b3fb4bca8 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index 6d9c99a695..0000000000 --- a/target/linux/mediatek/patches-4.4/0034-soc-mediatek-PMIC-wrap-split-SoC-specific-init-into-.patch +++ /dev/null @@ -1,122 +0,0 @@ -From a1bbd630710d5da89a9c347c84d7badd30e7e68a Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index 42fbe2e1ca..0000000000 --- a/target/linux/mediatek/patches-4.4/0035-soc-mediatek-PMIC-wrap-WRAP_INT_EN-needs-a-different.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 274fd9ba57170de88bbdf522cbd6c290c2e51fb8 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index a80bd731d9..0000000000 --- a/target/linux/mediatek/patches-4.4/0036-soc-mediatek-PMIC-wrap-SPI_WRITE-needs-a-different-b.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 511e697282c6425950b95373ac8dc59a42fd2485 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index 1e2c587605..0000000000 --- a/target/linux/mediatek/patches-4.4/0037-soc-mediatek-PMIC-wrap-move-wdt_src-into-the-pmic_wr.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 6aecbc79322efd3068c6140f74a68654fbe5b5f6 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index 001793f585..0000000000 --- a/target/linux/mediatek/patches-4.4/0038-soc-mediatek-PMIC-wrap-remove-pwrap_is_mt8135-and-pw.patch +++ /dev/null @@ -1,113 +0,0 @@ -From da09b34ad22e8f065a02af114668f7d86357244a Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index dea271af66..0000000000 --- a/target/linux/mediatek/patches-4.4/0039-soc-mediatek-PMIC-wrap-add-a-slave-specific-struct.patch +++ /dev/null @@ -1,297 +0,0 @@ -From 21bdcd324f769545b1765fe391d939a1edd07cbb Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index 51f06288fb..0000000000 --- a/target/linux/mediatek/patches-4.4/0040-soc-mediatek-PMIC-wrap-add-mt6323-slave-support.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 4418ba9a0bb105f00259d10ceb16f9e27199e9b0 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index a50a34af6a..0000000000 --- a/target/linux/mediatek/patches-4.4/0041-soc-mediatek-PMIC-wrap-add-MT2701-7623-support.patch +++ /dev/null @@ -1,232 +0,0 @@ -From 7736d97fe2c6c71c9009a1b45a94de06bfc94a37 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index 701ee67bad..0000000000 --- a/target/linux/mediatek/patches-4.4/0042-dt-bindings-mfd-Add-bindings-for-the-MediaTek-MT6323.patch +++ /dev/null @@ -1,50 +0,0 @@ -From c14dc2993a272c706650502ec579ceabe5f2355e Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Acked-by: Rob Herring -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 index 6b433b0dfa..0000000000 --- a/target/linux/mediatek/patches-4.4/0043-mfd-mt6397-int_con-and-int_status-may-vary-in-locati.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 8269ed007349714e9ef0e3408a68159d763145dd Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index bae05fb51b..0000000000 --- a/target/linux/mediatek/patches-4.4/0044-mfd-mt6397-add-support-for-different-Slave-types.patch +++ /dev/null @@ -1,100 +0,0 @@ -From c6c447480e51301faa2254c7316ab075e20c4b0c Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index d673a0a096..0000000000 --- a/target/linux/mediatek/patches-4.4/0045-mfd-mt6397-add-MT6323-support-to-MT6397-driver.patch +++ /dev/null @@ -1,519 +0,0 @@ -From 0ae7153c9f00361c3e6dac9da0c2d994557953f5 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 - #include - #include -+#include - #include -+#include - - #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 -+ * -+ * 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 -+ * -+ * 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 index d70631483a..0000000000 --- a/target/linux/mediatek/patches-4.4/0046-regulator-Add-document-for-MT6323-regulator.patch +++ /dev/null @@ -1,254 +0,0 @@ -From f536a600e0e20fd57475415ce5b3d909441d53b6 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Sun, 10 Jan 2016 17:31:46 +0100 -Subject: [PATCH 046/102] regulator: Add document for MT6323 regulator - -Signed-off-by: John Crispin -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_ and ldo_. 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 index 6456c27dce..0000000000 --- a/target/linux/mediatek/patches-4.4/0047-regulator-mt6323-Add-support-for-MT6323-regulator.patch +++ /dev/null @@ -1,538 +0,0 @@ -From 94c08223cd696d872cda7d9aa4e817956d0a0b84 Mon Sep 17 00:00:00 2001 -From: Chen Zhong -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 -Signed-off-by: John Crispin ---- - 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 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MT6323_LDO_MODE_NORMAL 0 -+#define MT6323_LDO_MODE_LP 1 -+ -+/* -+ * MT6323 regulators' information -+ * -+ * @desc: standard fields of regulator description. -+ * @qi: Mask for query enable signal status of regulators -+ * @vselon_reg: Register sections for hardware control mode of bucks -+ * @vselctrl_reg: Register for controlling the buck control mode. -+ * @vselctrl_mask: Mask for query buck's voltage control mode. -+ */ -+struct mt6323_regulator_info { -+ struct regulator_desc desc; -+ u32 qi; -+ u32 vselon_reg; -+ u32 vselctrl_reg; -+ u32 vselctrl_mask; -+ u32 modeset_reg; -+ u32 modeset_mask; -+}; -+ -+#define MT6323_BUCK(match, vreg, min, max, step, volt_ranges, enreg, \ -+ vosel, vosel_mask, voselon, vosel_ctrl) \ -+[MT6323_ID_##vreg] = { \ -+ .desc = { \ -+ .name = #vreg, \ -+ .of_match = of_match_ptr(match), \ -+ .ops = &mt6323_volt_range_ops, \ -+ .type = REGULATOR_VOLTAGE, \ -+ .id = MT6323_ID_##vreg, \ -+ .owner = THIS_MODULE, \ -+ .n_voltages = (max - min)/step + 1, \ -+ .linear_ranges = volt_ranges, \ -+ .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ -+ .vsel_reg = vosel, \ -+ .vsel_mask = vosel_mask, \ -+ .enable_reg = enreg, \ -+ .enable_mask = BIT(0), \ -+ }, \ -+ .qi = BIT(13), \ -+ .vselon_reg = voselon, \ -+ .vselctrl_reg = vosel_ctrl, \ -+ .vselctrl_mask = BIT(1), \ -+} -+ -+#define MT6323_LDO(match, vreg, ldo_volt_table, enreg, enbit, vosel, \ -+ vosel_mask, _modeset_reg, _modeset_mask) \ -+[MT6323_ID_##vreg] = { \ -+ .desc = { \ -+ .name = #vreg, \ -+ .of_match = of_match_ptr(match), \ -+ .ops = &mt6323_volt_table_ops, \ -+ .type = REGULATOR_VOLTAGE, \ -+ .id = MT6323_ID_##vreg, \ -+ .owner = THIS_MODULE, \ -+ .n_voltages = ARRAY_SIZE(ldo_volt_table), \ -+ .volt_table = ldo_volt_table, \ -+ .vsel_reg = vosel, \ -+ .vsel_mask = vosel_mask, \ -+ .enable_reg = enreg, \ -+ .enable_mask = BIT(enbit), \ -+ }, \ -+ .qi = BIT(15), \ -+ .modeset_reg = _modeset_reg, \ -+ .modeset_mask = _modeset_mask, \ -+} -+ -+#define MT6323_REG_FIXED(match, vreg, enreg, enbit, volt, \ -+ _modeset_reg, _modeset_mask) \ -+[MT6323_ID_##vreg] = { \ -+ .desc = { \ -+ .name = #vreg, \ -+ .of_match = of_match_ptr(match), \ -+ .ops = &mt6323_volt_fixed_ops, \ -+ .type = REGULATOR_VOLTAGE, \ -+ .id = MT6323_ID_##vreg, \ -+ .owner = THIS_MODULE, \ -+ .n_voltages = 1, \ -+ .enable_reg = enreg, \ -+ .enable_mask = BIT(enbit), \ -+ .min_uV = volt, \ -+ }, \ -+ .qi = BIT(15), \ -+ .modeset_reg = _modeset_reg, \ -+ .modeset_mask = _modeset_mask, \ -+} -+ -+static const struct regulator_linear_range buck_volt_range1[] = { -+ REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250), -+}; -+ -+static const struct regulator_linear_range buck_volt_range2[] = { -+ REGULATOR_LINEAR_RANGE(1400000, 0, 0x7f, 12500), -+}; -+ -+static const struct regulator_linear_range buck_volt_range3[] = { -+ REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000), -+}; -+ -+static const u32 ldo_volt_table1[] = { -+ 3300000, 3400000, 3500000, 3600000, -+}; -+ -+static const u32 ldo_volt_table2[] = { -+ 1500000, 1800000, 2500000, 2800000, -+}; -+ -+static const u32 ldo_volt_table3[] = { -+ 1800000, 3300000, -+}; -+ -+static const u32 ldo_volt_table4[] = { -+ 3000000, 3300000, -+}; -+ -+static const u32 ldo_volt_table5[] = { -+ 1200000, 1300000, 1500000, 1800000, 2000000, 2800000, 3000000, 3300000, -+}; -+ -+static const u32 ldo_volt_table6[] = { -+ 1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 2000000, -+}; -+ -+static const u32 ldo_volt_table7[] = { -+ 1200000, 1300000, 1500000, 1800000, -+}; -+ -+static const u32 ldo_volt_table8[] = { -+ 1800000, 3000000, -+}; -+ -+static const u32 ldo_volt_table9[] = { -+ 1200000, 1350000, 1500000, 1800000, -+}; -+ -+static const u32 ldo_volt_table10[] = { -+ 1200000, 1300000, 1500000, 1800000, -+}; -+ -+static int mt6323_get_status(struct regulator_dev *rdev) -+{ -+ int ret; -+ u32 regval; -+ struct mt6323_regulator_info *info = rdev_get_drvdata(rdev); -+ -+ ret = regmap_read(rdev->regmap, info->desc.enable_reg, ®val); -+ if (ret != 0) { -+ dev_err(&rdev->dev, "Failed to get enable reg: %d\n", ret); -+ return ret; -+ } -+ -+ return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF; -+} -+ -+static int mt6323_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode) -+{ -+ int ret, val = 0; -+ struct mt6323_regulator_info *info = rdev_get_drvdata(rdev); -+ -+ if (!info->modeset_mask) { -+ dev_err(&rdev->dev, "regulator %s doesn't support set_mode\n", -+ info->desc.name); -+ return -EINVAL; -+ } -+ -+ switch (mode) { -+ case REGULATOR_MODE_STANDBY: -+ val = MT6323_LDO_MODE_LP; -+ break; -+ case REGULATOR_MODE_NORMAL: -+ val = MT6323_LDO_MODE_NORMAL; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ val <<= ffs(info->modeset_mask) - 1; -+ -+ ret = regmap_update_bits(rdev->regmap, info->modeset_reg, -+ info->modeset_mask, val); -+ -+ return ret; -+} -+ -+static unsigned int mt6323_ldo_get_mode(struct regulator_dev *rdev) -+{ -+ unsigned int val; -+ unsigned int mode; -+ int ret; -+ struct mt6323_regulator_info *info = rdev_get_drvdata(rdev); -+ -+ if (!info->modeset_mask) { -+ dev_err(&rdev->dev, "regulator %s doesn't support get_mode\n", -+ info->desc.name); -+ return -EINVAL; -+ } -+ -+ ret = regmap_read(rdev->regmap, info->modeset_reg, &val); -+ if (ret < 0) -+ return ret; -+ -+ val &= info->modeset_mask; -+ val >>= ffs(info->modeset_mask) - 1; -+ -+ if (val & 0x1) -+ mode = REGULATOR_MODE_STANDBY; -+ else -+ mode = REGULATOR_MODE_NORMAL; -+ -+ return mode; -+} -+ -+static struct regulator_ops mt6323_volt_range_ops = { -+ .list_voltage = regulator_list_voltage_linear_range, -+ .map_voltage = regulator_map_voltage_linear_range, -+ .set_voltage_sel = regulator_set_voltage_sel_regmap, -+ .get_voltage_sel = regulator_get_voltage_sel_regmap, -+ .set_voltage_time_sel = regulator_set_voltage_time_sel, -+ .enable = regulator_enable_regmap, -+ .disable = regulator_disable_regmap, -+ .is_enabled = regulator_is_enabled_regmap, -+ .get_status = mt6323_get_status, -+}; -+ -+static struct regulator_ops mt6323_volt_table_ops = { -+ .list_voltage = regulator_list_voltage_table, -+ .map_voltage = regulator_map_voltage_iterate, -+ .set_voltage_sel = regulator_set_voltage_sel_regmap, -+ .get_voltage_sel = regulator_get_voltage_sel_regmap, -+ .set_voltage_time_sel = regulator_set_voltage_time_sel, -+ .enable = regulator_enable_regmap, -+ .disable = regulator_disable_regmap, -+ .is_enabled = regulator_is_enabled_regmap, -+ .get_status = mt6323_get_status, -+ .set_mode = mt6323_ldo_set_mode, -+ .get_mode = mt6323_ldo_get_mode, -+}; -+ -+static struct regulator_ops mt6323_volt_fixed_ops = { -+ .list_voltage = regulator_list_voltage_linear, -+ .enable = regulator_enable_regmap, -+ .disable = regulator_disable_regmap, -+ .is_enabled = regulator_is_enabled_regmap, -+ .get_status = mt6323_get_status, -+ .set_mode = mt6323_ldo_set_mode, -+ .get_mode = mt6323_ldo_get_mode, -+}; -+ -+/* The array is indexed by id(MT6323_ID_XXX) */ -+static struct mt6323_regulator_info mt6323_regulators[] = { -+ MT6323_BUCK("buck_vproc", VPROC, 700000, 1493750, 6250, -+ buck_volt_range1, MT6323_VPROC_CON7, MT6323_VPROC_CON9, 0x7f, -+ MT6323_VPROC_CON10, MT6323_VPROC_CON5), -+ MT6323_BUCK("buck_vsys", VSYS, 1400000, 2987500, 12500, -+ buck_volt_range2, MT6323_VSYS_CON7, MT6323_VSYS_CON9, 0x7f, -+ MT6323_VSYS_CON10, MT6323_VSYS_CON5), -+ MT6323_BUCK("buck_vpa", VPA, 500000, 3650000, 50000, -+ buck_volt_range3, MT6323_VPA_CON7, MT6323_VPA_CON9, -+ 0x3f, MT6323_VPA_CON10, MT6323_VPA_CON5), -+ MT6323_REG_FIXED("ldo_vtcxo", VTCXO, MT6323_ANALDO_CON1, 10, 2800000, -+ MT6323_ANALDO_CON1, 0x2), -+ MT6323_REG_FIXED("ldo_vcn28", VCN28, MT6323_ANALDO_CON19, 12, 2800000, -+ MT6323_ANALDO_CON20, 0x2), -+ MT6323_LDO("ldo_vcn33_bt", VCN33_BT, ldo_volt_table1, -+ MT6323_ANALDO_CON16, 7, MT6323_ANALDO_CON16, 0xC, -+ MT6323_ANALDO_CON21, 0x2), -+ MT6323_LDO("ldo_vcn33_wifi", VCN33_WIFI, ldo_volt_table1, -+ MT6323_ANALDO_CON17, 12, MT6323_ANALDO_CON16, 0xC, -+ MT6323_ANALDO_CON21, 0x2), -+ MT6323_REG_FIXED("ldo_va", VA, MT6323_ANALDO_CON2, 14, 2800000, -+ MT6323_ANALDO_CON2, 0x2), -+ MT6323_LDO("ldo_vcama", VCAMA, ldo_volt_table2, -+ MT6323_ANALDO_CON4, 15, MT6323_ANALDO_CON10, 0x60, -1, 0), -+ MT6323_REG_FIXED("ldo_vio28", VIO28, MT6323_DIGLDO_CON0, 14, 2800000, -+ MT6323_DIGLDO_CON0, 0x2), -+ MT6323_REG_FIXED("ldo_vusb", VUSB, MT6323_DIGLDO_CON2, 14, 3300000, -+ MT6323_DIGLDO_CON2, 0x2), -+ MT6323_LDO("ldo_vmc", VMC, ldo_volt_table3, -+ MT6323_DIGLDO_CON3, 12, MT6323_DIGLDO_CON24, 0x10, -+ MT6323_DIGLDO_CON3, 0x2), -+ MT6323_LDO("ldo_vmch", VMCH, ldo_volt_table4, -+ MT6323_DIGLDO_CON5, 14, MT6323_DIGLDO_CON26, 0x80, -+ MT6323_DIGLDO_CON5, 0x2), -+ MT6323_LDO("ldo_vemc3v3", VEMC3V3, ldo_volt_table4, -+ MT6323_DIGLDO_CON6, 14, MT6323_DIGLDO_CON27, 0x80, -+ MT6323_DIGLDO_CON6, 0x2), -+ MT6323_LDO("ldo_vgp1", VGP1, ldo_volt_table5, -+ MT6323_DIGLDO_CON7, 15, MT6323_DIGLDO_CON28, 0xE0, -+ MT6323_DIGLDO_CON7, 0x2), -+ MT6323_LDO("ldo_vgp2", VGP2, ldo_volt_table6, -+ MT6323_DIGLDO_CON8, 15, MT6323_DIGLDO_CON29, 0xE0, -+ MT6323_DIGLDO_CON8, 0x2), -+ MT6323_LDO("ldo_vgp3", VGP3, ldo_volt_table7, -+ MT6323_DIGLDO_CON9, 15, MT6323_DIGLDO_CON30, 0x60, -+ MT6323_DIGLDO_CON9, 0x2), -+ MT6323_REG_FIXED("ldo_vcn18", VCN18, MT6323_DIGLDO_CON11, 14, 1800000, -+ MT6323_DIGLDO_CON11, 0x2), -+ MT6323_LDO("ldo_vsim1", VSIM1, ldo_volt_table8, -+ MT6323_DIGLDO_CON13, 15, MT6323_DIGLDO_CON34, 0x20, -+ MT6323_DIGLDO_CON13, 0x2), -+ MT6323_LDO("ldo_vsim2", VSIM2, ldo_volt_table8, -+ MT6323_DIGLDO_CON14, 15, MT6323_DIGLDO_CON35, 0x20, -+ MT6323_DIGLDO_CON14, 0x2), -+ MT6323_REG_FIXED("ldo_vrtc", VRTC, MT6323_DIGLDO_CON15, 8, 2800000, -+ -1, 0), -+ MT6323_LDO("ldo_vcamaf", VCAMAF, ldo_volt_table5, -+ MT6323_DIGLDO_CON31, 15, MT6323_DIGLDO_CON32, 0xE0, -+ MT6323_DIGLDO_CON31, 0x2), -+ MT6323_LDO("ldo_vibr", VIBR, ldo_volt_table5, -+ MT6323_DIGLDO_CON39, 15, MT6323_DIGLDO_CON40, 0xE0, -+ MT6323_DIGLDO_CON39, 0x2), -+ MT6323_REG_FIXED("ldo_vrf18", VRF18, MT6323_DIGLDO_CON45, 15, 1825000, -+ MT6323_DIGLDO_CON45, 0x2), -+ MT6323_LDO("ldo_vm", VM, ldo_volt_table9, -+ MT6323_DIGLDO_CON47, 14, MT6323_DIGLDO_CON48, 0x30, -+ MT6323_DIGLDO_CON47, 0x2), -+ MT6323_REG_FIXED("ldo_vio18", VIO18, MT6323_DIGLDO_CON49, 14, 1800000, -+ MT6323_DIGLDO_CON49, 0x2), -+ MT6323_LDO("ldo_vcamd", VCAMD, ldo_volt_table10, -+ MT6323_DIGLDO_CON51, 14, MT6323_DIGLDO_CON52, 0x60, -+ MT6323_DIGLDO_CON51, 0x2), -+ MT6323_REG_FIXED("ldo_vcamio", VCAMIO, MT6323_DIGLDO_CON53, 14, 1800000, -+ MT6323_DIGLDO_CON53, 0x2), -+}; -+ -+static int mt6323_set_buck_vosel_reg(struct platform_device *pdev) -+{ -+ struct mt6397_chip *mt6323 = dev_get_drvdata(pdev->dev.parent); -+ int i; -+ u32 regval; -+ -+ for (i = 0; i < MT6323_MAX_REGULATOR; i++) { -+ if (mt6323_regulators[i].vselctrl_reg) { -+ if (regmap_read(mt6323->regmap, -+ mt6323_regulators[i].vselctrl_reg, -+ ®val) < 0) { -+ dev_err(&pdev->dev, -+ "Failed to read buck ctrl\n"); -+ return -EIO; -+ } -+ -+ if (regval & mt6323_regulators[i].vselctrl_mask) { -+ mt6323_regulators[i].desc.vsel_reg = -+ mt6323_regulators[i].vselon_reg; -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static int mt6323_regulator_probe(struct platform_device *pdev) -+{ -+ struct mt6397_chip *mt6323 = dev_get_drvdata(pdev->dev.parent); -+ struct regulator_config config = {}; -+ struct regulator_dev *rdev; -+ int i; -+ u32 reg_value; -+ -+ /* Query buck controller to select activated voltage register part */ -+ if (mt6323_set_buck_vosel_reg(pdev)) -+ return -EIO; -+ -+ /* Read PMIC chip revision to update constraints and voltage table */ -+ if (regmap_read(mt6323->regmap, MT6323_CID, ®_value) < 0) { -+ dev_err(&pdev->dev, "Failed to read Chip ID\n"); -+ return -EIO; -+ } -+ dev_info(&pdev->dev, "Chip ID = 0x%x\n", reg_value); -+ -+ for (i = 0; i < MT6323_MAX_REGULATOR; i++) { -+ config.dev = &pdev->dev; -+ config.driver_data = &mt6323_regulators[i]; -+ config.regmap = mt6323->regmap; -+ rdev = devm_regulator_register(&pdev->dev, -+ &mt6323_regulators[i].desc, &config); -+ if (IS_ERR(rdev)) { -+ dev_err(&pdev->dev, "failed to register %s\n", -+ mt6323_regulators[i].desc.name); -+ return PTR_ERR(rdev); -+ } -+ } -+ return 0; -+} -+ -+static const struct platform_device_id mt6323_platform_ids[] = { -+ {"mt6323-regulator", 0}, -+ { /* sentinel */ }, -+}; -+MODULE_DEVICE_TABLE(platform, mt6323_platform_ids); -+ -+static const struct of_device_id mt6323_of_match[] = { -+ { .compatible = "mediatek,mt6323-regulator", }, -+ { /* sentinel */ }, -+}; -+MODULE_DEVICE_TABLE(of, mt6323_of_match); -+ -+static struct platform_driver mt6323_regulator_driver = { -+ .driver = { -+ .name = "mt6323-regulator", -+ .of_match_table = of_match_ptr(mt6323_of_match), -+ }, -+ .probe = mt6323_regulator_probe, -+ .id_table = mt6323_platform_ids, -+}; -+ -+module_platform_driver(mt6323_regulator_driver); -+ -+MODULE_AUTHOR("Chen Zhong "); -+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 -+ * -+ * 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 index 8721d770fd..0000000000 --- a/target/linux/mediatek/patches-4.4/0048-net-next-mediatek-document-MediaTek-SoC-ethernet-bin.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 6efc8d9081b70dcf71d7e8efd7b51d48ee2541be Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Acked-by: Rob Herring -Cc: devicetree@vger.kernel.org ---- - .../devicetree/bindings/net/mediatek-net.txt | 77 ++++++++++++++++++++ - 1 file changed, 77 insertions(+) - create mode 100644 Documentation/devicetree/bindings/net/mediatek-net.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/mediatek-net.txt -@@ -0,0 +1,77 @@ -+MediaTek Frame Engine Ethernet controller -+========================================= -+ -+The frame engine ethernet controller can be found on MediaTek SoCs. These SoCs -+have dual GMAC each represented by a child node.. -+ -+* Ethernet controller node -+ -+Required properties: -+- compatible: Should be "mediatek,mt2701-eth" -+- reg: Address and length of the register set for the device -+- interrupts: Should contain the frame engines interrupt -+- clocks: the clock used by the core -+- clock-names: the names of the clock listed in the clocks property. These are -+ "ethif", "esw", "gp2", "gp1" -+- power-domains: phandle to the power domain that the ethernet is part of -+- resets: Should contain a phandle to the ethsys reset signal -+- reset-names: Should contain the reset signal name "eth" -+- mediatek,ethsys: phandle to the syscon node that handles the port setup -+- mediatek,pctl: phandle to the syscon node that handles the ports slew rate -+ and driver current -+ -+Optional properties: -+- interrupt-parent: Should be the phandle for the interrupt controller -+ that services interrupts for this device -+ -+ -+* Ethernet MAC node -+ -+Required properties: -+- compatible: Should be "mediatek,eth-mac" -+- reg: The number of the MAC -+- phy-handle: see ethernet.txt file in the same directory. -+ -+Example: -+ -+eth: ethernet@1b100000 { -+ compatible = "mediatek,mt2701-eth"; -+ reg = <0 0x1b100000 0 0x20000>; -+ clocks = <&topckgen CLK_TOP_ETHIF_SEL>, -+ <ðsys CLK_ETHSYS_ESW>, -+ <ðsys CLK_ETHSYS_GP2>, -+ <ðsys CLK_ETHSYS_GP1>; -+ clock-names = "ethif", "esw", "gp2", "gp1"; -+ interrupts = ; -+ power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; -+ resets = <ðsys MT2701_ETHSYS_ETH_RST>; -+ reset-names = "eth"; -+ mediatek,ethsys = <ðsys>; -+ mediatek,pctl = <&syscfg_pctl_a>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ gmac1: mac@0 { -+ compatible = "mediatek,eth-mac"; -+ reg = <0>; -+ phy-handle = <&phy0>; -+ }; -+ -+ gmac2: mac@1 { -+ compatible = "mediatek,eth-mac"; -+ reg = <1>; -+ phy-handle = <&phy1>; -+ }; -+ -+ mdio-bus { -+ phy0: ethernet-phy@0 { -+ reg = <0>; -+ phy-mode = "rgmii"; -+ }; -+ -+ phy1: ethernet-phy@1 { -+ reg = <1>; -+ phy-mode = "rgmii"; -+ }; -+ }; -+}; 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 index 9d445921aa..0000000000 --- a/target/linux/mediatek/patches-4.4/0049-net-next-mediatek-add-support-for-MT7623-ethernet.patch +++ /dev/null @@ -1,2262 +0,0 @@ -From 8cc84aa65121135d7b120ce71b4f10f81230c818 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Signed-off-by: Michael Lee -Signed-off-by: John Crispin ---- - 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 -+ * Copyright (C) 2009-2016 Felix Fietkau -+ * Copyright (C) 2013-2016 Michael Lee -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtk_eth_soc.h" -+ -+static int mtk_msg_level = -1; -+module_param_named(msg_level, mtk_msg_level, int, 0); -+MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)"); -+ -+#define MTK_ETHTOOL_STAT(x) { #x, \ -+ offsetof(struct mtk_hw_stats, x) / sizeof(u64) } -+ -+/* strings used by ethtool */ -+static const struct mtk_ethtool_stats { -+ char str[ETH_GSTRING_LEN]; -+ u32 offset; -+} mtk_ethtool_stats[] = { -+ MTK_ETHTOOL_STAT(tx_bytes), -+ MTK_ETHTOOL_STAT(tx_packets), -+ MTK_ETHTOOL_STAT(tx_skip), -+ MTK_ETHTOOL_STAT(tx_collisions), -+ MTK_ETHTOOL_STAT(rx_bytes), -+ MTK_ETHTOOL_STAT(rx_packets), -+ MTK_ETHTOOL_STAT(rx_overflow), -+ MTK_ETHTOOL_STAT(rx_fcs_errors), -+ MTK_ETHTOOL_STAT(rx_short_errors), -+ MTK_ETHTOOL_STAT(rx_long_errors), -+ MTK_ETHTOOL_STAT(rx_checksum_errors), -+ MTK_ETHTOOL_STAT(rx_flow_control_packets), -+}; -+ -+void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg) -+{ -+ __raw_writel(val, eth->base + reg); -+} -+ -+u32 mtk_r32(struct mtk_eth *eth, unsigned reg) -+{ -+ return __raw_readl(eth->base + reg); -+} -+ -+static int mtk_mdio_busy_wait(struct mtk_eth *eth) -+{ -+ unsigned long t_start = jiffies; -+ -+ while (1) { -+ if (!(mtk_r32(eth, MTK_PHY_IAC) & PHY_IAC_ACCESS)) -+ return 0; -+ if (time_after(jiffies, t_start + PHY_IAC_TIMEOUT)) -+ break; -+ usleep_range(10, 20); -+ } -+ -+ dev_err(eth->dev, "mdio: MDIO timeout\n"); -+ return -1; -+} -+ -+u32 _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, -+ u32 phy_register, u32 write_data) -+{ -+ if (mtk_mdio_busy_wait(eth)) -+ return -1; -+ -+ write_data &= 0xffff; -+ -+ mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_WRITE | -+ (phy_register << PHY_IAC_REG_SHIFT) | -+ (phy_addr << PHY_IAC_ADDR_SHIFT) | write_data, -+ MTK_PHY_IAC); -+ -+ if (mtk_mdio_busy_wait(eth)) -+ return -1; -+ -+ return 0; -+} -+ -+u32 _mtk_mdio_read(struct mtk_eth *eth, int phy_addr, int phy_reg) -+{ -+ u32 d; -+ -+ if (mtk_mdio_busy_wait(eth)) -+ return 0xffff; -+ -+ mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_READ | -+ (phy_reg << PHY_IAC_REG_SHIFT) | -+ (phy_addr << PHY_IAC_ADDR_SHIFT), -+ MTK_PHY_IAC); -+ -+ if (mtk_mdio_busy_wait(eth)) -+ return 0xffff; -+ -+ d = mtk_r32(eth, MTK_PHY_IAC) & 0xffff; -+ -+ return d; -+} -+ -+static int mtk_mdio_write(struct mii_bus *bus, int phy_addr, -+ int phy_reg, u16 val) -+{ -+ struct mtk_eth *eth = bus->priv; -+ -+ return _mtk_mdio_write(eth, phy_addr, phy_reg, val); -+} -+ -+static int mtk_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg) -+{ -+ struct mtk_eth *eth = bus->priv; -+ -+ return _mtk_mdio_read(eth, phy_addr, phy_reg); -+} -+ -+static void mtk_phy_link_adjust(struct net_device *dev) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ u32 mcr = MAC_MCR_MAX_RX_1536 | MAC_MCR_IPG_CFG | -+ MAC_MCR_FORCE_MODE | MAC_MCR_TX_EN | -+ MAC_MCR_RX_EN | MAC_MCR_BACKOFF_EN | -+ MAC_MCR_BACKPR_EN; -+ -+ switch (mac->phy_dev->speed) { -+ case SPEED_1000: -+ mcr |= MAC_MCR_SPEED_1000; -+ break; -+ case SPEED_100: -+ mcr |= MAC_MCR_SPEED_100; -+ break; -+ }; -+ -+ if (mac->phy_dev->link) -+ mcr |= MAC_MCR_FORCE_LINK; -+ -+ if (mac->phy_dev->duplex) -+ mcr |= MAC_MCR_FORCE_DPX; -+ -+ if (mac->phy_dev->pause) -+ mcr |= MAC_MCR_FORCE_RX_FC | MAC_MCR_FORCE_TX_FC; -+ -+ mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); -+ -+ if (mac->phy_dev->link) -+ netif_carrier_on(dev); -+ else -+ netif_carrier_off(dev); -+} -+ -+static int mtk_phy_connect_node(struct mtk_eth *eth, struct mtk_mac *mac, -+ struct device_node *phy_node) -+{ -+ const __be32 *_addr = NULL; -+ struct phy_device *phydev; -+ int phy_mode, addr; -+ -+ _addr = of_get_property(phy_node, "reg", NULL); -+ -+ if (!_addr || (be32_to_cpu(*_addr) >= 0x20)) { -+ pr_err("%s: invalid phy address\n", phy_node->name); -+ return -EINVAL; -+ } -+ addr = be32_to_cpu(*_addr); -+ phy_mode = of_get_phy_mode(phy_node); -+ if (phy_mode < 0) { -+ dev_err(eth->dev, "incorrect phy-mode %d\n", phy_mode); -+ return -EINVAL; -+ } -+ -+ phydev = of_phy_connect(eth->netdev[mac->id], phy_node, -+ mtk_phy_link_adjust, 0, phy_mode); -+ if (IS_ERR(phydev)) { -+ dev_err(eth->dev, "could not connect to PHY\n"); -+ return PTR_ERR(phydev); -+ } -+ -+ dev_info(eth->dev, -+ "connected mac %d to PHY at %s [uid=%08x, driver=%s]\n", -+ mac->id, phydev_name(phydev), phydev->phy_id, -+ phydev->drv->name); -+ -+ mac->phy_dev = phydev; -+ -+ return 0; -+} -+ -+static int mtk_phy_connect(struct mtk_mac *mac) -+{ -+ struct mtk_eth *eth = mac->hw; -+ struct device_node *np; -+ u32 val, ge_mode; -+ -+ np = of_parse_phandle(mac->of_node, "phy-handle", 0); -+ if (!np) -+ return -ENODEV; -+ -+ switch (of_get_phy_mode(np)) { -+ case PHY_INTERFACE_MODE_RGMII: -+ ge_mode = 0; -+ break; -+ case PHY_INTERFACE_MODE_MII: -+ ge_mode = 1; -+ break; -+ case PHY_INTERFACE_MODE_RMII: -+ ge_mode = 2; -+ break; -+ default: -+ dev_err(eth->dev, "invalid phy_mode\n"); -+ return -1; -+ } -+ -+ /* put the gmac into the right mode */ -+ regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val); -+ val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id); -+ val |= SYSCFG0_GE_MODE(ge_mode, mac->id); -+ regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val); -+ -+ mtk_phy_connect_node(eth, mac, np); -+ mac->phy_dev->autoneg = AUTONEG_ENABLE; -+ mac->phy_dev->speed = 0; -+ mac->phy_dev->duplex = 0; -+ mac->phy_dev->supported &= PHY_BASIC_FEATURES; -+ mac->phy_dev->advertising = mac->phy_dev->supported | -+ ADVERTISED_Autoneg; -+ phy_start_aneg(mac->phy_dev); -+ -+ return 0; -+} -+ -+static int mtk_mdio_init(struct mtk_eth *eth) -+{ -+ struct device_node *mii_np; -+ int err; -+ -+ mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus"); -+ if (!mii_np) { -+ dev_err(eth->dev, "no %s child node found", "mdio-bus"); -+ return -ENODEV; -+ } -+ -+ if (!of_device_is_available(mii_np)) { -+ err = 0; -+ goto err_put_node; -+ } -+ -+ eth->mii_bus = mdiobus_alloc(); -+ if (!eth->mii_bus) { -+ err = -ENOMEM; -+ goto err_put_node; -+ } -+ -+ eth->mii_bus->name = "mdio"; -+ eth->mii_bus->read = mtk_mdio_read; -+ eth->mii_bus->write = mtk_mdio_write; -+ eth->mii_bus->priv = eth; -+ eth->mii_bus->parent = eth->dev; -+ -+ snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%s", mii_np->name); -+ err = of_mdiobus_register(eth->mii_bus, mii_np); -+ if (err) -+ goto err_free_bus; -+ -+ return 0; -+ -+err_free_bus: -+ kfree(eth->mii_bus); -+ -+err_put_node: -+ of_node_put(mii_np); -+ eth->mii_bus = NULL; -+ return err; -+} -+ -+static void mtk_mdio_cleanup(struct mtk_eth *eth) -+{ -+ if (!eth->mii_bus) -+ return; -+ -+ mdiobus_unregister(eth->mii_bus); -+ of_node_put(eth->mii_bus->dev.of_node); -+ kfree(eth->mii_bus); -+} -+ -+static inline void mtk_irq_disable(struct mtk_eth *eth, u32 mask) -+{ -+ u32 val; -+ -+ val = mtk_r32(eth, MTK_QDMA_INT_MASK); -+ mtk_w32(eth, val & ~mask, MTK_QDMA_INT_MASK); -+ /* flush write */ -+ mtk_r32(eth, MTK_QDMA_INT_MASK); -+} -+ -+static inline void mtk_irq_enable(struct mtk_eth *eth, u32 mask) -+{ -+ u32 val; -+ -+ val = mtk_r32(eth, MTK_QDMA_INT_MASK); -+ mtk_w32(eth, val | mask, MTK_QDMA_INT_MASK); -+ /* flush write */ -+ mtk_r32(eth, MTK_QDMA_INT_MASK); -+} -+ -+static int mtk_set_mac_address(struct net_device *dev, void *p) -+{ -+ int ret = eth_mac_addr(dev, p); -+ struct mtk_mac *mac = netdev_priv(dev); -+ const char *macaddr = dev->dev_addr; -+ unsigned long flags; -+ -+ if (ret) -+ return ret; -+ -+ spin_lock_irqsave(&mac->hw->page_lock, flags); -+ mtk_w32(mac->hw, (macaddr[0] << 8) | macaddr[1], -+ MTK_GDMA_MAC_ADRH(mac->id)); -+ mtk_w32(mac->hw, (macaddr[2] << 24) | (macaddr[3] << 16) | -+ (macaddr[4] << 8) | macaddr[5], -+ MTK_GDMA_MAC_ADRL(mac->id)); -+ spin_unlock_irqrestore(&mac->hw->page_lock, flags); -+ -+ return 0; -+} -+ -+void mtk_stats_update_mac(struct mtk_mac *mac) -+{ -+ struct mtk_hw_stats *hw_stats = mac->hw_stats; -+ unsigned int base = MTK_GDM1_TX_GBCNT; -+ u64 stats; -+ -+ base += hw_stats->reg_offset; -+ -+ u64_stats_update_begin(&hw_stats->syncp); -+ -+ hw_stats->rx_bytes += mtk_r32(mac->hw, base); -+ stats = mtk_r32(mac->hw, base + 0x04); -+ if (stats) -+ hw_stats->rx_bytes += (stats << 32); -+ hw_stats->rx_packets += mtk_r32(mac->hw, base + 0x08); -+ hw_stats->rx_overflow += mtk_r32(mac->hw, base + 0x10); -+ hw_stats->rx_fcs_errors += mtk_r32(mac->hw, base + 0x14); -+ hw_stats->rx_short_errors += mtk_r32(mac->hw, base + 0x18); -+ hw_stats->rx_long_errors += mtk_r32(mac->hw, base + 0x1c); -+ hw_stats->rx_checksum_errors += mtk_r32(mac->hw, base + 0x20); -+ hw_stats->rx_flow_control_packets += -+ mtk_r32(mac->hw, base + 0x24); -+ hw_stats->tx_skip += mtk_r32(mac->hw, base + 0x28); -+ hw_stats->tx_collisions += mtk_r32(mac->hw, base + 0x2c); -+ hw_stats->tx_bytes += mtk_r32(mac->hw, base + 0x30); -+ stats = mtk_r32(mac->hw, base + 0x34); -+ if (stats) -+ hw_stats->tx_bytes += (stats << 32); -+ hw_stats->tx_packets += mtk_r32(mac->hw, base + 0x38); -+ u64_stats_update_end(&hw_stats->syncp); -+} -+ -+static void mtk_stats_update(struct mtk_eth *eth) -+{ -+ int i; -+ -+ for (i = 0; i < MTK_MAC_COUNT; i++) { -+ if (!eth->mac[i] || !eth->mac[i]->hw_stats) -+ continue; -+ if (spin_trylock(ð->mac[i]->hw_stats->stats_lock)) { -+ mtk_stats_update_mac(eth->mac[i]); -+ spin_unlock(ð->mac[i]->hw_stats->stats_lock); -+ } -+ } -+} -+ -+static struct rtnl_link_stats64 *mtk_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *storage) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_hw_stats *hw_stats = mac->hw_stats; -+ unsigned int start; -+ -+ if (netif_running(dev) && netif_device_present(dev)) { -+ if (spin_trylock(&hw_stats->stats_lock)) { -+ mtk_stats_update_mac(mac); -+ spin_unlock(&hw_stats->stats_lock); -+ } -+ } -+ -+ do { -+ start = u64_stats_fetch_begin_irq(&hw_stats->syncp); -+ storage->rx_packets = hw_stats->rx_packets; -+ storage->tx_packets = hw_stats->tx_packets; -+ storage->rx_bytes = hw_stats->rx_bytes; -+ storage->tx_bytes = hw_stats->tx_bytes; -+ storage->collisions = hw_stats->tx_collisions; -+ storage->rx_length_errors = hw_stats->rx_short_errors + -+ hw_stats->rx_long_errors; -+ storage->rx_over_errors = hw_stats->rx_overflow; -+ storage->rx_crc_errors = hw_stats->rx_fcs_errors; -+ storage->rx_errors = hw_stats->rx_checksum_errors; -+ storage->tx_aborted_errors = hw_stats->tx_skip; -+ } while (u64_stats_fetch_retry_irq(&hw_stats->syncp, start)); -+ -+ storage->tx_errors = dev->stats.tx_errors; -+ storage->rx_dropped = dev->stats.rx_dropped; -+ storage->tx_dropped = dev->stats.tx_dropped; -+ -+ return storage; -+} -+ -+static inline int mtk_max_frag_size(int mtu) -+{ -+ /* make sure buf_size will be at least MTK_MAX_RX_LENGTH */ -+ if (mtu + MTK_RX_ETH_HLEN < MTK_MAX_RX_LENGTH) -+ mtu = MTK_MAX_RX_LENGTH - MTK_RX_ETH_HLEN; -+ -+ return SKB_DATA_ALIGN(MTK_RX_HLEN + mtu) + -+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -+} -+ -+static inline int mtk_max_buf_size(int frag_size) -+{ -+ int buf_size = frag_size - NET_SKB_PAD - NET_IP_ALIGN - -+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -+ -+ WARN_ON(buf_size < MTK_MAX_RX_LENGTH); -+ -+ return buf_size; -+} -+ -+static inline void mtk_rx_get_desc(struct mtk_rx_dma *rxd, -+ struct mtk_rx_dma *dma_rxd) -+{ -+ rxd->rxd1 = READ_ONCE(dma_rxd->rxd1); -+ rxd->rxd2 = READ_ONCE(dma_rxd->rxd2); -+ rxd->rxd3 = READ_ONCE(dma_rxd->rxd3); -+ rxd->rxd4 = READ_ONCE(dma_rxd->rxd4); -+} -+ -+/* the qdma core needs scratch memory to be setup */ -+static int mtk_init_fq_dma(struct mtk_eth *eth) -+{ -+ unsigned int phy_ring_head, phy_ring_tail; -+ int cnt = MTK_DMA_SIZE; -+ dma_addr_t dma_addr; -+ int i; -+ -+ eth->scratch_ring = dma_alloc_coherent(eth->dev, -+ cnt * sizeof(struct mtk_tx_dma), -+ &phy_ring_head, -+ GFP_ATOMIC | __GFP_ZERO); -+ if (unlikely(!eth->scratch_ring)) -+ return -ENOMEM; -+ -+ eth->scratch_head = kcalloc(cnt, MTK_QDMA_PAGE_SIZE, -+ GFP_KERNEL); -+ dma_addr = dma_map_single(eth->dev, -+ eth->scratch_head, cnt * MTK_QDMA_PAGE_SIZE, -+ DMA_FROM_DEVICE); -+ if (unlikely(dma_mapping_error(eth->dev, dma_addr))) -+ return -ENOMEM; -+ -+ memset(eth->scratch_ring, 0x0, sizeof(struct mtk_tx_dma) * cnt); -+ phy_ring_tail = phy_ring_head + -+ (sizeof(struct mtk_tx_dma) * (cnt - 1)); -+ -+ for (i = 0; i < cnt; i++) { -+ eth->scratch_ring[i].txd1 = -+ (dma_addr + (i * MTK_QDMA_PAGE_SIZE)); -+ if (i < cnt - 1) -+ eth->scratch_ring[i].txd2 = (phy_ring_head + -+ ((i + 1) * sizeof(struct mtk_tx_dma))); -+ eth->scratch_ring[i].txd3 = TX_DMA_SDL(MTK_QDMA_PAGE_SIZE); -+ } -+ -+ mtk_w32(eth, phy_ring_head, MTK_QDMA_FQ_HEAD); -+ mtk_w32(eth, phy_ring_tail, MTK_QDMA_FQ_TAIL); -+ mtk_w32(eth, (cnt << 16) | cnt, MTK_QDMA_FQ_CNT); -+ mtk_w32(eth, MTK_QDMA_PAGE_SIZE << 16, MTK_QDMA_FQ_BLEN); -+ -+ return 0; -+} -+ -+static inline void *mtk_qdma_phys_to_virt(struct mtk_tx_ring *ring, u32 desc) -+{ -+ void *ret = ring->dma; -+ -+ return ret + (desc - ring->phys); -+} -+ -+static inline struct mtk_tx_buf *mtk_desc_to_tx_buf(struct mtk_tx_ring *ring, -+ struct mtk_tx_dma *txd) -+{ -+ int idx = txd - ring->dma; -+ -+ return &ring->buf[idx]; -+} -+ -+static void mtk_tx_unmap(struct device *dev, struct mtk_tx_buf *tx_buf) -+{ -+ if (tx_buf->flags & MTK_TX_FLAGS_SINGLE0) { -+ dma_unmap_single(dev, -+ dma_unmap_addr(tx_buf, dma_addr0), -+ dma_unmap_len(tx_buf, dma_len0), -+ DMA_TO_DEVICE); -+ } else if (tx_buf->flags & MTK_TX_FLAGS_PAGE0) { -+ dma_unmap_page(dev, -+ dma_unmap_addr(tx_buf, dma_addr0), -+ dma_unmap_len(tx_buf, dma_len0), -+ DMA_TO_DEVICE); -+ } -+ tx_buf->flags = 0; -+ if (tx_buf->skb && -+ (tx_buf->skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC)) -+ dev_kfree_skb_any(tx_buf->skb); -+ tx_buf->skb = NULL; -+} -+ -+static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, -+ int tx_num, struct mtk_tx_ring *ring, bool gso) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_eth *eth = mac->hw; -+ struct mtk_tx_dma *itxd, *txd; -+ struct mtk_tx_buf *tx_buf; -+ unsigned long flags; -+ dma_addr_t mapped_addr; -+ unsigned int nr_frags; -+ int i, n_desc = 1; -+ u32 txd4 = 0; -+ -+ itxd = ring->next_free; -+ if (itxd == ring->last_free) -+ return -ENOMEM; -+ -+ /* set the forward port */ -+ txd4 |= (mac->id + 1) << TX_DMA_FPORT_SHIFT; -+ -+ tx_buf = mtk_desc_to_tx_buf(ring, itxd); -+ memset(tx_buf, 0, sizeof(*tx_buf)); -+ -+ if (gso) -+ txd4 |= TX_DMA_TSO; -+ -+ /* TX Checksum offload */ -+ if (skb->ip_summed == CHECKSUM_PARTIAL) -+ txd4 |= TX_DMA_CHKSUM; -+ -+ /* VLAN header offload */ -+ if (skb_vlan_tag_present(skb)) -+ txd4 |= TX_DMA_INS_VLAN | skb_vlan_tag_get(skb); -+ -+ mapped_addr = dma_map_single(&dev->dev, skb->data, -+ skb_headlen(skb), DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(&dev->dev, mapped_addr))) -+ return -ENOMEM; -+ -+ /* normally we can rely on the stack not calling this more than once, -+ * however we have 2 queues running ont he same ring so we need to lock -+ * the ring access -+ */ -+ spin_lock_irqsave(ð->page_lock, flags); -+ WRITE_ONCE(itxd->txd1, mapped_addr); -+ tx_buf->flags |= MTK_TX_FLAGS_SINGLE0; -+ dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr); -+ dma_unmap_len_set(tx_buf, dma_len0, skb_headlen(skb)); -+ -+ /* TX SG offload */ -+ txd = itxd; -+ nr_frags = skb_shinfo(skb)->nr_frags; -+ for (i = 0; i < nr_frags; i++) { -+ struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; -+ unsigned int offset = 0; -+ int frag_size = skb_frag_size(frag); -+ -+ while (frag_size) { -+ bool last_frag = false; -+ unsigned int frag_map_size; -+ -+ txd = mtk_qdma_phys_to_virt(ring, txd->txd2); -+ if (txd == ring->last_free) -+ goto err_dma; -+ -+ n_desc++; -+ frag_map_size = min(frag_size, MTK_TX_DMA_BUF_LEN); -+ mapped_addr = skb_frag_dma_map(&dev->dev, frag, offset, -+ frag_map_size, -+ DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(&dev->dev, mapped_addr))) -+ goto err_dma; -+ -+ if (i == nr_frags - 1 && -+ (frag_size - frag_map_size) == 0) -+ last_frag = true; -+ -+ WRITE_ONCE(txd->txd1, mapped_addr); -+ WRITE_ONCE(txd->txd3, (TX_DMA_SWC | -+ TX_DMA_PLEN0(frag_map_size) | -+ last_frag * TX_DMA_LS0) | -+ mac->id); -+ WRITE_ONCE(txd->txd4, 0); -+ -+ tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC; -+ tx_buf = mtk_desc_to_tx_buf(ring, txd); -+ memset(tx_buf, 0, sizeof(*tx_buf)); -+ -+ tx_buf->flags |= MTK_TX_FLAGS_PAGE0; -+ dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr); -+ dma_unmap_len_set(tx_buf, dma_len0, frag_map_size); -+ frag_size -= frag_map_size; -+ offset += frag_map_size; -+ } -+ } -+ -+ /* store skb to cleanup */ -+ tx_buf->skb = skb; -+ -+ WRITE_ONCE(itxd->txd4, txd4); -+ WRITE_ONCE(itxd->txd3, (TX_DMA_SWC | TX_DMA_PLEN0(skb_headlen(skb)) | -+ (!nr_frags * TX_DMA_LS0))); -+ -+ spin_unlock_irqrestore(ð->page_lock, flags); -+ -+ netdev_sent_queue(dev, skb->len); -+ skb_tx_timestamp(skb); -+ -+ ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2); -+ atomic_sub(n_desc, &ring->free_count); -+ -+ /* make sure that all changes to the dma ring are flushed before we -+ * continue -+ */ -+ wmb(); -+ -+ if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) || !skb->xmit_more) -+ mtk_w32(eth, txd->txd2, MTK_QTX_CTX_PTR); -+ -+ return 0; -+ -+err_dma: -+ do { -+ tx_buf = mtk_desc_to_tx_buf(ring, txd); -+ -+ /* unmap dma */ -+ mtk_tx_unmap(&dev->dev, tx_buf); -+ -+ itxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; -+ itxd = mtk_qdma_phys_to_virt(ring, itxd->txd2); -+ } while (itxd != txd); -+ -+ return -ENOMEM; -+} -+ -+static inline int mtk_cal_txd_req(struct sk_buff *skb) -+{ -+ int i, nfrags; -+ struct skb_frag_struct *frag; -+ -+ nfrags = 1; -+ if (skb_is_gso(skb)) { -+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { -+ frag = &skb_shinfo(skb)->frags[i]; -+ nfrags += DIV_ROUND_UP(frag->size, MTK_TX_DMA_BUF_LEN); -+ } -+ } else { -+ nfrags += skb_shinfo(skb)->nr_frags; -+ } -+ -+ return DIV_ROUND_UP(nfrags, 2); -+} -+ -+static int mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_eth *eth = mac->hw; -+ struct mtk_tx_ring *ring = ð->tx_ring; -+ struct net_device_stats *stats = &dev->stats; -+ bool gso = false; -+ int tx_num; -+ -+ tx_num = mtk_cal_txd_req(skb); -+ if (unlikely(atomic_read(&ring->free_count) <= tx_num)) { -+ netif_stop_queue(dev); -+ netif_err(eth, tx_queued, dev, -+ "Tx Ring full when queue awake!\n"); -+ return NETDEV_TX_BUSY; -+ } -+ -+ /* TSO: fill MSS info in tcp checksum field */ -+ if (skb_is_gso(skb)) { -+ if (skb_cow_head(skb, 0)) { -+ netif_warn(eth, tx_err, dev, -+ "GSO expand head fail.\n"); -+ goto drop; -+ } -+ -+ if (skb_shinfo(skb)->gso_type & -+ (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { -+ gso = true; -+ tcp_hdr(skb)->check = htons(skb_shinfo(skb)->gso_size); -+ } -+ } -+ -+ if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) -+ goto drop; -+ -+ if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) { -+ netif_stop_queue(dev); -+ if (unlikely(atomic_read(&ring->free_count) > -+ ring->thresh)) -+ netif_wake_queue(dev); -+ } -+ -+ return NETDEV_TX_OK; -+ -+drop: -+ stats->tx_dropped++; -+ dev_kfree_skb(skb); -+ return NETDEV_TX_OK; -+} -+ -+static int mtk_poll_rx(struct napi_struct *napi, int budget, -+ struct mtk_eth *eth, u32 rx_intr) -+{ -+ struct mtk_rx_ring *ring = ð->rx_ring; -+ int idx = ring->calc_idx; -+ struct sk_buff *skb; -+ u8 *data, *new_data; -+ struct mtk_rx_dma *rxd, trxd; -+ int done = 0; -+ -+ while (done < budget) { -+ struct net_device *netdev; -+ unsigned int pktlen; -+ dma_addr_t dma_addr; -+ int mac = 0; -+ -+ idx = NEXT_RX_DESP_IDX(idx); -+ rxd = &ring->dma[idx]; -+ data = ring->data[idx]; -+ -+ mtk_rx_get_desc(&trxd, rxd); -+ if (!(trxd.rxd2 & RX_DMA_DONE)) -+ break; -+ -+ /* find out which mac the packet come from. values start at 1 */ -+ mac = (trxd.rxd4 >> RX_DMA_FPORT_SHIFT) & -+ RX_DMA_FPORT_MASK; -+ mac--; -+ -+ netdev = eth->netdev[mac]; -+ -+ /* alloc new buffer */ -+ new_data = napi_alloc_frag(ring->frag_size); -+ if (unlikely(!new_data)) { -+ netdev->stats.rx_dropped++; -+ goto release_desc; -+ } -+ dma_addr = dma_map_single(ð->netdev[mac]->dev, -+ new_data + NET_SKB_PAD, -+ ring->buf_size, -+ DMA_FROM_DEVICE); -+ if (unlikely(dma_mapping_error(&netdev->dev, dma_addr))) { -+ skb_free_frag(new_data); -+ goto release_desc; -+ } -+ -+ /* receive data */ -+ skb = build_skb(data, ring->frag_size); -+ if (unlikely(!skb)) { -+ put_page(virt_to_head_page(new_data)); -+ goto release_desc; -+ } -+ skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN); -+ -+ dma_unmap_single(&netdev->dev, trxd.rxd1, -+ ring->buf_size, DMA_FROM_DEVICE); -+ pktlen = RX_DMA_GET_PLEN0(trxd.rxd2); -+ skb->dev = netdev; -+ skb_put(skb, pktlen); -+ if (trxd.rxd4 & RX_DMA_L4_VALID) -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ else -+ skb_checksum_none_assert(skb); -+ skb->protocol = eth_type_trans(skb, netdev); -+ -+ if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX && -+ RX_DMA_VID(trxd.rxd3)) -+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), -+ RX_DMA_VID(trxd.rxd3)); -+ napi_gro_receive(napi, skb); -+ -+ ring->data[idx] = new_data; -+ rxd->rxd1 = (unsigned int)dma_addr; -+ -+release_desc: -+ rxd->rxd2 = RX_DMA_PLEN0(ring->buf_size); -+ -+ ring->calc_idx = idx; -+ /* make sure that all changes to the dma ring are flushed before -+ * we continue -+ */ -+ wmb(); -+ mtk_w32(eth, ring->calc_idx, MTK_QRX_CRX_IDX0); -+ done++; -+ } -+ -+ if (done < budget) -+ mtk_w32(eth, rx_intr, MTK_QMTK_INT_STATUS); -+ -+ return done; -+} -+ -+static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again) -+{ -+ struct mtk_tx_ring *ring = ð->tx_ring; -+ struct mtk_tx_dma *desc; -+ struct sk_buff *skb; -+ struct mtk_tx_buf *tx_buf; -+ int total = 0, done[MTK_MAX_DEVS]; -+ unsigned int bytes[MTK_MAX_DEVS]; -+ u32 cpu, dma; -+ static int condition; -+ int i; -+ -+ memset(done, 0, sizeof(done)); -+ memset(bytes, 0, sizeof(bytes)); -+ -+ cpu = mtk_r32(eth, MTK_QTX_CRX_PTR); -+ dma = mtk_r32(eth, MTK_QTX_DRX_PTR); -+ -+ desc = mtk_qdma_phys_to_virt(ring, cpu); -+ -+ while ((cpu != dma) && budget) { -+ u32 next_cpu = desc->txd2; -+ int mac; -+ -+ desc = mtk_qdma_phys_to_virt(ring, desc->txd2); -+ if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0) -+ break; -+ -+ mac = (desc->txd4 >> TX_DMA_FPORT_SHIFT) & -+ TX_DMA_FPORT_MASK; -+ mac--; -+ -+ tx_buf = mtk_desc_to_tx_buf(ring, desc); -+ skb = tx_buf->skb; -+ if (!skb) { -+ condition = 1; -+ break; -+ } -+ -+ if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) { -+ bytes[mac] += skb->len; -+ done[mac]++; -+ budget--; -+ } -+ mtk_tx_unmap(eth->dev, tx_buf); -+ -+ ring->last_free->txd2 = next_cpu; -+ ring->last_free = desc; -+ atomic_inc(&ring->free_count); -+ -+ cpu = next_cpu; -+ } -+ -+ mtk_w32(eth, cpu, MTK_QTX_CRX_PTR); -+ -+ for (i = 0; i < MTK_MAC_COUNT; i++) { -+ if (!eth->netdev[i] || !done[i]) -+ continue; -+ netdev_completed_queue(eth->netdev[i], done[i], bytes[i]); -+ total += done[i]; -+ } -+ -+ /* read hw index again make sure no new tx packet */ -+ if (cpu != dma || cpu != mtk_r32(eth, MTK_QTX_DRX_PTR)) -+ *tx_again = true; -+ else -+ mtk_w32(eth, MTK_TX_DONE_INT, MTK_QMTK_INT_STATUS); -+ -+ if (!total) -+ return 0; -+ -+ for (i = 0; i < MTK_MAC_COUNT; i++) { -+ if (!eth->netdev[i] || -+ unlikely(!netif_queue_stopped(eth->netdev[i]))) -+ continue; -+ if (atomic_read(&ring->free_count) > ring->thresh) -+ netif_wake_queue(eth->netdev[i]); -+ } -+ -+ return total; -+} -+ -+static int mtk_poll(struct napi_struct *napi, int budget) -+{ -+ struct mtk_eth *eth = container_of(napi, struct mtk_eth, rx_napi); -+ u32 status, status2, mask, tx_intr, rx_intr, status_intr; -+ int tx_done, rx_done; -+ bool tx_again = false; -+ -+ status = mtk_r32(eth, MTK_QMTK_INT_STATUS); -+ status2 = mtk_r32(eth, MTK_INT_STATUS2); -+ tx_intr = MTK_TX_DONE_INT; -+ rx_intr = MTK_RX_DONE_INT; -+ status_intr = (MTK_GDM1_AF | MTK_GDM2_AF); -+ tx_done = 0; -+ rx_done = 0; -+ tx_again = 0; -+ -+ if (status & tx_intr) -+ tx_done = mtk_poll_tx(eth, budget, &tx_again); -+ -+ if (status & rx_intr) -+ rx_done = mtk_poll_rx(napi, budget, eth, rx_intr); -+ -+ if (unlikely(status2 & status_intr)) { -+ mtk_stats_update(eth); -+ mtk_w32(eth, status_intr, MTK_INT_STATUS2); -+ } -+ -+ if (unlikely(netif_msg_intr(eth))) { -+ mask = mtk_r32(eth, MTK_QDMA_INT_MASK); -+ netdev_info(eth->netdev[0], -+ "done tx %d, rx %d, intr 0x%08x/0x%x\n", -+ tx_done, rx_done, status, mask); -+ } -+ -+ if (tx_again || rx_done == budget) -+ return budget; -+ -+ status = mtk_r32(eth, MTK_QMTK_INT_STATUS); -+ if (status & (tx_intr | rx_intr)) -+ return budget; -+ -+ napi_complete(napi); -+ mtk_irq_enable(eth, tx_intr | rx_intr); -+ -+ return rx_done; -+} -+ -+static int mtk_tx_alloc(struct mtk_eth *eth) -+{ -+ struct mtk_tx_ring *ring = ð->tx_ring; -+ int i, sz = sizeof(*ring->dma); -+ -+ ring->buf = kcalloc(MTK_DMA_SIZE, sizeof(*ring->buf), -+ GFP_KERNEL); -+ if (!ring->buf) -+ goto no_tx_mem; -+ -+ ring->dma = dma_alloc_coherent(eth->dev, -+ MTK_DMA_SIZE * sz, -+ &ring->phys, -+ GFP_ATOMIC | __GFP_ZERO); -+ if (!ring->dma) -+ goto no_tx_mem; -+ -+ memset(ring->dma, 0, MTK_DMA_SIZE * sz); -+ for (i = 0; i < MTK_DMA_SIZE; i++) { -+ int next = (i + 1) % MTK_DMA_SIZE; -+ u32 next_ptr = ring->phys + next * sz; -+ -+ ring->dma[i].txd2 = next_ptr; -+ ring->dma[i].txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; -+ } -+ -+ atomic_set(&ring->free_count, MTK_DMA_SIZE - 2); -+ ring->next_free = &ring->dma[0]; -+ ring->last_free = &ring->dma[MTK_DMA_SIZE - 2]; -+ ring->thresh = max((unsigned long)MTK_DMA_SIZE >> 2, -+ MAX_SKB_FRAGS); -+ -+ /* make sure that all changes to the dma ring are flushed before we -+ * continue -+ */ -+ wmb(); -+ -+ mtk_w32(eth, ring->phys, MTK_QTX_CTX_PTR); -+ mtk_w32(eth, ring->phys, MTK_QTX_DTX_PTR); -+ mtk_w32(eth, -+ ring->phys + ((MTK_DMA_SIZE - 1) * sz), -+ MTK_QTX_CRX_PTR); -+ mtk_w32(eth, -+ ring->phys + ((MTK_DMA_SIZE - 1) * sz), -+ MTK_QTX_DRX_PTR); -+ -+ return 0; -+ -+no_tx_mem: -+ return -ENOMEM; -+} -+ -+static void mtk_tx_clean(struct mtk_eth *eth) -+{ -+ struct mtk_tx_ring *ring = ð->tx_ring; -+ int i; -+ -+ if (ring->buf) { -+ for (i = 0; i < MTK_DMA_SIZE; i++) -+ mtk_tx_unmap(eth->dev, &ring->buf[i]); -+ kfree(ring->buf); -+ ring->buf = NULL; -+ } -+ -+ if (ring->dma) { -+ dma_free_coherent(eth->dev, -+ MTK_DMA_SIZE * sizeof(*ring->dma), -+ ring->dma, -+ ring->phys); -+ ring->dma = NULL; -+ } -+} -+ -+static int mtk_rx_alloc(struct mtk_eth *eth) -+{ -+ struct mtk_rx_ring *ring = ð->rx_ring; -+ int i; -+ -+ ring->frag_size = mtk_max_frag_size(ETH_DATA_LEN); -+ ring->buf_size = mtk_max_buf_size(ring->frag_size); -+ ring->data = kcalloc(MTK_DMA_SIZE, sizeof(*ring->data), -+ GFP_KERNEL); -+ if (!ring->data) -+ return -ENOMEM; -+ -+ for (i = 0; i < MTK_DMA_SIZE; i++) { -+ ring->data[i] = netdev_alloc_frag(ring->frag_size); -+ if (!ring->data[i]) -+ return -ENOMEM; -+ } -+ -+ ring->dma = dma_alloc_coherent(eth->dev, -+ MTK_DMA_SIZE * sizeof(*ring->dma), -+ &ring->phys, -+ GFP_ATOMIC | __GFP_ZERO); -+ if (!ring->dma) -+ return -ENOMEM; -+ -+ for (i = 0; i < MTK_DMA_SIZE; i++) { -+ dma_addr_t dma_addr = dma_map_single(eth->dev, -+ ring->data[i] + NET_SKB_PAD, -+ ring->buf_size, -+ DMA_FROM_DEVICE); -+ if (unlikely(dma_mapping_error(eth->dev, dma_addr))) -+ return -ENOMEM; -+ ring->dma[i].rxd1 = (unsigned int)dma_addr; -+ -+ ring->dma[i].rxd2 = RX_DMA_PLEN0(ring->buf_size); -+ } -+ ring->calc_idx = MTK_DMA_SIZE - 1; -+ /* make sure that all changes to the dma ring are flushed before we -+ * continue -+ */ -+ wmb(); -+ -+ mtk_w32(eth, eth->rx_ring.phys, MTK_QRX_BASE_PTR0); -+ mtk_w32(eth, MTK_DMA_SIZE, MTK_QRX_MAX_CNT0); -+ mtk_w32(eth, eth->rx_ring.calc_idx, MTK_QRX_CRX_IDX0); -+ mtk_w32(eth, MTK_PST_DRX_IDX0, MTK_QDMA_RST_IDX); -+ mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES, MTK_QTX_CFG(0)); -+ -+ return 0; -+} -+ -+static void mtk_rx_clean(struct mtk_eth *eth) -+{ -+ struct mtk_rx_ring *ring = ð->rx_ring; -+ int i; -+ -+ if (ring->data && ring->dma) { -+ for (i = 0; i < MTK_DMA_SIZE; i++) { -+ if (!ring->data[i]) -+ continue; -+ if (!ring->dma[i].rxd1) -+ continue; -+ dma_unmap_single(eth->dev, -+ ring->dma[i].rxd1, -+ ring->buf_size, -+ DMA_FROM_DEVICE); -+ skb_free_frag(ring->data[i]); -+ } -+ kfree(ring->data); -+ ring->data = NULL; -+ } -+ -+ if (ring->dma) { -+ dma_free_coherent(eth->dev, -+ MTK_DMA_SIZE * sizeof(*ring->dma), -+ ring->dma, -+ ring->phys); -+ ring->dma = NULL; -+ } -+} -+ -+/* wait for DMA to finish whatever it is doing before we start using it again */ -+static int mtk_dma_busy_wait(struct mtk_eth *eth) -+{ -+ unsigned long t_start = jiffies; -+ -+ while (1) { -+ if (!(mtk_r32(eth, MTK_QDMA_GLO_CFG) & -+ (MTK_RX_DMA_BUSY | MTK_TX_DMA_BUSY))) -+ return 0; -+ if (time_after(jiffies, t_start + MTK_DMA_BUSY_TIMEOUT)) -+ break; -+ } -+ -+ dev_err(eth->dev, "DMA init timeout\n"); -+ return -1; -+} -+ -+static int mtk_dma_init(struct mtk_eth *eth) -+{ -+ int err; -+ -+ if (mtk_dma_busy_wait(eth)) -+ return -EBUSY; -+ -+ /* QDMA needs scratch memory for internal reordering of the -+ * descriptors -+ */ -+ err = mtk_init_fq_dma(eth); -+ if (err) -+ return err; -+ -+ err = mtk_tx_alloc(eth); -+ if (err) -+ return err; -+ -+ err = mtk_rx_alloc(eth); -+ if (err) -+ return err; -+ -+ /* Enable random early drop and set drop threshold automatically */ -+ mtk_w32(eth, FC_THRES_DROP_MODE | FC_THRES_DROP_EN | FC_THRES_MIN, -+ MTK_QDMA_FC_THRES); -+ mtk_w32(eth, 0x0, MTK_QDMA_HRED2); -+ -+ return 0; -+} -+ -+static void mtk_dma_free(struct mtk_eth *eth) -+{ -+ int i; -+ -+ for (i = 0; i < MTK_MAC_COUNT; i++) -+ if (eth->netdev[i]) -+ netdev_reset_queue(eth->netdev[i]); -+ mtk_tx_clean(eth); -+ mtk_rx_clean(eth); -+ kfree(eth->scratch_head); -+} -+ -+static void mtk_tx_timeout(struct net_device *dev) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_eth *eth = mac->hw; -+ -+ eth->netdev[mac->id]->stats.tx_errors++; -+ netif_err(eth, tx_err, dev, -+ "transmit timed out\n"); -+ schedule_work(&mac->pending_work); -+} -+ -+static irqreturn_t mtk_handle_irq(int irq, void *_eth) -+{ -+ struct mtk_eth *eth = _eth; -+ u32 status; -+ -+ status = mtk_r32(eth, MTK_QMTK_INT_STATUS); -+ if (unlikely(!status)) -+ return IRQ_NONE; -+ -+ if (likely(status & (MTK_RX_DONE_INT | MTK_TX_DONE_INT))) { -+ if (likely(napi_schedule_prep(ð->rx_napi))) -+ __napi_schedule(ð->rx_napi); -+ } else { -+ mtk_w32(eth, status, MTK_QMTK_INT_STATUS); -+ } -+ mtk_irq_disable(eth, (MTK_RX_DONE_INT | MTK_TX_DONE_INT)); -+ -+ return IRQ_HANDLED; -+} -+ -+#ifdef CONFIG_NET_POLL_CONTROLLER -+static void mtk_poll_controller(struct net_device *dev) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_eth *eth = mac->hw; -+ u32 int_mask = MTK_TX_DONE_INT | MTK_RX_DONE_INT; -+ -+ mtk_irq_disable(eth, int_mask); -+ mtk_handle_irq(dev->irq, dev); -+ mtk_irq_enable(eth, int_mask); -+} -+#endif -+ -+static int mtk_start_dma(struct mtk_eth *eth) -+{ -+ int err; -+ -+ err = mtk_dma_init(eth); -+ if (err) { -+ mtk_dma_free(eth); -+ return err; -+ } -+ -+ mtk_w32(eth, -+ MTK_TX_WB_DDONE | MTK_RX_DMA_EN | MTK_TX_DMA_EN | -+ MTK_RX_2B_OFFSET | MTK_DMA_SIZE_16DWORDS | -+ MTK_RX_BT_32DWORDS, -+ MTK_QDMA_GLO_CFG); -+ -+ return 0; -+} -+ -+static int mtk_open(struct net_device *dev) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_eth *eth = mac->hw; -+ -+ /* we run 2 netdevs on the same dma ring so we only bring it up once */ -+ if (!atomic_read(ð->dma_refcnt)) { -+ int err = mtk_start_dma(eth); -+ -+ if (err) -+ return err; -+ -+ napi_enable(ð->rx_napi); -+ mtk_irq_enable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT); -+ } -+ atomic_inc(ð->dma_refcnt); -+ -+ phy_start(mac->phy_dev); -+ netif_start_queue(dev); -+ -+ return 0; -+} -+ -+static void mtk_stop_dma(struct mtk_eth *eth, u32 glo_cfg) -+{ -+ unsigned long flags; -+ u32 val; -+ int i; -+ -+ /* stop the dma engine */ -+ spin_lock_irqsave(ð->page_lock, flags); -+ val = mtk_r32(eth, glo_cfg); -+ mtk_w32(eth, val & ~(MTK_TX_WB_DDONE | MTK_RX_DMA_EN | MTK_TX_DMA_EN), -+ glo_cfg); -+ spin_unlock_irqrestore(ð->page_lock, flags); -+ -+ /* wait for dma stop */ -+ for (i = 0; i < 10; i++) { -+ val = mtk_r32(eth, glo_cfg); -+ if (val & (MTK_TX_DMA_BUSY | MTK_RX_DMA_BUSY)) { -+ msleep(20); -+ continue; -+ } -+ break; -+ } -+} -+ -+static int mtk_stop(struct net_device *dev) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_eth *eth = mac->hw; -+ -+ netif_tx_disable(dev); -+ phy_stop(mac->phy_dev); -+ -+ /* only shutdown DMA if this is the last user */ -+ if (!atomic_dec_and_test(ð->dma_refcnt)) -+ return 0; -+ -+ mtk_irq_disable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT); -+ napi_disable(ð->rx_napi); -+ -+ mtk_stop_dma(eth, MTK_QDMA_GLO_CFG); -+ -+ mtk_dma_free(eth); -+ -+ return 0; -+} -+ -+static int __init mtk_hw_init(struct mtk_eth *eth) -+{ -+ int err, i; -+ -+ /* reset the frame engine */ -+ reset_control_assert(eth->rstc); -+ usleep_range(10, 20); -+ reset_control_deassert(eth->rstc); -+ usleep_range(10, 20); -+ -+ /* Set GE2 driving and slew rate */ -+ regmap_write(eth->pctl, GPIO_DRV_SEL10, 0xa00); -+ -+ /* set GE2 TDSEL */ -+ regmap_write(eth->pctl, GPIO_OD33_CTRL8, 0x5); -+ -+ /* set GE2 TUNE */ -+ regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0); -+ -+ /* GE1, Force 1000M/FD, FC ON */ -+ mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(0)); -+ -+ /* GE2, Force 1000M/FD, FC ON */ -+ mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(1)); -+ -+ /* Enable RX VLan Offloading */ -+ mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); -+ -+ err = devm_request_irq(eth->dev, eth->irq, mtk_handle_irq, 0, -+ dev_name(eth->dev), eth); -+ if (err) -+ return err; -+ -+ err = mtk_mdio_init(eth); -+ if (err) -+ return err; -+ -+ /* disable delay and normal interrupt */ -+ mtk_w32(eth, 0, MTK_QDMA_DELAY_INT); -+ mtk_irq_disable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT); -+ mtk_w32(eth, RST_GL_PSE, MTK_RST_GL); -+ mtk_w32(eth, 0, MTK_RST_GL); -+ -+ /* FE int grouping */ -+ mtk_w32(eth, 0, MTK_FE_INT_GRP); -+ -+ for (i = 0; i < 2; i++) { -+ u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i)); -+ -+ /* setup the forward port to send frame to QDMA */ -+ val &= ~0xffff; -+ val |= 0x5555; -+ -+ /* Enable RX checksum */ -+ val |= MTK_GDMA_ICS_EN | MTK_GDMA_TCS_EN | MTK_GDMA_UCS_EN; -+ -+ /* setup the mac dma */ -+ mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i)); -+ } -+ -+ return 0; -+} -+ -+static int __init mtk_init(struct net_device *dev) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_eth *eth = mac->hw; -+ const char *mac_addr; -+ -+ mac_addr = of_get_mac_address(mac->of_node); -+ if (mac_addr) -+ ether_addr_copy(dev->dev_addr, mac_addr); -+ -+ /* If the mac address is invalid, use random mac address */ -+ if (!is_valid_ether_addr(dev->dev_addr)) { -+ random_ether_addr(dev->dev_addr); -+ dev_err(eth->dev, "generated random MAC address %pM\n", -+ dev->dev_addr); -+ dev->addr_assign_type = NET_ADDR_RANDOM; -+ } -+ -+ return mtk_phy_connect(mac); -+} -+ -+static void mtk_uninit(struct net_device *dev) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_eth *eth = mac->hw; -+ -+ phy_disconnect(mac->phy_dev); -+ mtk_mdio_cleanup(eth); -+ mtk_irq_disable(eth, ~0); -+ free_irq(dev->irq, dev); -+} -+ -+static int mtk_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ -+ switch (cmd) { -+ case SIOCGMIIPHY: -+ case SIOCGMIIREG: -+ case SIOCSMIIREG: -+ return phy_mii_ioctl(mac->phy_dev, ifr, cmd); -+ default: -+ break; -+ } -+ -+ return -EOPNOTSUPP; -+} -+ -+static void mtk_pending_work(struct work_struct *work) -+{ -+ struct mtk_mac *mac = container_of(work, struct mtk_mac, pending_work); -+ struct mtk_eth *eth = mac->hw; -+ struct net_device *dev = eth->netdev[mac->id]; -+ int err; -+ -+ rtnl_lock(); -+ mtk_stop(dev); -+ -+ err = mtk_open(dev); -+ if (err) { -+ netif_alert(eth, ifup, dev, -+ "Driver up/down cycle failed, closing device.\n"); -+ dev_close(dev); -+ } -+ rtnl_unlock(); -+} -+ -+static int mtk_cleanup(struct mtk_eth *eth) -+{ -+ int i; -+ -+ for (i = 0; i < MTK_MAC_COUNT; i++) { -+ struct mtk_mac *mac = netdev_priv(eth->netdev[i]); -+ -+ if (!eth->netdev[i]) -+ continue; -+ -+ unregister_netdev(eth->netdev[i]); -+ free_netdev(eth->netdev[i]); -+ cancel_work_sync(&mac->pending_work); -+ } -+ -+ return 0; -+} -+ -+static int mtk_get_settings(struct net_device *dev, -+ struct ethtool_cmd *cmd) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ int err; -+ -+ err = phy_read_status(mac->phy_dev); -+ if (err) -+ return -ENODEV; -+ -+ return phy_ethtool_gset(mac->phy_dev, cmd); -+} -+ -+static int mtk_set_settings(struct net_device *dev, -+ struct ethtool_cmd *cmd) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ -+ if (cmd->phy_address != mac->phy_dev->mdio.addr) { -+ mac->phy_dev = mdiobus_get_phy(mac->hw->mii_bus, -+ cmd->phy_address); -+ if (!mac->phy_dev) -+ return -ENODEV; -+ } -+ -+ return phy_ethtool_sset(mac->phy_dev, cmd); -+} -+ -+static void mtk_get_drvinfo(struct net_device *dev, -+ struct ethtool_drvinfo *info) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ -+ strlcpy(info->driver, mac->hw->dev->driver->name, sizeof(info->driver)); -+ strlcpy(info->bus_info, dev_name(mac->hw->dev), sizeof(info->bus_info)); -+ info->n_stats = ARRAY_SIZE(mtk_ethtool_stats); -+} -+ -+static u32 mtk_get_msglevel(struct net_device *dev) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ -+ return mac->hw->msg_enable; -+} -+ -+static void mtk_set_msglevel(struct net_device *dev, u32 value) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ -+ mac->hw->msg_enable = value; -+} -+ -+static int mtk_nway_reset(struct net_device *dev) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ -+ return genphy_restart_aneg(mac->phy_dev); -+} -+ -+static u32 mtk_get_link(struct net_device *dev) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ int err; -+ -+ err = genphy_update_link(mac->phy_dev); -+ if (err) -+ return ethtool_op_get_link(dev); -+ -+ return mac->phy_dev->link; -+} -+ -+static void mtk_get_strings(struct net_device *dev, u32 stringset, u8 *data) -+{ -+ int i; -+ -+ switch (stringset) { -+ case ETH_SS_STATS: -+ for (i = 0; i < ARRAY_SIZE(mtk_ethtool_stats); i++) { -+ memcpy(data, mtk_ethtool_stats[i].str, ETH_GSTRING_LEN); -+ data += ETH_GSTRING_LEN; -+ } -+ break; -+ } -+} -+ -+static int mtk_get_sset_count(struct net_device *dev, int sset) -+{ -+ switch (sset) { -+ case ETH_SS_STATS: -+ return ARRAY_SIZE(mtk_ethtool_stats); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static void mtk_get_ethtool_stats(struct net_device *dev, -+ struct ethtool_stats *stats, u64 *data) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_hw_stats *hwstats = mac->hw_stats; -+ u64 *data_src, *data_dst; -+ unsigned int start; -+ int i; -+ -+ if (netif_running(dev) && netif_device_present(dev)) { -+ if (spin_trylock(&hwstats->stats_lock)) { -+ mtk_stats_update_mac(mac); -+ spin_unlock(&hwstats->stats_lock); -+ } -+ } -+ -+ do { -+ data_src = (u64*)hwstats; -+ data_dst = data; -+ start = u64_stats_fetch_begin_irq(&hwstats->syncp); -+ -+ for (i = 0; i < ARRAY_SIZE(mtk_ethtool_stats); i++) -+ *data_dst++ = *(data_src + mtk_ethtool_stats[i].offset); -+ } while (u64_stats_fetch_retry_irq(&hwstats->syncp, start)); -+} -+ -+static struct ethtool_ops mtk_ethtool_ops = { -+ .get_settings = mtk_get_settings, -+ .set_settings = mtk_set_settings, -+ .get_drvinfo = mtk_get_drvinfo, -+ .get_msglevel = mtk_get_msglevel, -+ .set_msglevel = mtk_set_msglevel, -+ .nway_reset = mtk_nway_reset, -+ .get_link = mtk_get_link, -+ .get_strings = mtk_get_strings, -+ .get_sset_count = mtk_get_sset_count, -+ .get_ethtool_stats = mtk_get_ethtool_stats, -+}; -+ -+static const struct net_device_ops mtk_netdev_ops = { -+ .ndo_init = mtk_init, -+ .ndo_uninit = mtk_uninit, -+ .ndo_open = mtk_open, -+ .ndo_stop = mtk_stop, -+ .ndo_start_xmit = mtk_start_xmit, -+ .ndo_set_mac_address = mtk_set_mac_address, -+ .ndo_validate_addr = eth_validate_addr, -+ .ndo_do_ioctl = mtk_do_ioctl, -+ .ndo_change_mtu = eth_change_mtu, -+ .ndo_tx_timeout = mtk_tx_timeout, -+ .ndo_get_stats64 = mtk_get_stats64, -+#ifdef CONFIG_NET_POLL_CONTROLLER -+ .ndo_poll_controller = mtk_poll_controller, -+#endif -+}; -+ -+static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) -+{ -+ struct mtk_mac *mac; -+ const __be32 *_id = of_get_property(np, "reg", NULL); -+ int id, err; -+ -+ if (!_id) { -+ dev_err(eth->dev, "missing mac id\n"); -+ return -EINVAL; -+ } -+ -+ id = be32_to_cpup(_id); -+ if (id >= MTK_MAC_COUNT) { -+ dev_err(eth->dev, "%d is not a valid mac id\n", id); -+ return -EINVAL; -+ } -+ -+ if (eth->netdev[id]) { -+ dev_err(eth->dev, "duplicate mac id found: %d\n", id); -+ return -EINVAL; -+ } -+ -+ eth->netdev[id] = alloc_etherdev(sizeof(*mac)); -+ if (!eth->netdev[id]) { -+ dev_err(eth->dev, "alloc_etherdev failed\n"); -+ return -ENOMEM; -+ } -+ mac = netdev_priv(eth->netdev[id]); -+ eth->mac[id] = mac; -+ mac->id = id; -+ mac->hw = eth; -+ mac->of_node = np; -+ INIT_WORK(&mac->pending_work, mtk_pending_work); -+ -+ mac->hw_stats = devm_kzalloc(eth->dev, -+ sizeof(*mac->hw_stats), -+ GFP_KERNEL); -+ if (!mac->hw_stats) { -+ dev_err(eth->dev, "failed to allocate counter memory\n"); -+ err = -ENOMEM; -+ goto free_netdev; -+ } -+ spin_lock_init(&mac->hw_stats->stats_lock); -+ mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET; -+ -+ SET_NETDEV_DEV(eth->netdev[id], eth->dev); -+ eth->netdev[id]->netdev_ops = &mtk_netdev_ops; -+ eth->netdev[id]->base_addr = (unsigned long)eth->base; -+ eth->netdev[id]->vlan_features = MTK_HW_FEATURES & -+ ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX); -+ eth->netdev[id]->features |= MTK_HW_FEATURES; -+ eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops; -+ -+ err = register_netdev(eth->netdev[id]); -+ if (err) { -+ dev_err(eth->dev, "error bringing up device\n"); -+ goto free_netdev; -+ } -+ eth->netdev[id]->irq = eth->irq; -+ netif_info(eth, probe, eth->netdev[id], -+ "mediatek frame engine at 0x%08lx, irq %d\n", -+ eth->netdev[id]->base_addr, eth->netdev[id]->irq); -+ -+ return 0; -+ -+free_netdev: -+ free_netdev(eth->netdev[id]); -+ return err; -+} -+ -+static int mtk_probe(struct platform_device *pdev) -+{ -+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ struct device_node *mac_np; -+ const struct of_device_id *match; -+ struct mtk_soc_data *soc; -+ struct mtk_eth *eth; -+ int err; -+ -+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); -+ pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; -+ -+ device_reset(&pdev->dev); -+ -+ match = of_match_device(of_mtk_match, &pdev->dev); -+ soc = (struct mtk_soc_data *)match->data; -+ -+ eth = devm_kzalloc(&pdev->dev, sizeof(*eth), GFP_KERNEL); -+ if (!eth) -+ return -ENOMEM; -+ -+ eth->base = devm_ioremap_resource(&pdev->dev, res); -+ if (!eth->base) -+ return -EADDRNOTAVAIL; -+ -+ spin_lock_init(ð->page_lock); -+ -+ eth->ethsys = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, -+ "mediatek,ethsys"); -+ if (IS_ERR(eth->ethsys)) { -+ dev_err(&pdev->dev, "no ethsys regmap found\n"); -+ return PTR_ERR(eth->ethsys); -+ } -+ -+ eth->pctl = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, -+ "mediatek,pctl"); -+ if (IS_ERR(eth->pctl)) { -+ dev_err(&pdev->dev, "no pctl regmap found\n"); -+ return PTR_ERR(eth->pctl); -+ } -+ -+ eth->rstc = devm_reset_control_get(&pdev->dev, "eth"); -+ if (IS_ERR(eth->rstc)) { -+ dev_err(&pdev->dev, "no eth reset found\n"); -+ return PTR_ERR(eth->rstc); -+ } -+ -+ eth->irq = platform_get_irq(pdev, 0); -+ if (eth->irq < 0) { -+ dev_err(&pdev->dev, "no IRQ resource found\n"); -+ return -ENXIO; -+ } -+ -+ eth->clk_ethif = devm_clk_get(&pdev->dev, "ethif"); -+ eth->clk_esw = devm_clk_get(&pdev->dev, "esw"); -+ eth->clk_gp1 = devm_clk_get(&pdev->dev, "gp1"); -+ eth->clk_gp2 = devm_clk_get(&pdev->dev, "gp2"); -+ if (IS_ERR(eth->clk_esw) || IS_ERR(eth->clk_gp1) || -+ IS_ERR(eth->clk_gp2) || IS_ERR(eth->clk_ethif)) -+ return -ENODEV; -+ -+ clk_prepare_enable(eth->clk_ethif); -+ clk_prepare_enable(eth->clk_esw); -+ clk_prepare_enable(eth->clk_gp1); -+ clk_prepare_enable(eth->clk_gp2); -+ -+ eth->dev = &pdev->dev; -+ eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE); -+ -+ err = mtk_hw_init(eth); -+ if (err) -+ return err; -+ -+ for_each_child_of_node(pdev->dev.of_node, mac_np) { -+ if (!of_device_is_compatible(mac_np, -+ "mediatek,eth-mac")) -+ continue; -+ -+ if (!of_device_is_available(mac_np)) -+ continue; -+ -+ err = mtk_add_mac(eth, mac_np); -+ if (err) -+ goto err_free_dev; -+ } -+ -+ /* we run 2 devices on the same DMA ring so we need a dummy device -+ * for NAPI to work -+ */ -+ init_dummy_netdev(ð->dummy_dev); -+ netif_napi_add(ð->dummy_dev, ð->rx_napi, mtk_poll, -+ MTK_NAPI_WEIGHT); -+ -+ platform_set_drvdata(pdev, eth); -+ -+ return 0; -+ -+err_free_dev: -+ mtk_cleanup(eth); -+ return err; -+} -+ -+static int mtk_remove(struct platform_device *pdev) -+{ -+ struct mtk_eth *eth = platform_get_drvdata(pdev); -+ -+ clk_disable_unprepare(eth->clk_ethif); -+ clk_disable_unprepare(eth->clk_esw); -+ clk_disable_unprepare(eth->clk_gp1); -+ clk_disable_unprepare(eth->clk_gp2); -+ -+ netif_napi_del(ð->rx_napi); -+ mtk_cleanup(eth); -+ platform_set_drvdata(pdev, NULL); -+ -+ return 0; -+} -+ -+const struct of_device_id of_mtk_match[] = { -+ { .compatible = "mediatek,mt2701-eth" }, -+ {}, -+}; -+ -+static struct platform_driver mtk_driver = { -+ .probe = mtk_probe, -+ .remove = mtk_remove, -+ .driver = { -+ .name = "mtk_soc_eth", -+ .owner = THIS_MODULE, -+ .of_match_table = of_mtk_match, -+ }, -+}; -+ -+module_platform_driver(mtk_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("John Crispin "); -+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 -+ * Copyright (C) 2009-2016 Felix Fietkau -+ * Copyright (C) 2013-2016 Michael Lee -+ */ -+ -+#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 index 0c7a89e622..0000000000 --- a/target/linux/mediatek/patches-4.4/0050-net-next-mediatek-add-Kconfig-and-Makefile.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 31e907e5c3c2fc1c94d005bfccdd4a32b5a05f82 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index 10690b25ef..0000000000 --- a/target/linux/mediatek/patches-4.4/0051-net-next-mediatek-add-an-entry-to-MAINTAINERS.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 514e4ce65a5f1b5bfa3cbca153f672844f093f0e Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Signed-off-by: John Crispin ---- - 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 -+M: John Crispin -+L: netdev@vger.kernel.org -+S: Maintained -+F: drivers/net/ethernet/mediatek/ -+ - MEDIATEK MT7601U WIRELESS LAN DRIVER - M: Jakub Kicinski - 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 index 87e4a54ed3..0000000000 --- a/target/linux/mediatek/patches-4.4/0052-clk-dont-disable-unused-clocks.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 5238c5d1d38661955ed3b52f45c46e00bfc9eb6e Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 7 Apr 2016 07:18:35 +0200 -Subject: [PATCH 052/102] clk: dont disable unused clocks - -Signed-off-by: John Crispin ---- - 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 index 39939001f1..0000000000 --- a/target/linux/mediatek/patches-4.4/0053-clk-mediatek-enable-critical-clocks.patch +++ /dev/null @@ -1,69 +0,0 @@ -From c8fd103d6c07af5db47f061b70759b7c69169656 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 31 Mar 2016 06:46:51 +0200 -Subject: [PATCH 053/102] clk: mediatek: enable critical clocks - -Signed-off-by: John Crispin ---- - 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 index d5af5f0c82..0000000000 --- a/target/linux/mediatek/patches-4.4/0054-clk-mediatek-Export-CPU-mux-clocks-for-CPU-frequency.patch +++ /dev/null @@ -1,287 +0,0 @@ -From 1387d4f0ebf4b48c09f2ea0d27a02936c3fa0010 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 -+ * -+ * 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 -+#include -+#include -+ -+#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 -+ * -+ * 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 - -@@ -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 - -@@ -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 index 8b476361ff..0000000000 --- a/target/linux/mediatek/patches-4.4/0055-cpufreq-mediatek-add-driver.patch +++ /dev/null @@ -1,433 +0,0 @@ -From 60f4e41b367bdb29530468c91c1e613b17a37755 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Wed, 30 Mar 2016 23:48:53 +0200 -Subject: [PATCH 055/102] cpufreq: mediatek: add driver - -Signed-off-by: John Crispin ---- - 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 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 index fe81b47290..0000000000 --- a/target/linux/mediatek/patches-4.4/0056-arm-mediatek-make-a7-timer-work-Signed-off-by-John-C.patch +++ /dev/null @@ -1,31 +0,0 @@ -From f8cda0bc698706413b5dd6fde827f9a2601ac61b Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 31 Mar 2016 06:07:01 +0200 -Subject: [PATCH 056/102] arm: mediatek: make a7 timer work Signed-off-by: - John Crispin - ---- - 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 index f00e9682bc..0000000000 --- a/target/linux/mediatek/patches-4.4/0057-net-mediatek-checking-for-IS_ERR-instead-of-NULL.patch +++ /dev/null @@ -1,27 +0,0 @@ -From b9f9b937dd12dc57bd54a6c89b18eb40d4508424 Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -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 ---- - 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 index a3f861b72c..0000000000 --- a/target/linux/mediatek/patches-4.4/0058-net-mediatek-unlock-on-error-in-mtk_tx_map.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 6c12340c0c307d18b8d6120f64a8275b6d4d3e67 Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -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 ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -661,6 +661,8 @@ err_dma: - itxd = mtk_qdma_phys_to_virt(ring, itxd->txd2); - } while (itxd != txd); - -+ spin_unlock_irqrestore(ð->page_lock, flags); -+ - return -ENOMEM; - } - 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 index 0dd5f2d29d..0000000000 --- a/target/linux/mediatek/patches-4.4/0059-net-mediatek-use-dma_addr_t-correctly.patch +++ /dev/null @@ -1,30 +0,0 @@ -From a572747434b6153e75812c5466c0557e5ed69284 Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -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 ---- - 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 index d1df7327b1..0000000000 --- a/target/linux/mediatek/patches-4.4/0060-net-mediatek-remove-incorrect-dma_mask-assignment.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 8473af12d5aa34613070447d6fd8f785f31301de Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -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 ---- - 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 index ebc6d9b361..0000000000 --- a/target/linux/mediatek/patches-4.4/0061-net-mediatek-check-device_reset-return-code.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 99159791184752ece724b741f9fa6334fdc67123 Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -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 ---- - 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 index ca2e791a37..0000000000 --- a/target/linux/mediatek/patches-4.4/0062-net-mediatek-watchdog_timeo-was-not-set.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 387257cbd6f3f92de71e2f578d3a9414d0dada27 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index a81f165980..0000000000 --- a/target/linux/mediatek/patches-4.4/0063-net-mediatek-mtk_cal_txd_req-returns-bad-value.patch +++ /dev/null @@ -1,25 +0,0 @@ -From d8f3e96943334c91ecc0827ed0d3232068c389e6 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index 434a6e38ed..0000000000 --- a/target/linux/mediatek/patches-4.4/0064-net-mediatek-remove-superflous-reset-call.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 2597d2cedba62b2a3fdca9c044187705f98a0372 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index 1660e4204d..0000000000 --- a/target/linux/mediatek/patches-4.4/0065-net-mediatek-fix-stop-and-wakeup-of-queue.patch +++ /dev/null @@ -1,84 +0,0 @@ -From afc838dde560ab584d3fb0e4b011e4a6770dab3d Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index b233578106..0000000000 --- a/target/linux/mediatek/patches-4.4/0066-net-mediatek-fix-mtk_pending_work.patch +++ /dev/null @@ -1,58 +0,0 @@ -From e2cc73e6ddb0cc39b8f58654a449651a621916a9 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index d750de6af1..0000000000 --- a/target/linux/mediatek/patches-4.4/0067-net-mediatek-fix-TX-locking.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 6f152b2bdb295d86beb746494ef6fddf17986f8e Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 20 ++++++++++---------- - 1 file changed, 10 insertions(+), 10 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -536,7 +536,6 @@ static int mtk_tx_map(struct sk_buff *sk - struct mtk_eth *eth = mac->hw; - struct mtk_tx_dma *itxd, *txd; - struct mtk_tx_buf *tx_buf; -- unsigned long flags; - dma_addr_t mapped_addr; - unsigned int nr_frags; - int i, n_desc = 1; -@@ -568,11 +567,6 @@ static int mtk_tx_map(struct sk_buff *sk - if (unlikely(dma_mapping_error(&dev->dev, mapped_addr))) - return -ENOMEM; - -- /* normally we can rely on the stack not calling this more than once, -- * however we have 2 queues running ont he same ring so we need to lock -- * the ring access -- */ -- spin_lock_irqsave(ð->page_lock, flags); - WRITE_ONCE(itxd->txd1, mapped_addr); - tx_buf->flags |= MTK_TX_FLAGS_SINGLE0; - dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr); -@@ -632,8 +626,6 @@ static int mtk_tx_map(struct sk_buff *sk - WRITE_ONCE(itxd->txd3, (TX_DMA_SWC | TX_DMA_PLEN0(skb_headlen(skb)) | - (!nr_frags * TX_DMA_LS0))); - -- spin_unlock_irqrestore(ð->page_lock, flags); -- - netdev_sent_queue(dev, skb->len); - skb_tx_timestamp(skb); - -@@ -661,8 +653,6 @@ err_dma: - itxd = mtk_qdma_phys_to_virt(ring, itxd->txd2); - } while (itxd != txd); - -- spin_unlock_irqrestore(ð->page_lock, flags); -- - return -ENOMEM; - } - -@@ -712,14 +702,22 @@ static int mtk_start_xmit(struct sk_buff - struct mtk_eth *eth = mac->hw; - struct mtk_tx_ring *ring = ð->tx_ring; - struct net_device_stats *stats = &dev->stats; -+ unsigned long flags; - bool gso = false; - int tx_num; - -+ /* normally we can rely on the stack not calling this more than once, -+ * however we have 2 queues running ont he same ring so we need to lock -+ * the ring access -+ */ -+ spin_lock_irqsave(ð->page_lock, flags); -+ - tx_num = mtk_cal_txd_req(skb); - if (unlikely(atomic_read(&ring->free_count) <= tx_num)) { - mtk_stop_queue(eth); - netif_err(eth, tx_queued, dev, - "Tx Ring full when queue awake!\n"); -+ spin_unlock_irqrestore(ð->page_lock, flags); - return NETDEV_TX_BUSY; - } - -@@ -747,10 +745,12 @@ static int mtk_start_xmit(struct sk_buff - ring->thresh)) - mtk_wake_queue(eth); - } -+ spin_unlock_irqrestore(ð->page_lock, flags); - - return NETDEV_TX_OK; - - drop: -+ spin_unlock_irqrestore(ð->page_lock, flags); - stats->tx_dropped++; - dev_kfree_skb(skb); - return NETDEV_TX_OK; 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 index 497309144c..0000000000 --- a/target/linux/mediatek/patches-4.4/0068-net-mediatek-move-the-pending_work-struct-to-the-dev.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 29bc7a1e374425937b5dd2f316dbeef343d4c68a Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 10 ++++------ - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++-- - 2 files changed, 6 insertions(+), 8 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1193,7 +1193,7 @@ static void mtk_tx_timeout(struct net_de - eth->netdev[mac->id]->stats.tx_errors++; - netif_err(eth, tx_err, dev, - "transmit timed out\n"); -- schedule_work(&mac->pending_work); -+ schedule_work(ð->pending_work); - } - - static irqreturn_t mtk_handle_irq(int irq, void *_eth) -@@ -1438,7 +1438,7 @@ static void mtk_pending_work(struct work - - /* stop all devices to make sure that dma is properly shut down */ - for (i = 0; i < MTK_MAC_COUNT; i++) { -- if (!netif_oper_up(eth->netdev[i])) -+ if (!eth->netdev[i]) - continue; - mtk_stop(eth->netdev[i]); - __set_bit(i, &restart); -@@ -1464,15 +1464,13 @@ static int mtk_cleanup(struct mtk_eth *e - int i; - - for (i = 0; i < MTK_MAC_COUNT; i++) { -- struct mtk_mac *mac = netdev_priv(eth->netdev[i]); -- - if (!eth->netdev[i]) - continue; - - unregister_netdev(eth->netdev[i]); - free_netdev(eth->netdev[i]); -- cancel_work_sync(&mac->pending_work); - } -+ cancel_work_sync(ð->pending_work); - - return 0; - } -@@ -1660,7 +1658,6 @@ static int mtk_add_mac(struct mtk_eth *e - mac->id = id; - mac->hw = eth; - mac->of_node = np; -- INIT_WORK(&mac->pending_work, mtk_pending_work); - - mac->hw_stats = devm_kzalloc(eth->dev, - sizeof(*mac->hw_stats), -@@ -1762,6 +1759,7 @@ static int mtk_probe(struct platform_dev - - eth->dev = &pdev->dev; - eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE); -+ INIT_WORK(ð->pending_work, mtk_pending_work); - - err = mtk_hw_init(eth); - if (err) ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -363,6 +363,7 @@ struct mtk_rx_ring { - * @clk_gp1: The gmac1 clock - * @clk_gp2: The gmac2 clock - * @mii_bus: If there is a bus we need to create an instance for it -+ * @pending_work: The workqueue used to reset the dma ring - */ - - struct mtk_eth { -@@ -389,6 +390,7 @@ struct mtk_eth { - struct clk *clk_gp1; - struct clk *clk_gp2; - struct mii_bus *mii_bus; -+ struct work_struct pending_work; - }; - - /* struct mtk_mac - the structure that holds the info about the MACs of the -@@ -398,7 +400,6 @@ struct mtk_eth { - * @hw: Backpointer to our main datastruture - * @hw_stats: Packet statistics counter - * @phy_dev: The attached PHY if available -- * @pending_work: The workqueue used to reset the dma ring - */ - struct mtk_mac { - int id; -@@ -406,7 +407,6 @@ struct mtk_mac { - struct mtk_eth *hw; - struct mtk_hw_stats *hw_stats; - struct phy_device *phy_dev; -- struct work_struct pending_work; - }; - - /* the struct describing the SoC. these are declared in the soc_xyz.c files */ 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 index 72f96e2174..0000000000 --- a/target/linux/mediatek/patches-4.4/0069-net-mediatek-do-not-set-the-QID-field-in-the-TX-DMA-.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 4742349c1595d38b3e3b463e66cf21af4217c869 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index afb01748f1..0000000000 --- a/target/linux/mediatek/patches-4.4/0070-net-mediatek-update-the-IRQ-part-of-the-binding-docu.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 297ef52cd21e28da671996d7b4f39f268d2d0ec1 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 - Acked-by: Rob Herring ---- - Documentation/devicetree/bindings/net/mediatek-net.txt | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - ---- a/Documentation/devicetree/bindings/net/mediatek-net.txt -+++ b/Documentation/devicetree/bindings/net/mediatek-net.txt -@@ -9,7 +9,8 @@ have dual GMAC each represented by a chi - Required properties: - - compatible: Should be "mediatek,mt2701-eth" - - reg: Address and length of the register set for the device --- interrupts: Should contain the frame engines interrupt -+- interrupts: Should contain the three frame engines interrupts in numeric -+ order. These are fe_int0, fe_int1 and fe_int2. - - clocks: the clock used by the core - - clock-names: the names of the clock listed in the clocks property. These are - "ethif", "esw", "gp2", "gp1" -@@ -42,7 +43,9 @@ eth: ethernet@1b100000 { - <ðsys CLK_ETHSYS_GP2>, - <ðsys CLK_ETHSYS_GP1>; - clock-names = "ethif", "esw", "gp2", "gp1"; -- interrupts = ; -+ interrupts = ; - power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; - resets = <ðsys 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 index 8ca6c491e9..0000000000 --- a/target/linux/mediatek/patches-4.4/0071-pwm-add-pwm-mediatek.patch +++ /dev/null @@ -1,337 +0,0 @@ -From 6f5941c93bdf7649f392f1263b9068d360ceab4d Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 6 May 2016 02:55:48 +0200 -Subject: [PATCH 071/102] pwm: add pwm-mediatek - -Signed-off-by: John Crispin ---- - 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 = ; -+ }; -+ -+ pins_pwm2 { -+ pinmux = ; -+ }; -+ }; -+ - }; - - &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 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 "); -+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 index b45d3aa579..0000000000 --- a/target/linux/mediatek/patches-4.4/0072-mtd-backport-v4.7-0day-patches-from-Boris.patch +++ /dev/null @@ -1,5286 +0,0 @@ -From a369af5149e6eb442b22ce89b564dd7a76e03638 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 - #include - #include -+#include - #include - #include - #include -@@ -446,6 +447,7 @@ int add_mtd_device(struct mtd_info *mtd) - mtd->dev.devt = MTD_DEVT(i); - dev_set_name(&mtd->dev, "mtd%d", i); - dev_set_drvdata(&mtd->dev, mtd); -+ of_node_get(mtd_get_of_node(mtd)); - error = device_register(&mtd->dev); - if (error) - goto fail_added; -@@ -477,6 +479,7 @@ int add_mtd_device(struct mtd_info *mtd) - return 0; - - fail_added: -+ of_node_put(mtd_get_of_node(mtd)); - idr_remove(&mtd_idr, i); - fail_locked: - mutex_unlock(&mtd_table_mutex); -@@ -518,6 +521,7 @@ int del_mtd_device(struct mtd_info *mtd) - device_unregister(&mtd->dev); - - idr_remove(&mtd_idr, mtd->index); -+ of_node_put(mtd_get_of_node(mtd)); - - module_put(THIS_MODULE); - ret = 0; -@@ -529,9 +533,10 @@ out_error: - } - - static int mtd_add_device_partitions(struct mtd_info *mtd, -- struct mtd_partition *real_parts, -- int nbparts) -+ struct mtd_partitions *parts) - { -+ const struct mtd_partition *real_parts = parts->parts; -+ int nbparts = parts->nr_parts; - int ret; - - if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) { -@@ -600,29 +605,29 @@ int mtd_device_parse_register(struct mtd - const struct mtd_partition *parts, - int nr_parts) - { -+ struct mtd_partitions parsed; - int ret; -- struct mtd_partition *real_parts = NULL; - - mtd_set_dev_defaults(mtd); - -- ret = parse_mtd_partitions(mtd, types, &real_parts, parser_data); -- if (ret <= 0 && nr_parts && parts) { -- real_parts = kmemdup(parts, sizeof(*parts) * nr_parts, -- GFP_KERNEL); -- if (!real_parts) -- ret = -ENOMEM; -- else -- ret = nr_parts; -- } -- /* Didn't come up with either parsed OR fallback partitions */ -- if (ret < 0) { -- pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n", -+ memset(&parsed, 0, sizeof(parsed)); -+ -+ ret = parse_mtd_partitions(mtd, types, &parsed, parser_data); -+ if ((ret < 0 || parsed.nr_parts == 0) && parts && nr_parts) { -+ /* Fall back to driver-provided partitions */ -+ parsed = (struct mtd_partitions){ -+ .parts = parts, -+ .nr_parts = nr_parts, -+ }; -+ } else if (ret < 0) { -+ /* Didn't come up with parsed OR fallback partitions */ -+ pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n", - ret); - /* Don't abort on errors; we can still use unpartitioned MTD */ -- ret = 0; -+ memset(&parsed, 0, sizeof(parsed)); - } - -- ret = mtd_add_device_partitions(mtd, real_parts, ret); -+ ret = mtd_add_device_partitions(mtd, &parsed); - if (ret) - goto out; - -@@ -642,7 +647,8 @@ int mtd_device_parse_register(struct mtd - } - - out: -- kfree(real_parts); -+ /* Cleanup any parsed partitions */ -+ mtd_part_parser_cleanup(&parsed); - return ret; - } - EXPORT_SYMBOL_GPL(mtd_device_parse_register); -@@ -767,7 +773,6 @@ out: - } - EXPORT_SYMBOL_GPL(get_mtd_device); - -- - int __get_mtd_device(struct mtd_info *mtd) - { - int err; -@@ -1001,6 +1006,366 @@ int mtd_read_oob(struct mtd_info *mtd, l - } - EXPORT_SYMBOL_GPL(mtd_read_oob); - -+/** -+ * mtd_ooblayout_ecc - Get the OOB region definition of a specific ECC section -+ * @mtd: MTD device structure -+ * @section: ECC section. Depending on the layout you may have all the ECC -+ * bytes stored in a single contiguous section, or one section -+ * per ECC chunk (and sometime several sections for a single ECC -+ * ECC chunk) -+ * @oobecc: OOB region struct filled with the appropriate ECC position -+ * information -+ * -+ * This functions return ECC section information in the OOB area. I you want -+ * to get all the ECC bytes information, then you should call -+ * mtd_ooblayout_ecc(mtd, section++, oobecc) until it returns -ERANGE. -+ * -+ * Returns zero on success, a negative error code otherwise. -+ */ -+int mtd_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobecc) -+{ -+ memset(oobecc, 0, sizeof(*oobecc)); -+ -+ if (!mtd || section < 0) -+ return -EINVAL; -+ -+ if (!mtd->ooblayout || !mtd->ooblayout->ecc) -+ return -ENOTSUPP; -+ -+ return mtd->ooblayout->ecc(mtd, section, oobecc); -+} -+EXPORT_SYMBOL_GPL(mtd_ooblayout_ecc); -+ -+/** -+ * mtd_ooblayout_free - Get the OOB region definition of a specific free -+ * section -+ * @mtd: MTD device structure -+ * @section: Free section you are interested in. Depending on the layout -+ * you may have all the free bytes stored in a single contiguous -+ * section, or one section per ECC chunk plus an extra section -+ * for the remaining bytes (or other funky layout). -+ * @oobfree: OOB region struct filled with the appropriate free position -+ * information -+ * -+ * This functions return free bytes position in the OOB area. I you want -+ * to get all the free bytes information, then you should call -+ * mtd_ooblayout_free(mtd, section++, oobfree) until it returns -ERANGE. -+ * -+ * Returns zero on success, a negative error code otherwise. -+ */ -+int mtd_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobfree) -+{ -+ memset(oobfree, 0, sizeof(*oobfree)); -+ -+ if (!mtd || section < 0) -+ return -EINVAL; -+ -+ if (!mtd->ooblayout || !mtd->ooblayout->free) -+ return -ENOTSUPP; -+ -+ return mtd->ooblayout->free(mtd, section, oobfree); -+} -+EXPORT_SYMBOL_GPL(mtd_ooblayout_free); -+ -+/** -+ * mtd_ooblayout_find_region - Find the region attached to a specific byte -+ * @mtd: mtd info structure -+ * @byte: the byte we are searching for -+ * @sectionp: pointer where the section id will be stored -+ * @oobregion: used to retrieve the ECC position -+ * @iter: iterator function. Should be either mtd_ooblayout_free or -+ * mtd_ooblayout_ecc depending on the region type you're searching for -+ * -+ * This functions returns the section id and oobregion information of a -+ * specific byte. For example, say you want to know where the 4th ECC byte is -+ * stored, you'll use: -+ * -+ * mtd_ooblayout_find_region(mtd, 3, §ion, &oobregion, mtd_ooblayout_ecc); -+ * -+ * Returns zero on success, a negative error code otherwise. -+ */ -+static int mtd_ooblayout_find_region(struct mtd_info *mtd, int byte, -+ int *sectionp, struct mtd_oob_region *oobregion, -+ int (*iter)(struct mtd_info *, -+ int section, -+ struct mtd_oob_region *oobregion)) -+{ -+ int pos = 0, ret, section = 0; -+ -+ memset(oobregion, 0, sizeof(*oobregion)); -+ -+ while (1) { -+ ret = iter(mtd, section, oobregion); -+ if (ret) -+ return ret; -+ -+ if (pos + oobregion->length > byte) -+ break; -+ -+ pos += oobregion->length; -+ section++; -+ } -+ -+ /* -+ * Adjust region info to make it start at the beginning at the -+ * 'start' ECC byte. -+ */ -+ oobregion->offset += byte - pos; -+ oobregion->length -= byte - pos; -+ *sectionp = section; -+ -+ return 0; -+} -+ -+/** -+ * mtd_ooblayout_find_eccregion - Find the ECC region attached to a specific -+ * ECC byte -+ * @mtd: mtd info structure -+ * @eccbyte: the byte we are searching for -+ * @sectionp: pointer where the section id will be stored -+ * @oobregion: OOB region information -+ * -+ * Works like mtd_ooblayout_find_region() except it searches for a specific ECC -+ * byte. -+ * -+ * Returns zero on success, a negative error code otherwise. -+ */ -+int mtd_ooblayout_find_eccregion(struct mtd_info *mtd, int eccbyte, -+ int *section, -+ struct mtd_oob_region *oobregion) -+{ -+ return mtd_ooblayout_find_region(mtd, eccbyte, section, oobregion, -+ mtd_ooblayout_ecc); -+} -+EXPORT_SYMBOL_GPL(mtd_ooblayout_find_eccregion); -+ -+/** -+ * mtd_ooblayout_get_bytes - Extract OOB bytes from the oob buffer -+ * @mtd: mtd info structure -+ * @buf: destination buffer to store OOB bytes -+ * @oobbuf: OOB buffer -+ * @start: first byte to retrieve -+ * @nbytes: number of bytes to retrieve -+ * @iter: section iterator -+ * -+ * Extract bytes attached to a specific category (ECC or free) -+ * from the OOB buffer and copy them into buf. -+ * -+ * Returns zero on success, a negative error code otherwise. -+ */ -+static int mtd_ooblayout_get_bytes(struct mtd_info *mtd, u8 *buf, -+ const u8 *oobbuf, int start, int nbytes, -+ int (*iter)(struct mtd_info *, -+ int section, -+ struct mtd_oob_region *oobregion)) -+{ -+ struct mtd_oob_region oobregion = { }; -+ int section = 0, ret; -+ -+ ret = mtd_ooblayout_find_region(mtd, start, §ion, -+ &oobregion, iter); -+ -+ while (!ret) { -+ int cnt; -+ -+ cnt = oobregion.length > nbytes ? nbytes : oobregion.length; -+ memcpy(buf, oobbuf + oobregion.offset, cnt); -+ buf += cnt; -+ nbytes -= cnt; -+ -+ if (!nbytes) -+ break; -+ -+ ret = iter(mtd, ++section, &oobregion); -+ } -+ -+ return ret; -+} -+ -+/** -+ * mtd_ooblayout_set_bytes - put OOB bytes into the oob buffer -+ * @mtd: mtd info structure -+ * @buf: source buffer to get OOB bytes from -+ * @oobbuf: OOB buffer -+ * @start: first OOB byte to set -+ * @nbytes: number of OOB bytes to set -+ * @iter: section iterator -+ * -+ * Fill the OOB buffer with data provided in buf. The category (ECC or free) -+ * is selected by passing the appropriate iterator. -+ * -+ * Returns zero on success, a negative error code otherwise. -+ */ -+static int mtd_ooblayout_set_bytes(struct mtd_info *mtd, const u8 *buf, -+ u8 *oobbuf, int start, int nbytes, -+ int (*iter)(struct mtd_info *, -+ int section, -+ struct mtd_oob_region *oobregion)) -+{ -+ struct mtd_oob_region oobregion = { }; -+ int section = 0, ret; -+ -+ ret = mtd_ooblayout_find_region(mtd, start, §ion, -+ &oobregion, iter); -+ -+ while (!ret) { -+ int cnt; -+ -+ cnt = oobregion.length > nbytes ? nbytes : oobregion.length; -+ memcpy(oobbuf + oobregion.offset, buf, cnt); -+ buf += cnt; -+ nbytes -= cnt; -+ -+ if (!nbytes) -+ break; -+ -+ ret = iter(mtd, ++section, &oobregion); -+ } -+ -+ return ret; -+} -+ -+/** -+ * mtd_ooblayout_count_bytes - count the number of bytes in a OOB category -+ * @mtd: mtd info structure -+ * @iter: category iterator -+ * -+ * Count the number of bytes in a given category. -+ * -+ * Returns a positive value on success, a negative error code otherwise. -+ */ -+static int mtd_ooblayout_count_bytes(struct mtd_info *mtd, -+ int (*iter)(struct mtd_info *, -+ int section, -+ struct mtd_oob_region *oobregion)) -+{ -+ struct mtd_oob_region oobregion = { }; -+ int section = 0, ret, nbytes = 0; -+ -+ while (1) { -+ ret = iter(mtd, section++, &oobregion); -+ if (ret) { -+ if (ret == -ERANGE) -+ ret = nbytes; -+ break; -+ } -+ -+ nbytes += oobregion.length; -+ } -+ -+ return ret; -+} -+ -+/** -+ * mtd_ooblayout_get_eccbytes - extract ECC bytes from the oob buffer -+ * @mtd: mtd info structure -+ * @eccbuf: destination buffer to store ECC bytes -+ * @oobbuf: OOB buffer -+ * @start: first ECC byte to retrieve -+ * @nbytes: number of ECC bytes to retrieve -+ * -+ * Works like mtd_ooblayout_get_bytes(), except it acts on ECC bytes. -+ * -+ * Returns zero on success, a negative error code otherwise. -+ */ -+int mtd_ooblayout_get_eccbytes(struct mtd_info *mtd, u8 *eccbuf, -+ const u8 *oobbuf, int start, int nbytes) -+{ -+ return mtd_ooblayout_get_bytes(mtd, eccbuf, oobbuf, start, nbytes, -+ mtd_ooblayout_ecc); -+} -+EXPORT_SYMBOL_GPL(mtd_ooblayout_get_eccbytes); -+ -+/** -+ * mtd_ooblayout_set_eccbytes - set ECC bytes into the oob buffer -+ * @mtd: mtd info structure -+ * @eccbuf: source buffer to get ECC bytes from -+ * @oobbuf: OOB buffer -+ * @start: first ECC byte to set -+ * @nbytes: number of ECC bytes to set -+ * -+ * Works like mtd_ooblayout_set_bytes(), except it acts on ECC bytes. -+ * -+ * Returns zero on success, a negative error code otherwise. -+ */ -+int mtd_ooblayout_set_eccbytes(struct mtd_info *mtd, const u8 *eccbuf, -+ u8 *oobbuf, int start, int nbytes) -+{ -+ return mtd_ooblayout_set_bytes(mtd, eccbuf, oobbuf, start, nbytes, -+ mtd_ooblayout_ecc); -+} -+EXPORT_SYMBOL_GPL(mtd_ooblayout_set_eccbytes); -+ -+/** -+ * mtd_ooblayout_get_databytes - extract data bytes from the oob buffer -+ * @mtd: mtd info structure -+ * @databuf: destination buffer to store ECC bytes -+ * @oobbuf: OOB buffer -+ * @start: first ECC byte to retrieve -+ * @nbytes: number of ECC bytes to retrieve -+ * -+ * Works like mtd_ooblayout_get_bytes(), except it acts on free bytes. -+ * -+ * Returns zero on success, a negative error code otherwise. -+ */ -+int mtd_ooblayout_get_databytes(struct mtd_info *mtd, u8 *databuf, -+ const u8 *oobbuf, int start, int nbytes) -+{ -+ return mtd_ooblayout_get_bytes(mtd, databuf, oobbuf, start, nbytes, -+ mtd_ooblayout_free); -+} -+EXPORT_SYMBOL_GPL(mtd_ooblayout_get_databytes); -+ -+/** -+ * mtd_ooblayout_get_eccbytes - set data bytes into the oob buffer -+ * @mtd: mtd info structure -+ * @eccbuf: source buffer to get data bytes from -+ * @oobbuf: OOB buffer -+ * @start: first ECC byte to set -+ * @nbytes: number of ECC bytes to set -+ * -+ * Works like mtd_ooblayout_get_bytes(), except it acts on free bytes. -+ * -+ * Returns zero on success, a negative error code otherwise. -+ */ -+int mtd_ooblayout_set_databytes(struct mtd_info *mtd, const u8 *databuf, -+ u8 *oobbuf, int start, int nbytes) -+{ -+ return mtd_ooblayout_set_bytes(mtd, databuf, oobbuf, start, nbytes, -+ mtd_ooblayout_free); -+} -+EXPORT_SYMBOL_GPL(mtd_ooblayout_set_databytes); -+ -+/** -+ * mtd_ooblayout_count_freebytes - count the number of free bytes in OOB -+ * @mtd: mtd info structure -+ * -+ * Works like mtd_ooblayout_count_bytes(), except it count free bytes. -+ * -+ * Returns zero on success, a negative error code otherwise. -+ */ -+int mtd_ooblayout_count_freebytes(struct mtd_info *mtd) -+{ -+ return mtd_ooblayout_count_bytes(mtd, mtd_ooblayout_free); -+} -+EXPORT_SYMBOL_GPL(mtd_ooblayout_count_freebytes); -+ -+/** -+ * mtd_ooblayout_count_freebytes - count the number of ECC bytes in OOB -+ * @mtd: mtd info structure -+ * -+ * Works like mtd_ooblayout_count_bytes(), except it count ECC bytes. -+ * -+ * Returns zero on success, a negative error code otherwise. -+ */ -+int mtd_ooblayout_count_eccbytes(struct mtd_info *mtd) -+{ -+ return mtd_ooblayout_count_bytes(mtd, mtd_ooblayout_ecc); -+} -+EXPORT_SYMBOL_GPL(mtd_ooblayout_count_eccbytes); -+ - /* - * Method to access the protection register area, present in some flash - * devices. The user data is one time programmable but the factory data is read ---- a/drivers/mtd/mtdcore.h -+++ b/drivers/mtd/mtdcore.h -@@ -10,10 +10,15 @@ int add_mtd_device(struct mtd_info *mtd) - int del_mtd_device(struct mtd_info *mtd); - int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); - int del_mtd_partitions(struct mtd_info *); -+ -+struct mtd_partitions; -+ - int parse_mtd_partitions(struct mtd_info *master, const char * const *types, -- struct mtd_partition **pparts, -+ struct mtd_partitions *pparts, - struct mtd_part_parser_data *data); - -+void mtd_part_parser_cleanup(struct mtd_partitions *parts); -+ - int __init init_mtdchar(void); - void __exit cleanup_mtdchar(void); - ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -55,9 +55,12 @@ static void mtd_partition_split(struct m - - /* - * Given a pointer to the MTD object in the mtd_part structure, we can retrieve -- * the pointer to that structure with this macro. -+ * the pointer to that structure. - */ --#define PART(x) ((struct mtd_part *)(x)) -+static inline struct mtd_part *mtd_to_part(const struct mtd_info *mtd) -+{ -+ return container_of(mtd, struct mtd_part, mtd); -+} - - - /* -@@ -68,7 +71,7 @@ static void mtd_partition_split(struct m - static int part_read(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - struct mtd_ecc_stats stats; - int res; - -@@ -87,7 +90,7 @@ static int part_read(struct mtd_info *mt - static int part_point(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - - return part->master->_point(part->master, from + part->offset, len, - retlen, virt, phys); -@@ -95,7 +98,7 @@ static int part_point(struct mtd_info *m - - static int part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - - return part->master->_unpoint(part->master, from + part->offset, len); - } -@@ -105,7 +108,7 @@ static unsigned long part_get_unmapped_a - unsigned long offset, - unsigned long flags) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - - offset += part->offset; - return part->master->_get_unmapped_area(part->master, len, offset, -@@ -115,7 +118,7 @@ static unsigned long part_get_unmapped_a - static int part_read_oob(struct mtd_info *mtd, loff_t from, - struct mtd_oob_ops *ops) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - int res; - - if (from >= mtd->size) -@@ -130,10 +133,7 @@ static int part_read_oob(struct mtd_info - if (ops->oobbuf) { - size_t len, pages; - -- if (ops->mode == MTD_OPS_AUTO_OOB) -- len = mtd->oobavail; -- else -- len = mtd->oobsize; -+ len = mtd_oobavail(mtd, ops); - pages = mtd_div_by_ws(mtd->size, mtd); - pages -= mtd_div_by_ws(from, mtd); - if (ops->ooboffs + ops->ooblen > pages * len) -@@ -153,7 +153,7 @@ static int part_read_oob(struct mtd_info - static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from, - size_t len, size_t *retlen, u_char *buf) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - return part->master->_read_user_prot_reg(part->master, from, len, - retlen, buf); - } -@@ -161,7 +161,7 @@ static int part_read_user_prot_reg(struc - static int part_get_user_prot_info(struct mtd_info *mtd, size_t len, - size_t *retlen, struct otp_info *buf) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - return part->master->_get_user_prot_info(part->master, len, retlen, - buf); - } -@@ -169,7 +169,7 @@ static int part_get_user_prot_info(struc - static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, - size_t len, size_t *retlen, u_char *buf) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - return part->master->_read_fact_prot_reg(part->master, from, len, - retlen, buf); - } -@@ -177,7 +177,7 @@ static int part_read_fact_prot_reg(struc - static int part_get_fact_prot_info(struct mtd_info *mtd, size_t len, - size_t *retlen, struct otp_info *buf) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - return part->master->_get_fact_prot_info(part->master, len, retlen, - buf); - } -@@ -185,7 +185,7 @@ static int part_get_fact_prot_info(struc - static int part_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - return part->master->_write(part->master, to + part->offset, len, - retlen, buf); - } -@@ -193,7 +193,7 @@ static int part_write(struct mtd_info *m - static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - return part->master->_panic_write(part->master, to + part->offset, len, - retlen, buf); - } -@@ -201,7 +201,7 @@ static int part_panic_write(struct mtd_i - static int part_write_oob(struct mtd_info *mtd, loff_t to, - struct mtd_oob_ops *ops) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - - if (to >= mtd->size) - return -EINVAL; -@@ -213,7 +213,7 @@ static int part_write_oob(struct mtd_inf - static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from, - size_t len, size_t *retlen, u_char *buf) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - return part->master->_write_user_prot_reg(part->master, from, len, - retlen, buf); - } -@@ -221,21 +221,21 @@ static int part_write_user_prot_reg(stru - static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, - size_t len) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - return part->master->_lock_user_prot_reg(part->master, from, len); - } - - static int part_writev(struct mtd_info *mtd, const struct kvec *vecs, - unsigned long count, loff_t to, size_t *retlen) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - return part->master->_writev(part->master, vecs, count, - to + part->offset, retlen); - } - - static int part_erase(struct mtd_info *mtd, struct erase_info *instr) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - int ret; - - -@@ -299,7 +299,7 @@ static int part_erase(struct mtd_info *m - void mtd_erase_callback(struct erase_info *instr) - { - if (instr->mtd->_erase == part_erase) { -- struct mtd_part *part = PART(instr->mtd); -+ struct mtd_part *part = mtd_to_part(instr->mtd); - size_t wrlen = 0; - - if (instr->mtd->flags & MTD_ERASE_PARTIAL) { -@@ -330,13 +330,13 @@ EXPORT_SYMBOL_GPL(mtd_erase_callback); - - static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - return part->master->_lock(part->master, ofs + part->offset, len); - } - - static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - - ofs += part->offset; - if (mtd->flags & MTD_ERASE_PARTIAL) { -@@ -349,45 +349,45 @@ static int part_unlock(struct mtd_info * - - static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - return part->master->_is_locked(part->master, ofs + part->offset, len); - } - - static void part_sync(struct mtd_info *mtd) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - part->master->_sync(part->master); - } - - static int part_suspend(struct mtd_info *mtd) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - return part->master->_suspend(part->master); - } - - static void part_resume(struct mtd_info *mtd) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - part->master->_resume(part->master); - } - - static int part_block_isreserved(struct mtd_info *mtd, loff_t ofs) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - ofs += part->offset; - return part->master->_block_isreserved(part->master, ofs); - } - - static int part_block_isbad(struct mtd_info *mtd, loff_t ofs) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - ofs += part->offset; - return part->master->_block_isbad(part->master, ofs); - } - - static int part_block_markbad(struct mtd_info *mtd, loff_t ofs) - { -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - int res; - - ofs += part->offset; -@@ -397,6 +397,27 @@ static int part_block_markbad(struct mtd - return res; - } - -+static int part_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ struct mtd_part *part = mtd_to_part(mtd); -+ -+ return mtd_ooblayout_ecc(part->master, section, oobregion); -+} -+ -+static int part_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ struct mtd_part *part = mtd_to_part(mtd); -+ -+ return mtd_ooblayout_free(part->master, section, oobregion); -+} -+ -+static const struct mtd_ooblayout_ops part_ooblayout_ops = { -+ .ecc = part_ooblayout_ecc, -+ .free = part_ooblayout_free, -+}; -+ - static inline void free_partition(struct mtd_part *p) - { - kfree(p->mtd.name); -@@ -614,7 +635,7 @@ static struct mtd_part *allocate_partiti - slave->mtd.erasesize = slave->mtd.size; - } - -- slave->mtd.ecclayout = master->ecclayout; -+ mtd_set_ooblayout(&slave->mtd, &part_ooblayout_ops); - slave->mtd.ecc_step_size = master->ecc_step_size; - slave->mtd.ecc_strength = master->ecc_strength; - slave->mtd.bitflip_threshold = master->bitflip_threshold; -@@ -639,7 +660,7 @@ static ssize_t mtd_partition_offset_show - struct device_attribute *attr, char *buf) - { - struct mtd_info *mtd = dev_get_drvdata(dev); -- struct mtd_part *part = PART(mtd); -+ struct mtd_part *part = mtd_to_part(mtd); - return snprintf(buf, PAGE_SIZE, "%lld\n", part->offset); - } - -@@ -677,11 +698,10 @@ int mtd_add_partition(struct mtd_info *m - if (length <= 0) - return -EINVAL; - -+ memset(&part, 0, sizeof(part)); - part.name = name; - part.size = length; - part.offset = offset; -- part.mask_flags = 0; -- part.ecclayout = NULL; - - new = allocate_partition(master, &part, -1, offset); - if (IS_ERR(new)) -@@ -845,7 +865,7 @@ int add_mtd_partitions(struct mtd_info * - static DEFINE_SPINLOCK(part_parser_lock); - static LIST_HEAD(part_parsers); - --static struct mtd_part_parser *get_partition_parser(const char *name) -+static struct mtd_part_parser *mtd_part_parser_get(const char *name) - { - struct mtd_part_parser *p, *ret = NULL; - -@@ -862,7 +882,20 @@ static struct mtd_part_parser *get_parti - return ret; - } - --#define put_partition_parser(p) do { module_put((p)->owner); } while (0) -+static inline void mtd_part_parser_put(const struct mtd_part_parser *p) -+{ -+ module_put(p->owner); -+} -+ -+/* -+ * Many partition parsers just expected the core to kfree() all their data in -+ * one chunk. Do that by default. -+ */ -+static void mtd_part_parser_cleanup_default(const struct mtd_partition *pparts, -+ int nr_parts) -+{ -+ kfree(pparts); -+} - - static struct mtd_part_parser * - get_partition_parser_by_type(enum mtd_parser_type type, -@@ -874,7 +907,7 @@ get_partition_parser_by_type(enum mtd_pa - - p = list_prepare_entry(start, &part_parsers, list); - if (start) -- put_partition_parser(start); -+ mtd_part_parser_put(start); - - list_for_each_entry_continue(p, &part_parsers, list) { - if (p->type == type && try_module_get(p->owner)) { -@@ -888,13 +921,19 @@ get_partition_parser_by_type(enum mtd_pa - return ret; - } - --void register_mtd_parser(struct mtd_part_parser *p) --{ -+int __register_mtd_parser(struct mtd_part_parser *p, struct module *owner) -+ { -+ p->owner = owner; -+ -+ if (!p->cleanup) -+ p->cleanup = &mtd_part_parser_cleanup_default; -+ - spin_lock(&part_parser_lock); - list_add(&p->list, &part_parsers); - spin_unlock(&part_parser_lock); -+ return 0; - } --EXPORT_SYMBOL_GPL(register_mtd_parser); -+EXPORT_SYMBOL_GPL(__register_mtd_parser); - - void deregister_mtd_parser(struct mtd_part_parser *p) - { -@@ -954,7 +993,7 @@ static const char * const default_mtd_pa - * parse_mtd_partitions - parse MTD partitions - * @master: the master partition (describes whole MTD device) - * @types: names of partition parsers to try or %NULL -- * @pparts: array of partitions found is returned here -+ * @pparts: info about partitions found is returned here - * @data: MTD partition parser-specific data - * - * This function tries to find partition on MTD device @master. It uses MTD -@@ -966,45 +1005,42 @@ static const char * const default_mtd_pa - * - * This function may return: - * o a negative error code in case of failure -- * o zero if no partitions were found -- * o a positive number of found partitions, in which case on exit @pparts will -- * point to an array containing this number of &struct mtd_info objects. -+ * o zero otherwise, and @pparts will describe the partitions, number of -+ * partitions, and the parser which parsed them. Caller must release -+ * resources with mtd_part_parser_cleanup() when finished with the returned -+ * data. - */ - int parse_mtd_partitions(struct mtd_info *master, const char *const *types, -- struct mtd_partition **pparts, -+ struct mtd_partitions *pparts, - struct mtd_part_parser_data *data) - { - struct mtd_part_parser *parser; - int ret, err = 0; - const char *const *types_of = NULL; - -- if (data && data->of_node) { -- types_of = of_get_probes(data->of_node); -- if (types_of != NULL) -- types = types_of; -- } -- - if (!types) - types = default_mtd_part_types; - - for ( ; *types; types++) { - pr_debug("%s: parsing partitions %s\n", master->name, *types); -- parser = get_partition_parser(*types); -+ parser = mtd_part_parser_get(*types); - if (!parser && !request_module("%s", *types)) -- parser = get_partition_parser(*types); -+ parser = mtd_part_parser_get(*types); - pr_debug("%s: got parser %s\n", master->name, - parser ? parser->name : NULL); - if (!parser) - continue; -- ret = (*parser->parse_fn)(master, pparts, data); -+ ret = (*parser->parse_fn)(master, &pparts->parts, data); - pr_debug("%s: parser %s: %i\n", - master->name, parser->name, ret); -- put_partition_parser(parser); - if (ret > 0) { - printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", - ret, parser->name, master->name); -- return ret; -+ pparts->nr_parts = ret; -+ pparts->parser = parser; -+ return 0; - } -+ mtd_part_parser_put(parser); - /* - * Stash the first error we see; only report it if no parser - * succeeds -@@ -1034,7 +1070,7 @@ int parse_mtd_partitions_by_type(struct - ret = (*parser->parse_fn)(master, pparts, data); - - if (ret > 0) { -- put_partition_parser(parser); -+ mtd_part_parser_put(parser); - printk(KERN_NOTICE - "%d %s partitions found on MTD device %s\n", - ret, parser->name, master->name); -@@ -1048,6 +1084,22 @@ int parse_mtd_partitions_by_type(struct - } - EXPORT_SYMBOL_GPL(parse_mtd_partitions_by_type); - -+void mtd_part_parser_cleanup(struct mtd_partitions *parts) -+{ -+ const struct mtd_part_parser *parser; -+ -+ if (!parts) -+ return; -+ -+ parser = parts->parser; -+ if (parser) { -+ if (parser->cleanup) -+ parser->cleanup(parts->parts, parts->nr_parts); -+ -+ mtd_part_parser_put(parser); -+ } -+} -+ - int mtd_is_partition(const struct mtd_info *mtd) - { - struct mtd_part *part; -@@ -1070,7 +1122,7 @@ struct mtd_info *mtdpart_get_master(cons - if (!mtd_is_partition(mtd)) - return (struct mtd_info *)mtd; - -- return PART(mtd)->master; -+ return mtd_to_part(mtd)->master; - } - EXPORT_SYMBOL_GPL(mtdpart_get_master); - -@@ -1079,7 +1131,7 @@ uint64_t mtdpart_get_offset(const struct - if (!mtd_is_partition(mtd)) - return 0; - -- return PART(mtd)->offset; -+ return mtd_to_part(mtd)->offset; - } - EXPORT_SYMBOL_GPL(mtdpart_get_offset); - -@@ -1089,6 +1141,6 @@ uint64_t mtd_get_device_size(const struc - if (!mtd_is_partition(mtd)) - return mtd->size; - -- return PART(mtd)->master->size; -+ return mtd_to_part(mtd)->master->size; - } - EXPORT_SYMBOL_GPL(mtd_get_device_size); ---- a/drivers/mtd/mtdswap.c -+++ b/drivers/mtd/mtdswap.c -@@ -346,7 +346,7 @@ static int mtdswap_read_markers(struct m - if (mtd_can_have_bb(d->mtd) && mtd_block_isbad(d->mtd, offset)) - return MTDSWAP_SCANNED_BAD; - -- ops.ooblen = 2 * d->mtd->ecclayout->oobavail; -+ ops.ooblen = 2 * d->mtd->oobavail; - ops.oobbuf = d->oob_buf; - ops.ooboffs = 0; - ops.datbuf = NULL; -@@ -359,7 +359,7 @@ static int mtdswap_read_markers(struct m - - data = (struct mtdswap_oobdata *)d->oob_buf; - data2 = (struct mtdswap_oobdata *) -- (d->oob_buf + d->mtd->ecclayout->oobavail); -+ (d->oob_buf + d->mtd->oobavail); - - if (le16_to_cpu(data->magic) == MTDSWAP_MAGIC_CLEAN) { - eb->erase_count = le32_to_cpu(data->count); -@@ -933,7 +933,7 @@ static unsigned int mtdswap_eblk_passes( - - ops.mode = MTD_OPS_AUTO_OOB; - ops.len = mtd->writesize; -- ops.ooblen = mtd->ecclayout->oobavail; -+ ops.ooblen = mtd->oobavail; - ops.ooboffs = 0; - ops.datbuf = d->page_buf; - ops.oobbuf = d->oob_buf; -@@ -945,7 +945,7 @@ static unsigned int mtdswap_eblk_passes( - for (i = 0; i < mtd_pages; i++) { - patt = mtdswap_test_patt(test + i); - memset(d->page_buf, patt, mtd->writesize); -- memset(d->oob_buf, patt, mtd->ecclayout->oobavail); -+ memset(d->oob_buf, patt, mtd->oobavail); - ret = mtd_write_oob(mtd, pos, &ops); - if (ret) - goto error; -@@ -964,7 +964,7 @@ static unsigned int mtdswap_eblk_passes( - if (p1[j] != patt) - goto error; - -- for (j = 0; j < mtd->ecclayout->oobavail; j++) -+ for (j = 0; j < mtd->oobavail; j++) - if (p2[j] != (unsigned char)patt) - goto error; - -@@ -1387,7 +1387,7 @@ static int mtdswap_init(struct mtdswap_d - if (!d->page_buf) - goto page_buf_fail; - -- d->oob_buf = kmalloc(2 * mtd->ecclayout->oobavail, GFP_KERNEL); -+ d->oob_buf = kmalloc(2 * mtd->oobavail, GFP_KERNEL); - if (!d->oob_buf) - goto oob_buf_fail; - -@@ -1417,7 +1417,6 @@ static void mtdswap_add_mtd(struct mtd_b - unsigned long part; - unsigned int eblocks, eavailable, bad_blocks, spare_cnt; - uint64_t swap_size, use_size, size_limit; -- struct nand_ecclayout *oinfo; - int ret; - - parts = &partitions[0]; -@@ -1447,17 +1446,10 @@ static void mtdswap_add_mtd(struct mtd_b - return; - } - -- oinfo = mtd->ecclayout; -- if (!oinfo) { -- printk(KERN_ERR "%s: mtd%d does not have OOB\n", -- MTDSWAP_PREFIX, mtd->index); -- return; -- } -- -- if (!mtd->oobsize || oinfo->oobavail < MTDSWAP_OOBSIZE) { -+ if (!mtd->oobsize || mtd->oobavail < MTDSWAP_OOBSIZE) { - printk(KERN_ERR "%s: Not enough free bytes in OOB, " - "%d available, %zu needed.\n", -- MTDSWAP_PREFIX, oinfo->oobavail, MTDSWAP_OOBSIZE); -+ MTDSWAP_PREFIX, mtd->oobavail, MTDSWAP_OOBSIZE); - return; - } - ---- a/drivers/mtd/nand/Kconfig -+++ b/drivers/mtd/nand/Kconfig -@@ -55,7 +55,7 @@ config MTD_NAND_DENALI_PCI - config MTD_NAND_DENALI_DT - tristate "Support Denali NAND controller as a DT device" - select MTD_NAND_DENALI -- depends on HAS_DMA && HAVE_CLK -+ depends on HAS_DMA && HAVE_CLK && OF - help - Enable the driver for NAND flash on platforms using a Denali NAND - controller as a DT device. -@@ -74,6 +74,7 @@ config MTD_NAND_DENALI_SCRATCH_REG_ADDR - config MTD_NAND_GPIO - tristate "GPIO assisted NAND Flash driver" - depends on GPIOLIB || COMPILE_TEST -+ depends on HAS_IOMEM - help - This enables a NAND flash driver where control signals are - connected to GPIO pins, and commands and data are communicated -@@ -310,6 +311,7 @@ config MTD_NAND_CAFE - config MTD_NAND_CS553X - tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)" - depends on X86_32 -+ depends on !UML && HAS_IOMEM - help - The CS553x companion chips for the AMD Geode processor - include NAND flash controllers with built-in hardware ECC -@@ -463,6 +465,7 @@ config MTD_NAND_MPC5121_NFC - config MTD_NAND_VF610_NFC - tristate "Support for Freescale NFC for VF610/MPC5125" - depends on (SOC_VF610 || COMPILE_TEST) -+ depends on HAS_IOMEM - help - Enables support for NAND Flash Controller on some Freescale - processors like the VF610, MPC5125, MCF54418 or Kinetis K70. -@@ -480,7 +483,7 @@ config MTD_NAND_MXC - - config MTD_NAND_SH_FLCTL - tristate "Support for NAND on Renesas SuperH FLCTL" -- depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST -+ depends on SUPERH || COMPILE_TEST - depends on HAS_IOMEM - depends on HAS_DMA - help -@@ -519,6 +522,13 @@ config MTD_NAND_JZ4740 - help - Enables support for NAND Flash on JZ4740 SoC based boards. - -+config MTD_NAND_JZ4780 -+ tristate "Support for NAND on JZ4780 SoC" -+ depends on MACH_JZ4780 && JZ4780_NEMC -+ help -+ Enables support for NAND Flash connected to the NEMC on JZ4780 SoC -+ based boards, using the BCH controller for hardware error correction. -+ - config MTD_NAND_FSMC - tristate "Support for NAND on ST Micros FSMC" - depends on PLAT_SPEAR || ARCH_NOMADIK || ARCH_U8500 || MACH_U300 -@@ -546,4 +556,11 @@ config MTD_NAND_HISI504 - help - Enables support for NAND controller on Hisilicon SoC Hip04. - -+config MTD_NAND_QCOM -+ tristate "Support for NAND on QCOM SoCs" -+ depends on ARCH_QCOM -+ help -+ Enables support for NAND flash chips on SoCs containing the EBI2 NAND -+ controller. This controller is found on IPQ806x SoC. -+ - endif # MTD_NAND ---- a/drivers/mtd/nand/Makefile -+++ b/drivers/mtd/nand/Makefile -@@ -49,11 +49,13 @@ obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mp - obj-$(CONFIG_MTD_NAND_VF610_NFC) += vf610_nfc.o - obj-$(CONFIG_MTD_NAND_RICOH) += r852.o - obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o -+obj-$(CONFIG_MTD_NAND_JZ4780) += jz4780_nand.o jz4780_bch.o - obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/ - obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o - obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/ - obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_nand.o - obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o - obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/ -+obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o - - nand-objs := nand_base.o nand_bbt.o nand_timings.o ---- a/drivers/mtd/nand/nand_base.c -+++ b/drivers/mtd/nand/nand_base.c -@@ -48,50 +48,6 @@ - #include - #include - --/* Define default oob placement schemes for large and small page devices */ --static struct nand_ecclayout nand_oob_8 = { -- .eccbytes = 3, -- .eccpos = {0, 1, 2}, -- .oobfree = { -- {.offset = 3, -- .length = 2}, -- {.offset = 6, -- .length = 2} } --}; -- --static struct nand_ecclayout nand_oob_16 = { -- .eccbytes = 6, -- .eccpos = {0, 1, 2, 3, 6, 7}, -- .oobfree = { -- {.offset = 8, -- . length = 8} } --}; -- --static struct nand_ecclayout nand_oob_64 = { -- .eccbytes = 24, -- .eccpos = { -- 40, 41, 42, 43, 44, 45, 46, 47, -- 48, 49, 50, 51, 52, 53, 54, 55, -- 56, 57, 58, 59, 60, 61, 62, 63}, -- .oobfree = { -- {.offset = 2, -- .length = 38} } --}; -- --static struct nand_ecclayout nand_oob_128 = { -- .eccbytes = 48, -- .eccpos = { -- 80, 81, 82, 83, 84, 85, 86, 87, -- 88, 89, 90, 91, 92, 93, 94, 95, -- 96, 97, 98, 99, 100, 101, 102, 103, -- 104, 105, 106, 107, 108, 109, 110, 111, -- 112, 113, 114, 115, 116, 117, 118, 119, -- 120, 121, 122, 123, 124, 125, 126, 127}, -- .oobfree = { -- {.offset = 2, -- .length = 78} } --}; -- - static int nand_get_device(struct mtd_info *mtd, int new_state); - - static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, -@@ -103,10 +59,96 @@ static int nand_do_write_oob(struct mtd_ - */ - DEFINE_LED_TRIGGER(nand_led_trigger); - -+/* Define default oob placement schemes for large and small page devices */ -+static int nand_ooblayout_ecc_sp(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct nand_ecc_ctrl *ecc = &chip->ecc; -+ -+ if (section > 1) -+ return -ERANGE; -+ -+ if (!section) { -+ oobregion->offset = 0; -+ oobregion->length = 4; -+ } else { -+ oobregion->offset = 6; -+ oobregion->length = ecc->total - 4; -+ } -+ -+ return 0; -+} -+ -+static int nand_ooblayout_free_sp(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ if (section > 1) -+ return -ERANGE; -+ -+ if (mtd->oobsize == 16) { -+ if (section) -+ return -ERANGE; -+ -+ oobregion->length = 8; -+ oobregion->offset = 8; -+ } else { -+ oobregion->length = 2; -+ if (!section) -+ oobregion->offset = 3; -+ else -+ oobregion->offset = 6; -+ } -+ -+ return 0; -+} -+ -+const struct mtd_ooblayout_ops nand_ooblayout_sp_ops = { -+ .ecc = nand_ooblayout_ecc_sp, -+ .free = nand_ooblayout_free_sp, -+}; -+EXPORT_SYMBOL_GPL(nand_ooblayout_sp_ops); -+ -+static int nand_ooblayout_ecc_lp(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct nand_ecc_ctrl *ecc = &chip->ecc; -+ -+ if (section) -+ return -ERANGE; -+ -+ oobregion->length = ecc->total; -+ oobregion->offset = mtd->oobsize - oobregion->length; -+ -+ return 0; -+} -+ -+static int nand_ooblayout_free_lp(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct nand_ecc_ctrl *ecc = &chip->ecc; -+ -+ if (section) -+ return -ERANGE; -+ -+ oobregion->length = mtd->oobsize - ecc->total - 2; -+ oobregion->offset = 2; -+ -+ return 0; -+} -+ -+const struct mtd_ooblayout_ops nand_ooblayout_lp_ops = { -+ .ecc = nand_ooblayout_ecc_lp, -+ .free = nand_ooblayout_free_lp, -+}; -+EXPORT_SYMBOL_GPL(nand_ooblayout_lp_ops); -+ - static int check_offs_len(struct mtd_info *mtd, - loff_t ofs, uint64_t len) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - int ret = 0; - - /* Start address must align on block boundary */ -@@ -132,7 +174,7 @@ static int check_offs_len(struct mtd_inf - */ - static void nand_release_device(struct mtd_info *mtd) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - - /* Release the controller and the chip */ - spin_lock(&chip->controller->lock); -@@ -150,7 +192,7 @@ static void nand_release_device(struct m - */ - static uint8_t nand_read_byte(struct mtd_info *mtd) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - return readb(chip->IO_ADDR_R); - } - -@@ -163,7 +205,7 @@ static uint8_t nand_read_byte(struct mtd - */ - static uint8_t nand_read_byte16(struct mtd_info *mtd) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R)); - } - -@@ -175,7 +217,7 @@ static uint8_t nand_read_byte16(struct m - */ - static u16 nand_read_word(struct mtd_info *mtd) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - return readw(chip->IO_ADDR_R); - } - -@@ -188,7 +230,7 @@ static u16 nand_read_word(struct mtd_inf - */ - static void nand_select_chip(struct mtd_info *mtd, int chipnr) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - - switch (chipnr) { - case -1: -@@ -211,7 +253,7 @@ static void nand_select_chip(struct mtd_ - */ - static void nand_write_byte(struct mtd_info *mtd, uint8_t byte) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - - chip->write_buf(mtd, &byte, 1); - } -@@ -225,7 +267,7 @@ static void nand_write_byte(struct mtd_i - */ - static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - uint16_t word = byte; - - /* -@@ -257,7 +299,7 @@ static void nand_write_byte16(struct mtd - */ - static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - - iowrite8_rep(chip->IO_ADDR_W, buf, len); - } -@@ -272,7 +314,7 @@ static void nand_write_buf(struct mtd_in - */ - static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - - ioread8_rep(chip->IO_ADDR_R, buf, len); - } -@@ -287,7 +329,7 @@ static void nand_read_buf(struct mtd_inf - */ - static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - u16 *p = (u16 *) buf; - - iowrite16_rep(chip->IO_ADDR_W, p, len >> 1); -@@ -303,7 +345,7 @@ static void nand_write_buf16(struct mtd_ - */ - static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - u16 *p = (u16 *) buf; - - ioread16_rep(chip->IO_ADDR_R, p, len >> 1); -@@ -313,14 +355,13 @@ static void nand_read_buf16(struct mtd_i - * nand_block_bad - [DEFAULT] Read bad block marker from the chip - * @mtd: MTD device structure - * @ofs: offset from device start -- * @getchip: 0, if the chip is already selected - * - * Check, if the block is bad. - */ --static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) -+static int nand_block_bad(struct mtd_info *mtd, loff_t ofs) - { -- int page, chipnr, res = 0, i = 0; -- struct nand_chip *chip = mtd->priv; -+ int page, res = 0, i = 0; -+ struct nand_chip *chip = mtd_to_nand(mtd); - u16 bad; - - if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) -@@ -328,15 +369,6 @@ static int nand_block_bad(struct mtd_inf - - page = (int)(ofs >> chip->page_shift) & chip->pagemask; - -- if (getchip) { -- chipnr = (int)(ofs >> chip->chip_shift); -- -- nand_get_device(mtd, FL_READING); -- -- /* Select the NAND device */ -- chip->select_chip(mtd, chipnr); -- } -- - do { - if (chip->options & NAND_BUSWIDTH_16) { - chip->cmdfunc(mtd, NAND_CMD_READOOB, -@@ -361,11 +393,6 @@ static int nand_block_bad(struct mtd_inf - i++; - } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE)); - -- if (getchip) { -- chip->select_chip(mtd, -1); -- nand_release_device(mtd); -- } -- - return res; - } - -@@ -380,7 +407,7 @@ static int nand_block_bad(struct mtd_inf - */ - static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - struct mtd_oob_ops ops; - uint8_t buf[2] = { 0, 0 }; - int ret = 0, res, i = 0; -@@ -430,7 +457,7 @@ static int nand_default_block_markbad(st - */ - static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - int res, ret = 0; - - if (!(chip->bbt_options & NAND_BBT_NO_OOB_BBM)) { -@@ -471,7 +498,7 @@ static int nand_block_markbad_lowlevel(s - */ - static int nand_check_wp(struct mtd_info *mtd) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - - /* Broken xD cards report WP despite being writable */ - if (chip->options & NAND_BROKEN_XD) -@@ -491,7 +518,7 @@ static int nand_check_wp(struct mtd_info - */ - static int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - - if (!chip->bbt) - return 0; -@@ -503,19 +530,17 @@ static int nand_block_isreserved(struct - * nand_block_checkbad - [GENERIC] Check if a block is marked bad - * @mtd: MTD device structure - * @ofs: offset from device start -- * @getchip: 0, if the chip is already selected - * @allowbbt: 1, if its allowed to access the bbt area - * - * Check, if the block is bad. Either by reading the bad block table or - * calling of the scan function. - */ --static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, -- int allowbbt) -+static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int allowbbt) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - - if (!chip->bbt) -- return chip->block_bad(mtd, ofs, getchip); -+ return chip->block_bad(mtd, ofs); - - /* Return info from the table */ - return nand_isbad_bbt(mtd, ofs, allowbbt); -@@ -531,7 +556,7 @@ static int nand_block_checkbad(struct mt - */ - static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - int i; - - /* Wait for the device to get ready */ -@@ -551,7 +576,7 @@ static void panic_nand_wait_ready(struct - */ - void nand_wait_ready(struct mtd_info *mtd) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - unsigned long timeo = 400; - - if (in_interrupt() || oops_in_progress) -@@ -566,8 +591,8 @@ void nand_wait_ready(struct mtd_info *mt - cond_resched(); - } while (time_before(jiffies, timeo)); - -- pr_warn_ratelimited( -- "timeout while waiting for chip to become ready\n"); -+ if (!chip->dev_ready(mtd)) -+ pr_warn_ratelimited("timeout while waiting for chip to become ready\n"); - out: - led_trigger_event(nand_led_trigger, LED_OFF); - } -@@ -582,7 +607,7 @@ EXPORT_SYMBOL_GPL(nand_wait_ready); - */ - static void nand_wait_status_ready(struct mtd_info *mtd, unsigned long timeo) - { -- register struct nand_chip *chip = mtd->priv; -+ register struct nand_chip *chip = mtd_to_nand(mtd); - - timeo = jiffies + msecs_to_jiffies(timeo); - do { -@@ -605,7 +630,7 @@ static void nand_wait_status_ready(struc - static void nand_command(struct mtd_info *mtd, unsigned int command, - int column, int page_addr) - { -- register struct nand_chip *chip = mtd->priv; -+ register struct nand_chip *chip = mtd_to_nand(mtd); - int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE; - - /* Write out the command to the device */ -@@ -708,7 +733,7 @@ static void nand_command(struct mtd_info - static void nand_command_lp(struct mtd_info *mtd, unsigned int command, - int column, int page_addr) - { -- register struct nand_chip *chip = mtd->priv; -+ register struct nand_chip *chip = mtd_to_nand(mtd); - - /* Emulate NAND_CMD_READOOB */ - if (command == NAND_CMD_READOOB) { -@@ -832,7 +857,7 @@ static void panic_nand_get_device(struct - static int - nand_get_device(struct mtd_info *mtd, int new_state) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - spinlock_t *lock = &chip->controller->lock; - wait_queue_head_t *wq = &chip->controller->wq; - DECLARE_WAITQUEUE(wait, current); -@@ -952,7 +977,7 @@ static int __nand_unlock(struct mtd_info - { - int ret = 0; - int status, page; -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - - /* Submit address of first page to unlock */ - page = ofs >> chip->page_shift; -@@ -987,7 +1012,7 @@ int nand_unlock(struct mtd_info *mtd, lo - { - int ret = 0; - int chipnr; -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - - pr_debug("%s: start = 0x%012llx, len = %llu\n", - __func__, (unsigned long long)ofs, len); -@@ -1050,7 +1075,7 @@ int nand_lock(struct mtd_info *mtd, loff - { - int ret = 0; - int chipnr, status, page; -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - - pr_debug("%s: start = 0x%012llx, len = %llu\n", - __func__, (unsigned long long)ofs, len); -@@ -1309,13 +1334,12 @@ static int nand_read_page_raw_syndrome(s - static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, - uint8_t *buf, int oob_required, int page) - { -- int i, eccsize = chip->ecc.size; -+ int i, eccsize = chip->ecc.size, ret; - int eccbytes = chip->ecc.bytes; - int eccsteps = chip->ecc.steps; - uint8_t *p = buf; - uint8_t *ecc_calc = chip->buffers->ecccalc; - uint8_t *ecc_code = chip->buffers->ecccode; -- uint32_t *eccpos = chip->ecc.layout->eccpos; - unsigned int max_bitflips = 0; - - chip->ecc.read_page_raw(mtd, chip, buf, 1, page); -@@ -1323,8 +1347,10 @@ static int nand_read_page_swecc(struct m - for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) - chip->ecc.calculate(mtd, p, &ecc_calc[i]); - -- for (i = 0; i < chip->ecc.total; i++) -- ecc_code[i] = chip->oob_poi[eccpos[i]]; -+ ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0, -+ chip->ecc.total); -+ if (ret) -+ return ret; - - eccsteps = chip->ecc.steps; - p = buf; -@@ -1356,14 +1382,14 @@ static int nand_read_subpage(struct mtd_ - uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi, - int page) - { -- int start_step, end_step, num_steps; -- uint32_t *eccpos = chip->ecc.layout->eccpos; -+ int start_step, end_step, num_steps, ret; - uint8_t *p; - int data_col_addr, i, gaps = 0; - int datafrag_len, eccfrag_len, aligned_len, aligned_pos; - int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1; -- int index; -+ int index, section = 0; - unsigned int max_bitflips = 0; -+ struct mtd_oob_region oobregion = { }; - - /* Column address within the page aligned to ECC size (256bytes) */ - start_step = data_offs / chip->ecc.size; -@@ -1391,12 +1417,13 @@ static int nand_read_subpage(struct mtd_ - * The performance is faster if we position offsets according to - * ecc.pos. Let's make sure that there are no gaps in ECC positions. - */ -- for (i = 0; i < eccfrag_len - 1; i++) { -- if (eccpos[i + index] + 1 != eccpos[i + index + 1]) { -- gaps = 1; -- break; -- } -- } -+ ret = mtd_ooblayout_find_eccregion(mtd, index, §ion, &oobregion); -+ if (ret) -+ return ret; -+ -+ if (oobregion.length < eccfrag_len) -+ gaps = 1; -+ - if (gaps) { - chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1); - chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); -@@ -1405,20 +1432,23 @@ static int nand_read_subpage(struct mtd_ - * Send the command to read the particular ECC bytes take care - * about buswidth alignment in read_buf. - */ -- aligned_pos = eccpos[index] & ~(busw - 1); -+ aligned_pos = oobregion.offset & ~(busw - 1); - aligned_len = eccfrag_len; -- if (eccpos[index] & (busw - 1)) -+ if (oobregion.offset & (busw - 1)) - aligned_len++; -- if (eccpos[index + (num_steps * chip->ecc.bytes)] & (busw - 1)) -+ if ((oobregion.offset + (num_steps * chip->ecc.bytes)) & -+ (busw - 1)) - aligned_len++; - - chip->cmdfunc(mtd, NAND_CMD_RNDOUT, -- mtd->writesize + aligned_pos, -1); -+ mtd->writesize + aligned_pos, -1); - chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len); - } - -- for (i = 0; i < eccfrag_len; i++) -- chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + index]]; -+ ret = mtd_ooblayout_get_eccbytes(mtd, chip->buffers->ecccode, -+ chip->oob_poi, index, eccfrag_len); -+ if (ret) -+ return ret; - - p = bufpoi + data_col_addr; - for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) { -@@ -1426,6 +1456,16 @@ static int nand_read_subpage(struct mtd_ - - stat = chip->ecc.correct(mtd, p, - &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]); -+ if (stat == -EBADMSG && -+ (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { -+ /* check for empty pages with bitflips */ -+ stat = nand_check_erased_ecc_chunk(p, chip->ecc.size, -+ &chip->buffers->ecccode[i], -+ chip->ecc.bytes, -+ NULL, 0, -+ chip->ecc.strength); -+ } -+ - if (stat < 0) { - mtd->ecc_stats.failed++; - } else { -@@ -1449,13 +1489,12 @@ static int nand_read_subpage(struct mtd_ - static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, - uint8_t *buf, int oob_required, int page) - { -- int i, eccsize = chip->ecc.size; -+ int i, eccsize = chip->ecc.size, ret; - int eccbytes = chip->ecc.bytes; - int eccsteps = chip->ecc.steps; - uint8_t *p = buf; - uint8_t *ecc_calc = chip->buffers->ecccalc; - uint8_t *ecc_code = chip->buffers->ecccode; -- uint32_t *eccpos = chip->ecc.layout->eccpos; - unsigned int max_bitflips = 0; - - for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { -@@ -1465,8 +1504,10 @@ static int nand_read_page_hwecc(struct m - } - chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); - -- for (i = 0; i < chip->ecc.total; i++) -- ecc_code[i] = chip->oob_poi[eccpos[i]]; -+ ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0, -+ chip->ecc.total); -+ if (ret) -+ return ret; - - eccsteps = chip->ecc.steps; - p = buf; -@@ -1475,6 +1516,15 @@ static int nand_read_page_hwecc(struct m - int stat; - - stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); -+ if (stat == -EBADMSG && -+ (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { -+ /* check for empty pages with bitflips */ -+ stat = nand_check_erased_ecc_chunk(p, eccsize, -+ &ecc_code[i], eccbytes, -+ NULL, 0, -+ chip->ecc.strength); -+ } -+ - if (stat < 0) { - mtd->ecc_stats.failed++; - } else { -@@ -1502,12 +1552,11 @@ static int nand_read_page_hwecc(struct m - static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd, - struct nand_chip *chip, uint8_t *buf, int oob_required, int page) - { -- int i, eccsize = chip->ecc.size; -+ int i, eccsize = chip->ecc.size, ret; - int eccbytes = chip->ecc.bytes; - int eccsteps = chip->ecc.steps; - uint8_t *p = buf; - uint8_t *ecc_code = chip->buffers->ecccode; -- uint32_t *eccpos = chip->ecc.layout->eccpos; - uint8_t *ecc_calc = chip->buffers->ecccalc; - unsigned int max_bitflips = 0; - -@@ -1516,8 +1565,10 @@ static int nand_read_page_hwecc_oob_firs - chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); - chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page); - -- for (i = 0; i < chip->ecc.total; i++) -- ecc_code[i] = chip->oob_poi[eccpos[i]]; -+ ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0, -+ chip->ecc.total); -+ if (ret) -+ return ret; - - for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { - int stat; -@@ -1527,6 +1578,15 @@ static int nand_read_page_hwecc_oob_firs - chip->ecc.calculate(mtd, p, &ecc_calc[i]); - - stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL); -+ if (stat == -EBADMSG && -+ (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { -+ /* check for empty pages with bitflips */ -+ stat = nand_check_erased_ecc_chunk(p, eccsize, -+ &ecc_code[i], eccbytes, -+ NULL, 0, -+ chip->ecc.strength); -+ } -+ - if (stat < 0) { - mtd->ecc_stats.failed++; - } else { -@@ -1554,6 +1614,7 @@ static int nand_read_page_syndrome(struc - int i, eccsize = chip->ecc.size; - int eccbytes = chip->ecc.bytes; - int eccsteps = chip->ecc.steps; -+ int eccpadbytes = eccbytes + chip->ecc.prepad + chip->ecc.postpad; - uint8_t *p = buf; - uint8_t *oob = chip->oob_poi; - unsigned int max_bitflips = 0; -@@ -1573,19 +1634,29 @@ static int nand_read_page_syndrome(struc - chip->read_buf(mtd, oob, eccbytes); - stat = chip->ecc.correct(mtd, p, oob, NULL); - -- if (stat < 0) { -- mtd->ecc_stats.failed++; -- } else { -- mtd->ecc_stats.corrected += stat; -- max_bitflips = max_t(unsigned int, max_bitflips, stat); -- } -- - oob += eccbytes; - - if (chip->ecc.postpad) { - chip->read_buf(mtd, oob, chip->ecc.postpad); - oob += chip->ecc.postpad; - } -+ -+ if (stat == -EBADMSG && -+ (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { -+ /* check for empty pages with bitflips */ -+ stat = nand_check_erased_ecc_chunk(p, chip->ecc.size, -+ oob - eccpadbytes, -+ eccpadbytes, -+ NULL, 0, -+ chip->ecc.strength); -+ } -+ -+ if (stat < 0) { -+ mtd->ecc_stats.failed++; -+ } else { -+ mtd->ecc_stats.corrected += stat; -+ max_bitflips = max_t(unsigned int, max_bitflips, stat); -+ } - } - - /* Calculate remaining oob bytes */ -@@ -1598,14 +1669,17 @@ static int nand_read_page_syndrome(struc - - /** - * nand_transfer_oob - [INTERN] Transfer oob to client buffer -- * @chip: nand chip structure -+ * @mtd: mtd info structure - * @oob: oob destination address - * @ops: oob ops structure - * @len: size of oob to transfer - */ --static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, -+static uint8_t *nand_transfer_oob(struct mtd_info *mtd, uint8_t *oob, - struct mtd_oob_ops *ops, size_t len) - { -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ int ret; -+ - switch (ops->mode) { - - case MTD_OPS_PLACE_OOB: -@@ -1613,31 +1687,12 @@ static uint8_t *nand_transfer_oob(struct - memcpy(oob, chip->oob_poi + ops->ooboffs, len); - return oob + len; - -- case MTD_OPS_AUTO_OOB: { -- struct nand_oobfree *free = chip->ecc.layout->oobfree; -- uint32_t boffs = 0, roffs = ops->ooboffs; -- size_t bytes = 0; -- -- for (; free->length && len; free++, len -= bytes) { -- /* Read request not from offset 0? */ -- if (unlikely(roffs)) { -- if (roffs >= free->length) { -- roffs -= free->length; -- continue; -- } -- boffs = free->offset + roffs; -- bytes = min_t(size_t, len, -- (free->length - roffs)); -- roffs = 0; -- } else { -- bytes = min_t(size_t, len, free->length); -- boffs = free->offset; -- } -- memcpy(oob, chip->oob_poi + boffs, bytes); -- oob += bytes; -- } -- return oob; -- } -+ case MTD_OPS_AUTO_OOB: -+ ret = mtd_ooblayout_get_databytes(mtd, oob, chip->oob_poi, -+ ops->ooboffs, len); -+ BUG_ON(ret); -+ return oob + len; -+ - default: - BUG(); - } -@@ -1655,7 +1710,7 @@ static uint8_t *nand_transfer_oob(struct - */ - static int nand_setup_read_retry(struct mtd_info *mtd, int retry_mode) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - - pr_debug("setting READ RETRY mode %d\n", retry_mode); - -@@ -1680,12 +1735,11 @@ static int nand_do_read_ops(struct mtd_i - struct mtd_oob_ops *ops) - { - int chipnr, page, realpage, col, bytes, aligned, oob_required; -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - int ret = 0; - uint32_t readlen = ops->len; - uint32_t oobreadlen = ops->ooblen; -- uint32_t max_oobsize = ops->mode == MTD_OPS_AUTO_OOB ? -- mtd->oobavail : mtd->oobsize; -+ uint32_t max_oobsize = mtd_oobavail(mtd, ops); - - uint8_t *bufpoi, *oob, *buf; - int use_bufpoi; -@@ -1772,7 +1826,7 @@ read_retry: - int toread = min(oobreadlen, max_oobsize); - - if (toread) { -- oob = nand_transfer_oob(chip, -+ oob = nand_transfer_oob(mtd, - oob, ops, toread); - oobreadlen -= toread; - } -@@ -2024,7 +2078,7 @@ static int nand_do_read_oob(struct mtd_i - struct mtd_oob_ops *ops) - { - int page, realpage, chipnr; -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - struct mtd_ecc_stats stats; - int readlen = ops->ooblen; - int len; -@@ -2036,10 +2090,7 @@ static int nand_do_read_oob(struct mtd_i - - stats = mtd->ecc_stats; - -- if (ops->mode == MTD_OPS_AUTO_OOB) -- len = chip->ecc.layout->oobavail; -- else -- len = mtd->oobsize; -+ len = mtd_oobavail(mtd, ops); - - if (unlikely(ops->ooboffs >= len)) { - pr_debug("%s: attempt to start read outside oob\n", -@@ -2073,7 +2124,7 @@ static int nand_do_read_oob(struct mtd_i - break; - - len = min(len, readlen); -- buf = nand_transfer_oob(chip, buf, ops, len); -+ buf = nand_transfer_oob(mtd, buf, ops, len); - - if (chip->options & NAND_NEED_READRDY) { - /* Apply delay or wait for ready/busy pin */ -@@ -2232,19 +2283,20 @@ static int nand_write_page_swecc(struct - const uint8_t *buf, int oob_required, - int page) - { -- int i, eccsize = chip->ecc.size; -+ int i, eccsize = chip->ecc.size, ret; - int eccbytes = chip->ecc.bytes; - int eccsteps = chip->ecc.steps; - uint8_t *ecc_calc = chip->buffers->ecccalc; - const uint8_t *p = buf; -- uint32_t *eccpos = chip->ecc.layout->eccpos; - - /* Software ECC calculation */ - for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) - chip->ecc.calculate(mtd, p, &ecc_calc[i]); - -- for (i = 0; i < chip->ecc.total; i++) -- chip->oob_poi[eccpos[i]] = ecc_calc[i]; -+ ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0, -+ chip->ecc.total); -+ if (ret) -+ return ret; - - return chip->ecc.write_page_raw(mtd, chip, buf, 1, page); - } -@@ -2261,12 +2313,11 @@ static int nand_write_page_hwecc(struct - const uint8_t *buf, int oob_required, - int page) - { -- int i, eccsize = chip->ecc.size; -+ int i, eccsize = chip->ecc.size, ret; - int eccbytes = chip->ecc.bytes; - int eccsteps = chip->ecc.steps; - uint8_t *ecc_calc = chip->buffers->ecccalc; - const uint8_t *p = buf; -- uint32_t *eccpos = chip->ecc.layout->eccpos; - - for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { - chip->ecc.hwctl(mtd, NAND_ECC_WRITE); -@@ -2274,8 +2325,10 @@ static int nand_write_page_hwecc(struct - chip->ecc.calculate(mtd, p, &ecc_calc[i]); - } - -- for (i = 0; i < chip->ecc.total; i++) -- chip->oob_poi[eccpos[i]] = ecc_calc[i]; -+ ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0, -+ chip->ecc.total); -+ if (ret) -+ return ret; - - chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); - -@@ -2303,11 +2356,10 @@ static int nand_write_subpage_hwecc(stru - int ecc_size = chip->ecc.size; - int ecc_bytes = chip->ecc.bytes; - int ecc_steps = chip->ecc.steps; -- uint32_t *eccpos = chip->ecc.layout->eccpos; - uint32_t start_step = offset / ecc_size; - uint32_t end_step = (offset + data_len - 1) / ecc_size; - int oob_bytes = mtd->oobsize / ecc_steps; -- int step, i; -+ int step, ret; - - for (step = 0; step < ecc_steps; step++) { - /* configure controller for WRITE access */ -@@ -2335,8 +2387,10 @@ static int nand_write_subpage_hwecc(stru - /* copy calculated ECC for whole page to chip->buffer->oob */ - /* this include masked-value(0xFF) for unwritten subpages */ - ecc_calc = chip->buffers->ecccalc; -- for (i = 0; i < chip->ecc.total; i++) -- chip->oob_poi[eccpos[i]] = ecc_calc[i]; -+ ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0, -+ chip->ecc.total); -+ if (ret) -+ return ret; - - /* write OOB buffer to NAND device */ - chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); -@@ -2472,7 +2526,8 @@ static int nand_write_page(struct mtd_in - static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len, - struct mtd_oob_ops *ops) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ int ret; - - /* - * Initialise to all 0xFF, to avoid the possibility of left over OOB -@@ -2487,31 +2542,12 @@ static uint8_t *nand_fill_oob(struct mtd - memcpy(chip->oob_poi + ops->ooboffs, oob, len); - return oob + len; - -- case MTD_OPS_AUTO_OOB: { -- struct nand_oobfree *free = chip->ecc.layout->oobfree; -- uint32_t boffs = 0, woffs = ops->ooboffs; -- size_t bytes = 0; -- -- for (; free->length && len; free++, len -= bytes) { -- /* Write request not from offset 0? */ -- if (unlikely(woffs)) { -- if (woffs >= free->length) { -- woffs -= free->length; -- continue; -- } -- boffs = free->offset + woffs; -- bytes = min_t(size_t, len, -- (free->length - woffs)); -- woffs = 0; -- } else { -- bytes = min_t(size_t, len, free->length); -- boffs = free->offset; -- } -- memcpy(chip->oob_poi + boffs, oob, bytes); -- oob += bytes; -- } -- return oob; -- } -+ case MTD_OPS_AUTO_OOB: -+ ret = mtd_ooblayout_set_databytes(mtd, oob, chip->oob_poi, -+ ops->ooboffs, len); -+ BUG_ON(ret); -+ return oob + len; -+ - default: - BUG(); - } -@@ -2532,12 +2568,11 @@ static int nand_do_write_ops(struct mtd_ - struct mtd_oob_ops *ops) - { - int chipnr, realpage, page, blockmask, column; -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - uint32_t writelen = ops->len; - - uint32_t oobwritelen = ops->ooblen; -- uint32_t oobmaxlen = ops->mode == MTD_OPS_AUTO_OOB ? -- mtd->oobavail : mtd->oobsize; -+ uint32_t oobmaxlen = mtd_oobavail(mtd, ops); - - uint8_t *oob = ops->oobbuf; - uint8_t *buf = ops->datbuf; -@@ -2662,7 +2697,7 @@ err_out: - static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const uint8_t *buf) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - struct mtd_oob_ops ops; - int ret; - -@@ -2722,15 +2757,12 @@ static int nand_do_write_oob(struct mtd_ - struct mtd_oob_ops *ops) - { - int chipnr, page, status, len; -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - - pr_debug("%s: to = 0x%08x, len = %i\n", - __func__, (unsigned int)to, (int)ops->ooblen); - -- if (ops->mode == MTD_OPS_AUTO_OOB) -- len = chip->ecc.layout->oobavail; -- else -- len = mtd->oobsize; -+ len = mtd_oobavail(mtd, ops); - - /* Do not allow write past end of page */ - if ((ops->ooboffs + ops->ooblen) > len) { -@@ -2847,7 +2879,7 @@ out: - */ - static int single_erase(struct mtd_info *mtd, int page) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - /* Send commands to erase a block */ - chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page); - chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1); -@@ -2879,7 +2911,7 @@ int nand_erase_nand(struct mtd_info *mtd - int allowbbt) - { - int page, status, pages_per_block, ret, chipnr; -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - loff_t len; - - pr_debug("%s: start = 0x%012llx, len = %llu\n", -@@ -2918,7 +2950,7 @@ int nand_erase_nand(struct mtd_info *mtd - while (len) { - /* Check if we have a bad block, we do not erase bad blocks! */ - if (nand_block_checkbad(mtd, ((loff_t) page) << -- chip->page_shift, 0, allowbbt)) { -+ chip->page_shift, allowbbt)) { - pr_warn("%s: attempt to erase a bad block at page 0x%08x\n", - __func__, page); - instr->state = MTD_ERASE_FAILED; -@@ -3005,7 +3037,20 @@ static void nand_sync(struct mtd_info *m - */ - static int nand_block_isbad(struct mtd_info *mtd, loff_t offs) - { -- return nand_block_checkbad(mtd, offs, 1, 0); -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ int chipnr = (int)(offs >> chip->chip_shift); -+ int ret; -+ -+ /* Select the NAND device */ -+ nand_get_device(mtd, FL_READING); -+ chip->select_chip(mtd, chipnr); -+ -+ ret = nand_block_checkbad(mtd, offs, 0); -+ -+ chip->select_chip(mtd, -1); -+ nand_release_device(mtd); -+ -+ return ret; - } - - /** -@@ -3094,7 +3139,7 @@ static int nand_suspend(struct mtd_info - */ - static void nand_resume(struct mtd_info *mtd) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - - if (chip->state == FL_PM_SUSPENDED) - nand_release_device(mtd); -@@ -3266,7 +3311,7 @@ ext_out: - - static int nand_setup_read_retry_micron(struct mtd_info *mtd, int retry_mode) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {retry_mode}; - - return chip->onfi_set_features(mtd, chip, ONFI_FEATURE_ADDR_READ_RETRY, -@@ -3937,10 +3982,13 @@ ident_done: - return type; - } - --static int nand_dt_init(struct mtd_info *mtd, struct nand_chip *chip, -- struct device_node *dn) -+static int nand_dt_init(struct nand_chip *chip) - { -- int ecc_mode, ecc_strength, ecc_step; -+ struct device_node *dn = nand_get_flash_node(chip); -+ int ecc_mode, ecc_algo, ecc_strength, ecc_step; -+ -+ if (!dn) -+ return 0; - - if (of_get_nand_bus_width(dn) == 16) - chip->options |= NAND_BUSWIDTH_16; -@@ -3949,6 +3997,7 @@ static int nand_dt_init(struct mtd_info - chip->bbt_options |= NAND_BBT_USE_FLASH; - - ecc_mode = of_get_nand_ecc_mode(dn); -+ ecc_algo = of_get_nand_ecc_algo(dn); - ecc_strength = of_get_nand_ecc_strength(dn); - ecc_step = of_get_nand_ecc_step_size(dn); - -@@ -3961,6 +4010,9 @@ static int nand_dt_init(struct mtd_info - if (ecc_mode >= 0) - chip->ecc.mode = ecc_mode; - -+ if (ecc_algo >= 0) -+ chip->ecc.algo = ecc_algo; -+ - if (ecc_strength >= 0) - chip->ecc.strength = ecc_strength; - -@@ -3984,15 +4036,16 @@ int nand_scan_ident(struct mtd_info *mtd - struct nand_flash_dev *table) - { - int i, nand_maf_id, nand_dev_id; -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - struct nand_flash_dev *type; - int ret; - -- if (chip->flash_node) { -- ret = nand_dt_init(mtd, chip, chip->flash_node); -- if (ret) -- return ret; -- } -+ ret = nand_dt_init(chip); -+ if (ret) -+ return ret; -+ -+ if (!mtd->name && mtd->dev.parent) -+ mtd->name = dev_name(mtd->dev.parent); - - if (!mtd->name && mtd->dev.parent) - mtd->name = dev_name(mtd->dev.parent); -@@ -4055,7 +4108,7 @@ EXPORT_SYMBOL(nand_scan_ident); - */ - static bool nand_ecc_strength_good(struct mtd_info *mtd) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - struct nand_ecc_ctrl *ecc = &chip->ecc; - int corr, ds_corr; - -@@ -4083,10 +4136,10 @@ static bool nand_ecc_strength_good(struc - */ - int nand_scan_tail(struct mtd_info *mtd) - { -- int i; -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - struct nand_ecc_ctrl *ecc = &chip->ecc; - struct nand_buffers *nbuf; -+ int ret; - - /* New bad blocks should be marked in OOB, flash-based BBT, or both */ - BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) && -@@ -4113,19 +4166,15 @@ int nand_scan_tail(struct mtd_info *mtd) - /* - * If no default placement scheme is given, select an appropriate one. - */ -- if (!ecc->layout && (ecc->mode != NAND_ECC_SOFT_BCH)) { -+ if (!mtd->ooblayout && (ecc->mode != NAND_ECC_SOFT_BCH)) { - switch (mtd->oobsize) { - case 8: -- ecc->layout = &nand_oob_8; -- break; - case 16: -- ecc->layout = &nand_oob_16; -+ mtd_set_ooblayout(mtd, &nand_ooblayout_sp_ops); - break; - case 64: -- ecc->layout = &nand_oob_64; -- break; - case 128: -- ecc->layout = &nand_oob_128; -+ mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops); - break; - default: - pr_warn("No oob scheme defined for oobsize %d\n", -@@ -4168,7 +4217,7 @@ int nand_scan_tail(struct mtd_info *mtd) - ecc->write_oob = nand_write_oob_std; - if (!ecc->read_subpage) - ecc->read_subpage = nand_read_subpage; -- if (!ecc->write_subpage) -+ if (!ecc->write_subpage && ecc->hwctl && ecc->calculate) - ecc->write_subpage = nand_write_subpage_hwecc; - - case NAND_ECC_HW_SYNDROME: -@@ -4246,10 +4295,8 @@ int nand_scan_tail(struct mtd_info *mtd) - } - - /* See nand_bch_init() for details. */ -- ecc->bytes = DIV_ROUND_UP( -- ecc->strength * fls(8 * ecc->size), 8); -- ecc->priv = nand_bch_init(mtd, ecc->size, ecc->bytes, -- &ecc->layout); -+ ecc->bytes = 0; -+ ecc->priv = nand_bch_init(mtd); - if (!ecc->priv) { - pr_warn("BCH ECC initialization failed!\n"); - BUG(); -@@ -4280,20 +4327,9 @@ int nand_scan_tail(struct mtd_info *mtd) - if (!ecc->write_oob_raw) - ecc->write_oob_raw = ecc->write_oob; - -- /* -- * The number of bytes available for a client to place data into -- * the out of band area. -- */ -- ecc->layout->oobavail = 0; -- for (i = 0; ecc->layout->oobfree[i].length -- && i < ARRAY_SIZE(ecc->layout->oobfree); i++) -- ecc->layout->oobavail += ecc->layout->oobfree[i].length; -- mtd->oobavail = ecc->layout->oobavail; -- -- /* ECC sanity check: warn if it's too weak */ -- if (!nand_ecc_strength_good(mtd)) -- pr_warn("WARNING: %s: the ECC used on your system is too weak compared to the one required by the NAND chip\n", -- mtd->name); -+ /* propagate ecc info to mtd_info */ -+ mtd->ecc_strength = ecc->strength; -+ mtd->ecc_step_size = ecc->size; - - /* - * Set the number of read / write steps for one page depending on ECC -@@ -4306,6 +4342,21 @@ int nand_scan_tail(struct mtd_info *mtd) - } - ecc->total = ecc->steps * ecc->bytes; - -+ /* -+ * The number of bytes available for a client to place data into -+ * the out of band area. -+ */ -+ ret = mtd_ooblayout_count_freebytes(mtd); -+ if (ret < 0) -+ ret = 0; -+ -+ mtd->oobavail = ret; -+ -+ /* ECC sanity check: warn if it's too weak */ -+ if (!nand_ecc_strength_good(mtd)) -+ pr_warn("WARNING: %s: the ECC used on your system is too weak compared to the one required by the NAND chip\n", -+ mtd->name); -+ - /* Allow subpage writes up to ecc.steps. Not possible for MLC flash */ - if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && nand_is_slc(chip)) { - switch (ecc->steps) { -@@ -4362,10 +4413,6 @@ int nand_scan_tail(struct mtd_info *mtd) - mtd->_block_markbad = nand_block_markbad; - mtd->writebufsize = mtd->writesize; - -- /* propagate ecc info to mtd_info */ -- mtd->ecclayout = ecc->layout; -- mtd->ecc_strength = ecc->strength; -- mtd->ecc_step_size = ecc->size; - /* - * Initialize bitflip_threshold to its default prior scan_bbt() call. - * scan_bbt() might invoke mtd_read(), thus bitflip_threshold must be -@@ -4421,7 +4468,7 @@ EXPORT_SYMBOL(nand_scan); - */ - void nand_release(struct mtd_info *mtd) - { -- struct nand_chip *chip = mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - - if (chip->ecc.mode == NAND_ECC_SOFT_BCH) - nand_bch_free((struct nand_bch_control *)chip->ecc.priv); ---- a/drivers/mtd/nand/nand_bbt.c -+++ b/drivers/mtd/nand/nand_bbt.c -@@ -172,7 +172,7 @@ static int read_bbt(struct mtd_info *mtd - struct nand_bbt_descr *td, int offs) - { - int res, ret = 0, i, j, act = 0; -- struct nand_chip *this = mtd->priv; -+ struct nand_chip *this = mtd_to_nand(mtd); - size_t retlen, len, totlen; - loff_t from; - int bits = td->options & NAND_BBT_NRBITS_MSK; -@@ -263,7 +263,7 @@ static int read_bbt(struct mtd_info *mtd - */ - static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip) - { -- struct nand_chip *this = mtd->priv; -+ struct nand_chip *this = mtd_to_nand(mtd); - int res = 0, i; - - if (td->options & NAND_BBT_PERCHIP) { -@@ -388,7 +388,7 @@ static u32 bbt_get_ver_offs(struct mtd_i - static void read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, - struct nand_bbt_descr *td, struct nand_bbt_descr *md) - { -- struct nand_chip *this = mtd->priv; -+ struct nand_chip *this = mtd_to_nand(mtd); - - /* Read the primary version, if available */ - if (td->options & NAND_BBT_VERSION) { -@@ -454,7 +454,7 @@ static int scan_block_fast(struct mtd_in - static int create_bbt(struct mtd_info *mtd, uint8_t *buf, - struct nand_bbt_descr *bd, int chip) - { -- struct nand_chip *this = mtd->priv; -+ struct nand_chip *this = mtd_to_nand(mtd); - int i, numblocks, numpages; - int startblock; - loff_t from; -@@ -523,7 +523,7 @@ static int create_bbt(struct mtd_info *m - */ - static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) - { -- struct nand_chip *this = mtd->priv; -+ struct nand_chip *this = mtd_to_nand(mtd); - int i, chips; - int startblock, block, dir; - int scanlen = mtd->writesize + mtd->oobsize; -@@ -618,7 +618,7 @@ static int write_bbt(struct mtd_info *mt - struct nand_bbt_descr *td, struct nand_bbt_descr *md, - int chipsel) - { -- struct nand_chip *this = mtd->priv; -+ struct nand_chip *this = mtd_to_nand(mtd); - struct erase_info einfo; - int i, res, chip = 0; - int bits, startblock, dir, page, offs, numblocks, sft, sftmsk; -@@ -819,7 +819,7 @@ static int write_bbt(struct mtd_info *mt - */ - static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) - { -- struct nand_chip *this = mtd->priv; -+ struct nand_chip *this = mtd_to_nand(mtd); - - return create_bbt(mtd, this->buffers->databuf, bd, -1); - } -@@ -838,7 +838,7 @@ static inline int nand_memory_bbt(struct - static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd) - { - int i, chips, writeops, create, chipsel, res, res2; -- struct nand_chip *this = mtd->priv; -+ struct nand_chip *this = mtd_to_nand(mtd); - struct nand_bbt_descr *td = this->bbt_td; - struct nand_bbt_descr *md = this->bbt_md; - struct nand_bbt_descr *rd, *rd2; -@@ -962,7 +962,7 @@ static int check_create(struct mtd_info - */ - static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) - { -- struct nand_chip *this = mtd->priv; -+ struct nand_chip *this = mtd_to_nand(mtd); - int i, j, chips, block, nrblocks, update; - uint8_t oldval; - -@@ -1022,7 +1022,7 @@ static void mark_bbt_region(struct mtd_i - */ - static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd) - { -- struct nand_chip *this = mtd->priv; -+ struct nand_chip *this = mtd_to_nand(mtd); - u32 pattern_len; - u32 bits; - u32 table_size; -@@ -1074,7 +1074,7 @@ static void verify_bbt_descr(struct mtd_ - */ - static int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) - { -- struct nand_chip *this = mtd->priv; -+ struct nand_chip *this = mtd_to_nand(mtd); - int len, res; - uint8_t *buf; - struct nand_bbt_descr *td = this->bbt_td; -@@ -1147,7 +1147,7 @@ err: - */ - static int nand_update_bbt(struct mtd_info *mtd, loff_t offs) - { -- struct nand_chip *this = mtd->priv; -+ struct nand_chip *this = mtd_to_nand(mtd); - int len, res = 0; - int chip, chipsel; - uint8_t *buf; -@@ -1281,7 +1281,7 @@ static int nand_create_badblock_pattern( - */ - int nand_default_bbt(struct mtd_info *mtd) - { -- struct nand_chip *this = mtd->priv; -+ struct nand_chip *this = mtd_to_nand(mtd); - int ret; - - /* Is a flash based bad block table requested? */ -@@ -1317,7 +1317,7 @@ int nand_default_bbt(struct mtd_info *mt - */ - int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs) - { -- struct nand_chip *this = mtd->priv; -+ struct nand_chip *this = mtd_to_nand(mtd); - int block; - - block = (int)(offs >> this->bbt_erase_shift); -@@ -1332,7 +1332,7 @@ int nand_isreserved_bbt(struct mtd_info - */ - int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) - { -- struct nand_chip *this = mtd->priv; -+ struct nand_chip *this = mtd_to_nand(mtd); - int block, res; - - block = (int)(offs >> this->bbt_erase_shift); -@@ -1359,7 +1359,7 @@ int nand_isbad_bbt(struct mtd_info *mtd, - */ - int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs) - { -- struct nand_chip *this = mtd->priv; -+ struct nand_chip *this = mtd_to_nand(mtd); - int block, ret = 0; - - block = (int)(offs >> this->bbt_erase_shift); -@@ -1373,5 +1373,3 @@ int nand_markbad_bbt(struct mtd_info *mt - - return ret; - } -- --EXPORT_SYMBOL(nand_scan_bbt); ---- a/drivers/mtd/nand/nand_bch.c -+++ b/drivers/mtd/nand/nand_bch.c -@@ -32,13 +32,11 @@ - /** - * struct nand_bch_control - private NAND BCH control structure - * @bch: BCH control structure -- * @ecclayout: private ecc layout for this BCH configuration - * @errloc: error location array - * @eccmask: XOR ecc mask, allows erased pages to be decoded as valid - */ - struct nand_bch_control { - struct bch_control *bch; -- struct nand_ecclayout ecclayout; - unsigned int *errloc; - unsigned char *eccmask; - }; -@@ -52,7 +50,7 @@ struct nand_bch_control { - int nand_bch_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf, - unsigned char *code) - { -- const struct nand_chip *chip = mtd->priv; -+ const struct nand_chip *chip = mtd_to_nand(mtd); - struct nand_bch_control *nbc = chip->ecc.priv; - unsigned int i; - -@@ -79,7 +77,7 @@ EXPORT_SYMBOL(nand_bch_calculate_ecc); - int nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf, - unsigned char *read_ecc, unsigned char *calc_ecc) - { -- const struct nand_chip *chip = mtd->priv; -+ const struct nand_chip *chip = mtd_to_nand(mtd); - struct nand_bch_control *nbc = chip->ecc.priv; - unsigned int *errloc = nbc->errloc; - int i, count; -@@ -98,7 +96,7 @@ int nand_bch_correct_data(struct mtd_inf - } - } else if (count < 0) { - printk(KERN_ERR "ecc unrecoverable error\n"); -- count = -1; -+ count = -EBADMSG; - } - return count; - } -@@ -107,9 +105,6 @@ EXPORT_SYMBOL(nand_bch_correct_data); - /** - * nand_bch_init - [NAND Interface] Initialize NAND BCH error correction - * @mtd: MTD block structure -- * @eccsize: ecc block size in bytes -- * @eccbytes: ecc length in bytes -- * @ecclayout: output default layout - * - * Returns: - * a pointer to a new NAND BCH control structure, or NULL upon failure -@@ -123,14 +118,20 @@ EXPORT_SYMBOL(nand_bch_correct_data); - * @eccsize = 512 (thus, m=13 is the smallest integer such that 2^m-1 > 512*8) - * @eccbytes = 7 (7 bytes are required to store m*t = 13*4 = 52 bits) - */ --struct nand_bch_control * --nand_bch_init(struct mtd_info *mtd, unsigned int eccsize, unsigned int eccbytes, -- struct nand_ecclayout **ecclayout) -+struct nand_bch_control *nand_bch_init(struct mtd_info *mtd) - { -+ struct nand_chip *nand = mtd_to_nand(mtd); - unsigned int m, t, eccsteps, i; -- struct nand_ecclayout *layout; - struct nand_bch_control *nbc = NULL; - unsigned char *erased_page; -+ unsigned int eccsize = nand->ecc.size; -+ unsigned int eccbytes = nand->ecc.bytes; -+ unsigned int eccstrength = nand->ecc.strength; -+ -+ if (!eccbytes && eccstrength) { -+ eccbytes = DIV_ROUND_UP(eccstrength * fls(8 * eccsize), 8); -+ nand->ecc.bytes = eccbytes; -+ } - - if (!eccsize || !eccbytes) { - printk(KERN_WARNING "ecc parameters not supplied\n"); -@@ -158,7 +159,7 @@ nand_bch_init(struct mtd_info *mtd, unsi - eccsteps = mtd->writesize/eccsize; - - /* if no ecc placement scheme was provided, build one */ -- if (!*ecclayout) { -+ if (!mtd->ooblayout) { - - /* handle large page devices only */ - if (mtd->oobsize < 64) { -@@ -167,24 +168,7 @@ nand_bch_init(struct mtd_info *mtd, unsi - goto fail; - } - -- layout = &nbc->ecclayout; -- layout->eccbytes = eccsteps*eccbytes; -- -- /* reserve 2 bytes for bad block marker */ -- if (layout->eccbytes+2 > mtd->oobsize) { -- printk(KERN_WARNING "no suitable oob scheme available " -- "for oobsize %d eccbytes %u\n", mtd->oobsize, -- eccbytes); -- goto fail; -- } -- /* put ecc bytes at oob tail */ -- for (i = 0; i < layout->eccbytes; i++) -- layout->eccpos[i] = mtd->oobsize-layout->eccbytes+i; -- -- layout->oobfree[0].offset = 2; -- layout->oobfree[0].length = mtd->oobsize-2-layout->eccbytes; -- -- *ecclayout = layout; -+ mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops); - } - - /* sanity checks */ -@@ -192,7 +176,8 @@ nand_bch_init(struct mtd_info *mtd, unsi - printk(KERN_WARNING "eccsize %u is too large\n", eccsize); - goto fail; - } -- if ((*ecclayout)->eccbytes != (eccsteps*eccbytes)) { -+ -+ if (mtd_ooblayout_count_eccbytes(mtd) != (eccsteps*eccbytes)) { - printk(KERN_WARNING "invalid ecc layout\n"); - goto fail; - } -@@ -216,6 +201,9 @@ nand_bch_init(struct mtd_info *mtd, unsi - for (i = 0; i < eccbytes; i++) - nbc->eccmask[i] ^= 0xff; - -+ if (!eccstrength) -+ nand->ecc.strength = (eccbytes * 8) / fls(8 * eccsize); -+ - return nbc; - fail: - nand_bch_free(nbc); ---- a/drivers/mtd/nand/nand_ecc.c -+++ b/drivers/mtd/nand/nand_ecc.c -@@ -424,7 +424,7 @@ int nand_calculate_ecc(struct mtd_info * - unsigned char *code) - { - __nand_calculate_ecc(buf, -- ((struct nand_chip *)mtd->priv)->ecc.size, code); -+ mtd_to_nand(mtd)->ecc.size, code); - - return 0; - } -@@ -524,7 +524,7 @@ int nand_correct_data(struct mtd_info *m - unsigned char *read_ecc, unsigned char *calc_ecc) - { - return __nand_correct_data(buf, read_ecc, calc_ecc, -- ((struct nand_chip *)mtd->priv)->ecc.size); -+ mtd_to_nand(mtd)->ecc.size); - } - EXPORT_SYMBOL(nand_correct_data); - ---- a/drivers/mtd/nand/nand_ids.c -+++ b/drivers/mtd/nand/nand_ids.c -@@ -50,8 +50,8 @@ struct nand_flash_dev nand_flash_ids[] = - SZ_16K, SZ_8K, SZ_4M, 0, 6, 1280, NAND_ECC_INFO(40, SZ_1K) }, - {"H27UCG8T2ATR-BC 64G 3.3V 8-bit", - { .id = {0xad, 0xde, 0x94, 0xda, 0x74, 0xc4} }, -- SZ_8K, SZ_8K, SZ_2M, 0, 6, 640, NAND_ECC_INFO(40, SZ_1K), -- 4 }, -+ SZ_8K, SZ_8K, SZ_2M, NAND_NEED_SCRAMBLING, 6, 640, -+ NAND_ECC_INFO(40, SZ_1K), 4 }, - - LEGACY_ID_NAND("NAND 4MiB 5V 8-bit", 0x6B, 4, SZ_8K, SP_OPTIONS), - LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE3, 4, SZ_8K, SP_OPTIONS), ---- a/drivers/mtd/nand/nandsim.c -+++ b/drivers/mtd/nand/nandsim.c -@@ -666,8 +666,8 @@ static char *get_partition_name(int i) - */ - static int init_nandsim(struct mtd_info *mtd) - { -- struct nand_chip *chip = mtd->priv; -- struct nandsim *ns = chip->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct nandsim *ns = nand_get_controller_data(chip); - int i, ret = 0; - uint64_t remains; - uint64_t next_offset; -@@ -1908,7 +1908,8 @@ static void switch_state(struct nandsim - - static u_char ns_nand_read_byte(struct mtd_info *mtd) - { -- struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct nandsim *ns = nand_get_controller_data(chip); - u_char outb = 0x00; - - /* Sanity and correctness checks */ -@@ -1969,7 +1970,8 @@ static u_char ns_nand_read_byte(struct m - - static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte) - { -- struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct nandsim *ns = nand_get_controller_data(chip); - - /* Sanity and correctness checks */ - if (!ns->lines.ce) { -@@ -2123,7 +2125,8 @@ static void ns_nand_write_byte(struct mt - - static void ns_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int bitmask) - { -- struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct nandsim *ns = nand_get_controller_data(chip); - - ns->lines.cle = bitmask & NAND_CLE ? 1 : 0; - ns->lines.ale = bitmask & NAND_ALE ? 1 : 0; -@@ -2141,7 +2144,7 @@ static int ns_device_ready(struct mtd_in - - static uint16_t ns_nand_read_word(struct mtd_info *mtd) - { -- struct nand_chip *chip = (struct nand_chip *)mtd->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); - - NS_DBG("read_word\n"); - -@@ -2150,7 +2153,8 @@ static uint16_t ns_nand_read_word(struct - - static void ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) - { -- struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct nandsim *ns = nand_get_controller_data(chip); - - /* Check that chip is expecting data input */ - if (!(ns->state & STATE_DATAIN_MASK)) { -@@ -2177,7 +2181,8 @@ static void ns_nand_write_buf(struct mtd - - static void ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) - { -- struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv; -+ struct nand_chip *chip = mtd_to_nand(mtd); -+ struct nandsim *ns = nand_get_controller_data(chip); - - /* Sanity and correctness checks */ - if (!ns->lines.ce) { -@@ -2198,7 +2203,7 @@ static void ns_nand_read_buf(struct mtd_ - int i; - - for (i = 0; i < len; i++) -- buf[i] = ((struct nand_chip *)mtd->priv)->read_byte(mtd); -+ buf[i] = mtd_to_nand(mtd)->read_byte(mtd); - - return; - } -@@ -2236,16 +2241,15 @@ static int __init ns_init_module(void) - } - - /* Allocate and initialize mtd_info, nand_chip and nandsim structures */ -- nsmtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip) -- + sizeof(struct nandsim), GFP_KERNEL); -- if (!nsmtd) { -+ chip = kzalloc(sizeof(struct nand_chip) + sizeof(struct nandsim), -+ GFP_KERNEL); -+ if (!chip) { - NS_ERR("unable to allocate core structures.\n"); - return -ENOMEM; - } -- chip = (struct nand_chip *)(nsmtd + 1); -- nsmtd->priv = (void *)chip; -+ nsmtd = nand_to_mtd(chip); - nand = (struct nandsim *)(chip + 1); -- chip->priv = (void *)nand; -+ nand_set_controller_data(chip, (void *)nand); - - /* - * Register simulator's callbacks. -@@ -2257,6 +2261,7 @@ static int __init ns_init_module(void) - chip->read_buf = ns_nand_read_buf; - chip->read_word = ns_nand_read_word; - chip->ecc.mode = NAND_ECC_SOFT; -+ chip->ecc.algo = NAND_ECC_HAMMING; - /* The NAND_SKIP_BBTSCAN option is necessary for 'overridesize' */ - /* and 'badblocks' parameters to work */ - chip->options |= NAND_SKIP_BBTSCAN; -@@ -2335,6 +2340,7 @@ static int __init ns_init_module(void) - goto error; - } - chip->ecc.mode = NAND_ECC_SOFT_BCH; -+ chip->ecc.algo = NAND_ECC_BCH; - chip->ecc.size = 512; - chip->ecc.strength = bch; - chip->ecc.bytes = eccbytes; -@@ -2392,7 +2398,7 @@ err_exit: - for (i = 0;i < ARRAY_SIZE(nand->partitions); ++i) - kfree(nand->partitions[i].name); - error: -- kfree(nsmtd); -+ kfree(chip); - free_lists(); - - return retval; -@@ -2405,7 +2411,8 @@ module_init(ns_init_module); - */ - static void __exit ns_cleanup_module(void) - { -- struct nandsim *ns = ((struct nand_chip *)nsmtd->priv)->priv; -+ struct nand_chip *chip = mtd_to_nand(nsmtd); -+ struct nandsim *ns = nand_get_controller_data(chip); - int i; - - nandsim_debugfs_remove(ns); -@@ -2413,7 +2420,7 @@ static void __exit ns_cleanup_module(voi - nand_release(nsmtd); /* Unregister driver */ - for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i) - kfree(ns->partitions[i].name); -- kfree(nsmtd); /* Free other structures */ -+ kfree(mtd_to_nand(nsmtd)); /* Free other structures */ - free_lists(); - } - ---- a/drivers/mtd/ofpart.c -+++ b/drivers/mtd/ofpart.c -@@ -26,9 +26,10 @@ static bool node_has_compatible(struct d - } - - static int parse_ofpart_partitions(struct mtd_info *master, -- struct mtd_partition **pparts, -+ const struct mtd_partition **pparts, - struct mtd_part_parser_data *data) - { -+ struct mtd_partition *parts; - struct device_node *mtd_node; - struct device_node *ofpart_node; - const char *partname; -@@ -37,10 +38,8 @@ static int parse_ofpart_partitions(struc - bool dedicated = true; - - -- if (!data) -- return 0; -- -- mtd_node = data->of_node; -+ /* Pull of_node from the master device node */ -+ mtd_node = mtd_get_of_node(master); - if (!mtd_node) - return 0; - -@@ -72,8 +71,8 @@ static int parse_ofpart_partitions(struc - if (nr_parts == 0) - return 0; - -- *pparts = kzalloc(nr_parts * sizeof(**pparts), GFP_KERNEL); -- if (!*pparts) -+ parts = kzalloc(nr_parts * sizeof(*parts), GFP_KERNEL); -+ if (!parts) - return -ENOMEM; - - i = 0; -@@ -107,19 +106,19 @@ static int parse_ofpart_partitions(struc - goto ofpart_fail; - } - -- (*pparts)[i].offset = of_read_number(reg, a_cells); -- (*pparts)[i].size = of_read_number(reg + a_cells, s_cells); -+ parts[i].offset = of_read_number(reg, a_cells); -+ parts[i].size = of_read_number(reg + a_cells, s_cells); - - partname = of_get_property(pp, "label", &len); - if (!partname) - partname = of_get_property(pp, "name", &len); -- (*pparts)[i].name = partname; -+ parts[i].name = partname; - - if (of_get_property(pp, "read-only", &len)) -- (*pparts)[i].mask_flags |= MTD_WRITEABLE; -+ parts[i].mask_flags |= MTD_WRITEABLE; - - if (of_get_property(pp, "lock", &len)) -- (*pparts)[i].mask_flags |= MTD_POWERUP_LOCK; -+ parts[i].mask_flags |= MTD_POWERUP_LOCK; - - i++; - } -@@ -127,6 +126,7 @@ static int parse_ofpart_partitions(struc - if (!nr_parts) - goto ofpart_none; - -+ *pparts = parts; - return nr_parts; - - ofpart_fail: -@@ -135,21 +135,20 @@ ofpart_fail: - ret = -EINVAL; - ofpart_none: - of_node_put(pp); -- kfree(*pparts); -- *pparts = NULL; -+ kfree(parts); - return ret; - } - - static struct mtd_part_parser ofpart_parser = { -- .owner = THIS_MODULE, - .parse_fn = parse_ofpart_partitions, - .name = "ofpart", - }; - - static int parse_ofoldpart_partitions(struct mtd_info *master, -- struct mtd_partition **pparts, -+ const struct mtd_partition **pparts, - struct mtd_part_parser_data *data) - { -+ struct mtd_partition *parts; - struct device_node *dp; - int i, plen, nr_parts; - const struct { -@@ -157,10 +156,8 @@ static int parse_ofoldpart_partitions(st - } *part; - const char *names; - -- if (!data) -- return 0; -- -- dp = data->of_node; -+ /* Pull of_node from the master device node */ -+ dp = mtd_get_of_node(master); - if (!dp) - return 0; - -@@ -173,37 +170,37 @@ static int parse_ofoldpart_partitions(st - - nr_parts = plen / sizeof(part[0]); - -- *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL); -- if (!*pparts) -+ parts = kzalloc(nr_parts * sizeof(*parts), GFP_KERNEL); -+ if (!parts) - return -ENOMEM; - - names = of_get_property(dp, "partition-names", &plen); - - for (i = 0; i < nr_parts; i++) { -- (*pparts)[i].offset = be32_to_cpu(part->offset); -- (*pparts)[i].size = be32_to_cpu(part->len) & ~1; -+ parts[i].offset = be32_to_cpu(part->offset); -+ parts[i].size = be32_to_cpu(part->len) & ~1; - /* bit 0 set signifies read only partition */ - if (be32_to_cpu(part->len) & 1) -- (*pparts)[i].mask_flags = MTD_WRITEABLE; -+ parts[i].mask_flags = MTD_WRITEABLE; - - if (names && (plen > 0)) { - int len = strlen(names) + 1; - -- (*pparts)[i].name = names; -+ parts[i].name = names; - plen -= len; - names += len; - } else { -- (*pparts)[i].name = "unnamed"; -+ parts[i].name = "unnamed"; - } - - part++; - } - -+ *pparts = parts; - return nr_parts; - } - - static struct mtd_part_parser ofoldpart_parser = { -- .owner = THIS_MODULE, - .parse_fn = parse_ofoldpart_partitions, - .name = "ofoldpart", - }; ---- a/drivers/mtd/spi-nor/Kconfig -+++ b/drivers/mtd/spi-nor/Kconfig -@@ -7,6 +7,14 @@ menuconfig MTD_SPI_NOR - - if MTD_SPI_NOR - -+config MTD_MT81xx_NOR -+ tristate "Mediatek MT81xx SPI NOR flash controller" -+ depends on HAS_IOMEM -+ help -+ This enables access to SPI NOR flash, using MT81xx SPI NOR flash -+ controller. This controller does not support generic SPI BUS, it only -+ supports SPI NOR Flash. -+ - config MTD_SPI_NOR_USE_4K_SECTORS - bool "Use small 4096 B erase sectors" - default y -@@ -23,7 +31,7 @@ config MTD_SPI_NOR_USE_4K_SECTORS - - config SPI_FSL_QUADSPI - tristate "Freescale Quad SPI controller" -- depends on ARCH_MXC || COMPILE_TEST -+ depends on ARCH_MXC || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST - depends on HAS_IOMEM - help - This enables support for the Quad SPI controller in master mode. ---- a/drivers/mtd/spi-nor/Makefile -+++ b/drivers/mtd/spi-nor/Makefile -@@ -1,3 +1,4 @@ - obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o - obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o -+obj-$(CONFIG_MTD_MT81xx_NOR) += mtk-quadspi.o - obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o ---- /dev/null -+++ b/drivers/mtd/spi-nor/mtk-quadspi.c -@@ -0,0 +1,485 @@ -+/* -+ * Copyright (c) 2015 MediaTek Inc. -+ * Author: Bayi Cheng -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 index aa45441afa..0000000000 --- a/target/linux/mediatek/patches-4.4/0073-of-mtd-prepare-helper-reading-NAND-ECC-algo-from-DT.patch +++ /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?= -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 -Signed-off-by: Boris Brezillon ---- - 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 - 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 index 5f260e3e34..0000000000 --- a/target/linux/mediatek/patches-4.4/0074-mtd-mediatek-device-tree-docs-for-MTK-Smart-Device-G.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 5e1c00983efeca4522ac2e8574e3e3997d26a203 Mon Sep 17 00:00:00 2001 -From: Jorge Ramirez-Ortiz -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 ---- - 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 = ; -+ 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 = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ input-enable; -+ drive-strength = ; -+ bias-pull-up; -+ }; -+ -+ pins_we { -+ pinmux = ; -+ drive-strength = ; -+ bias-pull-up = ; -+ }; -+ -+ pins_ale { -+ pinmux = ; -+ drive-strength = ; -+ bias-pull-down = ; -+ }; -+ }; -+ }; -+ -+ &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 = ; -+ 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 index e5312eb08c..0000000000 --- a/target/linux/mediatek/patches-4.4/0075-mtd-mediatek-driver-for-MTK-Smart-Device-Gen1-NAND.patch +++ /dev/null @@ -1,2064 +0,0 @@ -From de18239fc971cfc17c53320c66ae64dd5ade032d Mon Sep 17 00:00:00 2001 -From: Jorge Ramirez-Ortiz -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 ---- - 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 -+ * Jorge Ramirez-Ortiz -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 "); -+MODULE_AUTHOR("Jorge Ramirez-Ortiz "); -+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 -+ * Jorge Ramirez-Ortiz -+ * 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 -+ -+#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 -+ * Jorge Ramirez-Ortiz -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#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 "); -+MODULE_AUTHOR("Jorge Ramirez-Ortiz "); -+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 index 7702246a4c..0000000000 --- a/target/linux/mediatek/patches-4.4/0076-mtd-nand-add-power-domains-to-the-mediatek-driver.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 5dc0d474396e04e6c140d71f0e113eb1c03501c5 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 - #include -+#include - #include - #include - #include -@@ -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 index c2fe21825c..0000000000 --- a/target/linux/mediatek/patches-4.4/0077-net-next-mediatek-use-mdiobus_free-in-favour-of-kfre.patch +++ /dev/null @@ -1,36 +0,0 @@ -From b1c85818c3fb00022dc125bb62d657d3fd3cf49c Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Signed-off-by: John Crispin ---- - 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 index 42adb9e786..0000000000 --- a/target/linux/mediatek/patches-4.4/0078-net-next-mediatek-fix-gigabit-and-flow-control-adver.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 09313f26999e2685e0b9434374e7308e1f447e55 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Signed-off-by: John Crispin ---- - 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 index 669febbdf1..0000000000 --- a/target/linux/mediatek/patches-4.4/0079-net-next-mediatek-add-fixed-phy-support.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 09f0b50ae838bd6e2bbf0aa22de9f352122297de Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Signed-off-by: John Crispin ---- - 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 index 1d176f2ece..0000000000 --- a/target/linux/mediatek/patches-4.4/0080-net-next-mediatek-properly-handle-RGMII-modes.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 25eaa5d6483a5899e6bf48b47f762f05c186b4b6 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Signed-off-by: John Crispin ---- - 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 index f1c7290aac..0000000000 --- a/target/linux/mediatek/patches-4.4/0081-net-next-mediatek-fix-DQL-support.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 81cdbda2a08375b9d5915567d2210bf2433e7332 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index 19cdbf0d3e..0000000000 --- a/target/linux/mediatek/patches-4.4/0082-net-next-mediatek-add-missing-return-code-check.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 51ca1e9f141499fd7c95bff5401215b706656754 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Signed-off-by: John Crispin ---- - 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 index 793875faf4..0000000000 --- a/target/linux/mediatek/patches-4.4/0083-net-next-mediatek-fix-missing-free-of-scratch-memory.patch +++ /dev/null @@ -1,92 +0,0 @@ -From b48745c534ced06005d2ba57198b54a6a160b39d Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 18 +++++++++++++----- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++ - 2 files changed, 15 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -484,14 +484,14 @@ static inline void mtk_rx_get_desc(struc - /* the qdma core needs scratch memory to be setup */ - static int mtk_init_fq_dma(struct mtk_eth *eth) - { -- dma_addr_t phy_ring_head, phy_ring_tail; -+ dma_addr_t phy_ring_tail; - int cnt = MTK_DMA_SIZE; - dma_addr_t dma_addr; - int i; - - eth->scratch_ring = dma_alloc_coherent(eth->dev, - cnt * sizeof(struct mtk_tx_dma), -- &phy_ring_head, -+ ð->phy_scratch_ring, - GFP_ATOMIC | __GFP_ZERO); - if (unlikely(!eth->scratch_ring)) - return -ENOMEM; -@@ -508,19 +508,19 @@ static int mtk_init_fq_dma(struct mtk_et - return -ENOMEM; - - memset(eth->scratch_ring, 0x0, sizeof(struct mtk_tx_dma) * cnt); -- phy_ring_tail = phy_ring_head + -+ phy_ring_tail = eth->phy_scratch_ring + - (sizeof(struct mtk_tx_dma) * (cnt - 1)); - - for (i = 0; i < cnt; i++) { - eth->scratch_ring[i].txd1 = - (dma_addr + (i * MTK_QDMA_PAGE_SIZE)); - if (i < cnt - 1) -- eth->scratch_ring[i].txd2 = (phy_ring_head + -+ eth->scratch_ring[i].txd2 = (eth->phy_scratch_ring + - ((i + 1) * sizeof(struct mtk_tx_dma))); - eth->scratch_ring[i].txd3 = TX_DMA_SDL(MTK_QDMA_PAGE_SIZE); - } - -- mtk_w32(eth, phy_ring_head, MTK_QDMA_FQ_HEAD); -+ mtk_w32(eth, eth->phy_scratch_ring, MTK_QDMA_FQ_HEAD); - mtk_w32(eth, phy_ring_tail, MTK_QDMA_FQ_TAIL); - mtk_w32(eth, (cnt << 16) | cnt, MTK_QDMA_FQ_CNT); - mtk_w32(eth, MTK_QDMA_PAGE_SIZE << 16, MTK_QDMA_FQ_BLEN); -@@ -1220,6 +1220,14 @@ static void mtk_dma_free(struct mtk_eth - for (i = 0; i < MTK_MAC_COUNT; i++) - if (eth->netdev[i]) - netdev_reset_queue(eth->netdev[i]); -+ if (eth->scratch_ring) { -+ dma_free_coherent(eth->dev, -+ MTK_DMA_SIZE * sizeof(struct mtk_tx_dma), -+ eth->scratch_ring, -+ eth->phy_scratch_ring); -+ eth->scratch_ring = NULL; -+ eth->phy_scratch_ring = 0; -+ } - mtk_tx_clean(eth); - mtk_rx_clean(eth); - kfree(eth->scratch_head); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -357,6 +357,7 @@ struct mtk_rx_ring { - * @rx_ring: Pointer to the memore holding info about the RX ring - * @rx_napi: The NAPI struct - * @scratch_ring: Newer SoCs need memory for a second HW managed TX ring -+ * @phy_scratch_ring: physical address of scratch_ring - * @scratch_head: The scratch memory that scratch_ring points to. - * @clk_ethif: The ethif clock - * @clk_esw: The switch clock -@@ -384,6 +385,7 @@ struct mtk_eth { - struct mtk_rx_ring rx_ring; - struct napi_struct rx_napi; - struct mtk_tx_dma *scratch_ring; -+ dma_addr_t phy_scratch_ring; - void *scratch_head; - struct clk *clk_ethif; - struct clk *clk_esw; 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 index eb44af6f89..0000000000 --- a/target/linux/mediatek/patches-4.4/0084-net-next-mediatek-invalid-buffer-lookup-in-mtk_tx_ma.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 1eea1536dbbbfda418751ec6f5387acb521ddb97 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Signed-off-by: John Crispin ---- - 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 index 2b2a011b3d..0000000000 --- a/target/linux/mediatek/patches-4.4/0085-net-next-mediatek-dropped-rx-packets-are-not-being-c.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 98aac832925a99afee8722cdfd5a848dd6086b8f Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Signed-off-by: John Crispin ---- - 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 index cd4bdf8fa4..0000000000 --- a/target/linux/mediatek/patches-4.4/0086-net-next-mediatek-add-next-data-pointer-coherency-pr.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 5077ac38a86023124ebbe24cd1b7ecbd0f8edaff Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Signed-off-by: John Crispin ---- - 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 index 6e809b9315..0000000000 --- a/target/linux/mediatek/patches-4.4/0087-net-next-mediatek-disable-all-interrupts-during-prob.patch +++ /dev/null @@ -1,26 +0,0 @@ -From f9a08e142fd87c72a7803203ce4ecc94806046ca Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index c35975b072..0000000000 --- a/target/linux/mediatek/patches-4.4/0088-net-next-mediatek-fix-threshold-value.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 34ea0f209e0759158e363039852a04b1facc3acd Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index 96928d232a..0000000000 --- a/target/linux/mediatek/patches-4.4/0089-net-next-mediatek-increase-watchdog_timeo.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 2cbf3f95a49925317ef4138ceaf7f7f30f353f0f Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index b6f32fc451..0000000000 --- a/target/linux/mediatek/patches-4.4/0090-net-next-mediatek-fix-off-by-one-in-the-TX-ring-allo.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 94425de9ede5ef0eafbfced65140c30e7c0b6c0d Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Signed-off-by: John Crispin ---- - 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 index 257634c4c3..0000000000 --- a/target/linux/mediatek/patches-4.4/0091-net-next-mediatek-only-wake-the-queue-if-it-is-stopp.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 1473b4cce85760c0202a08e6a48ec51867dc1bf7 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 index fe08958b5c..0000000000 --- a/target/linux/mediatek/patches-4.4/0092-net-next-mediatek-remove-superfluous-queue-wake-up-c.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 538020913db04d199ce4d7e845444880e8200b5f Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -795,12 +795,9 @@ static int mtk_start_xmit(struct sk_buff - if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) - goto drop; - -- if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) { -+ if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) - mtk_stop_queue(eth); -- if (unlikely(atomic_read(&ring->free_count) > -- ring->thresh)) -- mtk_wake_queue(eth); -- } -+ - spin_unlock_irqrestore(ð->page_lock, flags); - - return NETDEV_TX_OK; 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 index 3ddbbc6fd6..0000000000 --- a/target/linux/mediatek/patches-4.4/0093-net-next-mediatek-remove-superfluous-register-reads.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 31428406bf4b9da2a322ae947096414ff0489fb5 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Signed-off-by: John Crispin ---- - 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 index 983d0c2712..0000000000 --- a/target/linux/mediatek/patches-4.4/0094-net-next-mediatek-don-t-use-intermediate-variables-t.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 441d87495f33fd444a2b2a16f6df07892dac3f89 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 ++++++++++------------ - 1 file changed, 10 insertions(+), 12 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -806,7 +806,7 @@ drop: - } - - static int mtk_poll_rx(struct napi_struct *napi, int budget, -- struct mtk_eth *eth, u32 rx_intr) -+ struct mtk_eth *eth) - { - struct mtk_rx_ring *ring = ð->rx_ring; - int idx = ring->calc_idx; -@@ -894,7 +894,7 @@ release_desc: - } - - if (done < budget) -- mtk_w32(eth, rx_intr, MTK_QMTK_INT_STATUS); -+ mtk_w32(eth, MTK_RX_DONE_INT, MTK_QMTK_INT_STATUS); - - return done; - } -@@ -977,28 +977,26 @@ static int mtk_poll_tx(struct mtk_eth *e - static int mtk_poll(struct napi_struct *napi, int budget) - { - struct mtk_eth *eth = container_of(napi, struct mtk_eth, rx_napi); -- u32 status, status2, mask, tx_intr, rx_intr, status_intr; -+ u32 status, status2, mask; - int tx_done, rx_done; - bool tx_again = false; - - status = mtk_r32(eth, MTK_QMTK_INT_STATUS); - status2 = mtk_r32(eth, MTK_INT_STATUS2); -- tx_intr = MTK_TX_DONE_INT; -- rx_intr = MTK_RX_DONE_INT; -- status_intr = (MTK_GDM1_AF | MTK_GDM2_AF); - tx_done = 0; - rx_done = 0; - tx_again = 0; - -- if (status & tx_intr) -+ if (status & MTK_TX_DONE_INT) - tx_done = mtk_poll_tx(eth, budget, &tx_again); - -- if (status & rx_intr) -- rx_done = mtk_poll_rx(napi, budget, eth, rx_intr); -+ if (status & MTK_RX_DONE_INT) -+ rx_done = mtk_poll_rx(napi, budget, eth); - -- if (unlikely(status2 & status_intr)) { -+ if (unlikely(status2 & (MTK_GDM1_AF | MTK_GDM2_AF))) { - mtk_stats_update(eth); -- mtk_w32(eth, status_intr, MTK_INT_STATUS2); -+ mtk_w32(eth, (MTK_GDM1_AF | MTK_GDM2_AF), -+ MTK_INT_STATUS2); - } - - if (unlikely(netif_msg_intr(eth))) { -@@ -1016,7 +1014,7 @@ static int mtk_poll(struct napi_struct * - return budget; - - napi_complete(napi); -- mtk_irq_enable(eth, tx_intr | rx_intr); -+ mtk_irq_enable(eth, MTK_RX_DONE_INT | MTK_RX_DONE_INT); - - return rx_done; - } 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 index bf27aac15c..0000000000 --- a/target/linux/mediatek/patches-4.4/0095-net-next-mediatek-add-IRQ-locking.patch +++ /dev/null @@ -1,64 +0,0 @@ -From dd08d1ac4cfc86fbea5ee207b9615922ede88ec6 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Signed-off-by: John Crispin ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 +++++++ - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + - 2 files changed, 8 insertions(+) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -331,18 +331,24 @@ static void mtk_mdio_cleanup(struct mtk_ - - static inline void mtk_irq_disable(struct mtk_eth *eth, u32 mask) - { -+ unsigned long flags; - u32 val; - -+ spin_lock_irqsave(ð->irq_lock, flags); - val = mtk_r32(eth, MTK_QDMA_INT_MASK); - mtk_w32(eth, val & ~mask, MTK_QDMA_INT_MASK); -+ spin_unlock_irqrestore(ð->irq_lock, flags); - } - - static inline void mtk_irq_enable(struct mtk_eth *eth, u32 mask) - { -+ unsigned long flags; - u32 val; - -+ spin_lock_irqsave(ð->irq_lock, flags); - val = mtk_r32(eth, MTK_QDMA_INT_MASK); - mtk_w32(eth, val | mask, MTK_QDMA_INT_MASK); -+ spin_unlock_irqrestore(ð->irq_lock, flags); - } - - static int mtk_set_mac_address(struct net_device *dev, void *p) -@@ -1771,6 +1777,7 @@ static int mtk_probe(struct platform_dev - return -EADDRNOTAVAIL; - - spin_lock_init(ð->page_lock); -+ spin_lock_init(ð->irq_lock); - - eth->ethsys = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, - "mediatek,ethsys"); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -373,6 +373,7 @@ struct mtk_eth { - void __iomem *base; - struct reset_control *rstc; - spinlock_t page_lock; -+ spinlock_t irq_lock; - struct net_device dummy_dev; - struct net_device *netdev[MTK_MAX_DEVS]; - struct mtk_mac *mac[MTK_MAX_DEVS]; 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 index 727073ebcd..0000000000 --- a/target/linux/mediatek/patches-4.4/0096-net-next-mediatek-add-support-for-IRQ-grouping.patch +++ /dev/null @@ -1,361 +0,0 @@ -From 190df1a9dbf4d8809b7f991194ce60e47f2290a2 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 156 +++++++++++++++++---------- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 15 ++- - 2 files changed, 111 insertions(+), 60 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -905,14 +905,13 @@ release_desc: - return done; - } - --static int mtk_poll_tx(struct mtk_eth *eth, int budget, bool *tx_again) -+static int mtk_poll_tx(struct mtk_eth *eth, int budget) - { - struct mtk_tx_ring *ring = ð->tx_ring; - struct mtk_tx_dma *desc; - struct sk_buff *skb; - struct mtk_tx_buf *tx_buf; -- int total = 0, done = 0; -- unsigned int bytes = 0; -+ unsigned int bytes = 0, done = 0; - u32 cpu, dma; - static int condition; - int i; -@@ -964,63 +963,82 @@ static int mtk_poll_tx(struct mtk_eth *e - netdev_completed_queue(eth->netdev[i], done, bytes); - } - -- /* read hw index again make sure no new tx packet */ -- if (cpu != dma || cpu != mtk_r32(eth, MTK_QTX_DRX_PTR)) -- *tx_again = true; -- else -- mtk_w32(eth, MTK_TX_DONE_INT, MTK_QMTK_INT_STATUS); -- -- if (!total) -- return 0; -- - if (mtk_queue_stopped(eth) && - (atomic_read(&ring->free_count) > ring->thresh)) - mtk_wake_queue(eth); - -- return total; -+ return done; - } - --static int mtk_poll(struct napi_struct *napi, int budget) -+static void mtk_handle_status_irq(struct mtk_eth *eth) - { -- struct mtk_eth *eth = container_of(napi, struct mtk_eth, rx_napi); -- u32 status, status2, mask; -- int tx_done, rx_done; -- bool tx_again = false; -- -- status = mtk_r32(eth, MTK_QMTK_INT_STATUS); -- status2 = mtk_r32(eth, MTK_INT_STATUS2); -- tx_done = 0; -- rx_done = 0; -- tx_again = 0; -- -- if (status & MTK_TX_DONE_INT) -- tx_done = mtk_poll_tx(eth, budget, &tx_again); -- -- if (status & MTK_RX_DONE_INT) -- rx_done = mtk_poll_rx(napi, budget, eth); -+ u32 status2 = mtk_r32(eth, MTK_INT_STATUS2); - - if (unlikely(status2 & (MTK_GDM1_AF | MTK_GDM2_AF))) { - mtk_stats_update(eth); - mtk_w32(eth, (MTK_GDM1_AF | MTK_GDM2_AF), - MTK_INT_STATUS2); - } -+} -+ -+static int mtk_napi_tx(struct napi_struct *napi, int budget) -+{ -+ struct mtk_eth *eth = container_of(napi, struct mtk_eth, tx_napi); -+ u32 status, mask; -+ int tx_done = 0; -+ -+ mtk_handle_status_irq(eth); -+ mtk_w32(eth, MTK_TX_DONE_INT, MTK_QMTK_INT_STATUS); -+ tx_done = mtk_poll_tx(eth, budget); - - if (unlikely(netif_msg_intr(eth))) { -+ status = mtk_r32(eth, MTK_QMTK_INT_STATUS); - mask = mtk_r32(eth, MTK_QDMA_INT_MASK); -- netdev_info(eth->netdev[0], -- "done tx %d, rx %d, intr 0x%08x/0x%x\n", -- tx_done, rx_done, status, mask); -+ dev_info(eth->dev, -+ "done tx %d, intr 0x%08x/0x%x\n", -+ tx_done, status, mask); - } - -- if (tx_again || rx_done == budget) -+ if (tx_done == budget) - return budget; - - status = mtk_r32(eth, MTK_QMTK_INT_STATUS); -- if (status & (tx_intr | rx_intr)) -+ if (status & MTK_TX_DONE_INT) - return budget; - - napi_complete(napi); -- mtk_irq_enable(eth, MTK_RX_DONE_INT | MTK_RX_DONE_INT); -+ mtk_irq_enable(eth, MTK_TX_DONE_INT); -+ -+ return tx_done; -+} -+ -+static int mtk_napi_rx(struct napi_struct *napi, int budget) -+{ -+ struct mtk_eth *eth = container_of(napi, struct mtk_eth, rx_napi); -+ u32 status, mask; -+ int rx_done = 0; -+ -+ mtk_handle_status_irq(eth); -+ mtk_w32(eth, MTK_RX_DONE_INT, MTK_QMTK_INT_STATUS); -+ rx_done = mtk_poll_rx(napi, budget, eth); -+ -+ if (unlikely(netif_msg_intr(eth))) { -+ status = mtk_r32(eth, MTK_QMTK_INT_STATUS); -+ mask = mtk_r32(eth, MTK_QDMA_INT_MASK); -+ dev_info(eth->dev, -+ "done rx %d, intr 0x%08x/0x%x\n", -+ rx_done, status, mask); -+ } -+ -+ if (rx_done == budget) -+ return budget; -+ -+ status = mtk_r32(eth, MTK_QMTK_INT_STATUS); -+ if (status & MTK_RX_DONE_INT) -+ return budget; -+ -+ napi_complete(napi); -+ mtk_irq_enable(eth, MTK_RX_DONE_INT); - - return rx_done; - } -@@ -1256,22 +1274,26 @@ static void mtk_tx_timeout(struct net_de - schedule_work(ð->pending_work); - } - --static irqreturn_t mtk_handle_irq(int irq, void *_eth) -+static irqreturn_t mtk_handle_irq_rx(int irq, void *_eth) - { - struct mtk_eth *eth = _eth; -- u32 status; - -- status = mtk_r32(eth, MTK_QMTK_INT_STATUS); -- if (unlikely(!status)) -- return IRQ_NONE; -+ if (likely(napi_schedule_prep(ð->rx_napi))) { -+ __napi_schedule(ð->rx_napi); -+ mtk_irq_disable(eth, MTK_RX_DONE_INT); -+ } - -- if (likely(status & (MTK_RX_DONE_INT | MTK_TX_DONE_INT))) { -- if (likely(napi_schedule_prep(ð->rx_napi))) -- __napi_schedule(ð->rx_napi); -- } else { -- mtk_w32(eth, status, MTK_QMTK_INT_STATUS); -+ return IRQ_HANDLED; -+} -+ -+static irqreturn_t mtk_handle_irq_tx(int irq, void *_eth) -+{ -+ struct mtk_eth *eth = _eth; -+ -+ if (likely(napi_schedule_prep(ð->tx_napi))) { -+ __napi_schedule(ð->tx_napi); -+ mtk_irq_disable(eth, MTK_TX_DONE_INT); - } -- mtk_irq_disable(eth, (MTK_RX_DONE_INT | MTK_TX_DONE_INT)); - - return IRQ_HANDLED; - } -@@ -1284,7 +1306,7 @@ static void mtk_poll_controller(struct n - u32 int_mask = MTK_TX_DONE_INT | MTK_RX_DONE_INT; - - mtk_irq_disable(eth, int_mask); -- mtk_handle_irq(dev->irq, dev); -+ mtk_handle_irq(dev->irq[0], dev); - mtk_irq_enable(eth, int_mask); - } - #endif -@@ -1320,6 +1342,7 @@ static int mtk_open(struct net_device *d - if (err) - return err; - -+ napi_enable(ð->tx_napi); - napi_enable(ð->rx_napi); - mtk_irq_enable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT); - } -@@ -1368,6 +1391,7 @@ static int mtk_stop(struct net_device *d - return 0; - - mtk_irq_disable(eth, MTK_TX_DONE_INT | MTK_RX_DONE_INT); -+ napi_disable(ð->tx_napi); - napi_disable(ð->rx_napi); - - mtk_stop_dma(eth, MTK_QDMA_GLO_CFG); -@@ -1405,7 +1429,11 @@ static int __init mtk_hw_init(struct mtk - /* Enable RX VLan Offloading */ - mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); - -- err = devm_request_irq(eth->dev, eth->irq, mtk_handle_irq, 0, -+ err = devm_request_irq(eth->dev, eth->irq[1], mtk_handle_irq_tx, 0, -+ dev_name(eth->dev), eth); -+ if (err) -+ return err; -+ err = devm_request_irq(eth->dev, eth->irq[2], mtk_handle_irq_rx, 0, - dev_name(eth->dev), eth); - if (err) - return err; -@@ -1421,7 +1449,11 @@ static int __init mtk_hw_init(struct mtk - mtk_w32(eth, 0, MTK_RST_GL); - - /* FE int grouping */ -- mtk_w32(eth, 0, MTK_FE_INT_GRP); -+ mtk_w32(eth, MTK_TX_DONE_INT, MTK_PDMA_INT_GRP1); -+ mtk_w32(eth, MTK_RX_DONE_INT, MTK_PDMA_INT_GRP2); -+ mtk_w32(eth, MTK_TX_DONE_INT, MTK_QDMA_INT_GRP1); -+ mtk_w32(eth, MTK_RX_DONE_INT, MTK_QDMA_INT_GRP2); -+ mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); - - for (i = 0; i < 2; i++) { - u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i)); -@@ -1469,7 +1501,9 @@ static void mtk_uninit(struct net_device - phy_disconnect(mac->phy_dev); - mtk_mdio_cleanup(eth); - mtk_irq_disable(eth, ~0); -- free_irq(dev->irq, dev); -+ free_irq(eth->irq[0], dev); -+ free_irq(eth->irq[1], dev); -+ free_irq(eth->irq[2], dev); - } - - static int mtk_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -@@ -1744,10 +1778,10 @@ static int mtk_add_mac(struct mtk_eth *e - dev_err(eth->dev, "error bringing up device\n"); - goto free_netdev; - } -- eth->netdev[id]->irq = eth->irq; -+ eth->netdev[id]->irq = eth->irq[0]; - netif_info(eth, probe, eth->netdev[id], - "mediatek frame engine at 0x%08lx, irq %d\n", -- eth->netdev[id]->base_addr, eth->netdev[id]->irq); -+ eth->netdev[id]->base_addr, eth->irq[0]); - - return 0; - -@@ -1764,6 +1798,7 @@ static int mtk_probe(struct platform_dev - struct mtk_soc_data *soc; - struct mtk_eth *eth; - int err; -+ int i; - - match = of_match_device(of_mtk_match, &pdev->dev); - soc = (struct mtk_soc_data *)match->data; -@@ -1799,10 +1834,12 @@ static int mtk_probe(struct platform_dev - return PTR_ERR(eth->rstc); - } - -- eth->irq = platform_get_irq(pdev, 0); -- if (eth->irq < 0) { -- dev_err(&pdev->dev, "no IRQ resource found\n"); -- return -ENXIO; -+ for (i = 0; i < 3; i++) { -+ eth->irq[i] = platform_get_irq(pdev, i); -+ if (eth->irq[i] < 0) { -+ dev_err(&pdev->dev, "no IRQ%d resource found\n", i); -+ return -ENXIO; -+ } - } - - eth->clk_ethif = devm_clk_get(&pdev->dev, "ethif"); -@@ -1843,7 +1880,9 @@ static int mtk_probe(struct platform_dev - * for NAPI to work - */ - init_dummy_netdev(ð->dummy_dev); -- netif_napi_add(ð->dummy_dev, ð->rx_napi, mtk_poll, -+ netif_napi_add(ð->dummy_dev, ð->tx_napi, mtk_napi_tx, -+ MTK_NAPI_WEIGHT); -+ netif_napi_add(ð->dummy_dev, ð->rx_napi, mtk_napi_rx, - MTK_NAPI_WEIGHT); - - platform_set_drvdata(pdev, eth); -@@ -1864,6 +1903,7 @@ static int mtk_remove(struct platform_de - clk_disable_unprepare(eth->clk_gp1); - clk_disable_unprepare(eth->clk_gp2); - -+ netif_napi_del(ð->tx_napi); - netif_napi_del(ð->rx_napi); - mtk_cleanup(eth); - platform_set_drvdata(pdev, NULL); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -68,6 +68,10 @@ - /* Unicast Filter MAC Address Register - High */ - #define MTK_GDMA_MAC_ADRH(x) (0x50C + (x * 0x1000)) - -+/* PDMA Interrupt grouping registers */ -+#define MTK_PDMA_INT_GRP1 0xa50 -+#define MTK_PDMA_INT_GRP2 0xa54 -+ - /* QDMA TX Queue Configuration Registers */ - #define MTK_QTX_CFG(x) (0x1800 + (x * 0x10)) - #define QDMA_RES_THRES 4 -@@ -125,6 +129,11 @@ - #define MTK_TX_DONE_INT (MTK_TX_DONE_INT0 | MTK_TX_DONE_INT1 | \ - MTK_TX_DONE_INT2 | MTK_TX_DONE_INT3) - -+/* QDMA Interrupt grouping registers */ -+#define MTK_QDMA_INT_GRP1 0x1a20 -+#define MTK_QDMA_INT_GRP2 0x1a24 -+#define MTK_RLS_DONE_INT BIT(0) -+ - /* QDMA Interrupt Status Register */ - #define MTK_QDMA_INT_MASK 0x1A1C - -@@ -356,7 +365,8 @@ struct mtk_rx_ring { - * @dma_refcnt: track how many netdevs are using the DMA engine - * @tx_ring: Pointer to the memore holding info about the TX ring - * @rx_ring: Pointer to the memore holding info about the RX ring -- * @rx_napi: The NAPI struct -+ * @tx_napi: The TX NAPI struct -+ * @rx_napi: The RX NAPI struct - * @scratch_ring: Newer SoCs need memory for a second HW managed TX ring - * @phy_scratch_ring: physical address of scratch_ring - * @scratch_head: The scratch memory that scratch_ring points to. -@@ -377,7 +387,7 @@ struct mtk_eth { - struct net_device dummy_dev; - struct net_device *netdev[MTK_MAX_DEVS]; - struct mtk_mac *mac[MTK_MAX_DEVS]; -- int irq; -+ int irq[3]; - u32 msg_enable; - unsigned long sysclk; - struct regmap *ethsys; -@@ -385,6 +395,7 @@ struct mtk_eth { - atomic_t dma_refcnt; - struct mtk_tx_ring tx_ring; - struct mtk_rx_ring rx_ring; -+ struct napi_struct tx_napi; - struct napi_struct rx_napi; - struct mtk_tx_dma *scratch_ring; - dma_addr_t phy_scratch_ring; 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 index 472d58b55a..0000000000 --- a/target/linux/mediatek/patches-4.4/0097-net-next-mediatek-change-my-email-address.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 7c955062aaa563b1894671af3ae250460b3fa82d Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 -+ * Copyright (C) 2009-2016 John Crispin - * Copyright (C) 2009-2016 Felix Fietkau - * Copyright (C) 2013-2016 Michael Lee - */ -@@ -1929,5 +1929,5 @@ static struct platform_driver mtk_driver - module_platform_driver(mtk_driver); - - MODULE_LICENSE("GPL"); --MODULE_AUTHOR("John Crispin "); -+MODULE_AUTHOR("John Crispin "); - 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 index cc18be53b4..0000000000 --- a/target/linux/mediatek/patches-4.4/0098-net-next-mediatek-only-trigger-the-tx-watchdog-reset.patch +++ /dev/null @@ -1,57 +0,0 @@ -From cd1343c14328a5de1a58c47b81b8a2febb31d542 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Signed-off-by: John Crispin ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 14 ++++++++++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + - 2 files changed, 13 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1267,11 +1267,21 @@ static void mtk_tx_timeout(struct net_de - { - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; -+ int i, reset = 0; - - eth->netdev[mac->id]->stats.tx_errors++; - netif_err(eth, tx_err, dev, - "transmit timed out\n"); -- schedule_work(ð->pending_work); -+ -+ for (i = 0; i < MTK_MAC_COUNT; i++) { -+ if (!eth->netdev[i] || -+ time_after(jiffies, dev_trans_start(eth->netdev[i]) + -+ MTK_WDT_TIMEOUT)) -+ reset++; -+ } -+ -+ if (reset == MTK_MAC_COUNT) -+ schedule_work(ð->pending_work); - } - - static irqreturn_t mtk_handle_irq_rx(int irq, void *_eth) -@@ -1765,7 +1775,7 @@ static int mtk_add_mac(struct mtk_eth *e - mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET; - - SET_NETDEV_DEV(eth->netdev[id], eth->dev); -- eth->netdev[id]->watchdog_timeo = 5 * HZ; -+ eth->netdev[id]->watchdog_timeo = MTK_WDT_TIMEOUT; - eth->netdev[id]->netdev_ops = &mtk_netdev_ops; - eth->netdev[id]->base_addr = (unsigned long)eth->base; - eth->netdev[id]->vlan_features = MTK_HW_FEATURES & ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -15,6 +15,7 @@ - #ifndef MTK_ETH_H - #define MTK_ETH_H - -+#define MTK_WDT_TIMEOUT (4 * HZ) - #define MTK_QDMA_PAGE_SIZE 2048 - #define MTK_MAX_RX_LENGTH 1536 - #define MTK_TX_DMA_BUF_LEN 0x3fff 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 index 1bad613a80..0000000000 --- a/target/linux/mediatek/patches-4.4/0099-MAINTAINERS-change-my-email-address.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 2023b1652745fec5e691a5c9a9742ba6dd45e466 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 ---- - 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 --M: John Crispin -+M: John Crispin - 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 index 145868c1f0..0000000000 --- a/target/linux/mediatek/patches-4.4/0100-MAINTAINERS-add-Sean-as-mediatek-ethernet-maintainer.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 69c89cb453c0beac5d8349108cee8f6806e5db19 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 -Signed-off-by: John Crispin ---- - 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 - M: John Crispin -+M: Sean Wang - 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 index 4d931fc0fa..0000000000 --- a/target/linux/mediatek/patches-4.4/0101-net-mediatek-add-gsw-mt7530-driver.patch +++ /dev/null @@ -1,2360 +0,0 @@ -From 6b8a7257e7bcb56782c3f8048311670fe6a80209 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Mon, 11 Apr 2016 03:11:54 +0200 -Subject: [PATCH 101/102] net: mediatek add gsw/mt7530 driver - -Signed-off-by: John Crispin ---- - 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 -+ * Copyright (C) 2009-2016 Felix Fietkau -+ * Copyright (C) 2013-2016 Michael Lee -+ */ -+ -+#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 -+ * Copyright (C) 2009-2016 Felix Fietkau -+ * Copyright (C) 2013-2016 Michael Lee -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 "); -+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 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 -+ */ -+ -+#ifndef _MT7530_H__ -+#define _MT7530_H__ -+ -+int mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus, int vlan); -+ -+#endif ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -24,6 +24,9 @@ - - #include "mtk_eth_soc.h" - -+/* the callback used by the driver core to bringup the switch */ -+int mtk_gsw_init(struct mtk_eth *eth); -+ - static int mtk_msg_level = -1; - module_param_named(msg_level, mtk_msg_level, int, 0); - MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)"); -@@ -69,7 +72,7 @@ static int mtk_mdio_busy_wait(struct mtk - return 0; - if (time_after(jiffies, t_start + PHY_IAC_TIMEOUT)) - break; -- usleep_range(10, 20); -+// usleep_range(10, 20); - } - - dev_err(eth->dev, "mdio: MDIO timeout\n"); -@@ -1421,15 +1424,6 @@ static int __init mtk_hw_init(struct mtk - reset_control_deassert(eth->rstc); - usleep_range(10, 20); - -- /* Set GE2 driving and slew rate */ -- regmap_write(eth->pctl, GPIO_DRV_SEL10, 0xa00); -- -- /* set GE2 TDSEL */ -- regmap_write(eth->pctl, GPIO_OD33_CTRL8, 0x5); -- -- /* set GE2 TUNE */ -- regmap_write(eth->pctl, GPIO_BIAS_CTRL, 0x0); -- - /* GE1, Force 1000M/FD, FC ON */ - mtk_w32(eth, MAC_MCR_FIXED_LINK, MTK_MAC_MCR(0)); - -@@ -1452,6 +1446,8 @@ static int __init mtk_hw_init(struct mtk - if (err) - return err; - -+ mtk_gsw_init(eth); -+ - /* disable delay and normal interrupt */ - mtk_w32(eth, 0, MTK_QDMA_DELAY_INT); - mtk_irq_disable(eth, ~0); -@@ -1479,6 +1475,8 @@ static int __init mtk_hw_init(struct mtk - mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i)); - } - -+ mt7623_gsw_config(eth); -+ - return 0; - } - -@@ -1734,7 +1732,7 @@ static int mtk_add_mac(struct mtk_eth *e - { - struct mtk_mac *mac; - const __be32 *_id = of_get_property(np, "reg", NULL); -- int id, err; -+ int id; - - if (!_id) { - dev_err(eth->dev, "missing mac id\n"); -@@ -1768,8 +1766,8 @@ static int mtk_add_mac(struct mtk_eth *e - GFP_KERNEL); - if (!mac->hw_stats) { - dev_err(eth->dev, "failed to allocate counter memory\n"); -- err = -ENOMEM; -- goto free_netdev; -+ free_netdev(eth->netdev[id]); -+ return -ENOMEM; - } - spin_lock_init(&mac->hw_stats->stats_lock); - mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET; -@@ -1783,21 +1781,9 @@ static int mtk_add_mac(struct mtk_eth *e - eth->netdev[id]->features |= MTK_HW_FEATURES; - eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops; - -- err = register_netdev(eth->netdev[id]); -- if (err) { -- dev_err(eth->dev, "error bringing up device\n"); -- goto free_netdev; -- } - eth->netdev[id]->irq = eth->irq[0]; -- netif_info(eth, probe, eth->netdev[id], -- "mediatek frame engine at 0x%08lx, irq %d\n", -- eth->netdev[id]->base_addr, eth->irq[0]); - - return 0; -- --free_netdev: -- free_netdev(eth->netdev[id]); -- return err; - } - - static int mtk_probe(struct platform_device *pdev) -@@ -1865,14 +1851,13 @@ static int mtk_probe(struct platform_dev - clk_prepare_enable(eth->clk_gp1); - clk_prepare_enable(eth->clk_gp2); - -+ eth->switch_np = of_parse_phandle(pdev->dev.of_node, -+ "mediatek,switch", 0); -+ - eth->dev = &pdev->dev; - eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE); - INIT_WORK(ð->pending_work, mtk_pending_work); - -- err = mtk_hw_init(eth); -- if (err) -- return err; -- - for_each_child_of_node(pdev->dev.of_node, mac_np) { - if (!of_device_is_compatible(mac_np, - "mediatek,eth-mac")) -@@ -1886,6 +1871,22 @@ static int mtk_probe(struct platform_dev - goto err_free_dev; - } - -+ err = mtk_hw_init(eth); -+ if (err) -+ return err; -+ -+ for (i = 0; i < MTK_MAX_DEVS; i++) { -+ if (!eth->netdev[i]) -+ continue; -+ err = register_netdev(eth->netdev[i]); -+ if (err) -+ dev_err(eth->dev, "error bringing up device\n"); -+ else -+ netif_info(eth, probe, eth->netdev[i], -+ "mediatek frame engine at 0x%08lx, irq %d\n", -+ eth->netdev[i]->base_addr, eth->irq[0]); -+ } -+ - /* we run 2 devices on the same DMA ring so we need a dummy device - * for NAPI to work - */ ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -407,6 +407,9 @@ struct mtk_eth { - struct clk *clk_gp2; - struct mii_bus *mii_bus; - struct work_struct pending_work; -+ -+ struct device_node *switch_np; -+ void *sw_priv; - }; - - /* struct mtk_mac - the structure that holds the info about the MACs of the -@@ -434,4 +437,6 @@ void mtk_stats_update_mac(struct mtk_mac - void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg); - u32 mtk_r32(struct mtk_eth *eth, unsigned reg); - -+int mt7623_gsw_config(struct mtk_eth *eth); -+ - #endif /* MTK_ETH_H */ 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 index 3561b4020c..0000000000 --- a/target/linux/mediatek/patches-4.4/0102-net-mediatek-v4.4-backports.patch +++ /dev/null @@ -1,46 +0,0 @@ -From c1ff5519a7fd849da5d169036d8175383f807962 Mon Sep 17 00:00:00 2001 -From: John Crispin -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 index 92f34c5fc2..0000000000 --- a/target/linux/mediatek/patches-4.4/0103-nand_fixes.patch +++ /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 index eb743c7247..0000000000 --- a/target/linux/mediatek/patches-4.4/0200-devicetree.patch +++ /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 index 395884b730..0000000000 --- a/target/linux/mediatek/patches-4.4/0201-block2mtd.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- a/drivers/mtd/devices/block2mtd.c -+++ b/drivers/mtd/devices/block2mtd.c -@@ -32,6 +32,8 @@ - #include - #include - -+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 index 0000000000..2fedae701b --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0000-pinctrl-esw.patch @@ -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 index 0000000000..b60eac0efc --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0001-NET-multi-phy-support.patch @@ -0,0 +1,53 @@ +From 1e021917e634b173d466bf0dd3d2ae84e51a77ff Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sun, 27 Jul 2014 09:38:50 +0100 +Subject: [PATCH 001/102] NET: multi phy support + +Signed-off-by: John Crispin +--- + 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 index 0000000000..132d6c89c8 --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0004-soc-mediatek-Add-MT2701-power-dt-bindings.patch @@ -0,0 +1,44 @@ +From 7c5b29de78f1b15c5bde40a6ca4510fc09588457 Mon Sep 17 00:00:00 2001 +From: Shunli Wang +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 +Signed-off-by: James Liao +--- + 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 index 0000000000..552b46e565 --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0009-clk-mediatek-Add-MT2701-clock-support.patch @@ -0,0 +1,1431 @@ +From a4c507d052390b42d7e8c59241e3c336796f730f Mon Sep 17 00:00:00 2001 +From: Shunli Wang +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 +Signed-off-by: James Liao +--- + 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 ++ * ++ * 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 ++#include ++#include ++ ++#include "clk-mtk.h" ++#include "clk-gate.h" ++ ++#include ++ ++static DEFINE_SPINLOCK(lock); ++ ++static const struct mtk_fixed_clk top_fixed_clks[] __initconst = { ++ FIXED_CLK(CLK_TOP_DPI, "dpi_ck", "clk26m", 108 * MHZ), ++ FIXED_CLK(CLK_TOP_DMPLL, "dmpll_ck", "clk26m", 400 * MHZ), ++ FIXED_CLK(CLK_TOP_VENCPLL, "vencpll_ck", "clk26m", 295750000), ++ FIXED_CLK(CLK_TOP_HDMI_0_PIX340M, "hdmi_0_pix340m", "clk26m", 340 * MHZ), ++ FIXED_CLK(CLK_TOP_HDMI_0_DEEP340M, "hdmi_0_deep340m", "clk26m", 340 * MHZ), ++ FIXED_CLK(CLK_TOP_HDMI_0_PLL340M, "hdmi_0_pll340m", "clk26m", 340 * MHZ), ++ FIXED_CLK(CLK_TOP_HDMITX_CLKDIG_CTS, "hdmitx_dig_cts", "clk26m", 300 * MHZ), ++ FIXED_CLK(CLK_TOP_HADDS2_FB, "hadds2_fbclk", "clk26m", 27 * MHZ), ++ FIXED_CLK(CLK_TOP_WBG_DIG_416M, "wbg_dig_ck_416m", "clk26m", 416 * MHZ), ++}; ++ ++static const struct mtk_fixed_factor top_fixed_divs[] __initconst = { ++ FACTOR(CLK_TOP_SYSPLL, "syspll_ck", "mainpll", 1, 1), ++ FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2), ++ FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1, 3), ++ FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5), ++ FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll", 1, 7), ++ FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "syspll_d2", 1, 2), ++ FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "syspll_d2", 1, 4), ++ FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "syspll_d2", 1, 8), ++ FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "syspll_d2", 1, 16), ++ FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "syspll_d3", 1, 2), ++ FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "syspll_d3", 1, 4), ++ FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "syspll_d3", 1, 8), ++ FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "syspll_d5", 1, 2), ++ FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "syspll_d5", 1, 4), ++ FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "syspll_d7", 1, 2), ++ FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "syspll_d7", 1, 4), ++ ++ FACTOR(CLK_TOP_UNIVPLL, "univpll_ck", "univpll", 1, 1), ++ FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2), ++ FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3), ++ FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5), ++ FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7), ++ FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll", 1, 26), ++ FACTOR(CLK_TOP_UNIVPLL_D52, "univpll_d52", "univpll", 1, 52), ++ FACTOR(CLK_TOP_UNIVPLL_D108, "univpll_d108", "univpll", 1, 108), ++ FACTOR(CLK_TOP_USB_PHY48M, "USB_PHY48M_CK", "univpll", 1, 26), ++ FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_d2", 1, 2), ++ FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_d2", 1, 4), ++ FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_d2", 1, 8), ++ FACTOR(CLK_TOP_8BDAC, "8bdac_ck", "univpll_d2", 1, 1), ++ FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_d3", 1, 2), ++ FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_d3", 1, 4), ++ FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_d3", 1, 8), ++ FACTOR(CLK_TOP_UNIVPLL2_D16, "univpll2_d16", "univpll_d3", 1, 16), ++ FACTOR(CLK_TOP_UNIVPLL2_D32, "univpll2_d32", "univpll_d3", 1, 32), ++ FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll_d5", 1, 2), ++ FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll_d5", 1, 4), ++ FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univpll_d5", 1, 8), ++ ++ FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1), ++ FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2), ++ FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4), ++ FACTOR(CLK_TOP_MSDCPLL_D8, "msdcpll_d8", "msdcpll", 1, 8), ++ ++ FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1, 1), ++ FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2), ++ ++ FACTOR(CLK_TOP_DMPLL_D2, "dmpll_d2", "dmpll_ck", 1, 2), ++ FACTOR(CLK_TOP_DMPLL_D4, "dmpll_d4", "dmpll_ck", 1, 4), ++ FACTOR(CLK_TOP_DMPLL_X2, "dmpll_x2", "dmpll_ck", 1, 1), ++ ++ FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll", 1, 1), ++ FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll", 1, 2), ++ FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4), ++ ++ FACTOR(CLK_TOP_VDECPLL, "vdecpll_ck", "vdecpll", 1, 1), ++ FACTOR(CLK_TOP_TVD2PLL, "tvd2pll_ck", "tvd2pll", 1, 1), ++ FACTOR(CLK_TOP_TVD2PLL_D2, "tvd2pll_d2", "tvd2pll", 1, 2), ++ ++ FACTOR(CLK_TOP_MIPIPLL, "mipipll", "dpi_ck", 1, 1), ++ FACTOR(CLK_TOP_MIPIPLL_D2, "mipipll_d2", "dpi_ck", 1, 2), ++ FACTOR(CLK_TOP_MIPIPLL_D4, "mipipll_d4", "dpi_ck", 1, 4), ++ ++ FACTOR(CLK_TOP_HDMIPLL, "hdmipll_ck", "hdmitx_dig_cts", 1, 1), ++ FACTOR(CLK_TOP_HDMIPLL_D2, "hdmipll_d2", "hdmitx_dig_cts", 1, 2), ++ FACTOR(CLK_TOP_HDMIPLL_D3, "hdmipll_d3", "hdmitx_dig_cts", 1, 3), ++ ++ FACTOR(CLK_TOP_ARMPLL_1P3G, "armpll_1p3g_ck", "armpll", 1, 1), ++ ++ FACTOR(CLK_TOP_AUDPLL, "audpll", "audpll_sel", 1, 1), ++ FACTOR(CLK_TOP_AUDPLL_D4, "audpll_d4", "audpll_sel", 1, 4), ++ FACTOR(CLK_TOP_AUDPLL_D8, "audpll_d8", "audpll_sel", 1, 8), ++ FACTOR(CLK_TOP_AUDPLL_D16, "audpll_d16", "audpll_sel", 1, 16), ++ FACTOR(CLK_TOP_AUDPLL_D24, "audpll_d24", "audpll_sel", 1, 24), ++ ++ FACTOR(CLK_TOP_AUD1PLL_98M, "aud1pll_98m_ck", "aud1pll", 1, 3), ++ FACTOR(CLK_TOP_AUD2PLL_90M, "aud2pll_90m_ck", "aud2pll", 1, 3), ++ FACTOR(CLK_TOP_HADDS2PLL_98M, "hadds2pll_98m", "hadds2pll", 1, 3), ++ FACTOR(CLK_TOP_HADDS2PLL_294M, "hadds2pll_294m", "hadds2pll", 1, 1), ++ FACTOR(CLK_TOP_ETHPLL_500M, "ethpll_500m_ck", "ethpll", 1, 1), ++ FACTOR(CLK_TOP_CLK26M_D8, "clk26m_d8", "clk26m", 1, 8), ++ FACTOR(CLK_TOP_32K_INTERNAL, "32k_internal", "clk26m", 1, 793), ++ FACTOR(CLK_TOP_32K_EXTERNAL, "32k_external", "rtc32k", 1, 1), ++}; ++ ++static const char * const axi_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d2", ++ "syspll_d5", ++ "syspll1_d4", ++ "univpll_d5", ++ "univpll2_d2", ++ "mmpll_d2", ++ "dmpll_d2" ++}; ++ ++static const char * const mem_parents[] __initconst = { ++ "clk26m", ++ "dmpll_ck" ++}; ++ ++static const char * const ddrphycfg_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d8" ++}; ++ ++static const char * const mm_parents[] __initconst = { ++ "clk26m", ++ "vencpll_ck", ++ "syspll1_d2", ++ "syspll1_d4", ++ "univpll_d5", ++ "univpll1_d2", ++ "univpll2_d2", ++ "dmpll_ck" ++}; ++ ++static const char * const pwm_parents[] __initconst = { ++ "clk26m", ++ "univpll2_d4", ++ "univpll3_d2", ++ "univpll1_d4", ++}; ++ ++static const char * const vdec_parents[] __initconst = { ++ "clk26m", ++ "vdecpll_ck", ++ "syspll_d5", ++ "syspll1_d4", ++ "univpll_d5", ++ "univpll2_d2", ++ "vencpll_ck", ++ "msdcpll_d2", ++ "mmpll_d2" ++}; ++ ++static const char * const mfg_parents[] __initconst = { ++ "clk26m", ++ "mmpll_ck", ++ "dmpll_x2_ck", ++ "msdcpll_ck", ++ "clk26m", ++ "syspll_d3", ++ "univpll_d3", ++ "univpll1_d2" ++}; ++ ++static const char * const camtg_parents[] __initconst = { ++ "clk26m", ++ "univpll_d26", ++ "univpll2_d2", ++ "syspll3_d2", ++ "syspll3_d4", ++ "msdcpll_d2", ++ "mmpll_d2" ++}; ++ ++static const char * const uart_parents[] __initconst = { ++ "clk26m", ++ "univpll2_d8" ++}; ++ ++static const char * const spi_parents[] __initconst = { ++ "clk26m", ++ "syspll3_d2", ++ "syspll4_d2", ++ "univpll2_d4", ++ "univpll1_d8" ++}; ++ ++static const char * const usb20_parents[] __initconst = { ++ "clk26m", ++ "univpll1_d8", ++ "univpll3_d4" ++}; ++ ++static const char * const msdc30_parents[] __initconst = { ++ "clk26m", ++ "msdcpll_d2", ++ "syspll2_d2", ++ "syspll1_d4", ++ "univpll1_d4", ++ "univpll2_d4" ++}; ++ ++static const char * const audio_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d16" ++}; ++ ++static const char * const aud_intbus_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d4", ++ "syspll3_d2", ++ "syspll4_d2", ++ "univpll3_d2", ++ "univpll2_d4" ++}; ++ ++static const char * const pmicspi_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d8", ++ "syspll2_d4", ++ "syspll4_d2", ++ "syspll3_d4", ++ "syspll2_d8", ++ "syspll1_d16", ++ "univpll3_d4", ++ "univpll_d26", ++ "dmpll_d2", ++ "dmpll_d4" ++}; ++ ++static const char * const scp_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d8", ++ "dmpll_d2", ++ "dmpll_d4" ++}; ++ ++static const char * const dpi0_parents[] __initconst = { ++ "clk26m", ++ "mipipll", ++ "mipipll_d2", ++ "mipipll_d4", ++ "clk26m", ++ "tvdpll_ck", ++ "tvdpll_d2", ++ "tvdpll_d4" ++}; ++ ++static const char * const dpi1_parents[] __initconst = { ++ "clk26m", ++ "tvdpll_ck", ++ "tvdpll_d2", ++ "tvdpll_d4" ++}; ++ ++static const char * const tve_parents[] __initconst = { ++ "clk26m", ++ "mipipll", ++ "mipipll_d2", ++ "mipipll_d4", ++ "clk26m", ++ "tvdpll_ck", ++ "tvdpll_d2", ++ "tvdpll_d4" ++}; ++ ++static const char * const hdmi_parents[] __initconst = { ++ "clk26m", ++ "hdmipll_ck", ++ "hdmipll_d2", ++ "hdmipll_d3" ++}; ++ ++static const char * const apll_parents[] __initconst = { ++ "clk26m", ++ "audpll", ++ "audpll_d4", ++ "audpll_d8", ++ "audpll_d16", ++ "audpll_d24", ++ "clk26m", ++ "clk26m" ++}; ++ ++static const char * const rtc_parents[] __initconst = { ++ "32k_internal", ++ "32k_external", ++ "clk26m", ++ "univpll3_d8" ++}; ++ ++static const char * const nfi2x_parents[] __initconst = { ++ "clk26m", ++ "syspll2_d2", ++ "syspll_d7", ++ "univpll3_d2", ++ "syspll2_d4", ++ "univpll3_d4", ++ "syspll4_d4", ++ "clk26m" ++}; ++ ++static const char * const emmc_hclk_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d2", ++ "syspll1_d4", ++ "syspll2_d2" ++}; ++ ++static const char * const flash_parents[] __initconst = { ++ "clk26m_d8", ++ "clk26m", ++ "syspll2_d8", ++ "syspll3_d4", ++ "univpll3_d4", ++ "syspll4_d2", ++ "syspll2_d4", ++ "univpll2_d4" ++}; ++ ++static const char * const di_parents[] __initconst = { ++ "clk26m", ++ "tvd2pll_ck", ++ "tvd2pll_d2", ++ "clk26m" ++}; ++ ++static const char * const nr_osd_parents[] __initconst = { ++ "clk26m", ++ "vencpll_ck", ++ "syspll1_d2", ++ "syspll1_d4", ++ "univpll_d5", ++ "univpll1_d2", ++ "univpll2_d2", ++ "dmpll_ck" ++}; ++ ++static const char * const hdmirx_bist_parents[] __initconst = { ++ "clk26m", ++ "syspll_d3", ++ "clk26m", ++ "syspll1_d16", ++ "syspll4_d2", ++ "syspll1_d4", ++ "vencpll_ck", ++ "clk26m" ++}; ++ ++static const char * const intdir_parents[] __initconst = { ++ "clk26m", ++ "mmpll_ck", ++ "syspll_d2", ++ "univpll_d2" ++}; ++ ++static const char * const asm_parents[] __initconst = { ++ "clk26m", ++ "univpll2_d4", ++ "univpll2_d2", ++ "syspll_d5" ++}; ++ ++static const char * const ms_card_parents[] __initconst = { ++ "clk26m", ++ "univpll3_d8", ++ "syspll4_d4" ++}; ++ ++static const char * const ethif_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d2", ++ "syspll_d5", ++ "syspll1_d4", ++ "univpll_d5", ++ "univpll1_d2", ++ "dmpll_ck", ++ "dmpll_d2" ++}; ++ ++static const char * const hdmirx_parents[] __initconst = { ++ "clk26m", ++ "univpll_d52" ++}; ++ ++static const char * const cmsys_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d2", ++ "univpll1_d2", ++ "univpll_d5", ++ "syspll_d5", ++ "syspll2_d2", ++ "syspll1_d4", ++ "syspll3_d2", ++ "syspll2_d4", ++ "syspll1_d8", ++ "clk26m", ++ "clk26m", ++ "clk26m", ++ "clk26m", ++ "clk26m" ++}; ++ ++static const char * const clk_8bdac_parents[] __initconst = { ++ "clkrtc_int", ++ "8bdac_ck_pre", ++ "clk26m", ++ "clk26m" ++}; ++ ++static const char * const aud2dvd_parents[] __initconst = { ++ "a1sys_hp_ck", ++ "a2sys_hp_ck" ++}; ++ ++static const char * const padmclk_parents[] __initconst = { ++ "clk26m", ++ "univpll_d26", ++ "univpll_d52", ++ "univpll_d108", ++ "univpll2_d8", ++ "univpll2_d16", ++ "univpll2_d32" ++}; ++ ++static const char * const aud_mux_parents[] __initconst = { ++ "clk26m", ++ "aud1pll_98m_ck", ++ "aud2pll_90m_ck", ++ "hadds2pll_98m", ++ "audio_ext1_ck", ++ "audio_ext2_ck" ++}; ++ ++static const char * const aud_src_parents[] __initconst = { ++ "aud_mux1_sel", ++ "aud_mux2_sel" ++}; ++ ++static const char * const cpu_parents[] __initconst = { ++ "clk26m", ++ "armpll", ++ "mainpll", ++ "mmpll" ++}; ++ ++static const struct mtk_composite top_muxes[] __initconst = { ++ MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, ++ 0x0040, 0, 3, INVALID_MUX_GATE_BIT), ++ MUX_GATE(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x0040, 8, 1, 15), ++ MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents, 0x0040, 16, 1, 23), ++ MUX_GATE(CLK_TOP_MM_SEL, "mm_sel", mm_parents, 0x0040, 24, 3, 31), ++ ++ MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x0050, 0, 2, 7), ++ MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x0050, 8, 4, 15), ++ MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0050, 16, 3, 23), ++ MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x0050, 24, 3, 31), ++ MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x0060, 0, 1, 7), ++ ++ MUX_GATE(CLK_TOP_SPI0_SEL, "spi0_sel", spi_parents, 0x0060, 8, 3, 15), ++ MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x0060, 16, 2, 23), ++ MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_parents, 0x0060, 24, 3, 31), ++ ++ MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_parents, 0x0070, 0, 3, 7), ++ MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_parents, 0x0070, 8, 3, 15), ++ MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", msdc30_parents, 0x0070, 16, 1, 23), ++ MUX_GATE(CLK_TOP_AUDINTBUS_SEL, "aud_intbus_sel", aud_intbus_parents, 0x0070, 24, 3, 31), ++ ++ MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x0080, 0, 4, 7), ++ MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, 0x0080, 8, 2, 15), ++ MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents, 0x0080, 16, 3, 23), ++ MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0080, 24, 2, 31), ++ ++ MUX_GATE(CLK_TOP_TVE_SEL, "tve_sel", tve_parents, 0x0090, 0, 3, 7), ++ MUX_GATE(CLK_TOP_HDMI_SEL, "hdmi_sel", hdmi_parents, 0x0090, 8, 2, 15), ++ MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", apll_parents, 0x0090, 16, 3, 23), ++ ++ MUX_GATE(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents, 0x00A0, 0, 2, 7), ++ MUX_GATE(CLK_TOP_NFI2X_SEL, "nfi2x_sel", nfi2x_parents, 0x00A0, 8, 3, 15), ++ MUX_GATE(CLK_TOP_EMMC_HCLK_SEL, "emmc_hclk_sel", emmc_hclk_parents, 0x00A0, 24, 2, 31), ++ ++ MUX_GATE(CLK_TOP_FLASH_SEL, "flash_sel", flash_parents, 0x00B0, 0, 3, 7), ++ MUX_GATE(CLK_TOP_DI_SEL, "di_sel", di_parents, 0x00B0, 8, 2, 15), ++ MUX_GATE(CLK_TOP_NR_SEL, "nr_sel", nr_osd_parents, 0x00B0, 16, 3, 23), ++ MUX_GATE(CLK_TOP_OSD_SEL, "osd_sel", nr_osd_parents, 0x00B0, 24, 3, 31), ++ ++ MUX_GATE(CLK_TOP_HDMIRX_BIST_SEL, "hdmirx_bist_sel", hdmirx_bist_parents, 0x00C0, 0, 3, 7), ++ MUX_GATE(CLK_TOP_INTDIR_SEL, "intdir_sel", intdir_parents, 0x00C0, 8, 2, 15), ++ MUX_GATE(CLK_TOP_ASM_I_SEL, "asm_i_sel", asm_parents, 0x00C0, 16, 2, 23), ++ MUX_GATE(CLK_TOP_ASM_M_SEL, "asm_m_sel", asm_parents, 0x00C0, 24, 3, 31), ++ ++ MUX_GATE(CLK_TOP_ASM_H_SEL, "asm_h_sel", asm_parents, 0x00D0, 0, 2, 7), ++ MUX_GATE(CLK_TOP_MS_CARD_SEL, "ms_card_sel", ms_card_parents, 0x00D0, 16, 2, 23), ++ MUX_GATE(CLK_TOP_ETHIF_SEL, "ethif_sel", ethif_parents, 0x00D0, 24, 3, 31), ++ ++ MUX_GATE(CLK_TOP_HDMIRX26_24_SEL, "hdmirx26_24_sel", hdmirx_parents, 0x00E0, 0, 1, 7), ++ MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_parents, 0x00E0, 8, 3, 15), ++ MUX_GATE(CLK_TOP_CMSYS_SEL, "cmsys_sel", cmsys_parents, 0x00E0, 16, 4, 23), ++ ++ MUX_GATE(CLK_TOP_SPI1_SEL, "spi2_sel", spi_parents, 0x00E0, 24, 3, 31), ++ MUX_GATE(CLK_TOP_SPI2_SEL, "spi1_sel", spi_parents, 0x00F0, 0, 3, 7), ++ MUX_GATE(CLK_TOP_8BDAC_SEL, "8bdac_sel", clk_8bdac_parents, 0x00F0, 8, 2, 15), ++ MUX_GATE(CLK_TOP_AUD2DVD_SEL, "aud2dvd_sel", aud2dvd_parents, 0x00F0, 16, 1, 23), ++ ++ MUX(CLK_TOP_PADMCLK_SEL, "padmclk_sel", padmclk_parents, 0x0100, 0, 3), ++ ++ MUX(CLK_TOP_AUD_MUX1_SEL, "aud_mux1_sel", aud_mux_parents, 0x012c, 0, 3), ++ MUX(CLK_TOP_AUD_MUX2_SEL, "aud_mux2_sel", aud_mux_parents, 0x012c, 3, 3), ++ MUX(CLK_TOP_AUDPLL_MUX_SEL, "audpll_sel", aud_mux_parents, 0x012c, 6, 3), ++ MUX_GATE(CLK_TOP_AUD_K1_SRC_SEL, "aud_k1_src_sel", aud_src_parents, 0x012c, 15, 1, 23), ++ MUX_GATE(CLK_TOP_AUD_K2_SRC_SEL, "aud_k2_src_sel", aud_src_parents, 0x012c, 16, 1, 24), ++ MUX_GATE(CLK_TOP_AUD_K3_SRC_SEL, "aud_k3_src_sel", aud_src_parents, 0x012c, 17, 1, 25), ++ MUX_GATE(CLK_TOP_AUD_K4_SRC_SEL, "aud_k4_src_sel", aud_src_parents, 0x012c, 18, 1, 26), ++ MUX_GATE(CLK_TOP_AUD_K5_SRC_SEL, "aud_k5_src_sel", aud_src_parents, 0x012c, 19, 1, 27), ++ MUX_GATE(CLK_TOP_AUD_K6_SRC_SEL, "aud_k6_src_sel", aud_src_parents, 0x012c, 20, 1, 28), ++}; ++ ++static const struct mtk_clk_divider top_adj_divs[] __initconst = { ++ DIV_ADJ(CLK_TOP_AUD_EXTCK1_DIV, "audio_ext1_ck", "aud_ext_ck1", 0x0120, 0, 8), ++ DIV_ADJ(CLK_TOP_AUD_EXTCK2_DIV, "audio_ext2_ck", "aud_ext_ck2", 0x0120, 8, 8), ++ DIV_ADJ(CLK_TOP_AUD_MUX1_DIV, "aud_mux1_div", "aud_mux1_sel", 0x0120, 16, 8), ++ DIV_ADJ(CLK_TOP_AUD_MUX2_DIV, "aud_mux2_div", "aud_mux2_sel", 0x0120, 24, 8), ++ DIV_ADJ(CLK_TOP_AUD_K1_SRC_DIV, "aud_k1_src_div", "aud_k1_src_sel", 0x0124, 0, 8), ++ DIV_ADJ(CLK_TOP_AUD_K2_SRC_DIV, "aud_k2_src_div", "aud_k2_src_sel", 0x0124, 8, 8), ++ DIV_ADJ(CLK_TOP_AUD_K3_SRC_DIV, "aud_k3_src_div", "aud_k3_src_sel", 0x0124, 16, 8), ++ DIV_ADJ(CLK_TOP_AUD_K4_SRC_DIV, "aud_k4_src_div", "aud_k4_src_sel", 0x0124, 24, 8), ++ DIV_ADJ(CLK_TOP_AUD_K5_SRC_DIV, "aud_k5_src_div", "aud_k5_src_sel", 0x0128, 0, 8), ++ DIV_ADJ(CLK_TOP_AUD_K6_SRC_DIV, "aud_k6_src_div", "aud_k6_src_sel", 0x0128, 8, 8), ++}; ++ ++static const struct mtk_gate_regs top_aud_cg_regs __initconst = { ++ .sta_ofs = 0x012C, ++}; ++ ++#define GATE_TOP_AUD(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &top_aud_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_no_setclr, \ ++ } ++ ++static const struct mtk_gate top_clks[] __initconst = { ++ GATE_TOP_AUD(CLK_TOP_AUD_48K_TIMING, "a1sys_hp_ck", "aud_mux1_div", 21), ++ GATE_TOP_AUD(CLK_TOP_AUD_44K_TIMING, "a2sys_hp_ck", "aud_mux2_div", 22), ++ GATE_TOP_AUD(CLK_TOP_AUD_I2S1_MCLK, "aud_i2s1_mclk", "aud_k1_src_div", 23), ++ GATE_TOP_AUD(CLK_TOP_AUD_I2S2_MCLK, "aud_i2s2_mclk", "aud_k2_src_div", 24), ++ GATE_TOP_AUD(CLK_TOP_AUD_I2S3_MCLK, "aud_i2s3_mclk", "aud_k3_src_div", 25), ++ GATE_TOP_AUD(CLK_TOP_AUD_I2S4_MCLK, "aud_i2s4_mclk", "aud_k4_src_div", 26), ++ GATE_TOP_AUD(CLK_TOP_AUD_I2S5_MCLK, "aud_i2s5_mclk", "aud_k5_src_div", 27), ++ GATE_TOP_AUD(CLK_TOP_AUD_I2S6_MCLK, "aud_i2s6_mclk", "aud_k6_src_div", 28), ++}; ++ ++static void __init mtk_topckgen_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ void __iomem *base; ++ int r; ++ ++ base = of_iomap(node, 0); ++ if (!base) { ++ pr_err("%s(): ioremap failed\n", __func__); ++ return; ++ } ++ ++ clk_data = mtk_alloc_clk_data(CLK_TOP_NR); ++ ++ mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), ++ clk_data); ++ ++ mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs), ++ clk_data); ++ ++ mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), ++ base, &lock, clk_data); ++ ++ mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs), ++ base, &lock, clk_data); ++ ++ mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), ++ clk_data); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++} ++CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt2701-topckgen", mtk_topckgen_init); ++ ++static const struct mtk_gate_regs infra_cg_regs __initconst = { ++ .set_ofs = 0x0040, ++ .clr_ofs = 0x0044, ++ .sta_ofs = 0x0048, ++}; ++ ++#define GATE_ICG(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &infra_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr, \ ++ } ++ ++static const struct mtk_gate infra_clks[] __initconst = { ++ GATE_ICG(CLK_INFRA_DBG, "dbgclk", "axi_sel", 0), ++ GATE_ICG(CLK_INFRA_SMI, "smi_ck", "mm_sel", 1), ++ GATE_ICG(CLK_INFRA_QAXI_CM4, "cm4_ck", "axi_sel", 2), ++ GATE_ICG(CLK_INFRA_AUD_SPLIN_B, "audio_splin_bck", "hadds2_294m_ck", 4), ++ GATE_ICG(CLK_INFRA_AUDIO, "audio_ck", "clk_null", 5), ++ GATE_ICG(CLK_INFRA_EFUSE, "efuse_ck", "clk26m", 6), ++ GATE_ICG(CLK_INFRA_L2C_SRAM, "l2c_sram_ck", "mm_sel", 7), ++ GATE_ICG(CLK_INFRA_M4U, "m4u_ck", "mem_sel", 8), ++ GATE_ICG(CLK_INFRA_CONNMCU, "connsys_bus", "wbg_dig_ck_416m", 12), ++ GATE_ICG(CLK_INFRA_TRNG, "trng_ck", "axi_sel", 13), ++ GATE_ICG(CLK_INFRA_RAMBUFIF, "rambufif_ck", "mem_sel", 14), ++ GATE_ICG(CLK_INFRA_CPUM, "cpum_ck", "mem_sel", 15), ++ GATE_ICG(CLK_INFRA_KP, "kp_ck", "axi_sel", 16), ++ GATE_ICG(CLK_INFRA_CEC, "cec_ck", "rtc_sel", 18), ++ GATE_ICG(CLK_INFRA_IRRX, "irrx_ck", "axi_sel", 19), ++ GATE_ICG(CLK_INFRA_PMICSPI, "pmicspi_ck", "pmicspi_sel", 22), ++ GATE_ICG(CLK_INFRA_PMICWRAP, "pmicwrap_ck", "axi_sel", 23), ++ GATE_ICG(CLK_INFRA_DDCCI, "ddcci_ck", "axi_sel", 24), ++}; ++ ++static const struct mtk_fixed_factor infra_fixed_divs[] __initconst = { ++ FACTOR(CLK_INFRA_CLK_13M, "clk13m", "clk26m", 1, 2), ++}; ++ ++static void __init mtk_infrasys_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ int r; ++ ++ clk_data = mtk_alloc_clk_data(CLK_INFRA_NR); ++ ++ mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), ++ clk_data); ++ mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs), ++ clk_data); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++} ++CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt2701-infracfg", mtk_infrasys_init); ++ ++static const struct mtk_gate_regs peri0_cg_regs __initconst = { ++ .set_ofs = 0x0008, ++ .clr_ofs = 0x0010, ++ .sta_ofs = 0x0018, ++}; ++ ++static const struct mtk_gate_regs peri1_cg_regs __initconst = { ++ .set_ofs = 0x000c, ++ .clr_ofs = 0x0014, ++ .sta_ofs = 0x001c, ++}; ++ ++#define GATE_PERI0(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &peri0_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr, \ ++ } ++ ++#define GATE_PERI1(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &peri1_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr, \ ++ } ++ ++static const struct mtk_gate peri_clks[] __initconst = { ++ GATE_PERI1(CLK_PERI_USB0_MCU, "usb0_mcu_ck", "axi_sel", 31), ++ GATE_PERI1(CLK_PERI_ETH, "eth_ck", "clk26m", 30), ++ GATE_PERI1(CLK_PERI_SPI0, "spi0_ck", "spi0_sel", 29), ++ GATE_PERI1(CLK_PERI_AUXADC, "auxadc_ck", "clk26m", 28), ++ GATE_PERI0(CLK_PERI_I2C3, "i2c3_ck", "clk26m", 27), ++ GATE_PERI0(CLK_PERI_I2C2, "i2c2_ck", "axi_sel", 26), ++ GATE_PERI0(CLK_PERI_I2C1, "i2c1_ck", "axi_sel", 25), ++ GATE_PERI0(CLK_PERI_I2C0, "i2c0_ck", "axi_sel", 24), ++ GATE_PERI0(CLK_PERI_BTIF, "bitif_ck", "axi_sel", 23), ++ GATE_PERI0(CLK_PERI_UART3, "uart3_ck", "axi_sel", 22), ++ GATE_PERI0(CLK_PERI_UART2, "uart2_ck", "axi_sel", 21), ++ GATE_PERI0(CLK_PERI_UART1, "uart1_ck", "axi_sel", 20), ++ GATE_PERI0(CLK_PERI_UART0, "uart0_ck", "axi_sel", 19), ++ GATE_PERI0(CLK_PERI_NLI, "nli_ck", "axi_sel", 18), ++ GATE_PERI0(CLK_PERI_MSDC50_3, "msdc50_3_ck", "emmc_hclk_sel", 17), ++ GATE_PERI0(CLK_PERI_MSDC30_3, "msdc30_3_ck", "msdc30_3_sel", 16), ++ GATE_PERI0(CLK_PERI_MSDC30_2, "msdc30_2_ck", "msdc30_2_sel", 15), ++ GATE_PERI0(CLK_PERI_MSDC30_1, "msdc30_1_ck", "msdc30_1_sel", 14), ++ GATE_PERI0(CLK_PERI_MSDC30_0, "msdc30_0_ck", "msdc30_0_sel", 13), ++ GATE_PERI0(CLK_PERI_AP_DMA, "ap_dma_ck", "axi_sel", 12), ++ GATE_PERI0(CLK_PERI_USB1, "usb1_ck", "usb20_sel", 11), ++ GATE_PERI0(CLK_PERI_USB0, "usb0_ck", "usb20_sel", 10), ++ GATE_PERI0(CLK_PERI_PWM, "pwm_ck", "axi_sel", 9), ++ GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axi_sel", 8), ++ GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axi_sel", 7), ++ GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axi_sel", 6), ++ GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axi_sel", 5), ++ GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axi_sel", 4), ++ GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axi_sel", 3), ++ GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axi_sel", 2), ++ GATE_PERI0(CLK_PERI_THERM, "therm_ck", "axi_sel", 1), ++ GATE_PERI0(CLK_PERI_NFI, "nfi_ck", "nfi2x_sel", 0), ++ ++ GATE_PERI1(CLK_PERI_FCI, "fci_ck", "ms_card", 11), ++ GATE_PERI1(CLK_PERI_SPI2, "spi2_ck", "spi2_sel", 10), ++ GATE_PERI1(CLK_PERI_SPI1, "spi1_ck", "spi1_sel", 9), ++ GATE_PERI1(CLK_PERI_HOST89_DVD, "host89_dvd_ck", "aud2dvd_sel", 8), ++ GATE_PERI1(CLK_PERI_HOST89_SPI, "host89_spi_ck", "spi0_sel", 7), ++ GATE_PERI1(CLK_PERI_HOST89_INT, "host89_int_ck", "axi_sel", 6), ++ GATE_PERI1(CLK_PERI_FLASH, "flash_ck", "nfi2x_sel", 5), ++ GATE_PERI1(CLK_PERI_NFI_PAD, "nfi_pad_ck", "nfi_sel", 4), ++ GATE_PERI1(CLK_PERI_NFI_ECC, "nfi_ecc_ck", "nfi_sel", 3), ++ GATE_PERI1(CLK_PERI_GCPU, "gcpu_ck", "axi_sel", 2), ++ GATE_PERI1(CLK_PERI_USB_SLV, "usbslv_ck", "axi_sel", 1), ++ GATE_PERI1(CLK_PERI_USB1_MCU, "usb1_mcu_ck", "axi_sel", 0), ++}; ++ ++static const char * const uart_ck_sel_parents[] __initconst = { ++ "clk26m", ++ "uart_sel", ++}; ++ ++static const struct mtk_composite peri_muxs[] __initconst = { ++ MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents, 0x40c, 0, 1), ++ MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents, 0x40c, 1, 1), ++ MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents, 0x40c, 2, 1), ++ MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1), ++}; ++ ++static void __init mtk_pericfg_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ void __iomem *base; ++ int r; ++ ++ base = of_iomap(node, 0); ++ if (!base) { ++ pr_err("%s(): ioremap failed\n", __func__); ++ return; ++ } ++ ++ clk_data = mtk_alloc_clk_data(CLK_PERI_NR); ++ ++ mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks), ++ clk_data); ++ ++ mtk_clk_register_composites(peri_muxs, ARRAY_SIZE(peri_muxs), base, ++ &lock, clk_data); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++} ++CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt2701-pericfg", mtk_pericfg_init); ++ ++static const struct mtk_gate_regs disp0_cg_regs __initconst = { ++ .set_ofs = 0x0104, ++ .clr_ofs = 0x0108, ++ .sta_ofs = 0x0100, ++}; ++ ++static const struct mtk_gate_regs disp1_cg_regs __initconst = { ++ .set_ofs = 0x0114, ++ .clr_ofs = 0x0118, ++ .sta_ofs = 0x0110, ++}; ++ ++#define GATE_DISP0(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &disp0_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr, \ ++ } ++ ++#define GATE_DISP1(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &disp1_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr, \ ++ } ++ ++static const struct mtk_gate mm_clks[] __initconst = { ++ GATE_DISP0(CLK_MM_SMI_COMMON, "mm_smi_comm", "mm_sel", 0), ++ GATE_DISP0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1), ++ GATE_DISP0(CLK_MM_CMDQ, "mm_cmdq", "mm_sel", 2), ++ GATE_DISP0(CLK_MM_MUTEX, "mm_mutex", "mm_sel", 3), ++ GATE_DISP0(CLK_MM_DISP_COLOR, "mm_disp_color", "mm_sel", 4), ++ GATE_DISP0(CLK_MM_DISP_BLS, "mm_disp_bls", "mm_sel", 5), ++ GATE_DISP0(CLK_MM_DISP_WDMA, "mm_disp_wdma", "mm_sel", 6), ++ GATE_DISP0(CLK_MM_DISP_RDMA, "mm_disp_rdma", "mm_sel", 7), ++ GATE_DISP0(CLK_MM_DISP_OVL, "mm_disp_ovl", "mm_sel", 8), ++ GATE_DISP0(CLK_MM_MDP_TDSHP, "mm_mdp_tdshp", "mm_sel", 9), ++ GATE_DISP0(CLK_MM_MDP_WROT, "mm_mdp_wrot", "mm_sel", 10), ++ GATE_DISP0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11), ++ GATE_DISP0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 12), ++ GATE_DISP0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 13), ++ GATE_DISP0(CLK_MM_MDP_RDMA, "mm_mdp_rdma", "mm_sel", 14), ++ GATE_DISP0(CLK_MM_MDP_BLS_26M, "mm_mdp_bls_26m", "clk26m", 15), ++ GATE_DISP0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 16), ++ GATE_DISP0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 17), ++ GATE_DISP0(CLK_MM_MUTEX_32K, "mm_mutex_32k", "rtc_sel", 18), ++ GATE_DISP0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 19), ++ GATE_DISP0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 20), ++ GATE_DISP1(CLK_MM_DSI_ENGINE, "mm_dsi_eng", "mm_sel", 0), ++ GATE_DISP1(CLK_MM_DSI_DIG, "mm_dsi_dig", "dsio_lntc_dsiclk", 1), ++ GATE_DISP1(CLK_MM_DPI_DIGL, "mm_dpi_digl", "dpi0_sel", 2), ++ GATE_DISP1(CLK_MM_DPI_ENGINE, "mm_dpi_eng", "mm_sel", 3), ++ GATE_DISP1(CLK_MM_DPI1_DIGL, "mm_dpi1_digl", "dpi1_sel", 4), ++ GATE_DISP1(CLK_MM_DPI1_ENGINE, "mm_dpi1_eng", "mm_sel", 5), ++ GATE_DISP1(CLK_MM_TVE_OUTPUT, "mm_tve_output", "tve_sel", 6), ++ GATE_DISP1(CLK_MM_TVE_INPUT, "mm_tve_input", "dpi0_sel", 7), ++ GATE_DISP1(CLK_MM_HDMI_PIXEL, "mm_hdmi_pixel", "dpi1_sel", 8), ++ GATE_DISP1(CLK_MM_HDMI_PLL, "mm_hdmi_pll", "hdmi_sel", 9), ++ GATE_DISP1(CLK_MM_HDMI_AUDIO, "mm_hdmi_audio", "apll_sel", 10), ++ GATE_DISP1(CLK_MM_HDMI_SPDIF, "mm_hdmi_spdif", "apll_sel", 11), ++ GATE_DISP1(CLK_MM_TVE_FMM, "mm_tve_fmm", "mm_sel", 14), ++}; ++ ++static void __init mtk_mmsys_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ int r; ++ ++ clk_data = mtk_alloc_clk_data(CLK_MM_NR); ++ ++ mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks), ++ clk_data); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++} ++CLK_OF_DECLARE(mtk_mmsys, "mediatek,mt2701-mmsys", mtk_mmsys_init); ++ ++static const struct mtk_gate_regs img_cg_regs __initconst = { ++ .set_ofs = 0x0004, ++ .clr_ofs = 0x0008, ++ .sta_ofs = 0x0000, ++}; ++ ++#define GATE_IMG(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &img_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr, \ ++ } ++ ++static const struct mtk_gate img_clks[] __initconst = { ++ GATE_IMG(CLK_IMG_SMI_COMM, "img_smi_comm", "mm_sel", 0), ++ GATE_IMG(CLK_IMG_RESZ, "img_resz", "mm_sel", 1), ++ GATE_IMG(CLK_IMG_JPGDEC, "img_jpgdec", "mm_sel", 5), ++ GATE_IMG(CLK_IMG_VENC_LT, "img_venc_lt", "mm_sel", 8), ++ GATE_IMG(CLK_IMG_VENC, "img_venc", "mm_sel", 9), ++}; ++ ++static void __init mtk_imgsys_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ int r; ++ ++ clk_data = mtk_alloc_clk_data(CLK_IMG_NR); ++ ++ mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks), ++ clk_data); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++} ++CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt2701-imgsys", mtk_imgsys_init); ++ ++static const struct mtk_gate_regs vdec0_cg_regs __initconst = { ++ .set_ofs = 0x0000, ++ .clr_ofs = 0x0004, ++ .sta_ofs = 0x0000, ++}; ++ ++static const struct mtk_gate_regs vdec1_cg_regs __initconst = { ++ .set_ofs = 0x0008, ++ .clr_ofs = 0x000c, ++ .sta_ofs = 0x0008, ++}; ++ ++#define GATE_VDEC0(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &vdec0_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr_inv, \ ++ } ++ ++#define GATE_VDEC1(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &vdec1_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr_inv, \ ++ } ++ ++static const struct mtk_gate vdec_clks[] __initconst = { ++ GATE_VDEC0(CLK_VDEC_CKGEN, "vdec_cken", "vdec_sel", 0), ++ GATE_VDEC1(CLK_VDEC_LARB, "vdec_larb_cken", "mm_sel", 0), ++}; ++ ++static void __init mtk_vdecsys_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ int r; ++ ++ clk_data = mtk_alloc_clk_data(CLK_VDEC_NR); ++ ++ mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks), ++ clk_data); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++} ++CLK_OF_DECLARE(mtk_vdecsys, "mediatek,mt2701-vdecsys", mtk_vdecsys_init); ++ ++static const struct mtk_gate_regs hif_cg_regs __initconst = { ++ .sta_ofs = 0x0008, ++}; ++ ++#define GATE_HIF(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &hif_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_no_setclr_inv, \ ++ } ++ ++static const struct mtk_gate hif_clks[] __initconst = { ++ GATE_HIF(CLK_HIFSYS_USB0PHY, "usb0_phy_clk", "ethpll_500m_ck", 21), ++ GATE_HIF(CLK_HIFSYS_USB1PHY, "usb1_phy_clk", "ethpll_500m_ck", 22), ++ GATE_HIF(CLK_HIFSYS_PCIE0, "pcie0_clk", "ethpll_500m_ck", 24), ++ GATE_HIF(CLK_HIFSYS_PCIE1, "pcie1_clk", "ethpll_500m_ck", 25), ++ GATE_HIF(CLK_HIFSYS_PCIE2, "pcie2_clk", "ethpll_500m_ck", 26), ++}; ++ ++static void __init mtk_hifsys_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ int r; ++ ++ clk_data = mtk_alloc_clk_data(CLK_HIFSYS_NR); ++ ++ mtk_clk_register_gates(node, hif_clks, ARRAY_SIZE(hif_clks), ++ clk_data); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++} ++CLK_OF_DECLARE(mtk_hifsys, "mediatek,mt2701-hifsys", mtk_hifsys_init); ++ ++static const struct mtk_gate_regs eth_cg_regs __initconst = { ++ .sta_ofs = 0x0030, ++}; ++ ++#define GATE_eth(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = ð_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_no_setclr_inv, \ ++ } ++ ++static const struct mtk_gate eth_clks[] __initconst = { ++ GATE_HIF(CLK_ETHSYS_HSDMA, "hsdma_clk", "ethif_sel", 5), ++ GATE_HIF(CLK_ETHSYS_ESW, "esw_clk", "ethpll_500m_ck", 6), ++ GATE_HIF(CLK_ETHSYS_GP2, "gp2_clk", "trgpll", 7), ++ GATE_HIF(CLK_ETHSYS_GP1, "gp1_clk", "ethpll_500m_ck", 8), ++ GATE_HIF(CLK_ETHSYS_PCM, "pcm_clk", "ethif_sel", 11), ++ GATE_HIF(CLK_ETHSYS_GDMA, "gdma_clk", "ethif_sel", 14), ++ GATE_HIF(CLK_ETHSYS_I2S, "i2s_clk", "ethif_sel", 17), ++ GATE_HIF(CLK_ETHSYS_CRYPTO, "crypto_clk", "ethif_sel", 29), ++}; ++ ++static void __init mtk_ethsys_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ int r; ++ ++ clk_data = mtk_alloc_clk_data(CLK_ETHSYS_NR); ++ ++ mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks), ++ clk_data); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++} ++CLK_OF_DECLARE(mtk_ethsys, "mediatek,mt2701-ethsys", mtk_ethsys_init); ++ ++static const struct mtk_gate_regs bdp0_cg_regs __initconst = { ++ .set_ofs = 0x0104, ++ .clr_ofs = 0x0108, ++ .sta_ofs = 0x0100, ++}; ++ ++static const struct mtk_gate_regs bdp1_cg_regs __initconst = { ++ .set_ofs = 0x0114, ++ .clr_ofs = 0x0118, ++ .sta_ofs = 0x0110, ++}; ++ ++#define GATE_BDP0(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &bdp0_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr_inv, \ ++ } ++ ++#define GATE_BDP1(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &bdp1_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr_inv, \ ++ } ++ ++static const struct mtk_gate bdp_clks[] __initconst = { ++ GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0), ++ GATE_BDP0(CLK_BDP_BRG_DRAM, "brg_dram", "mm_sel", 1), ++ GATE_BDP0(CLK_BDP_LARB_DRAM, "larb_dram", "mm_sel", 2), ++ GATE_BDP0(CLK_BDP_WR_VDI_PXL, "wr_vdi_pxl", "hdmi_0_deep340m", 3), ++ GATE_BDP0(CLK_BDP_WR_VDI_DRAM, "wr_vdi_dram", "mm_sel", 4), ++ GATE_BDP0(CLK_BDP_WR_B, "wr_bclk", "mm_sel", 5), ++ GATE_BDP0(CLK_BDP_DGI_IN, "dgi_in", "dpi1_sel", 6), ++ GATE_BDP0(CLK_BDP_DGI_OUT, "dgi_out", "dpi_sel", 7), ++ GATE_BDP0(CLK_BDP_FMT_MAST_27, "fmt_mast_27", "dpi1_sel", 8), ++ GATE_BDP0(CLK_BDP_FMT_B, "fmt_bclk", "mm_sel", 9), ++ GATE_BDP0(CLK_BDP_OSD_B, "osd_bclk", "mm_sel", 10), ++ GATE_BDP0(CLK_BDP_OSD_DRAM, "osd_dram", "mm_sel", 11), ++ GATE_BDP0(CLK_BDP_OSD_AGENT, "osd_agent", "osd_sel", 12), ++ GATE_BDP0(CLK_BDP_OSD_PXL, "osd_pxl", "dpi1_sel", 13), ++ GATE_BDP0(CLK_BDP_RLE_B, "rle_bclk", "mm_sel", 14), ++ GATE_BDP0(CLK_BDP_RLE_AGENT, "rle_agent", "mm_sel", 15), ++ GATE_BDP0(CLK_BDP_RLE_DRAM, "rle_dram", "mm_sel", 16), ++ GATE_BDP0(CLK_BDP_F27M, "f27m", "di_sel", 17), ++ GATE_BDP0(CLK_BDP_F27M_VDOUT, "f27m_vdout", "di_sel", 18), ++ GATE_BDP0(CLK_BDP_F27_74_74, "f27_74_74", "di_sel", 19), ++ GATE_BDP0(CLK_BDP_F2FS, "f2fs", "di_sel", 20), ++ GATE_BDP0(CLK_BDP_F2FS74_148, "f2fs74_148", "di_sel", 21), ++ GATE_BDP0(CLK_BDP_FB, "fbclk", "mm_sel", 22), ++ GATE_BDP0(CLK_BDP_VDO_DRAM, "vdo_dram", "mm_sel", 23), ++ GATE_BDP0(CLK_BDP_VDO_2FS, "vdo_2fs", "di_sel", 24), ++ GATE_BDP0(CLK_BDP_VDO_B, "vdo_bclk", "mm_sel", 25), ++ GATE_BDP0(CLK_BDP_WR_DI_PXL, "wr_di_pxl", "di_sel", 26), ++ GATE_BDP0(CLK_BDP_WR_DI_DRAM, "wr_di_dram", "mm_sel", 27), ++ GATE_BDP0(CLK_BDP_WR_DI_B, "wr_di_bclk", "mm_sel", 28), ++ GATE_BDP0(CLK_BDP_NR_PXL, "nr_pxl", "nr_sel", 29), ++ GATE_BDP0(CLK_BDP_NR_DRAM, "nr_dram", "mm_sel", 30), ++ GATE_BDP0(CLK_BDP_NR_B, "nr_bclk", "mm_sel", 31), ++ GATE_BDP1(CLK_BDP_RX_F, "rx_fclk", "hadds2_fbclk", 0), ++ GATE_BDP1(CLK_BDP_RX_X, "rx_xclk", "clk26m", 1), ++ GATE_BDP1(CLK_BDP_RXPDT, "rxpdtclk", "hdmi_0_pix340m", 2), ++ GATE_BDP1(CLK_BDP_RX_CSCL_N, "rx_cscl_n", "clk26m", 3), ++ GATE_BDP1(CLK_BDP_RX_CSCL, "rx_cscl", "clk26m", 4), ++ GATE_BDP1(CLK_BDP_RX_DDCSCL_N, "rx_ddcscl_n", "hdmi_scl_rx", 5), ++ GATE_BDP1(CLK_BDP_RX_DDCSCL, "rx_ddcscl", "hdmi_scl_rx", 6), ++ GATE_BDP1(CLK_BDP_RX_VCO, "rx_vcoclk", "hadds2pll_294m", 7), ++ GATE_BDP1(CLK_BDP_RX_DP, "rx_dpclk", "hdmi_0_pll340m", 8), ++ GATE_BDP1(CLK_BDP_RX_P, "rx_pclk", "hdmi_0_pll340m", 9), ++ GATE_BDP1(CLK_BDP_RX_M, "rx_mclk", "hadds2pll_294m", 10), ++ GATE_BDP1(CLK_BDP_RX_PLL, "rx_pllclk", "hdmi_0_pix340m", 11), ++ GATE_BDP1(CLK_BDP_BRG_RT_B, "brg_rt_bclk", "mm_sel", 12), ++ GATE_BDP1(CLK_BDP_BRG_RT_DRAM, "brg_rt_dram", "mm_sel", 13), ++ GATE_BDP1(CLK_BDP_LARBRT_DRAM, "larbrt_dram", "mm_sel", 14), ++ GATE_BDP1(CLK_BDP_TMDS_SYN, "tmds_syn", "hdmi_0_pll340m", 15), ++ GATE_BDP1(CLK_BDP_HDMI_MON, "hdmi_mon", "hdmi_0_mon", 16), ++}; ++ ++static void __init mtk_bdpsys_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ int r; ++ ++ clk_data = mtk_alloc_clk_data(CLK_BDP_NR); ++ ++ mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks), ++ clk_data); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++} ++CLK_OF_DECLARE(mtk_bdpsys, "mediatek,mt2701-bdpsys", mtk_bdpsys_init); ++ ++#define MT8590_PLL_FMAX (2000 * MHZ) ++#define CON0_MT8590_RST_BAR BIT(27) ++ ++#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \ ++ _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .reg = _reg, \ ++ .pwr_reg = _pwr_reg, \ ++ .en_mask = _en_mask, \ ++ .flags = _flags, \ ++ .rst_bar_mask = CON0_MT8590_RST_BAR, \ ++ .fmax = MT8590_PLL_FMAX, \ ++ .pcwbits = _pcwbits, \ ++ .pd_reg = _pd_reg, \ ++ .pd_shift = _pd_shift, \ ++ .tuner_reg = _tuner_reg, \ ++ .pcw_reg = _pcw_reg, \ ++ .pcw_shift = _pcw_shift, \ ++ } ++ ++static const struct mtk_pll_data apmixed_plls[] = { ++ PLL(CLK_APMIXED_ARMPLL, "armpll", 0x200, 0x20c, 0x80000001, 0, ++ 21, 0x204, 24, 0x0, 0x204, 0), ++ PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x210, 0x21c, 0xf0000001, ++ HAVE_RST_BAR, 21, 0x210, 4, 0x0, 0x214, 0), ++ PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x220, 0x22c, 0xf3000001, ++ HAVE_RST_BAR, 7, 0x220, 4, 0x0, 0x224, 14), ++ PLL(CLK_APMIXED_MMPLL, "mmpll", 0x230, 0x23c, 0x00000001, 0, ++ 21, 0x230, 4, 0x0, 0x234, 0), ++ PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x240, 0x24c, 0x00000001, 0, ++ 21, 0x240, 4, 0x0, 0x244, 0), ++ PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x250, 0x25c, 0x00000001, 0, ++ 21, 0x250, 4, 0x0, 0x254, 0), ++ PLL(CLK_APMIXED_AUD1PLL, "aud1pll", 0x270, 0x27c, 0x00000001, 0, ++ 31, 0x270, 4, 0x0, 0x274, 0), ++ PLL(CLK_APMIXED_TRGPLL, "trgpll", 0x280, 0x28c, 0x00000001, 0, ++ 31, 0x280, 4, 0x0, 0x284, 0), ++ PLL(CLK_APMIXED_ETHPLL, "ethpll", 0x290, 0x29c, 0x00000001, 0, ++ 31, 0x290, 4, 0x0, 0x294, 0), ++ PLL(CLK_APMIXED_VDECPLL, "vdecpll", 0x2a0, 0x2ac, 0x00000001, 0, ++ 31, 0x2a0, 4, 0x0, 0x2a4, 0), ++ PLL(CLK_APMIXED_HADDS2PLL, "hadds2pll", 0x2b0, 0x2bc, 0x00000001, 0, ++ 31, 0x2b0, 4, 0x0, 0x2b4, 0), ++ PLL(CLK_APMIXED_AUD2PLL, "aud2pll", 0x2c0, 0x2cc, 0x00000001, 0, ++ 31, 0x2c0, 4, 0x0, 0x2c4, 0), ++ PLL(CLK_APMIXED_TVD2PLL, "tvd2pll", 0x2d0, 0x2dc, 0x00000001, 0, ++ 21, 0x2d0, 4, 0x0, 0x2d4, 0), ++}; ++ ++static void __init mtk_apmixedsys_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ int r; ++ ++ clk_data = mtk_alloc_clk_data(ARRAY_SIZE(apmixed_plls)); ++ if (!clk_data) ++ return; ++ ++ mtk_clk_register_plls(node, apmixed_plls, ARRAY_SIZE(apmixed_plls), ++ clk_data); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++} ++CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt2701-apmixedsys", ++ mtk_apmixedsys_init); +--- a/drivers/clk/mediatek/clk-mtk.c ++++ b/drivers/clk/mediatek/clk-mtk.c +@@ -244,3 +244,28 @@ + clk_data->clks[mc->id] = clk; + } + } ++ ++void __init mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, ++ int num, void __iomem *base, spinlock_t *lock, ++ struct clk_onecell_data *clk_data) ++{ ++ struct clk *clk; ++ int i; ++ ++ for (i = 0; i < num; i++) { ++ const struct mtk_clk_divider *mcd = &mcds[i]; ++ ++ clk = clk_register_divider(NULL, mcd->name, mcd->parent_name, ++ mcd->flags, base + mcd->div_reg, mcd->div_shift, ++ mcd->div_width, mcd->clk_divider_flags, lock); ++ ++ if (IS_ERR(clk)) { ++ pr_err("Failed to register clk %s: %ld\n", ++ mcd->name, PTR_ERR(clk)); ++ continue; ++ } ++ ++ if (clk_data) ++ clk_data->clks[mcd->id] = clk; ++ } ++} +--- a/drivers/clk/mediatek/clk-mtk.h ++++ b/drivers/clk/mediatek/clk-mtk.h +@@ -121,7 +121,8 @@ + .flags = CLK_SET_RATE_PARENT, \ + } + +-#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, _div_width, _div_shift) { \ ++#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, \ ++ _div_width, _div_shift) { \ + .id = _id, \ + .parent = _parent, \ + .name = _name, \ +@@ -156,8 +157,36 @@ + const struct clk_ops *ops; + }; + +-int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks, +- int num, struct clk_onecell_data *clk_data); ++int mtk_clk_register_gates(struct device_node *node, ++ const struct mtk_gate *clks, int num, ++ struct clk_onecell_data *clk_data); ++ ++struct mtk_clk_divider { ++ int id; ++ const char *name; ++ const char *parent_name; ++ unsigned long flags; ++ ++ uint32_t div_reg; ++ unsigned char div_shift; ++ unsigned char div_width; ++ unsigned char clk_divider_flags; ++ const struct clk_div_table *clk_div_table; ++}; ++ ++#define DIV_ADJ(_id, _name, _parent, _reg, _shift, _width) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .flags = CLK_SET_RATE_PARENT, \ ++ .div_reg = _reg, \ ++ .div_shift = _shift, \ ++ .div_width = _width, \ ++} ++ ++void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, ++ int num, void __iomem *base, spinlock_t *lock, ++ struct clk_onecell_data *clk_data); + + struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num); + 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 index 0000000000..18d4fbf252 --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0011-reset-mediatek-mt2701-reset-driver.patch @@ -0,0 +1,36 @@ +From 3ba0020ea70ffb5503eff1823be7fa5ceda38286 Mon Sep 17 00:00:00 2001 +From: Shunli Wang +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 +Acked-by: Philipp Zabel +--- + 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 index 0000000000..696dea6179 --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0012-ARM-mediatek-Add-MT2701-config-options-for-mediatek-.patch @@ -0,0 +1,29 @@ +From 32fa899c6ab79953e4f470fb23c38bcc40edc5c8 Mon Sep 17 00:00:00 2001 +From: Erin Lo +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 +Acked-by: Linus Walleij +--- + 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 index 0000000000..60940f3239 --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0017-clk-add-hifsys-reset.patch @@ -0,0 +1,31 @@ +From f7121d2b19ddad33a09408a2c5923bfd95da8533 Mon Sep 17 00:00:00 2001 +From: John Crispin +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 +--- + 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 index 0000000000..d6fe977793 --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0024-dt-bindings-add-MediaTek-PCIe-binding-documentation.patch @@ -0,0 +1,154 @@ +From 05be818061b9f2a0fa5ad0cde6881917ff14a2f2 Mon Sep 17 00:00:00 2001 +From: John Crispin +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 +--- + .../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 = , ++ , ++ ; ++ 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 index 0000000000..71081fbcdb --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0025-PCI-mediatek-add-support-for-PCIe-found-on-MT7623-MT.patch @@ -0,0 +1,698 @@ +From 8ab1d4e0a9a68e03f472dee1c036a01d0198c20c Mon Sep 17 00:00:00 2001 +From: John Crispin +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 +--- + 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 ++ * Copyright (C) 2015 John Crispin ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 index 0000000000..b5047f76b8 --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0026-scpsys-various-fixes.patch @@ -0,0 +1,22 @@ +From 59aafd667d2880c90776931b6102b8252214d93c Mon Sep 17 00:00:00 2001 +From: John Crispin +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 index 0000000000..87e4a54ed3 --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0052-clk-dont-disable-unused-clocks.patch @@ -0,0 +1,21 @@ +From 5238c5d1d38661955ed3b52f45c46e00bfc9eb6e Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Thu, 7 Apr 2016 07:18:35 +0200 +Subject: [PATCH 052/102] clk: dont disable unused clocks + +Signed-off-by: John Crispin +--- + 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 index 0000000000..39939001f1 --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0053-clk-mediatek-enable-critical-clocks.patch @@ -0,0 +1,69 @@ +From c8fd103d6c07af5db47f061b70759b7c69169656 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Thu, 31 Mar 2016 06:46:51 +0200 +Subject: [PATCH 053/102] clk: mediatek: enable critical clocks + +Signed-off-by: John Crispin +--- + 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 index 0000000000..2ff6990d10 --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0054-clk-mediatek-Export-CPU-mux-clocks-for-CPU-frequency.patch @@ -0,0 +1,287 @@ +From 1387d4f0ebf4b48c09f2ea0d27a02936c3fa0010 Mon Sep 17 00:00:00 2001 +From: John Crispin +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 +--- + 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 ++ * ++ * 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 ++#include ++#include ++ ++#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 ++ * ++ * 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 + +@@ -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 + +@@ -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 index 0000000000..8b476361ff --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0055-cpufreq-mediatek-add-driver.patch @@ -0,0 +1,433 @@ +From 60f4e41b367bdb29530468c91c1e613b17a37755 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Wed, 30 Mar 2016 23:48:53 +0200 +Subject: [PATCH 055/102] cpufreq: mediatek: add driver + +Signed-off-by: John Crispin +--- + 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 ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 index 0000000000..75796ab0fa --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0071-pwm-add-pwm-mediatek.patch @@ -0,0 +1,304 @@ +From 6f5941c93bdf7649f392f1263b9068d360ceab4d Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Fri, 6 May 2016 02:55:48 +0200 +Subject: [PATCH 071/102] pwm: add pwm-mediatek + +Signed-off-by: John Crispin +--- + 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 = ; ++ }; ++ ++ pins_pwm2 { ++ pinmux = ; ++ }; ++ };*/ ++ + }; + + &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 ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 "); ++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 index 0000000000..a90f49055e --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0101-net-mediatek-add-gsw-mt7530-driver.patch @@ -0,0 +1,2322 @@ +From 6b8a7257e7bcb56782c3f8048311670fe6a80209 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Mon, 11 Apr 2016 03:11:54 +0200 +Subject: [PATCH 101/102] net: mediatek add gsw/mt7530 driver + +Signed-off-by: John Crispin +--- + 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 ++ * Copyright (C) 2009-2016 Felix Fietkau ++ * Copyright (C) 2013-2016 Michael Lee ++ */ ++ ++#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 ++ * Copyright (C) 2009-2016 Felix Fietkau ++ * Copyright (C) 2013-2016 Michael Lee ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 "); ++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 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++ */ ++ ++#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 index 0000000000..92f34c5fc2 --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0103-nand_fixes.patch @@ -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 index 0000000000..eb743c7247 --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0200-devicetree.patch @@ -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 index 0000000000..395884b730 --- /dev/null +++ b/target/linux/mediatek/patches-4.9/0201-block2mtd.patch @@ -0,0 +1,32 @@ +--- a/drivers/mtd/devices/block2mtd.c ++++ b/drivers/mtd/devices/block2mtd.c +@@ -32,6 +32,8 @@ + #include + #include + ++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; + }