mediatek: bump to v4.14
This drops support for all the !emmc EVB and adds banannaPi-R2 Also drop mtkhnat until the nftables offoad driver is ready Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
		| @@ -9,7 +9,7 @@ SUBTARGETS:=32 | ||||
| FEATURES:=squashfs nand ubifs | ||||
| MAINTAINER:=John Crispin <john@phrozen.org> | ||||
|  | ||||
| KERNEL_PATCHVER:=4.9 | ||||
| KERNEL_PATCHVER:=4.14 | ||||
|  | ||||
| KERNELNAME:=Image dtbs zImage | ||||
|  | ||||
|   | ||||
| @@ -9,13 +9,11 @@ mediatek_setup_interfaces() | ||||
| 	local board="$1" | ||||
|  | ||||
| 	case $board in | ||||
| 	'bananapi,bpi-r2' | \ | ||||
| 	'mediatek,mt7623-rfb-emmc' | \ | ||||
| 	'mediatek,mt7623-rfb-nand-ephy') | ||||
| 	'mediatek,mt7623a-rfb-emmc') | ||||
| 		ucidef_set_interface_lan "lan0 lan1 lan2 lan3" | ||||
| 		ucidef_set_interface_wan eth1 | ||||
| 		;; | ||||
| 	'mediatek,mt7623-rfb-nand') | ||||
| 	'bananapi,bpi-r2')  | ||||
| 		ucidef_set_interface_lan "lan0 lan1 lan2 lan3" | ||||
| 		ucidef_set_interface_wan wan | ||||
| 		;; | ||||
|   | ||||
| @@ -1,60 +0,0 @@ | ||||
| config global global | ||||
| 	option enable 0 | ||||
| 	option upstream 1000000 | ||||
| 	option downstream 1000000 | ||||
|  | ||||
| config queue | ||||
| 	option id 0 | ||||
| 	option minrate 10 | ||||
| 	option maxrate 50 | ||||
| 	option weight 7 | ||||
| 	option resv 32 | ||||
|  | ||||
| config queue | ||||
| 	option id 1 | ||||
| 	option minrate 30 | ||||
| 	option maxrate 100 | ||||
| 	option weight 7 | ||||
| 	option resv 32 | ||||
|  | ||||
| config queue | ||||
| 	option id 2 | ||||
| 	option minrate 30 | ||||
| 	option maxrate 100 | ||||
| 	option weight 7 | ||||
| 	option resv 32 | ||||
|  | ||||
| config queue | ||||
| 	option id 3 | ||||
| 	option minrate 30 | ||||
| 	option maxrate 100 | ||||
| 	option weight 7 | ||||
| 	option resv 32 | ||||
|  | ||||
| config queue | ||||
| 	option id 4 | ||||
| 	option minrate 25 | ||||
| 	option maxrate 100 | ||||
| 	option weight 7 | ||||
| 	option resv 32 | ||||
|  | ||||
| config queue | ||||
| 	option id 5 | ||||
| 	option minrate 25 | ||||
| 	option maxrate 100 | ||||
| 	option weight 7 | ||||
| 	option resv 32 | ||||
|  | ||||
| config queue | ||||
| 	option id 6 | ||||
| 	option minrate 25 | ||||
| 	option maxrate 100 | ||||
| 	option weight 7 | ||||
| 	option resv 32 | ||||
|  | ||||
| config queue | ||||
| 	option id 7 | ||||
| 	option minrate 25 | ||||
| 	option maxrate 100 | ||||
| 	option weight 7 | ||||
| 	option resv 32 | ||||
| @@ -1,13 +0,0 @@ | ||||
| #!/bin/sh /etc/rc.common | ||||
|  | ||||
| START=90 | ||||
|  | ||||
| USE_PROCD=1 | ||||
| NAME=mtkhnat | ||||
| PROG=/sbin/mtkhnat | ||||
|  | ||||
| start_service() { | ||||
| 	procd_open_instance | ||||
| 	procd_set_param command "${PROG}" | ||||
| 	procd_close_instance | ||||
| } | ||||
| @@ -1,9 +0,0 @@ | ||||
| echo "iptables -t mangle -A FORWARD -i br-lan -o eth1 -p tcp -m mark --mark 0/0x7 -j MARK --set-mark 4/0x7" >> /etc/firewall.user | ||||
| echo "iptables -t mangle -A FORWARD -i br-lan -o eth1 -p udp -m mark --mark 0/0x7 -j MARK --set-mark 5/0x7" >> /etc/firewall.user | ||||
| echo "iptables -t mangle -A FORWARD -i eth1 -o br-lan -p tcp -m mark --mark 0/0x7 -j MARK --set-mark 4/0x7" >> /etc/firewall.user | ||||
| echo "iptables -t mangle -A FORWARD -i eth1 -o br-lan -p udp -m mark --mark 0/0x7 -j MARK --set-mark 5/0x7" >> /etc/firewall.user | ||||
|  | ||||
| echo "iptables -t mangle -A FORWARD -p udp -m mark --mark 0/0xf8 -j MARK --or-mark 0x60" >> /etc/firewall.user | ||||
| echo "iptables -t mangle -A FORWARD -p tcp -m mark --mark 0/0xf8 -j MARK --or-mark 0xc0" >> /etc/firewall.user | ||||
|  | ||||
| exit 0 | ||||
| @@ -20,13 +20,8 @@ platform_check_image() { | ||||
| 	local board=$(board_name) | ||||
|  | ||||
| 	case "$board" in | ||||
| 	mediatek,mt7623-rfb-nand-ephy |\ | ||||
| 	mediatek,mt7623-rfb-nand) | ||||
| 		nand_do_platform_check $board $1 | ||||
| 		return $? | ||||
| 		;; | ||||
| 	bananapi,bpi-r2 |\ | ||||
| 	mediatek,mt7623-rfb-emmc) | ||||
| 	mediatek,mt7623a-rfb-emmc) | ||||
| 		local kernel_length=`(tar xf $tar_file sysupgrade-$board/kernel -O | wc -c) 2> /dev/null` | ||||
| 		local rootfs_length=`(tar xf $tar_file sysupgrade-$board/root -O | wc -c) 2> /dev/null` | ||||
| 		;; | ||||
| @@ -44,12 +39,3 @@ platform_check_image() { | ||||
|  | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| platform_pre_upgrade() { | ||||
| 	case "$(board_name)" in | ||||
| 	mediatek,mt7623-rfb-nand-ephy |\ | ||||
| 	mediatek,mt7623-rfb-nand) | ||||
| 		nand_do_upgrade $1 | ||||
| 		;; | ||||
| 	esac | ||||
| } | ||||
|   | ||||
| @@ -1,64 +0,0 @@ | ||||
| #!/bin/sh | ||||
|  | ||||
| . /lib/functions.sh | ||||
|  | ||||
| config_load mtkhnat | ||||
| config_get enable global enable 0 | ||||
|  | ||||
| [ "${enable}" -eq 1 ] || { | ||||
| 	echo 0 ${sch_upstream} > /sys/kernel/debug/hnat/scheduler0 | ||||
| 	echo 0 ${sch_downstream} > /sys/kernel/debug/hnat/scheduler1 | ||||
|  | ||||
| 	rmmod mtkhnat | ||||
| 	exit 0 | ||||
| } | ||||
|  | ||||
| insmod mtkhnat | ||||
|  | ||||
| sleep 1 | ||||
|  | ||||
| config_get sch_upstream global upstream 100000 | ||||
| config_get sch_downstream global downstream 100000 | ||||
|  | ||||
| echo 1 ${sch_upstream} > /sys/kernel/debug/hnat/scheduler0 | ||||
| echo 1 ${sch_downstream} > /sys/kernel/debug/hnat/scheduler1 | ||||
|  | ||||
| setup_queue() { | ||||
| 	local queue_id queue_scheduler queue_minebl queue_maxebl queue_minrate queue_maxrate queue_resv minrate maxrate queue_weight | ||||
|  | ||||
| 	config_get queue_id $1 id 0 | ||||
| 	config_get queue_minrate $1 minrate 0 | ||||
| 	config_get queue_maxrate $1 maxrate 0 | ||||
| 	config_get queue_resv $1 resv 22 | ||||
| 	config_get queue_weight $1 weight 7 | ||||
|  | ||||
| 	[ "${queue_id}" -gt 7 ] && return 0 | ||||
|  | ||||
| 	queue_minebl=1 | ||||
| 	queue_maxebl=1 | ||||
| 	queue_scheduler=0 | ||||
|  | ||||
| 	[ "${queue_minrate}" -eq 0 ] && queue_minebl=0 | ||||
| 	[ "${queue_maxrate}" -eq 0 ] && queue_maxebl=0 | ||||
|  | ||||
| 	minrate=$((sch_upstream * $queue_minrate)) | ||||
| 	minrate=$((minrate / 100)) | ||||
|  | ||||
| 	maxrate=$((sch_upstream * $queue_maxrate)) | ||||
| 	maxrate=$((maxrate / 100)) | ||||
|  | ||||
| 	echo 0 ${queue_minebl} ${minrate} ${queue_maxebl} ${maxrate} ${queue_weight} ${queue_resv} > /sys/kernel/debug/hnat/queue${queue_id}  | ||||
|  | ||||
| 	queue_id=$((queue_id + 8)) | ||||
|  | ||||
| 	minrate=$((sch_downstream * $queue_minrate)) | ||||
| 	minrate=$((minrate / 100)) | ||||
|  | ||||
| 	maxrate=$((sch_downstream * $queue_maxrate)) | ||||
| 	maxrate=$((maxrate / 100)) | ||||
|  | ||||
| 	echo 1 ${queue_minebl} ${minrate} ${queue_maxebl} ${maxrate} ${queue_weight} ${queue_resv} > /sys/kernel/debug/hnat/queue${queue_id}  | ||||
| } | ||||
|  | ||||
| config_foreach setup_scheduler scheduler | ||||
| config_foreach setup_queue queue | ||||
							
								
								
									
										496
									
								
								target/linux/mediatek/config-4.14
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										496
									
								
								target/linux/mediatek/config-4.14
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,496 @@ | ||||
| # CONFIG_AIO is not set | ||||
| CONFIG_ALIGNMENT_TRAP=y | ||||
| CONFIG_ARCH_CLOCKSOURCE_DATA=y | ||||
| CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y | ||||
| CONFIG_ARCH_HAS_ELF_RANDOMIZE=y | ||||
| CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y | ||||
| CONFIG_ARCH_HAS_SET_MEMORY=y | ||||
| CONFIG_ARCH_HAS_SG_CHAIN=y | ||||
| CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y | ||||
| CONFIG_ARCH_HAS_STRICT_MODULE_RWX=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_OPTIONAL_KERNEL_RWX=y | ||||
| CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y | ||||
| # 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_WANTS_THP_SWAP is not set | ||||
| CONFIG_ARCH_WANT_GENERAL_HUGETLB=y | ||||
| CONFIG_ARCH_WANT_IPC_PARSE_VERSION=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_MEDIATEK_CPUFREQ=y | ||||
| CONFIG_ARM_PATCH_IDIV=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_BLK_MQ_PCI=y | ||||
| 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_CLONE_BACKWARDS=y | ||||
| CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 rootfstype=squashfs,jffs2" | ||||
| CONFIG_CMDLINE_FORCE=y | ||||
| CONFIG_COMMON_CLK=y | ||||
| CONFIG_COMMON_CLK_MEDIATEK=y | ||||
| CONFIG_COMMON_CLK_MT2701=y | ||||
| CONFIG_COMMON_CLK_MT2701_BDPSYS=y | ||||
| CONFIG_COMMON_CLK_MT2701_ETHSYS=y | ||||
| CONFIG_COMMON_CLK_MT2701_HIFSYS=y | ||||
| CONFIG_COMMON_CLK_MT2701_IMGSYS=y | ||||
| CONFIG_COMMON_CLK_MT2701_MMSYS=y | ||||
| CONFIG_COMMON_CLK_MT2701_VDECSYS=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_ATTR_SET=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_HOTPLUG_STATE_CONTROL is not set | ||||
| # CONFIG_CPU_ICACHE_DISABLE is not set | ||||
| CONFIG_CPU_PABRT_V7=y | ||||
| CONFIG_CPU_PM=y | ||||
| CONFIG_CPU_RMAP=y | ||||
| # CONFIG_CPU_THERMAL is not set | ||||
| CONFIG_CPU_THUMB_CAPABLE=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_ACOMP2=y | ||||
| CONFIG_CRYPTO_AEAD=y | ||||
| CONFIG_CRYPTO_AEAD2=y | ||||
| CONFIG_CRYPTO_CTR=y | ||||
| CONFIG_CRYPTO_DEFLATE=y | ||||
| CONFIG_CRYPTO_DEV_MEDIATEK=y | ||||
| CONFIG_CRYPTO_DRBG=y | ||||
| CONFIG_CRYPTO_DRBG_HMAC=y | ||||
| CONFIG_CRYPTO_DRBG_MENU=y | ||||
| CONFIG_CRYPTO_HASH=y | ||||
| CONFIG_CRYPTO_HASH2=y | ||||
| CONFIG_CRYPTO_HMAC=y | ||||
| CONFIG_CRYPTO_HW=y | ||||
| CONFIG_CRYPTO_JITTERENTROPY=y | ||||
| CONFIG_CRYPTO_LZO=y | ||||
| CONFIG_CRYPTO_MANAGER=y | ||||
| CONFIG_CRYPTO_MANAGER2=y | ||||
| CONFIG_CRYPTO_NULL=y | ||||
| CONFIG_CRYPTO_NULL2=y | ||||
| CONFIG_CRYPTO_RNG=y | ||||
| CONFIG_CRYPTO_RNG2=y | ||||
| CONFIG_CRYPTO_RNG_DEFAULT=y | ||||
| CONFIG_CRYPTO_SEQIV=y | ||||
| CONFIG_CRYPTO_SHA1=y | ||||
| CONFIG_CRYPTO_SHA256=y | ||||
| CONFIG_CRYPTO_SHA512=y | ||||
| CONFIG_CRYPTO_WORKQUEUE=y | ||||
| CONFIG_DCACHE_WORD_ACCESS=y | ||||
| CONFIG_DEBUG_ALIGN_RODATA=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_NOOP_OPS is not set | ||||
| CONFIG_DMA_OF=y | ||||
| # CONFIG_DMA_VIRT_OPS is not set | ||||
| # CONFIG_DRM_LIB_RANDOM is not set | ||||
| CONFIG_DTC=y | ||||
| CONFIG_EARLY_PRINTK=y | ||||
| CONFIG_EDAC_ATOMIC_SCRUB=y | ||||
| CONFIG_EDAC_SUPPORT=y | ||||
| CONFIG_ELF_CORE=y | ||||
| CONFIG_EXPORTFS=y | ||||
| CONFIG_FIXED_PHY=y | ||||
| CONFIG_FIX_EARLYCON_MEM=y | ||||
| CONFIG_FREEZER=y | ||||
| CONFIG_FUTEX_PI=y | ||||
| CONFIG_GENERIC_ALLOCATOR=y | ||||
| CONFIG_GENERIC_BUG=y | ||||
| CONFIG_GENERIC_CLOCKEVENTS=y | ||||
| CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y | ||||
| CONFIG_GENERIC_CPU_AUTOPROBE=y | ||||
| CONFIG_GENERIC_EARLY_IOREMAP=y | ||||
| CONFIG_GENERIC_IDLE_POLL_SETUP=y | ||||
| CONFIG_GENERIC_IO=y | ||||
| CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y | ||||
| CONFIG_GENERIC_IRQ_SHOW=y | ||||
| CONFIG_GENERIC_IRQ_SHOW_LEVEL=y | ||||
| CONFIG_GENERIC_MSI_IRQ=y | ||||
| CONFIG_GENERIC_MSI_IRQ_DOMAIN=y | ||||
| CONFIG_GENERIC_PCI_IOMAP=y | ||||
| CONFIG_GENERIC_PHY=y | ||||
| CONFIG_GENERIC_PINCONF=y | ||||
| CONFIG_GENERIC_PINCTRL_GROUPS=y | ||||
| CONFIG_GENERIC_PINMUX_FUNCTIONS=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_SYSFS=y | ||||
| # CONFIG_GRO_CELLS is not set | ||||
| 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_ARM_SMCCC=y | ||||
| # CONFIG_HAVE_BOOTMEM_INFO_NODE is not set | ||||
| 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_CONTIGUOUS=y | ||||
| CONFIG_HAVE_DYNAMIC_FTRACE=y | ||||
| CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y | ||||
| CONFIG_HAVE_EBPF_JIT=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_HW_RANDOM_MTK=y | ||||
| CONFIG_HZ_FIXED=0 | ||||
| CONFIG_I2C=y | ||||
| CONFIG_I2C_BOARDINFO=y | ||||
| CONFIG_I2C_CHARDEV=y | ||||
| CONFIG_I2C_MT65XX=y | ||||
| CONFIG_ICPLUS_PHY=y | ||||
| CONFIG_IIO=y | ||||
| # CONFIG_IIO_BUFFER is not set | ||||
| # CONFIG_IIO_TRIGGER is not set | ||||
| CONFIG_INITRAMFS_COMPRESSION="" | ||||
| # CONFIG_INITRAMFS_FORCE is not set | ||||
| 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_ARMV7S is not set | ||||
| # 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_LEDS_MT6323=y | ||||
| CONFIG_LIBFDT=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_BUS=y | ||||
| CONFIG_MDIO_DEVICE=y | ||||
| CONFIG_MDIO_GPIO=y | ||||
| CONFIG_MEDIATEK_MT6577_AUXADC=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_EFUSE=y | ||||
| CONFIG_MTK_INFRACFG=y | ||||
| # CONFIG_MTK_IOMMU is not set | ||||
| # CONFIG_MTK_IOMMU_V1 is not set | ||||
| CONFIG_MTK_PMIC_WRAP=y | ||||
| CONFIG_MTK_SCPSYS=y | ||||
| CONFIG_MTK_THERMAL=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_DSA=y | ||||
| CONFIG_NET_DSA_MT7530=y | ||||
| # CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set | ||||
| CONFIG_NET_DSA_TAG_MTK=y | ||||
| CONFIG_NET_FLOW_LIMIT=y | ||||
| CONFIG_NET_MEDIATEK_SOC=y | ||||
| CONFIG_NET_SWITCHDEV=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_NVMEM=y | ||||
| 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_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_PADATA=y | ||||
| CONFIG_PAGE_OFFSET=0xC0000000 | ||||
| CONFIG_PCI=y | ||||
| CONFIG_PCIEAER=y | ||||
| CONFIG_PCIEPORTBUS=y | ||||
| CONFIG_PCIE_MEDIATEK=y | ||||
| CONFIG_PCIE_PME=y | ||||
| CONFIG_PCI_DOMAINS=y | ||||
| CONFIG_PCI_DOMAINS_GENERIC=y | ||||
| CONFIG_PCI_MSI=y | ||||
| CONFIG_PCI_MSI_IRQ_DOMAIN=y | ||||
| CONFIG_PERF_USE_VMALLOC=y | ||||
| CONFIG_PGTABLE_LEVELS=2 | ||||
| CONFIG_PHYLIB=y | ||||
| CONFIG_PHY_MTK_TPHY=y | ||||
| CONFIG_PINCTRL=y | ||||
| CONFIG_PINCTRL_MT2701=y | ||||
| CONFIG_PINCTRL_MT6397=y | ||||
| CONFIG_PINCTRL_MT8127=y | ||||
| CONFIG_PINCTRL_MTK=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_RAS=y | ||||
| CONFIG_RATIONAL=y | ||||
| CONFIG_RCU_CPU_STALL_TIMEOUT=21 | ||||
| # CONFIG_RCU_EXPERT is not set | ||||
| CONFIG_RCU_NEED_SEGCBLIST=y | ||||
| CONFIG_RCU_STALL_COMMON=y | ||||
| CONFIG_REGMAP=y | ||||
| CONFIG_REGMAP_I2C=y | ||||
| CONFIG_REGMAP_MMIO=y | ||||
| CONFIG_REGMAP_SPI=y | ||||
| CONFIG_REGULATOR=y | ||||
| CONFIG_REGULATOR_FIXED_VOLTAGE=y | ||||
| CONFIG_REGULATOR_GPIO=y | ||||
| CONFIG_REGULATOR_MT6323=y | ||||
| # CONFIG_REGULATOR_MT6380 is not set | ||||
| # 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_RTC_I2C_AND_SPI=y | ||||
| CONFIG_RWSEM_SPIN_ON_OWNER=y | ||||
| CONFIG_RWSEM_XCHGADD_ALGORITHM=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_SWPHY=y | ||||
| CONFIG_SWP_EMULATE=y | ||||
| CONFIG_SYS_SUPPORTS_APM_EMULATION=y | ||||
| CONFIG_TASKS_RCU=y | ||||
| CONFIG_THERMAL=y | ||||
| CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y | ||||
| CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 | ||||
| CONFIG_THERMAL_GOV_STEP_WISE=y | ||||
| CONFIG_THERMAL_OF=y | ||||
| CONFIG_THIN_ARCHIVES=y | ||||
| # CONFIG_THUMB2_KERNEL is not set | ||||
| CONFIG_TICK_CPU_ACCOUNTING=y | ||||
| CONFIG_TIMER_OF=y | ||||
| CONFIG_TIMER_PROBE=y | ||||
| CONFIG_TREE_SRCU=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_XHCI_HCD=y | ||||
| CONFIG_USB_XHCI_MTK=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 | ||||
| @@ -1,804 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (c) 2016 MediaTek Inc. | ||||
|  * Author: John Crispin <blogic@openwrt.org> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  */ | ||||
|  | ||||
| #include <dt-bindings/interrupt-controller/irq.h> | ||||
| #include <dt-bindings/interrupt-controller/arm-gic.h> | ||||
| #include <dt-bindings/clock/mt2701-clk.h> | ||||
| #include <dt-bindings/power/mt2701-power.h> | ||||
| #include <dt-bindings/phy/phy.h> | ||||
| #include <dt-bindings/reset/mt2701-resets.h> | ||||
| #include <dt-bindings/pinctrl/mt7623-pinfunc.h> | ||||
| #include <dt-bindings/gpio/gpio.h> | ||||
| #include "skeleton64.dtsi" | ||||
|  | ||||
|  | ||||
| / { | ||||
| 	compatible = "mediatek,mt7623"; | ||||
| 	interrupt-parent = <&sysirq>; | ||||
|  | ||||
| 	cpus { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 		enable-method = "mediatek,mt6589-smp"; | ||||
|  | ||||
| 		cpu0: cpu@0 { | ||||
| 			device_type = "cpu"; | ||||
| 			compatible = "arm,cortex-a7"; | ||||
| 			reg = <0x0>; | ||||
| 			clocks = <&infracfg CLK_INFRA_CPUSEL>, | ||||
| 				 <&apmixedsys CLK_APMIXED_MAINPLL>; | ||||
| 			clock-names = "cpu", "intermediate"; | ||||
| 			operating-points = < | ||||
| 				598000 1150000 | ||||
| 				747500 1150000 | ||||
| 				1040000 1150000 | ||||
| 				1196000 1200000 | ||||
| 				1300000 1300000 | ||||
| 			>; | ||||
| 		}; | ||||
| 		cpu1: cpu@1 { | ||||
| 			device_type = "cpu"; | ||||
| 			compatible = "arm,cortex-a7"; | ||||
| 			reg = <0x1>; | ||||
| 			clocks = <&infracfg CLK_INFRA_CPUSEL>, | ||||
| 				 <&apmixedsys CLK_APMIXED_MAINPLL>; | ||||
| 			clock-names = "cpu", "intermediate"; | ||||
| 			operating-points = < | ||||
| 				598000 1150000 | ||||
| 				747500 1150000 | ||||
| 				1040000 1150000 | ||||
| 				1196000 1200000 | ||||
| 				1300000 1300000 | ||||
| 			>; | ||||
| 		}; | ||||
| 		cpu2: cpu@2 { | ||||
| 			device_type = "cpu"; | ||||
| 			compatible = "arm,cortex-a7"; | ||||
| 			reg = <0x2>; | ||||
| 			clocks = <&infracfg CLK_INFRA_CPUSEL>, | ||||
| 				 <&apmixedsys CLK_APMIXED_MAINPLL>; | ||||
| 			clock-names = "cpu", "intermediate"; | ||||
| 			operating-points = < | ||||
| 				598000 1150000 | ||||
| 				747500 1150000 | ||||
| 				1040000 1150000 | ||||
| 				1196000 1200000 | ||||
| 				1300000 1300000 | ||||
| 			>; | ||||
| 		}; | ||||
| 		cpu3: cpu@3 { | ||||
| 			device_type = "cpu"; | ||||
| 			compatible = "arm,cortex-a7"; | ||||
| 			reg = <0x3>; | ||||
| 			clocks = <&infracfg CLK_INFRA_CPUSEL>, | ||||
| 				 <&apmixedsys CLK_APMIXED_MAINPLL>; | ||||
| 			clock-names = "cpu", "intermediate"; | ||||
| 			operating-points = < | ||||
| 				598000 1150000 | ||||
| 				747500 1150000 | ||||
| 				1040000 1150000 | ||||
| 				1196000 1200000 | ||||
| 				1300000 1300000 | ||||
| 			>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	system_clk: dummy13m { | ||||
| 		compatible = "fixed-clock"; | ||||
| 		clock-frequency = <13000000>; | ||||
| 		#clock-cells = <0>; | ||||
| 	}; | ||||
|  | ||||
| 	rtc_clk: dummy32k { | ||||
| 		compatible = "fixed-clock"; | ||||
| 		clock-frequency = <32000>; | ||||
| 		#clock-cells = <0>; | ||||
| 		clock-output-names = "clk32k"; | ||||
| 	}; | ||||
|  | ||||
| 	clk26m: dummy26m { | ||||
| 		compatible = "fixed-clock"; | ||||
| 		clock-frequency = <26000000>; | ||||
| 		#clock-cells = <0>; | ||||
| 		clock-output-names = "clk26m"; | ||||
| 	}; | ||||
|  | ||||
| 	timer { | ||||
| 		compatible = "arm,armv7-timer"; | ||||
| 		interrupt-parent = <&gic>; | ||||
| 		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, | ||||
| 			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, | ||||
| 			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, | ||||
| 			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; | ||||
| 		clock-frequency = <13000000>; | ||||
| 		arm,cpu-registers-not-fw-configured; | ||||
| 	}; | ||||
|  | ||||
| 	topckgen: power-controller@10000000 { | ||||
| 		compatible = "mediatek,mt7623-topckgen", | ||||
| 			     "mediatek,mt2701-topckgen", | ||||
| 			     "syscon"; | ||||
| 		reg = <0 0x10000000 0 0x1000>; | ||||
| 		#clock-cells = <1>; | ||||
| 	}; | ||||
|  | ||||
| 	infracfg: power-controller@10001000 { | ||||
| 		compatible = "mediatek,mt7623-infracfg", | ||||
| 			     "mediatek,mt2701-infracfg", | ||||
| 			     "syscon"; | ||||
| 		reg = <0 0x10001000 0 0x1000>; | ||||
| 		#clock-cells = <1>; | ||||
| 		#reset-cells = <1>; | ||||
| 	}; | ||||
|  | ||||
| 	pericfg: pericfg@10003000 { | ||||
| 		compatible = "mediatek,mt7623-pericfg", | ||||
| 			     "mediatek,mt2701-pericfg", | ||||
| 			     "syscon"; | ||||
| 		reg = <0 0x10003000 0 0x1000>; | ||||
| 		#clock-cells = <1>; | ||||
| 		#reset-cells = <1>; | ||||
| 	}; | ||||
|  | ||||
| 	pio: pinctrl@10005000 { | ||||
| 		compatible = "mediatek,mt7623-pinctrl"; | ||||
| 		reg = <0 0x1000b000 0 0x1000>; | ||||
| 		mediatek,pctl-regmap = <&syscfg_pctl_a>; | ||||
| 		pins-are-numbered; | ||||
| 		gpio-controller; | ||||
| 		#gpio-cells = <2>; | ||||
| 		interrupt-controller; | ||||
| 		interrupt-parent = <&gic>; | ||||
| 		#interrupt-cells = <2>; | ||||
| 		interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>, | ||||
| 			     <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; | ||||
| 	}; | ||||
|  | ||||
| 	syscfg_pctl_a: syscfg@10005000 { | ||||
| 		compatible = "mediatek,mt7623-pctl-a-syscfg", | ||||
| 			     "mediatek,mt2701-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>, | ||||
| 			 <&topckgen CLK_TOP_ETHIF_SEL>; | ||||
| 		clock-names = "mfg", "mm", "ethif"; | ||||
| 	}; | ||||
|  | ||||
| 	watchdog: watchdog@10007000 { | ||||
| 		compatible = "mediatek,mt7623-wdt", | ||||
| 			     "mediatek,mt6589-wdt"; | ||||
| 		reg = <0 0x10007000 0 0x100>; | ||||
| 	}; | ||||
|  | ||||
| 	timer: timer@10008000 { | ||||
| 		compatible = "mediatek,mt7623-timer", | ||||
| 			     "mediatek,mt6577-timer"; | ||||
| 		reg = <0 0x10008000 0 0x80>; | ||||
| 		interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&system_clk>, <&rtc_clk>; | ||||
| 		clock-names = "system-clk", "rtc-clk"; | ||||
| 	}; | ||||
|  | ||||
| 	pwrap: pwrap@1000d000 { | ||||
| 		compatible = "mediatek,mt7623-pwrap", | ||||
| 			     "mediatek,mt2701-pwrap"; | ||||
| 		reg = <0 0x1000d000 0 0x1000>; | ||||
| 		reg-names = "pwrap"; | ||||
| 		interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>; | ||||
| 		resets = <&infracfg MT2701_INFRA_PMIC_WRAP_RST>; | ||||
| 		reset-names = "pwrap"; | ||||
| 		clocks = <&infracfg CLK_INFRA_PMICSPI>, | ||||
| 			 <&infracfg CLK_INFRA_PMICWRAP>; | ||||
| 		clock-names = "spi", "wrap"; | ||||
| 	}; | ||||
|  | ||||
| 	cir: cir@10013000 { | ||||
| 		compatible = "mediatek,mt7623-cir"; | ||||
| 		reg = <0 0x10013000 0 0x1000>; | ||||
| 		interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&infracfg CLK_INFRA_IRRX>; | ||||
| 		clock-names = "clk"; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	sysirq: interrupt-controller@10200100 { | ||||
| 		compatible = "mediatek,mt7623-sysirq", | ||||
| 			     "mediatek,mt6577-sysirq"; | ||||
| 		interrupt-controller; | ||||
| 		#interrupt-cells = <3>; | ||||
| 		interrupt-parent = <&gic>; | ||||
| 		reg = <0 0x10200100 0 0x1c>; | ||||
| 	}; | ||||
|  | ||||
| 	efuse: efuse@10206000 { | ||||
| 		compatible = "mediatek,mt7623-efuse", | ||||
| 			     "mediatek,efuse"; | ||||
| 		reg	   = <0 0x10206000 0 0x1000>; | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <1>; | ||||
|  | ||||
| 		/* Data cells */ | ||||
| 		thermal_calibration: calib@424 { | ||||
| 			reg = <0x424 0xc>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	apmixedsys: apmixedsys@10209000 { | ||||
| 		compatible = "mediatek,mt7623-apmixedsys", | ||||
| 			     "mediatek,mt2701-apmixedsys"; | ||||
| 		reg = <0 0x10209000 0 0x1000>; | ||||
| 		#clock-cells = <1>; | ||||
| 	}; | ||||
|  | ||||
| 	rng: rng@1020f000 { | ||||
| 		compatible = "mediatek,mt7623-rng"; | ||||
| 		reg = <0 0x1020f000 0 0x1000>; | ||||
| 		clocks = <&infracfg CLK_INFRA_TRNG>; | ||||
| 		clock-names = "rng"; | ||||
| 	}; | ||||
|  | ||||
| 	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>; | ||||
| 	}; | ||||
|  | ||||
| 	auxadc: adc@11001000 { | ||||
| 		compatible = "mediatek,mt7623-auxadc", | ||||
| 			     "mediatek,mt2701-auxadc"; | ||||
| 		reg = <0 0x11001000 0 0x1000>; | ||||
| 		clocks = <&pericfg CLK_PERI_AUXADC>; | ||||
| 		clock-names = "main"; | ||||
| 		#io-channel-cells = <1>; | ||||
| 	}; | ||||
|  | ||||
| 	uart0: serial@11002000 { | ||||
| 		compatible = "mediatek,mt7623-uart", | ||||
| 			     "mediatek,mt6577-uart"; | ||||
| 		reg = <0 0x11002000 0 0x400>; | ||||
| 		interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&pericfg CLK_PERI_UART0_SEL>, | ||||
| 			 <&pericfg CLK_PERI_UART0>; | ||||
| 		clock-names = "baud", "bus"; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	uart1: serial@11003000 { | ||||
| 		compatible = "mediatek,mt7623-uart", | ||||
| 			     "mediatek,mt6577-uart"; | ||||
| 		reg = <0 0x11003000 0 0x400>; | ||||
| 		interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&pericfg CLK_PERI_UART1_SEL>, | ||||
| 			 <&pericfg CLK_PERI_UART1>; | ||||
| 		clock-names = "baud", "bus"; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	uart2: serial@11004000 { | ||||
| 		compatible = "mediatek,mt7623-uart", | ||||
| 			     "mediatek,mt6577-uart"; | ||||
| 		reg = <0 0x11004000 0 0x400>; | ||||
| 		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&pericfg CLK_PERI_UART2_SEL>, | ||||
| 			 <&pericfg CLK_PERI_UART2>; | ||||
| 		clock-names = "baud", "bus"; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	uart3: serial@11005000 { | ||||
| 		compatible = "mediatek,mt7623-uart", | ||||
| 			     "mediatek,mt6577-uart"; | ||||
| 		reg = <0 0x11005000 0 0x400>; | ||||
| 		interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&pericfg CLK_PERI_UART3_SEL>, | ||||
| 			 <&pericfg CLK_PERI_UART3>; | ||||
| 		clock-names = "baud", "bus"; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	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"; | ||||
| 	}; | ||||
|  | ||||
| 	i2c0: i2c@11007000 { | ||||
| 		compatible = "mediatek,mt7623-i2c", | ||||
| 			     "mediatek,mt6577-i2c"; | ||||
| 		reg = <0 0x11007000 0 0x70>, | ||||
| 		      <0 0x11000200 0 0x80>; | ||||
| 		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clock-div = <16>; | ||||
| 		clocks = <&pericfg CLK_PERI_I2C0>, | ||||
| 			 <&pericfg CLK_PERI_AP_DMA>; | ||||
| 		clock-names = "main", "dma"; | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	i2c1: i2c@11008000 { | ||||
| 		compatible = "mediatek,mt7623-i2c", | ||||
| 			     "mediatek,mt6577-i2c"; | ||||
| 		reg = <0 0x11008000 0 0x70>, | ||||
| 		      <0 0x11000280 0 0x80>; | ||||
| 		interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clock-div = <16>; | ||||
| 		clocks = <&pericfg CLK_PERI_I2C1>, | ||||
| 			 <&pericfg CLK_PERI_AP_DMA>; | ||||
| 		clock-names = "main", "dma"; | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	i2c2: i2c@11009000 { | ||||
| 		compatible = "mediatek,mt7623-i2c", | ||||
| 			     "mediatek,mt6577-i2c"; | ||||
| 		reg = <0 0x11009000 0 0x70>, | ||||
| 		      <0 0x11000300 0 0x80>; | ||||
| 		interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clock-div = <16>; | ||||
| 		clocks = <&pericfg CLK_PERI_I2C2>, | ||||
| 			 <&pericfg CLK_PERI_AP_DMA>; | ||||
| 		clock-names = "main", "dma"; | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	spi0: spi@1100a000 { | ||||
| 		compatible = "mediatek,mt7623-spi", | ||||
| 			     "mediatek,mt6589-spi"; | ||||
| 		reg = <0 0x1100a000 0 0x1000>; | ||||
| 		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&pericfg CLK_PERI_SPI0>; | ||||
| 		clock-names = "main"; | ||||
|  | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	thermal: thermal@1100b000 { | ||||
| 		#thermal-sensor-cells = <1>; | ||||
| 		compatible = "mediatek,mt2701-thermal", | ||||
| 			     "mediatek,mt2701-thermal"; | ||||
| 		reg = <0 0x1100b000 0 0x1000>; | ||||
| 		interrupts = <0 70 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&pericfg CLK_PERI_THERM>, | ||||
| 			 <&pericfg CLK_PERI_AUXADC>; | ||||
| 		clock-names = "therm", "auxadc"; | ||||
| 		resets = <&pericfg MT2701_PERI_THERM_SW_RST>; | ||||
| 		reset-names = "therm"; | ||||
| 		mediatek,auxadc = <&auxadc>; | ||||
| 		mediatek,apmixedsys = <&apmixedsys>; | ||||
|  | ||||
| 		nvmem-cells = <&thermal_calibration>; | ||||
| 		nvmem-cell-names = "calibration-data"; | ||||
| 	}; | ||||
|  | ||||
| 	spi1: spi@11016000 { | ||||
| 		compatible = "mediatek,mt7623-spi", | ||||
| 			     "mediatek,mt2701-spi"; | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 		reg = <0 0x11016000 0 0x100>; | ||||
| 		interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&topckgen CLK_TOP_SYSPLL3_D2>, | ||||
| 			 <&topckgen CLK_TOP_SPI1_SEL>, | ||||
| 			 <&pericfg CLK_PERI_SPI1>; | ||||
| 		clock-names = "parent-clk", "sel-clk", "spi-clk"; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	spi2: spi@11017000 { | ||||
| 		compatible = "mediatek,mt7623-spi", | ||||
| 			"mediatek,mt2701-spi"; | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 		reg = <0 0x11017000 0 0x1000>; | ||||
| 		interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&topckgen CLK_TOP_SYSPLL3_D2>, | ||||
| 			 <&topckgen CLK_TOP_SPI2_SEL>, | ||||
| 			 <&pericfg CLK_PERI_SPI2>; | ||||
| 		clock-names = "parent-clk", "sel-clk", "spi-clk"; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	nandc: nfi@1100d000 { | ||||
| 		compatible = "mediatek,mt7623-nfc", | ||||
| 			     "mediatek,mt2701-nfc"; | ||||
| 		reg = <0 0x1100d000 0 0x1000>; | ||||
| 		power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; | ||||
| 		interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&pericfg CLK_PERI_NFI>, | ||||
| 			 <&pericfg CLK_PERI_NFI_PAD>; | ||||
| 		clock-names = "nfi_clk", "pad_clk"; | ||||
| 		status = "disabled"; | ||||
| 		ecc-engine = <&bch>; | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 	}; | ||||
|  | ||||
| 	bch: ecc@1100e000 { | ||||
| 		compatible = "mediatek,mt7623-ecc", | ||||
| 			     "mediatek,mt2701-ecc"; | ||||
| 		reg = <0 0x1100e000 0 0x1000>; | ||||
| 		interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&pericfg CLK_PERI_NFI_ECC>; | ||||
| 		clock-names = "nfiecc_clk"; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	afe: audio-controller@11220000 { | ||||
| 	compatible = "mediatek,mt7623-audio", | ||||
| 		     "mediatek,mt2701-audio"; | ||||
| 	reg = <0 0x11220000 0 0x2000>, | ||||
| 	      <0 0x112a0000 0 0x20000>; | ||||
| 	interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>; | ||||
| 	power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; | ||||
| 	 | ||||
| 	clocks = <&infracfg CLK_INFRA_AUDIO>, | ||||
| 		 <&topckgen CLK_TOP_AUD_MUX1_SEL>, | ||||
| 		 <&topckgen CLK_TOP_AUD_MUX2_SEL>, | ||||
| 		 <&topckgen CLK_TOP_AUD_MUX1_DIV>, | ||||
| 		 <&topckgen CLK_TOP_AUD_MUX2_DIV>, | ||||
| 		 <&topckgen CLK_TOP_AUD_48K_TIMING>, | ||||
| 		 <&topckgen CLK_TOP_AUD_44K_TIMING>, | ||||
| 		 <&topckgen CLK_TOP_AUDPLL_MUX_SEL>, | ||||
| 		 <&topckgen CLK_TOP_APLL_SEL>, | ||||
| 		 <&topckgen CLK_TOP_AUD1PLL_98M>, | ||||
| 		 <&topckgen CLK_TOP_AUD2PLL_90M>, | ||||
| 		 <&topckgen CLK_TOP_HADDS2PLL_98M>, | ||||
| 		 <&topckgen CLK_TOP_HADDS2PLL_294M>, | ||||
| 		 <&topckgen CLK_TOP_AUDPLL>, | ||||
| 		 <&topckgen CLK_TOP_AUDPLL_D4>, | ||||
| 		 <&topckgen CLK_TOP_AUDPLL_D8>, | ||||
| 		 <&topckgen CLK_TOP_AUDPLL_D16>, | ||||
| 		 <&topckgen CLK_TOP_AUDPLL_D24>, | ||||
| 		 <&topckgen CLK_TOP_AUDINTBUS_SEL>, | ||||
| 		 <&clk26m>, | ||||
| 		 <&topckgen CLK_TOP_SYSPLL1_D4>, | ||||
| 		 <&topckgen CLK_TOP_AUD_K1_SRC_SEL>, | ||||
| 		 <&topckgen CLK_TOP_AUD_K2_SRC_SEL>, | ||||
| 		 <&topckgen CLK_TOP_AUD_K3_SRC_SEL>, | ||||
| 		 <&topckgen CLK_TOP_AUD_K4_SRC_SEL>, | ||||
| 		 <&topckgen CLK_TOP_AUD_K5_SRC_SEL>, | ||||
| 		 <&topckgen CLK_TOP_AUD_K6_SRC_SEL>, | ||||
| 		 <&topckgen CLK_TOP_AUD_K1_SRC_DIV>, | ||||
| 		 <&topckgen CLK_TOP_AUD_K2_SRC_DIV>, | ||||
| 		 <&topckgen CLK_TOP_AUD_K3_SRC_DIV>, | ||||
| 		 <&topckgen CLK_TOP_AUD_K4_SRC_DIV>, | ||||
| 		 <&topckgen CLK_TOP_AUD_K5_SRC_DIV>, | ||||
| 		 <&topckgen CLK_TOP_AUD_K6_SRC_DIV>, | ||||
| 		 <&topckgen CLK_TOP_AUD_I2S1_MCLK>, | ||||
| 		 <&topckgen CLK_TOP_AUD_I2S2_MCLK>, | ||||
| 		 <&topckgen CLK_TOP_AUD_I2S3_MCLK>, | ||||
| 		 <&topckgen CLK_TOP_AUD_I2S4_MCLK>, | ||||
| 		 <&topckgen CLK_TOP_AUD_I2S5_MCLK>, | ||||
| 		 <&topckgen CLK_TOP_AUD_I2S6_MCLK>, | ||||
| 		 <&topckgen CLK_TOP_ASM_M_SEL>, | ||||
| 		 <&topckgen CLK_TOP_ASM_H_SEL>, | ||||
| 		 <&topckgen CLK_TOP_UNIVPLL2_D4>, | ||||
| 		 <&topckgen CLK_TOP_UNIVPLL2_D2>, | ||||
| 		 <&topckgen CLK_TOP_SYSPLL_D5>; | ||||
| 	clock-names = "infra_sys_audio_clk", | ||||
| 		"top_audio_mux1_sel", | ||||
| 		"top_audio_mux2_sel", | ||||
| 		"top_audio_mux1_div", | ||||
| 		"top_audio_mux2_div", | ||||
| 		"top_audio_48k_timing", | ||||
| 		"top_audio_44k_timing", | ||||
| 		"top_audpll_mux_sel", | ||||
| 		"top_apll_sel", | ||||
| 		"top_aud1_pll_98M", | ||||
| 		"top_aud2_pll_90M", | ||||
| 		"top_hadds2_pll_98M", | ||||
| 		"top_hadds2_pll_294M", | ||||
| 		"top_audpll", | ||||
| 		"top_audpll_d4", | ||||
| 		"top_audpll_d8", | ||||
| 		"top_audpll_d16", | ||||
| 		"top_audpll_d24", | ||||
| 		"top_audintbus_sel", | ||||
| 		"clk_26m", | ||||
| 		"top_syspll1_d4", | ||||
| 		"top_aud_k1_src_sel", | ||||
| 		"top_aud_k2_src_sel", | ||||
| 		"top_aud_k3_src_sel", | ||||
| 		"top_aud_k4_src_sel", | ||||
| 		"top_aud_k5_src_sel", | ||||
| 		"top_aud_k6_src_sel", | ||||
| 		"top_aud_k1_src_div", | ||||
| 		"top_aud_k2_src_div", | ||||
| 		"top_aud_k3_src_div", | ||||
| 		"top_aud_k4_src_div", | ||||
| 		"top_aud_k5_src_div", | ||||
| 		"top_aud_k6_src_div", | ||||
| 		"top_aud_i2s1_mclk", | ||||
| 		"top_aud_i2s2_mclk", | ||||
| 		"top_aud_i2s3_mclk", | ||||
| 		"top_aud_i2s4_mclk", | ||||
| 		"top_aud_i2s5_mclk", | ||||
| 		"top_aud_i2s6_mclk", | ||||
| 		"top_asm_m_sel", | ||||
| 		"top_asm_h_sel", | ||||
| 		"top_univpll2_d4", | ||||
| 		"top_univpll2_d2", | ||||
| 		"top_syspll_d5"; | ||||
| 	}; | ||||
|  | ||||
| 	mmc0: mmc@11230000 { | ||||
| 		compatible = "mediatek,mt7623-mmc", | ||||
| 			     "mediatek,mt8135-mmc"; | ||||
| 		reg = <0 0x11230000 0 0x1000>; | ||||
| 		interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&pericfg CLK_PERI_MSDC30_0>, | ||||
| 			 <&topckgen CLK_TOP_MSDC30_0_SEL>; | ||||
| 		clock-names = "source", "hclk"; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	mmc1: mmc@11240000 { | ||||
| 		compatible = "mediatek,mt7623-mmc", | ||||
| 			     "mediatek,mt8135-mmc"; | ||||
| 		reg = <0 0x11240000 0 0x1000>; | ||||
| 		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&pericfg CLK_PERI_MSDC30_1>, | ||||
| 			 <&topckgen CLK_TOP_MSDC30_1_SEL>; | ||||
| 		clock-names = "source", "hclk"; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	usb1: usb@1a1c0000 { | ||||
| 		compatible = "mediatek,mt7623-xhci", | ||||
| 			     "mediatek,mt8173-xhci"; | ||||
| 		reg = <0 0x1a1c0000 0 0x1000>, | ||||
| 		      <0 0x1a1c4700 0 0x0100>; | ||||
| 		interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&hifsys CLK_HIFSYS_USB0PHY>, | ||||
| 			 <&topckgen CLK_TOP_ETHIF_SEL>; | ||||
| 		clock-names = "sys_ck", "ethif"; | ||||
| 		power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; | ||||
| 		phys = <&phy_port0 PHY_TYPE_USB3>; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	u3phy1: usb-phy@1a1c4000 { | ||||
| 		compatible = "mediatek,mt2701-u3phy", | ||||
| 			     "mediatek,mt8173-u3phy"; | ||||
| 		reg = <0 0x1a1c4000 0 0x0700>; | ||||
| 		clocks = <&clk26m>; | ||||
| 		clock-names = "u3phya_ref"; | ||||
| 		#phy-cells = <1>; | ||||
| 		#address-cells = <2>; | ||||
| 		#size-cells = <2>; | ||||
| 		ranges; | ||||
| 		status = "disabled"; | ||||
|  | ||||
| 		phy_port0: phy_port0: port@1a1c4800 { | ||||
| 			reg = <0 0x1a1c4800 0 0x800>; | ||||
| 			#phy-cells = <1>; | ||||
| 			status = "okay"; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	usb2: usb@1a240000 { | ||||
| 		compatible = "mediatek,mt2701-xhci", | ||||
| 			     "mediatek,mt8173-xhci"; | ||||
| 		reg = <0 0x1a240000 0 0x1000>, | ||||
| 		      <0 0x1a244700 0 0x0100>; | ||||
| 		interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&hifsys CLK_HIFSYS_USB1PHY>, | ||||
| 			 <&topckgen CLK_TOP_ETHIF_SEL>; | ||||
| 		clock-names = "sys_ck", "ethif"; | ||||
| 		power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; | ||||
| 		phys = <&u3phy2 0>; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	u3phy2: usb-phy@1a244000 { | ||||
| 		compatible = "mediatek,mt2701-u3phy", | ||||
| 			     "mediatek,mt8173-u3phy"; | ||||
| 		reg = <0 0x1a244000 0 0x0700>, | ||||
| 		      <0 0x1a244800 0 0x0800>; | ||||
| 		clocks = <&clk26m>; | ||||
| 		clock-names = "u3phya_ref"; | ||||
| 		#phy-cells = <1>; | ||||
| 		status = "disabled"; | ||||
| 	}; | ||||
|  | ||||
| 	hifsys: clock-controller@1a000000 { | ||||
| 		compatible = "mediatek,mt7623-hifsys", | ||||
| 			     "mediatek,mt2701-hifsys", | ||||
| 			     "syscon"; | ||||
| 		reg = <0 0x1a000000 0 0x1000>; | ||||
| 		#clock-cells = <1>; | ||||
| 		#reset-cells = <1>; | ||||
| 	}; | ||||
|  | ||||
| 	pcie: pcie@1a140000 { | ||||
| 		compatible = "mediatek,mt7623-pcie"; | ||||
| 		device_type = "pci"; | ||||
| 		reg = <0 0x1a140000 0 0x8000>, /* PCI-Express registers */ | ||||
| 		      <0 0x1a149000 0 0x1000>, /* PCI-Express PHY0 */ | ||||
| 		      <0 0x1a14a000 0 0x1000>, /* PCI-Express PHY1 */ | ||||
| 		      <0 0x1a244000 0 0x1000>; /* PCI-Express PHY2 */ | ||||
| 		reg-names = "pcie", "pcie phy0", "pcie phy1", "pcie phy2"; | ||||
| 		interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>, | ||||
| 			     <GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>, | ||||
| 			     <GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		interrupt-names = "pcie0", "pcie1", "pcie2"; | ||||
| 		clocks = <&topckgen CLK_TOP_ETHIF_SEL>; | ||||
| 		clock-names = "pcie"; | ||||
| 		power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; | ||||
| 		resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>, | ||||
| 			 <&hifsys MT2701_HIFSYS_PCIE1_RST>, | ||||
| 			 <&hifsys MT2701_HIFSYS_PCIE2_RST>; | ||||
| 		reset-names = "pcie0", "pcie1", "pcie2"; | ||||
|  | ||||
| 		mediatek,hifsys = <&hifsys>; | ||||
|  | ||||
| 		bus-range = <0x00 0xff>; | ||||
| 		#address-cells = <3>; | ||||
| 		#size-cells = <2>; | ||||
|  | ||||
| 		ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000 /* io space */ | ||||
| 			  0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* pci memory */ | ||||
|  | ||||
| 		status = "disabled"; | ||||
|  | ||||
| 		pcie@1,0 { | ||||
| 			device_type = "pci"; | ||||
| 			reg = <0x0800 0 0 0 0>; | ||||
|  | ||||
| 			#address-cells = <3>; | ||||
| 			#size-cells = <2>; | ||||
| 			ranges; | ||||
| 		}; | ||||
|  | ||||
| 		pcie@2,0{ | ||||
| 			device_type = "pci"; | ||||
| 			reg = <0x1000 0 0 0 0>; | ||||
|  | ||||
| 			#address-cells = <3>; | ||||
| 			#size-cells = <2>; | ||||
| 			ranges; | ||||
| 		}; | ||||
|  | ||||
| 		pcie@3,0{ | ||||
| 			device_type = "pci"; | ||||
| 			reg = <0x1800 0 0 0 0>; | ||||
|  | ||||
| 			#address-cells = <3>; | ||||
| 			#size-cells = <2>; | ||||
| 			ranges; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	ethsys: syscon@1b000000 { | ||||
| 		compatible = "mediatek,mt7623-ethsys", | ||||
| 			     "mediatek,mt2701-ethsys", | ||||
| 			     "syscon"; | ||||
| 		reg = <0 0x1b000000 0 0x1000>; | ||||
| 		#reset-cells = <1>; | ||||
| 		#clock-cells = <1>; | ||||
| 	}; | ||||
|  | ||||
| 	eth: ethernet@1b100000 { | ||||
| 		compatible = "mediatek,mt7623-eth", | ||||
| 			     "mediatek,mt2701-eth", | ||||
| 			     "syscon"; | ||||
| 		reg = <0 0x1b100000 0 0x20000>; | ||||
|  | ||||
| 		clocks = <&topckgen CLK_TOP_ETHIF_SEL>, | ||||
| 			 <ðsys CLK_ETHSYS_ESW>, | ||||
| 			 <ðsys CLK_ETHSYS_GP2>, | ||||
| 			 <ðsys CLK_ETHSYS_GP1>, | ||||
| 			 <&apmixedsys CLK_APMIXED_TRGPLL>; | ||||
| 		clock-names = "ethif", "esw", "gp2", "gp1", "trgpll"; | ||||
| 		interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_LOW | ||||
| 			      GIC_SPI 199 IRQ_TYPE_LEVEL_LOW | ||||
| 			      GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; | ||||
|  | ||||
| 		resets = <ðsys 6>; | ||||
| 		reset-names = "eth"; | ||||
|  | ||||
| 		mediatek,ethsys = <ðsys>; | ||||
| 		mediatek,pctl = <&syscfg_pctl_a>; | ||||
|  | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
|  | ||||
| 		status = "disabled"; | ||||
|  | ||||
| 		gmac1: mac@0 { | ||||
| 			compatible = "mediatek,eth-mac"; | ||||
| 			reg = <0>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
|  | ||||
| 			phy-mode = "trgmii"; | ||||
|  | ||||
| 			fixed-link { | ||||
| 				speed = <1000>; | ||||
| 				full-duplex; | ||||
| 				pause; | ||||
| 			}; | ||||
| 		}; | ||||
|  | ||||
| 		gmac2: mac@1 { | ||||
| 			compatible = "mediatek,eth-mac"; | ||||
| 			reg = <1>; | ||||
|  | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
|  | ||||
| 		mdio0: mdio-bus { | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	hnat: hnat@1b000000 { | ||||
| 		compatible = "mediatek,mt7623-hnat"; | ||||
| 		reg = <0 0x1b100000 0 0x3000>; | ||||
| 		mtketh-wan = "eth1"; | ||||
| 		resets = <ðsys 0>; | ||||
| 		reset-names = "mtketh"; | ||||
| 	}; | ||||
|  | ||||
| 	crypto: crypto@1b240000 { | ||||
| 		compatible = "mediatek,mt7623-crypto", "mediatek,eip97-crypto"; | ||||
| 		reg = <0 0x1b240000 0 0x20000>; | ||||
| 		interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_LOW>, | ||||
| 			     <GIC_SPI 83 IRQ_TYPE_LEVEL_LOW>, | ||||
| 			     <GIC_SPI 84 IRQ_TYPE_LEVEL_LOW>, | ||||
| 			     <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>, | ||||
| 			     <GIC_SPI 97 IRQ_TYPE_LEVEL_LOW>; | ||||
| 		clocks = <&topckgen CLK_TOP_ETHIF_SEL>, | ||||
| 			 <ðsys CLK_ETHSYS_CRYPTO>; | ||||
| 		clock-names = "ethif","cryp"; | ||||
| 		power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; | ||||
| 	}; | ||||
| }; | ||||
| @@ -1,241 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (c) 2017 MediaTek Inc. | ||||
|  * Author: John Crispin <john@phrozen.org> | ||||
|  *	   Sean Wang <sean.wang@mediatek.com> | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  */ | ||||
|  | ||||
| &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>; | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
| @@ -1,523 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (c) 2016 MediaTek Inc. | ||||
|  * Author: John Crispin <blogic@openwrt.org> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  */ | ||||
|  | ||||
| /dts-v1/; | ||||
|  | ||||
| #include "_mt7623.dtsi" | ||||
| #include <dt-bindings/gpio/gpio.h> | ||||
|  | ||||
| / { | ||||
| 	model = "MediaTek MT7623 NAND reference board"; | ||||
| 	compatible = "mediatek,mt7623-rfb-nand-ephy", "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>; | ||||
| 			}; | ||||
| 		}; | ||||
|  | ||||
| 		mt6323led: leds { | ||||
| 			compatible = "mediatek,mt6323-led"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
|  | ||||
| 			led@0 { | ||||
| 				reg = <0>; | ||||
| 				label = "LED0"; | ||||
| 				linux,default-trigger = "timer"; | ||||
| 				default-state = "on"; | ||||
| 			}; | ||||
| 			led@1 { | ||||
| 				reg = <1>; | ||||
| 				label = "LED1"; | ||||
| 				default-state = "off"; | ||||
| 			}; | ||||
| 			led@2 { | ||||
| 				reg = <2>; | ||||
| 				label = "LED2"; | ||||
| 				default-state = "on"; | ||||
| 			}; | ||||
| 			led@3 { | ||||
| 				reg = <3>; | ||||
| 				label = "LED3"; | ||||
| 				default-state = "on"; | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &uart2 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &pio { | ||||
| 	nand_pins_default: nanddefault { | ||||
| 		pins_dat { | ||||
| 			pinmux = <MT7623_PIN_111_MSDC0_DAT7_FUNC_NLD7>, | ||||
| 				 <MT7623_PIN_112_MSDC0_DAT6_FUNC_NLD6>, | ||||
| 				 <MT7623_PIN_114_MSDC0_DAT4_FUNC_NLD4>, | ||||
| 				 <MT7623_PIN_118_MSDC0_DAT3_FUNC_NLD3>, | ||||
| 				 <MT7623_PIN_121_MSDC0_DAT0_FUNC_NLD0>, | ||||
| 				 <MT7623_PIN_120_MSDC0_DAT1_FUNC_NLD1>, | ||||
| 				 <MT7623_PIN_113_MSDC0_DAT5_FUNC_NLD5>, | ||||
| 				 <MT7623_PIN_115_MSDC0_RSTB_FUNC_NLD8>, | ||||
| 				 <MT7623_PIN_119_MSDC0_DAT2_FUNC_NLD2>; | ||||
| 				input-enable; | ||||
| 				drive-strength = <MTK_DRIVE_8mA>; | ||||
| 				bias-pull-up; | ||||
| 		}; | ||||
|  | ||||
| 		pins_we { | ||||
| 			pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_NWEB>; | ||||
| 			drive-strength = <MTK_DRIVE_8mA>; | ||||
| 			bias-pull-up = <MTK_PUPD_SET_R1R0_10>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_ale { | ||||
| 			pinmux = <MT7623_PIN_116_MSDC0_CMD_FUNC_NALE>; | ||||
| 			drive-strength = <MTK_DRIVE_8mA>; | ||||
| 			bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	eth_default: eth { | ||||
| 		pins_eth { | ||||
| 			pinmux = <MT7623_PIN_275_G2_MDC_FUNC_MDC>, | ||||
| 				 <MT7623_PIN_276_G2_MDIO_FUNC_MDIO>, | ||||
| 				 <MT7623_PIN_262_G2_TXEN_FUNC_G2_TXEN>, | ||||
| 				 <MT7623_PIN_263_G2_TXD3_FUNC_G2_TXD3>, | ||||
| 				 <MT7623_PIN_264_G2_TXD2_FUNC_G2_TXD2>, | ||||
| 				 <MT7623_PIN_265_G2_TXD1_FUNC_G2_TXD1>, | ||||
| 				 <MT7623_PIN_266_G2_TXD0_FUNC_G2_TXD0>, | ||||
| 				 <MT7623_PIN_267_G2_TXCLK_FUNC_G2_TXC>, | ||||
| 				 <MT7623_PIN_268_G2_RXCLK_FUNC_G2_RXC>, | ||||
| 				 <MT7623_PIN_269_G2_RXD0_FUNC_G2_RXD0>, | ||||
| 				 <MT7623_PIN_270_G2_RXD1_FUNC_G2_RXD1>, | ||||
| 				 <MT7623_PIN_271_G2_RXD2_FUNC_G2_RXD2>, | ||||
| 				 <MT7623_PIN_272_G2_RXD3_FUNC_G2_RXD3>, | ||||
| 				 <MT7623_PIN_274_G2_RXDV_FUNC_G2_RXDV>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_eth_rst { | ||||
| 			pinmux = <MT7623_PIN_15_GPIO15_FUNC_GPIO15>; | ||||
| 			output-low; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	pwm_pins: pwm { | ||||
| 		pins_pwm1 { | ||||
| 			pinmux = <MT7623_PIN_204_PWM1_FUNC_PWM1>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_pwm2 { | ||||
| 			pinmux = <MT7623_PIN_205_PWM2_FUNC_PWM2>; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &nandc { | ||||
| 	status = "okay"; | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&nand_pins_default>; | ||||
| 	nand@0 { | ||||
| 		reg = <0>; | ||||
| 		spare_per_sector = <64>; | ||||
| 		nand-ecc-mode = "hw"; | ||||
| 		nand-ecc-strength = <12>; | ||||
| 		nand-ecc-step-size = <1024>; | ||||
| 		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 = "ubi"; | ||||
| 				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"; | ||||
|  | ||||
| 	phy-handle = <&phy5>; | ||||
| }; | ||||
|  | ||||
| &mdio0 { | ||||
| 	switch@0 { | ||||
| 		compatible = "mediatek,mt7530"; | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 		reg = <0>; | ||||
|  | ||||
| 		pinctrl-names = "default"; | ||||
| 		pinctrl-0 = <ð_default>; | ||||
|  | ||||
| 		core-supply = <&mt6323_vpa_reg>; | ||||
| 		io-supply = <&mt6323_vemc3v3_reg>; | ||||
|  | ||||
| 		mediatek,mcm; | ||||
| 		resets = <ðsys 2>; | ||||
| 		reset-names = "mcm"; | ||||
|  | ||||
| 		ports { | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 			reg = <0>; | ||||
| 			port@0 { | ||||
| 				reg = <0>; | ||||
| 				label = "lan0"; | ||||
| 			}; | ||||
|  | ||||
| 			port@1 { | ||||
| 				reg = <1>; | ||||
| 				label = "lan1"; | ||||
| 			}; | ||||
|  | ||||
| 			port@2 { | ||||
| 				reg = <2>; | ||||
| 				label = "lan2"; | ||||
| 			}; | ||||
|  | ||||
| 			port@3 { | ||||
| 				reg = <3>; | ||||
| 				label = "lan3"; | ||||
| 			}; | ||||
|  | ||||
| 			port@6 { | ||||
| 				reg = <6>; | ||||
| 				label = "cpu"; | ||||
| 				ethernet = <&gmac1>; | ||||
| 				phy-mode = "trgmii"; | ||||
| 				fixed-link { | ||||
| 					speed = <1000>; | ||||
| 					full-duplex; | ||||
| 				}; | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	phy5: ethernet-phy@5 { | ||||
| 		reg = <5>; | ||||
| 		phy-mode = "rgmii-rxid"; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &pwm { | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&pwm_pins>; | ||||
| 	status = "okay"; | ||||
| }; | ||||
| @@ -1,553 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (c) 2016 MediaTek Inc. | ||||
|  * Author: John Crispin <blogic@openwrt.org> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  */ | ||||
|  | ||||
| /dts-v1/; | ||||
|  | ||||
| #include "_mt7623.dtsi" | ||||
| #include <dt-bindings/gpio/gpio.h> | ||||
|  | ||||
| / { | ||||
| 	model = "MediaTek MT7623 NAND reference board"; | ||||
| 	compatible = "mediatek,mt7623-rfb-nand", "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>; | ||||
| 			}; | ||||
| 		}; | ||||
|  | ||||
| 		mt6323led: leds { | ||||
| 			compatible = "mediatek,mt6323-led"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
|  | ||||
| 			led@0 { | ||||
| 				reg = <0>; | ||||
| 				label = "LED0"; | ||||
| 				linux,default-trigger = "timer"; | ||||
| 				default-state = "on"; | ||||
| 			}; | ||||
| 			led@1 { | ||||
| 				reg = <1>; | ||||
| 				label = "LED1"; | ||||
| 				default-state = "off"; | ||||
| 			}; | ||||
| 			led@2 { | ||||
| 				reg = <2>; | ||||
| 				label = "LED2"; | ||||
| 				default-state = "on"; | ||||
| 			}; | ||||
| 			led@3 { | ||||
| 				reg = <3>; | ||||
| 				label = "LED3"; | ||||
| 				default-state = "on"; | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &uart2 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &pio { | ||||
| 	nand_pins_default: nanddefault { | ||||
| 		pins_dat { | ||||
| 			pinmux = <MT7623_PIN_111_MSDC0_DAT7_FUNC_NLD7>, | ||||
| 				 <MT7623_PIN_112_MSDC0_DAT6_FUNC_NLD6>, | ||||
| 				 <MT7623_PIN_114_MSDC0_DAT4_FUNC_NLD4>, | ||||
| 				 <MT7623_PIN_118_MSDC0_DAT3_FUNC_NLD3>, | ||||
| 				 <MT7623_PIN_121_MSDC0_DAT0_FUNC_NLD0>, | ||||
| 				 <MT7623_PIN_120_MSDC0_DAT1_FUNC_NLD1>, | ||||
| 				 <MT7623_PIN_113_MSDC0_DAT5_FUNC_NLD5>, | ||||
| 				 <MT7623_PIN_115_MSDC0_RSTB_FUNC_NLD8>, | ||||
| 				 <MT7623_PIN_119_MSDC0_DAT2_FUNC_NLD2>; | ||||
| 				input-enable; | ||||
| 				drive-strength = <MTK_DRIVE_8mA>; | ||||
| 				bias-pull-up; | ||||
| 		}; | ||||
|  | ||||
| 		pins_we { | ||||
| 			pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_NWEB>; | ||||
| 			drive-strength = <MTK_DRIVE_8mA>; | ||||
| 			bias-pull-up = <MTK_PUPD_SET_R1R0_10>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_ale { | ||||
| 			pinmux = <MT7623_PIN_116_MSDC0_CMD_FUNC_NALE>; | ||||
| 			drive-strength = <MTK_DRIVE_8mA>; | ||||
| 			bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	eth_default: eth { | ||||
| 		pins_eth { | ||||
| 			pinmux = <MT7623_PIN_275_G2_MDC_FUNC_MDC>, | ||||
| 				 <MT7623_PIN_276_G2_MDIO_FUNC_MDIO>, | ||||
| 				 <MT7623_PIN_262_G2_TXEN_FUNC_G2_TXEN>, | ||||
| 				 <MT7623_PIN_263_G2_TXD3_FUNC_G2_TXD3>, | ||||
| 				 <MT7623_PIN_264_G2_TXD2_FUNC_G2_TXD2>, | ||||
| 				 <MT7623_PIN_265_G2_TXD1_FUNC_G2_TXD1>, | ||||
| 				 <MT7623_PIN_266_G2_TXD0_FUNC_G2_TXD0>, | ||||
| 				 <MT7623_PIN_267_G2_TXCLK_FUNC_G2_TXC>, | ||||
| 				 <MT7623_PIN_268_G2_RXCLK_FUNC_G2_RXC>, | ||||
| 				 <MT7623_PIN_269_G2_RXD0_FUNC_G2_RXD0>, | ||||
| 				 <MT7623_PIN_270_G2_RXD1_FUNC_G2_RXD1>, | ||||
| 				 <MT7623_PIN_271_G2_RXD2_FUNC_G2_RXD2>, | ||||
| 				 <MT7623_PIN_272_G2_RXD3_FUNC_G2_RXD3>, | ||||
| 				 <MT7623_PIN_274_G2_RXDV_FUNC_G2_RXDV>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_eth_rst { | ||||
| 			pinmux = <MT7623_PIN_15_GPIO15_FUNC_GPIO15>; | ||||
| 			output-low; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	pwm_pins: pwm { | ||||
| 		pins_pwm1 { | ||||
| 			pinmux = <MT7623_PIN_204_PWM1_FUNC_PWM1>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_pwm2 { | ||||
| 			pinmux = <MT7623_PIN_205_PWM2_FUNC_PWM2>; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &nandc { | ||||
| 	status = "okay"; | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&nand_pins_default>; | ||||
| 	nand@0 { | ||||
| 		reg = <0>; | ||||
| 		spare_per_sector = <64>; | ||||
| 		nand-ecc-mode = "hw"; | ||||
| 		nand-ecc-strength = <12>; | ||||
| 		nand-ecc-step-size = <1024>; | ||||
| 		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 = "ubi"; | ||||
| 				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"; | ||||
|  | ||||
| 	phy-mode = "trgmii"; | ||||
|  | ||||
| 	fixed-link { | ||||
| 		speed = <1000>; | ||||
| 		full-duplex; | ||||
| 		pause; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &gmac2 { | ||||
| 	mac-address = [00 11 22 33 44 55]; | ||||
| 	status = "okay"; | ||||
|  | ||||
| 	phy-mode = "trgmii"; | ||||
|  | ||||
| 	fixed-link { | ||||
| 		speed = <1000>; | ||||
| 		full-duplex; | ||||
| 		pause; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &mdio0 { | ||||
| 	switch@0 { | ||||
| 		compatible = "mediatek,mt7530"; | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 		reg = <0>; | ||||
|  | ||||
| 		pinctrl-names = "default"; | ||||
| 		pinctrl-0 = <ð_default>; | ||||
|  | ||||
| 		core-supply = <&mt6323_vpa_reg>; | ||||
| 		io-supply = <&mt6323_vemc3v3_reg>; | ||||
|  | ||||
| 		mediatek,mcm; | ||||
| 		resets = <ðsys 2>; | ||||
| 		reset-names = "mcm"; | ||||
|  | ||||
| 		ports { | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 			reg = <0>; | ||||
| 			port@0 { | ||||
| 				reg = <0>; | ||||
| 				label = "lan0"; | ||||
| 				cpu = <&cpu_port0>; | ||||
| 			}; | ||||
|  | ||||
| 			port@1 { | ||||
| 				reg = <1>; | ||||
| 				label = "lan1"; | ||||
| 				cpu = <&cpu_port0>; | ||||
| 			}; | ||||
|  | ||||
| 			port@2 { | ||||
| 				reg = <2>; | ||||
| 				label = "lan2"; | ||||
| 				cpu = <&cpu_port0>; | ||||
| 			}; | ||||
|  | ||||
| 			port@3 { | ||||
| 				reg = <3>; | ||||
| 				label = "lan3"; | ||||
| 				cpu = <&cpu_port0>; | ||||
| 			}; | ||||
|  | ||||
| 			port@4 { | ||||
| 				reg = <4>; | ||||
| 				label = "wan"; | ||||
| 				cpu = <&cpu_port1>; | ||||
| 			}; | ||||
|  | ||||
| 			cpu_port1: port@5 { | ||||
| 				reg = <5>; | ||||
| 				label = "cpu"; | ||||
| 				ethernet = <&gmac2>; | ||||
| 				phy-mode = "trgmii"; | ||||
| 				fixed-link { | ||||
| 					speed = <1000>; | ||||
| 					full-duplex; | ||||
| 				}; | ||||
| 			}; | ||||
|  | ||||
| 			cpu_port0: port@6 { | ||||
| 				reg = <6>; | ||||
| 				label = "cpu"; | ||||
| 				ethernet = <&gmac1>; | ||||
| 				phy-mode = "trgmii"; | ||||
| 				fixed-link { | ||||
| 					speed = <1000>; | ||||
| 					full-duplex; | ||||
| 				}; | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &pwm { | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&pwm_pins>; | ||||
| 	status = "okay"; | ||||
| }; | ||||
| @@ -1,547 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (c) 2016 MediaTek Inc. | ||||
|  * Author: John Crispin <blogic@openwrt.org> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  */ | ||||
|  | ||||
| /dts-v1/; | ||||
|  | ||||
| #include "_mt7623.dtsi" | ||||
| #include <dt-bindings/gpio/gpio.h> | ||||
|  | ||||
| / { | ||||
| 	model = "MediaTek MT7623 eMMC reference board"; | ||||
| 	compatible = "mediatek,mt7623-rfb-emmc", "mediatek,mt7623"; | ||||
|  | ||||
| 	chosen { | ||||
| 		stdout-path = &uart2; | ||||
| 		bootargs = "earlyprintk 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"; | ||||
| 	}; | ||||
|  | ||||
| 	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; | ||||
| 	}; | ||||
|  | ||||
| 	switch { | ||||
| 		compatible = "mediatek,mt7530"; | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 		reg = <0>; | ||||
|  | ||||
| 		dsa,mii-bus = <&mdio0>; | ||||
|  | ||||
| 		pinctrl-names = "default"; | ||||
| 		pinctrl-0 = <ð_default>; | ||||
|  | ||||
| 		core-supply = <&mt6323_vpa_reg>; | ||||
| 		io-supply = <&mt6323_vemc3v3_reg>; | ||||
|  | ||||
| 		mediatek,mcm; | ||||
| 		resets = <ðsys 2>; | ||||
| 		reset-names = "mcm"; | ||||
|  | ||||
| 		ports { | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 			reg = <0>; | ||||
| 			port@0 { | ||||
| 				reg = <0>; | ||||
| 				label = "lan0"; | ||||
| 			}; | ||||
|  | ||||
| 			port@1 { | ||||
| 				reg = <1>; | ||||
| 				label = "lan1"; | ||||
| 			}; | ||||
|  | ||||
| 			port@2 { | ||||
| 				reg = <2>; | ||||
| 				label = "lan2"; | ||||
| 			}; | ||||
|  | ||||
| 			port@3 { | ||||
| 				reg = <3>; | ||||
| 				label = "lan3"; | ||||
| 			}; | ||||
|  | ||||
| 			port@6 { | ||||
| 				reg = <6>; | ||||
| 				label = "cpu"; | ||||
| 				ethernet = <&gmac1>; | ||||
| 				phy-mode = "trgmii"; | ||||
| 				fixed-link { | ||||
| 					speed = <1000>; | ||||
| 					full-duplex; | ||||
| 				}; | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &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"; | ||||
| }; | ||||
|  | ||||
| &mmc0 { | ||||
| 	status = "okay"; | ||||
| 	pinctrl-names = "default", "state_uhs"; | ||||
| 	pinctrl-0 = <&mmc0_pins_default>; | ||||
| 	pinctrl-1 = <&mmc0_pins_uhs>; | ||||
| 	bus-width = <8>; | ||||
| 	max-frequency = <50000000>; | ||||
| 	cap-mmc-highspeed; | ||||
| 	vmmc-supply = <&mt6323_vemc3v3_reg>; | ||||
| 	vqmmc-supply = <&mt6323_vio18_reg>; | ||||
| 	non-removable; | ||||
| }; | ||||
|  | ||||
| &mmc1 { | ||||
| 	status = "okay"; | ||||
| 	pinctrl-names = "default", "state_uhs"; | ||||
| 	pinctrl-0 = <&mmc1_pins_default>; | ||||
| 	pinctrl-1 = <&mmc1_pins_uhs>; | ||||
| 	bus-width = <4>; | ||||
| 	max-frequency = <50000000>; | ||||
| 	cap-sd-highspeed; | ||||
| 	sd-uhs-sdr25; | ||||
| //	cd-gpios = <&pio 132 0>; | ||||
| 	vmmc-supply = <&mt6323_vmch_reg>; | ||||
| 	vqmmc-supply = <&mt6323_vmc_reg>; | ||||
| }; | ||||
|  | ||||
| &pio { | ||||
| 	mmc0_pins_default: mmc0default { | ||||
| 		pins_cmd_dat { | ||||
| 			pinmux = <MT7623_PIN_111_MSDC0_DAT7_FUNC_MSDC0_DAT7>, | ||||
| 				 <MT7623_PIN_112_MSDC0_DAT6_FUNC_MSDC0_DAT6>, | ||||
| 				 <MT7623_PIN_113_MSDC0_DAT5_FUNC_MSDC0_DAT5>, | ||||
| 				 <MT7623_PIN_114_MSDC0_DAT4_FUNC_MSDC0_DAT4>, | ||||
| 				 <MT7623_PIN_118_MSDC0_DAT3_FUNC_MSDC0_DAT3>, | ||||
| 				 <MT7623_PIN_119_MSDC0_DAT2_FUNC_MSDC0_DAT2>, | ||||
| 				 <MT7623_PIN_120_MSDC0_DAT1_FUNC_MSDC0_DAT1>, | ||||
| 				 <MT7623_PIN_121_MSDC0_DAT0_FUNC_MSDC0_DAT0>, | ||||
| 				 <MT7623_PIN_116_MSDC0_CMD_FUNC_MSDC0_CMD>; | ||||
| 			input-enable; | ||||
| 			bias-pull-up; | ||||
| 		}; | ||||
|  | ||||
| 		pins_clk { | ||||
| 			pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_MSDC0_CLK>; | ||||
| 			bias-pull-down; | ||||
| 		}; | ||||
|  | ||||
| 		pins_rst { | ||||
| 			pinmux = <MT7623_PIN_115_MSDC0_RSTB_FUNC_MSDC0_RSTB>; | ||||
| 			bias-pull-up; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	mmc0_pins_uhs: mmc0 { | ||||
| 		pins_cmd_dat { | ||||
| 			pinmux = <MT7623_PIN_111_MSDC0_DAT7_FUNC_MSDC0_DAT7>, | ||||
| 				 <MT7623_PIN_112_MSDC0_DAT6_FUNC_MSDC0_DAT6>, | ||||
| 				 <MT7623_PIN_113_MSDC0_DAT5_FUNC_MSDC0_DAT5>, | ||||
| 				 <MT7623_PIN_114_MSDC0_DAT4_FUNC_MSDC0_DAT4>, | ||||
| 				 <MT7623_PIN_118_MSDC0_DAT3_FUNC_MSDC0_DAT3>, | ||||
| 				 <MT7623_PIN_119_MSDC0_DAT2_FUNC_MSDC0_DAT2>, | ||||
| 				 <MT7623_PIN_120_MSDC0_DAT1_FUNC_MSDC0_DAT1>, | ||||
| 				 <MT7623_PIN_121_MSDC0_DAT0_FUNC_MSDC0_DAT0>, | ||||
| 				 <MT7623_PIN_116_MSDC0_CMD_FUNC_MSDC0_CMD>; | ||||
| 			input-enable; | ||||
| 			drive-strength = <MTK_DRIVE_2mA>; | ||||
| 			bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_clk { | ||||
| 			pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_MSDC0_CLK>; | ||||
| 			drive-strength = <MTK_DRIVE_2mA>; | ||||
| 			bias-pull-down = <MTK_PUPD_SET_R1R0_01>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_rst { | ||||
| 			pinmux = <MT7623_PIN_115_MSDC0_RSTB_FUNC_MSDC0_RSTB>; | ||||
| 			bias-pull-up; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	mmc1_pins_default: mmc1default { | ||||
| 		pins_cmd_dat { | ||||
| 			pinmux = <MT7623_PIN_107_MSDC1_DAT0_FUNC_MSDC1_DAT0>, | ||||
| 				 <MT7623_PIN_108_MSDC1_DAT1_FUNC_MSDC1_DAT1>, | ||||
| 				 <MT7623_PIN_109_MSDC1_DAT2_FUNC_MSDC1_DAT2>, | ||||
| 				 <MT7623_PIN_110_MSDC1_DAT3_FUNC_MSDC1_DAT3>, | ||||
| 				 <MT7623_PIN_105_MSDC1_CMD_FUNC_MSDC1_CMD>; | ||||
| 			input-enable; | ||||
| 			drive-strength = <MTK_DRIVE_4mA>; | ||||
| 			bias-pull-up = <MTK_PUPD_SET_R1R0_10>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_clk { | ||||
| 			pinmux = <MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK>; | ||||
| 			bias-pull-down; | ||||
| 			drive-strength = <MTK_DRIVE_4mA>; | ||||
| 		}; | ||||
|  | ||||
| //		pins_insert { | ||||
| //			pinmux = <MT8173_PIN_132_I2S0_DATA1_FUNC_GPIO132>; | ||||
| //			bias-pull-up; | ||||
| //		}; | ||||
| 	}; | ||||
|  | ||||
| 	mmc1_pins_uhs: mmc1 { | ||||
| 		pins_cmd_dat { | ||||
| 			pinmux = <MT7623_PIN_107_MSDC1_DAT0_FUNC_MSDC1_DAT0>, | ||||
| 				 <MT7623_PIN_108_MSDC1_DAT1_FUNC_MSDC1_DAT1>, | ||||
| 				 <MT7623_PIN_109_MSDC1_DAT2_FUNC_MSDC1_DAT2>, | ||||
| 				 <MT7623_PIN_110_MSDC1_DAT3_FUNC_MSDC1_DAT3>, | ||||
| 				 <MT7623_PIN_105_MSDC1_CMD_FUNC_MSDC1_CMD>; | ||||
| 			input-enable; | ||||
| 			drive-strength = <MTK_DRIVE_4mA>; | ||||
| 			bias-pull-up = <MTK_PUPD_SET_R1R0_10>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_clk { | ||||
| 			pinmux = <MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK>; | ||||
| 			drive-strength = <MTK_DRIVE_4mA>; | ||||
| 			bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	eth_default: eth { | ||||
| 		pins_eth { | ||||
| 			pinmux = <MT7623_PIN_275_G2_MDC_FUNC_MDC>, | ||||
| 				 <MT7623_PIN_276_G2_MDIO_FUNC_MDIO>, | ||||
| 				 <MT7623_PIN_262_G2_TXEN_FUNC_G2_TXEN>, | ||||
| 				 <MT7623_PIN_263_G2_TXD3_FUNC_G2_TXD3>, | ||||
| 				 <MT7623_PIN_264_G2_TXD2_FUNC_G2_TXD2>, | ||||
| 				 <MT7623_PIN_265_G2_TXD1_FUNC_G2_TXD1>, | ||||
| 				 <MT7623_PIN_266_G2_TXD0_FUNC_G2_TXD0>, | ||||
| 				 <MT7623_PIN_267_G2_TXCLK_FUNC_G2_TXC>, | ||||
| 				 <MT7623_PIN_268_G2_RXCLK_FUNC_G2_RXC>, | ||||
| 				 <MT7623_PIN_269_G2_RXD0_FUNC_G2_RXD0>, | ||||
| 				 <MT7623_PIN_270_G2_RXD1_FUNC_G2_RXD1>, | ||||
| 				 <MT7623_PIN_271_G2_RXD2_FUNC_G2_RXD2>, | ||||
| 				 <MT7623_PIN_272_G2_RXD3_FUNC_G2_RXD3>, | ||||
| 				 <MT7623_PIN_274_G2_RXDV_FUNC_G2_RXDV>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_eth_rst { | ||||
| 			pinmux = <MT7623_PIN_15_GPIO15_FUNC_GPIO15>; | ||||
| 			output-low; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	pwm_pins: pwm { | ||||
| 		pins_pwm1 { | ||||
| 			pinmux = <MT7623_PIN_204_PWM1_FUNC_PWM1>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_pwm2 { | ||||
| 			pinmux = <MT7623_PIN_205_PWM2_FUNC_PWM2>; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &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"; | ||||
|  | ||||
| 	phy-handle = <&phy5>; | ||||
| }; | ||||
|  | ||||
| &mdio0 { | ||||
| 	phy5: ethernet-phy@5 { | ||||
| 		reg = <5>; | ||||
| 		phy-mode = "rgmii-rxid"; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &pwm { | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&pwm_pins>; | ||||
| 	status = "okay"; | ||||
| }; | ||||
| @@ -1,50 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (c) 2016 MediaTek Inc. | ||||
|  * Author: John Crispin <blogic@openwrt.org> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  */ | ||||
|  | ||||
| /dts-v1/; | ||||
| #include "mt7623.dtsi" | ||||
|  | ||||
| / { | ||||
| 	model = "MediaTek MT7623 evaluation board"; | ||||
| 	compatible = "mediatek,mt7623-evb", "mediatek,mt7623"; | ||||
|  | ||||
| 	chosen { | ||||
| 		stdout-path = &uart2; | ||||
| 	}; | ||||
|  | ||||
| 	memory { | ||||
| 		reg = <0 0x80000000 0 0x40000000>; | ||||
| 	}; | ||||
| /* | ||||
| 	pwm_pins: pwm { | ||||
| 		pins_pwm1 { | ||||
| 			pinmux = <MT7623_PIN_204_PWM1_FUNC_PWM1>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_pwm2 { | ||||
| 			pinmux = <MT7623_PIN_205_PWM2_FUNC_PWM2>; | ||||
| 		}; | ||||
| 	};*/ | ||||
|  | ||||
| }; | ||||
|  | ||||
| &uart2 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| /*&pwm { | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&pwm_pins>; | ||||
| 	status = "okay"; | ||||
| };*/ | ||||
| @@ -1,443 +0,0 @@ | ||||
| /* | ||||
|  * Copyright 2017 Sean Wang <sean.wang@mediatek.com> | ||||
|  * | ||||
|  * SPDX-License-Identifier: (GPL-2.0+ OR MIT) | ||||
|  */ | ||||
|  | ||||
| /dts-v1/; | ||||
| #include <dt-bindings/input/input.h> | ||||
| #include "_mt7623.dtsi" | ||||
| #include "mt6323.dtsi" | ||||
|  | ||||
| / { | ||||
| 	model = "Bananapi BPI-R2"; | ||||
| 	compatible = "bananapi,bpi-r2", "mediatek,mt7623"; | ||||
|  | ||||
| 	aliases { | ||||
| 		serial2 = &uart2; | ||||
| 	}; | ||||
|  | ||||
| 	chosen { | ||||
| 		stdout-path = "serial2:115200n8"; | ||||
| 	}; | ||||
|  | ||||
| 	cpus { | ||||
| 		cpu@0 { | ||||
| 			proc-supply = <&mt6323_vproc_reg>; | ||||
| 		}; | ||||
|  | ||||
| 		cpu@1 { | ||||
| 			proc-supply = <&mt6323_vproc_reg>; | ||||
| 		}; | ||||
|  | ||||
| 		cpu@2 { | ||||
| 			proc-supply = <&mt6323_vproc_reg>; | ||||
| 		}; | ||||
|  | ||||
| 		cpu@3 { | ||||
| 			proc-supply = <&mt6323_vproc_reg>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	gpio_keys { | ||||
| 		compatible = "gpio-keys"; | ||||
| 		pinctrl-names = "default"; | ||||
| 		pinctrl-0 = <&key_pins_a>; | ||||
|  | ||||
| 		factory { | ||||
| 			label = "factory"; | ||||
| 			linux,code = <BTN_0>; | ||||
| 			gpios = <&pio 256 GPIO_ACTIVE_LOW>; | ||||
| 		}; | ||||
|  | ||||
| 		wps { | ||||
| 			label = "wps"; | ||||
| 			linux,code = <KEY_WPS_BUTTON>; | ||||
| 			gpios = <&pio 257 GPIO_ACTIVE_HIGH>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	leds { | ||||
| 		compatible = "gpio-leds"; | ||||
| 		pinctrl-names = "default"; | ||||
| 		pinctrl-0 = <&led_pins_a>; | ||||
|  | ||||
| 		red { | ||||
| 			label = "bpi-r2:pio:red"; | ||||
| 			gpios = <&pio 239 GPIO_ACTIVE_HIGH>; | ||||
| 			default-state = "off"; | ||||
| 		}; | ||||
|  | ||||
| 		green { | ||||
| 			label = "bpi-r2:pio:green"; | ||||
| 			gpios = <&pio 240 GPIO_ACTIVE_HIGH>; | ||||
| 			default-state = "off"; | ||||
| 		}; | ||||
|  | ||||
| 		blue { | ||||
| 			label = "bpi-r2:pio:blue"; | ||||
| 			gpios = <&pio 241 GPIO_ACTIVE_HIGH>; | ||||
| 			default-state = "off"; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	memory@80000000 { | ||||
| 		reg = <0 0x80000000 0 0x40000000>; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &cir { | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&cir_pins_a>; | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &crypto { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| ð { | ||||
| 	status = "okay"; | ||||
| 	gmac0: mac@0 { | ||||
| 		compatible = "mediatek,eth-mac"; | ||||
| 		reg = <0>; | ||||
| 		phy-mode = "trgmii"; | ||||
| 		fixed-link { | ||||
| 			speed = <1000>; | ||||
| 			full-duplex; | ||||
| 			pause; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	mdio: mdio-bus { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <0>; | ||||
| 		switch@0 { | ||||
| 			compatible = "mediatek,mt7530"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 			reg = <0>; | ||||
|  | ||||
| 			pinctrl-names = "default"; | ||||
| 			reset-gpios = <&pio 33 0>; | ||||
| 			core-supply = <&mt6323_vpa_reg>; | ||||
| 			io-supply = <&mt6323_vemc3v3_reg>; | ||||
|  | ||||
| 			ports { | ||||
| 				#address-cells = <1>; | ||||
| 				#size-cells = <0>; | ||||
| 				reg = <0>; | ||||
| 				port@0 { | ||||
| 					reg = <0>; | ||||
| 					label = "wan"; | ||||
| 				}; | ||||
|  | ||||
| 				port@1 { | ||||
| 					reg = <1>; | ||||
| 					label = "lan0"; | ||||
| 				}; | ||||
|  | ||||
| 				port@2 { | ||||
| 					reg = <2>; | ||||
| 					label = "lan1"; | ||||
| 				}; | ||||
|  | ||||
| 				port@3 { | ||||
| 					reg = <3>; | ||||
| 					label = "lan2"; | ||||
| 				}; | ||||
|  | ||||
| 				port@4 { | ||||
| 					reg = <4>; | ||||
| 					label = "lan3"; | ||||
| 				}; | ||||
|  | ||||
| 				port@6 { | ||||
| 					reg = <6>; | ||||
| 					label = "cpu"; | ||||
| 					ethernet = <&gmac0>; | ||||
| 					phy-mode = "trgmii"; | ||||
| 					fixed-link { | ||||
| 						speed = <1000>; | ||||
| 						full-duplex; | ||||
| 					}; | ||||
| 				}; | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &i2c0 { | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&i2c0_pins_a>; | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &i2c1 { | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&i2c1_pins_a>; | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &pio { | ||||
| 	cir_pins_a:cir@0 { | ||||
| 		pins_cir { | ||||
| 			pinmux = <MT7623_PIN_46_IR_FUNC_IR>; | ||||
| 			bias-disable; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	i2c0_pins_a: i2c@0 { | ||||
| 		pins_i2c0 { | ||||
| 			pinmux = <MT7623_PIN_75_SDA0_FUNC_SDA0>, | ||||
| 				 <MT7623_PIN_76_SCL0_FUNC_SCL0>; | ||||
| 			bias-disable; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	i2c1_pins_a: i2c@1 { | ||||
| 		pin_i2c1 { | ||||
| 			pinmux = <MT7623_PIN_57_SDA1_FUNC_SDA1>, | ||||
| 				 <MT7623_PIN_58_SCL1_FUNC_SCL1>; | ||||
| 			bias-disable; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	i2s0_pins_a: i2s@0 { | ||||
| 		pin_i2s0 { | ||||
| 			pinmux = <MT7623_PIN_49_I2S0_DATA_FUNC_I2S0_DATA>, | ||||
| 				 <MT7623_PIN_72_I2S0_DATA_IN_FUNC_I2S0_DATA_IN>, | ||||
| 				 <MT7623_PIN_73_I2S0_LRCK_FUNC_I2S0_LRCK>, | ||||
| 				 <MT7623_PIN_74_I2S0_BCK_FUNC_I2S0_BCK>, | ||||
| 				 <MT7623_PIN_126_I2S0_MCLK_FUNC_I2S0_MCLK>; | ||||
| 			drive-strength = <MTK_DRIVE_12mA>; | ||||
| 			bias-pull-down; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	i2s1_pins_a: i2s@1 { | ||||
| 		pin_i2s1 { | ||||
| 			pinmux = <MT7623_PIN_33_I2S1_DATA_FUNC_I2S1_DATA>, | ||||
| 				 <MT7623_PIN_34_I2S1_DATA_IN_FUNC_I2S1_DATA_IN>, | ||||
| 				 <MT7623_PIN_35_I2S1_BCK_FUNC_I2S1_BCK>, | ||||
| 				 <MT7623_PIN_36_I2S1_LRCK_FUNC_I2S1_LRCK>, | ||||
| 				 <MT7623_PIN_37_I2S1_MCLK_FUNC_I2S1_MCLK>; | ||||
| 			drive-strength = <MTK_DRIVE_12mA>; | ||||
| 			bias-pull-down; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	key_pins_a: keys@0 { | ||||
| 		pins_keys { | ||||
| 			pinmux = <MT7623_PIN_256_GPIO256_FUNC_GPIO256>, | ||||
| 				 <MT7623_PIN_257_GPIO257_FUNC_GPIO257> ; | ||||
| 			input-enable; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	led_pins_a: leds@0 { | ||||
| 		pins_leds { | ||||
| 			pinmux = <MT7623_PIN_239_EXT_SDIO0_FUNC_GPIO239>, | ||||
| 				 <MT7623_PIN_240_EXT_XCS_FUNC_GPIO240>, | ||||
| 				 <MT7623_PIN_241_EXT_SCK_FUNC_GPIO241>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	mmc0_pins_default: mmc0default { | ||||
| 		pins_cmd_dat { | ||||
| 			pinmux = <MT7623_PIN_111_MSDC0_DAT7_FUNC_MSDC0_DAT7>, | ||||
| 				 <MT7623_PIN_112_MSDC0_DAT6_FUNC_MSDC0_DAT6>, | ||||
| 				 <MT7623_PIN_113_MSDC0_DAT5_FUNC_MSDC0_DAT5>, | ||||
| 				 <MT7623_PIN_114_MSDC0_DAT4_FUNC_MSDC0_DAT4>, | ||||
| 				 <MT7623_PIN_118_MSDC0_DAT3_FUNC_MSDC0_DAT3>, | ||||
| 				 <MT7623_PIN_119_MSDC0_DAT2_FUNC_MSDC0_DAT2>, | ||||
| 				 <MT7623_PIN_120_MSDC0_DAT1_FUNC_MSDC0_DAT1>, | ||||
| 				 <MT7623_PIN_121_MSDC0_DAT0_FUNC_MSDC0_DAT0>, | ||||
| 				 <MT7623_PIN_116_MSDC0_CMD_FUNC_MSDC0_CMD>; | ||||
| 			input-enable; | ||||
| 			bias-pull-up; | ||||
| 		}; | ||||
|  | ||||
| 		pins_clk { | ||||
| 			pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_MSDC0_CLK>; | ||||
| 			bias-pull-down; | ||||
| 		}; | ||||
|  | ||||
| 		pins_rst { | ||||
| 			pinmux = <MT7623_PIN_115_MSDC0_RSTB_FUNC_MSDC0_RSTB>; | ||||
| 			bias-pull-up; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	mmc0_pins_uhs: mmc0 { | ||||
| 		pins_cmd_dat { | ||||
| 			pinmux = <MT7623_PIN_111_MSDC0_DAT7_FUNC_MSDC0_DAT7>, | ||||
| 				 <MT7623_PIN_112_MSDC0_DAT6_FUNC_MSDC0_DAT6>, | ||||
| 				 <MT7623_PIN_113_MSDC0_DAT5_FUNC_MSDC0_DAT5>, | ||||
| 				 <MT7623_PIN_114_MSDC0_DAT4_FUNC_MSDC0_DAT4>, | ||||
| 				 <MT7623_PIN_118_MSDC0_DAT3_FUNC_MSDC0_DAT3>, | ||||
| 				 <MT7623_PIN_119_MSDC0_DAT2_FUNC_MSDC0_DAT2>, | ||||
| 				 <MT7623_PIN_120_MSDC0_DAT1_FUNC_MSDC0_DAT1>, | ||||
| 				 <MT7623_PIN_121_MSDC0_DAT0_FUNC_MSDC0_DAT0>, | ||||
| 				 <MT7623_PIN_116_MSDC0_CMD_FUNC_MSDC0_CMD>; | ||||
| 			input-enable; | ||||
| 			drive-strength = <MTK_DRIVE_2mA>; | ||||
| 			bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_clk { | ||||
| 			pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_MSDC0_CLK>; | ||||
| 			drive-strength = <MTK_DRIVE_2mA>; | ||||
| 			bias-pull-down = <MTK_PUPD_SET_R1R0_01>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_rst { | ||||
| 			pinmux = <MT7623_PIN_115_MSDC0_RSTB_FUNC_MSDC0_RSTB>; | ||||
| 			bias-pull-up; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	mmc1_pins_default: mmc1default { | ||||
| 		pins_cmd_dat { | ||||
| 			pinmux = <MT7623_PIN_107_MSDC1_DAT0_FUNC_MSDC1_DAT0>, | ||||
| 				 <MT7623_PIN_108_MSDC1_DAT1_FUNC_MSDC1_DAT1>, | ||||
| 				 <MT7623_PIN_109_MSDC1_DAT2_FUNC_MSDC1_DAT2>, | ||||
| 				 <MT7623_PIN_110_MSDC1_DAT3_FUNC_MSDC1_DAT3>, | ||||
| 				 <MT7623_PIN_105_MSDC1_CMD_FUNC_MSDC1_CMD>; | ||||
| 			input-enable; | ||||
| 			drive-strength = <MTK_DRIVE_4mA>; | ||||
| 			bias-pull-up = <MTK_PUPD_SET_R1R0_10>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_clk { | ||||
| 			pinmux = <MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK>; | ||||
| 			bias-pull-down; | ||||
| 			drive-strength = <MTK_DRIVE_4mA>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	mmc1_pins_uhs: mmc1 { | ||||
| 		pins_cmd_dat { | ||||
| 			pinmux = <MT7623_PIN_107_MSDC1_DAT0_FUNC_MSDC1_DAT0>, | ||||
| 				 <MT7623_PIN_108_MSDC1_DAT1_FUNC_MSDC1_DAT1>, | ||||
| 				 <MT7623_PIN_109_MSDC1_DAT2_FUNC_MSDC1_DAT2>, | ||||
| 				 <MT7623_PIN_110_MSDC1_DAT3_FUNC_MSDC1_DAT3>, | ||||
| 				 <MT7623_PIN_105_MSDC1_CMD_FUNC_MSDC1_CMD>; | ||||
| 			input-enable; | ||||
| 			drive-strength = <MTK_DRIVE_4mA>; | ||||
| 			bias-pull-up = <MTK_PUPD_SET_R1R0_10>; | ||||
| 		}; | ||||
|  | ||||
| 		pins_clk { | ||||
| 			pinmux = <MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK>; | ||||
| 			drive-strength = <MTK_DRIVE_4mA>; | ||||
| 			bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	spi0_pins_a: spi@0 { | ||||
| 		pins_spi { | ||||
| 			pinmux = <MT7623_PIN_53_SPI0_CSN_FUNC_SPI0_CS>, | ||||
| 				<MT7623_PIN_54_SPI0_CK_FUNC_SPI0_CK>, | ||||
| 				<MT7623_PIN_55_SPI0_MI_FUNC_SPI0_MI>, | ||||
| 				<MT7623_PIN_56_SPI0_MO_FUNC_SPI0_MO>; | ||||
| 			bias-disable; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	pwm_pins_a: pwm@0 { | ||||
| 		pins_pwm { | ||||
| 			pinmux = <MT7623_PIN_203_PWM0_FUNC_PWM0>, | ||||
| 				 <MT7623_PIN_204_PWM1_FUNC_PWM1>, | ||||
| 				 <MT7623_PIN_205_PWM2_FUNC_PWM2>, | ||||
| 				 <MT7623_PIN_206_PWM3_FUNC_PWM3>, | ||||
| 				 <MT7623_PIN_207_PWM4_FUNC_PWM4>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	uart0_pins_a: uart@0 { | ||||
| 		pins_dat { | ||||
| 			pinmux = <MT7623_PIN_79_URXD0_FUNC_URXD0>, | ||||
| 				 <MT7623_PIN_80_UTXD0_FUNC_UTXD0>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | ||||
| 	uart1_pins_a: uart@1 { | ||||
| 		pins_dat { | ||||
| 			pinmux = <MT7623_PIN_81_URXD1_FUNC_URXD1>, | ||||
| 				 <MT7623_PIN_82_UTXD1_FUNC_UTXD1>; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &pwm { | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&pwm_pins_a>; | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &pwrap { | ||||
| 	mt6323 { | ||||
| 		mt6323led: led { | ||||
| 			compatible = "mediatek,mt6323-led"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
|  | ||||
| 			led@0 { | ||||
| 				reg = <0>; | ||||
| 				label = "bpi-r2:isink:green"; | ||||
| 				default-state = "off"; | ||||
| 			}; | ||||
| 			led@1 { | ||||
| 				reg = <1>; | ||||
| 				label = "bpi-r2:isink:red"; | ||||
| 				default-state = "off"; | ||||
| 			}; | ||||
| 			led@2 { | ||||
| 				reg = <2>; | ||||
| 				label = "bpi-r2:isink:blue"; | ||||
| 				default-state = "off"; | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| &spi0 { | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&spi0_pins_a>; | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &uart0 { | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&uart0_pins_a>; | ||||
| 	status = "disabled"; | ||||
| }; | ||||
|  | ||||
| &u3phy1 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &u3phy2 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &uart1 { | ||||
| 	pinctrl-names = "default"; | ||||
| 	pinctrl-0 = <&uart1_pins_a>; | ||||
| 	status = "disabled"; | ||||
| }; | ||||
|  | ||||
| &uart2 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &usb1 { | ||||
| 	vusb33-supply = <&mt6323_vusb_reg>; | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  | ||||
| &usb2 { | ||||
| 	vusb33-supply = <&mt6323_vusb_reg>; | ||||
| 	status = "okay"; | ||||
| }; | ||||
| @@ -1,168 +0,0 @@ | ||||
| /* | ||||
|  * Driver for Mediatek Hardware Random Number Generator | ||||
|  * | ||||
|  * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.com> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License 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. | ||||
|  */ | ||||
| #define MTK_RNG_DEV KBUILD_MODNAME | ||||
|  | ||||
| #include <linux/clk.h> | ||||
| #include <linux/delay.h> | ||||
| #include <linux/err.h> | ||||
| #include <linux/hw_random.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/iopoll.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/of.h> | ||||
| #include <linux/platform_device.h> | ||||
|  | ||||
| #define USEC_POLL			2 | ||||
| #define TIMEOUT_POLL			20 | ||||
|  | ||||
| #define RNG_CTRL			0x00 | ||||
| #define RNG_EN				BIT(0) | ||||
| #define RNG_READY			BIT(31) | ||||
|  | ||||
| #define RNG_DATA			0x08 | ||||
|  | ||||
| #define to_mtk_rng(p)	container_of(p, struct mtk_rng, rng) | ||||
|  | ||||
| struct mtk_rng { | ||||
| 	void __iomem *base; | ||||
| 	struct clk *clk; | ||||
| 	struct hwrng rng; | ||||
| }; | ||||
|  | ||||
| static int mtk_rng_init(struct hwrng *rng) | ||||
| { | ||||
| 	struct mtk_rng *priv = to_mtk_rng(rng); | ||||
| 	u32 val; | ||||
| 	int err; | ||||
|  | ||||
| 	err = clk_prepare_enable(priv->clk); | ||||
| 	if (err) | ||||
| 		return err; | ||||
|  | ||||
| 	val = readl(priv->base + RNG_CTRL); | ||||
| 	val |= RNG_EN; | ||||
| 	writel(val, priv->base + RNG_CTRL); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void mtk_rng_cleanup(struct hwrng *rng) | ||||
| { | ||||
| 	struct mtk_rng *priv = to_mtk_rng(rng); | ||||
| 	u32 val; | ||||
|  | ||||
| 	val = readl(priv->base + RNG_CTRL); | ||||
| 	val &= ~RNG_EN; | ||||
| 	writel(val, priv->base + RNG_CTRL); | ||||
|  | ||||
| 	clk_disable_unprepare(priv->clk); | ||||
| } | ||||
|  | ||||
| static bool mtk_rng_wait_ready(struct hwrng *rng, bool wait) | ||||
| { | ||||
| 	struct mtk_rng *priv = to_mtk_rng(rng); | ||||
| 	int ready; | ||||
|  | ||||
| 	ready = readl(priv->base + RNG_CTRL) & RNG_READY; | ||||
| 	if (!ready && wait) | ||||
| 		readl_poll_timeout_atomic(priv->base + RNG_CTRL, ready, | ||||
| 					  ready & RNG_READY, USEC_POLL, | ||||
| 					  TIMEOUT_POLL); | ||||
| 	return !!ready; | ||||
| } | ||||
|  | ||||
| static int mtk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) | ||||
| { | ||||
| 	struct mtk_rng *priv = to_mtk_rng(rng); | ||||
| 	int retval = 0; | ||||
|  | ||||
| 	while (max >= sizeof(u32)) { | ||||
| 		if (!mtk_rng_wait_ready(rng, wait)) | ||||
| 			break; | ||||
|  | ||||
| 		*(u32 *)buf = readl(priv->base + RNG_DATA); | ||||
| 		retval += sizeof(u32); | ||||
| 		buf += sizeof(u32); | ||||
| 		max -= sizeof(u32); | ||||
| 	} | ||||
|  | ||||
| 	return retval || !wait ? retval : -EIO; | ||||
| } | ||||
|  | ||||
| static int mtk_rng_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	struct resource *res; | ||||
| 	int ret; | ||||
| 	struct mtk_rng *priv; | ||||
|  | ||||
| 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||||
| 	if (!res) { | ||||
| 		dev_err(&pdev->dev, "no iomem resource\n"); | ||||
| 		return -ENXIO; | ||||
| 	} | ||||
|  | ||||
| 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | ||||
| 	if (!priv) | ||||
| 		return -ENOMEM; | ||||
|  | ||||
| 	priv->rng.name = pdev->name; | ||||
| 	priv->rng.init = mtk_rng_init; | ||||
| 	priv->rng.cleanup = mtk_rng_cleanup; | ||||
| 	priv->rng.read = mtk_rng_read; | ||||
|  | ||||
| 	priv->clk = devm_clk_get(&pdev->dev, "rng"); | ||||
| 	if (IS_ERR(priv->clk)) { | ||||
| 		ret = PTR_ERR(priv->clk); | ||||
| 		dev_err(&pdev->dev, "no clock for device: %d\n", ret); | ||||
| 		return ret; | ||||
| 	} | ||||
|  | ||||
| 	priv->base = devm_ioremap_resource(&pdev->dev, res); | ||||
| 	if (IS_ERR(priv->base)) | ||||
| 		return PTR_ERR(priv->base); | ||||
|  | ||||
| 	ret = devm_hwrng_register(&pdev->dev, &priv->rng); | ||||
| 	if (ret) { | ||||
| 		dev_err(&pdev->dev, "failed to register rng device: %d\n", | ||||
| 			ret); | ||||
| 		return ret; | ||||
| 	} | ||||
|  | ||||
| 	dev_info(&pdev->dev, "registered RNG driver\n"); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static const struct of_device_id mtk_rng_match[] = { | ||||
| 	{ .compatible = "mediatek,mt7623-rng" }, | ||||
| 	{}, | ||||
| }; | ||||
| MODULE_DEVICE_TABLE(of, mtk_rng_match); | ||||
|  | ||||
| static struct platform_driver mtk_rng_driver = { | ||||
| 	.probe          = mtk_rng_probe, | ||||
| 	.driver = { | ||||
| 		.name = MTK_RNG_DEV, | ||||
| 		.of_match_table = mtk_rng_match, | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| module_platform_driver(mtk_rng_driver); | ||||
|  | ||||
| MODULE_DESCRIPTION("Mediatek Random Number Generator Driver"); | ||||
| MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); | ||||
| MODULE_LICENSE("GPL"); | ||||
| @@ -1,2 +0,0 @@ | ||||
| obj-$(CONFIG_CRYPTO_DEV_MEDIATEK) += mtk-crypto.o | ||||
| mtk-crypto-objs:= mtk-platform.o mtk-aes.o mtk-sha.o | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,607 +0,0 @@ | ||||
| /* | ||||
|  * Driver for EIP97 cryptographic accelerator. | ||||
|  * | ||||
|  * Copyright (c) 2016 Ryder Lee <ryder.lee@mediatek.com> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <linux/clk.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/pm_runtime.h> | ||||
| #include "mtk-platform.h" | ||||
|  | ||||
| #define MTK_BURST_SIZE_MSK		GENMASK(7, 4) | ||||
| #define MTK_BURST_SIZE(x)		((x) << 4) | ||||
| #define MTK_DESC_SIZE(x)		((x) << 0) | ||||
| #define MTK_DESC_OFFSET(x)		((x) << 16) | ||||
| #define MTK_DESC_FETCH_SIZE(x)		((x) << 0) | ||||
| #define MTK_DESC_FETCH_THRESH(x)	((x) << 16) | ||||
| #define MTK_DESC_OVL_IRQ_EN		BIT(25) | ||||
| #define MTK_DESC_ATP_PRESENT		BIT(30) | ||||
|  | ||||
| #define MTK_DFSE_IDLE			GENMASK(3, 0) | ||||
| #define MTK_DFSE_THR_CTRL_EN		BIT(30) | ||||
| #define MTK_DFSE_THR_CTRL_RESET		BIT(31) | ||||
| #define MTK_DFSE_RING_ID(x)		(((x) >> 12) & GENMASK(3, 0)) | ||||
| #define MTK_DFSE_MIN_DATA(x)		((x) << 0) | ||||
| #define MTK_DFSE_MAX_DATA(x)		((x) << 8) | ||||
| #define MTK_DFE_MIN_CTRL(x)		((x) << 16) | ||||
| #define MTK_DFE_MAX_CTRL(x)		((x) << 24) | ||||
|  | ||||
| #define MTK_IN_BUF_MIN_THRESH(x)	((x) << 8) | ||||
| #define MTK_IN_BUF_MAX_THRESH(x)	((x) << 12) | ||||
| #define MTK_OUT_BUF_MIN_THRESH(x)	((x) << 0) | ||||
| #define MTK_OUT_BUF_MAX_THRESH(x)	((x) << 4) | ||||
| #define MTK_IN_TBUF_SIZE(x)		(((x) >> 4) & GENMASK(3, 0)) | ||||
| #define MTK_IN_DBUF_SIZE(x)		(((x) >> 8) & GENMASK(3, 0)) | ||||
| #define MTK_OUT_DBUF_SIZE(x)		(((x) >> 16) & GENMASK(3, 0)) | ||||
| #define MTK_CMD_FIFO_SIZE(x)		(((x) >> 8) & GENMASK(3, 0)) | ||||
| #define MTK_RES_FIFO_SIZE(x)		(((x) >> 12) & GENMASK(3, 0)) | ||||
|  | ||||
| #define MTK_PE_TK_LOC_AVL		BIT(2) | ||||
| #define MTK_PE_PROC_HELD		BIT(14) | ||||
| #define MTK_PE_TK_TIMEOUT_EN		BIT(22) | ||||
| #define MTK_PE_INPUT_DMA_ERR		BIT(0) | ||||
| #define MTK_PE_OUTPUT_DMA_ERR		BIT(1) | ||||
| #define MTK_PE_PKT_PORC_ERR		BIT(2) | ||||
| #define MTK_PE_PKT_TIMEOUT		BIT(3) | ||||
| #define MTK_PE_FATAL_ERR		BIT(14) | ||||
| #define MTK_PE_INPUT_DMA_ERR_EN		BIT(16) | ||||
| #define MTK_PE_OUTPUT_DMA_ERR_EN	BIT(17) | ||||
| #define MTK_PE_PKT_PORC_ERR_EN		BIT(18) | ||||
| #define MTK_PE_PKT_TIMEOUT_EN		BIT(19) | ||||
| #define MTK_PE_FATAL_ERR_EN		BIT(30) | ||||
| #define MTK_PE_INT_OUT_EN		BIT(31) | ||||
|  | ||||
| #define MTK_HIA_SIGNATURE		((u16)0x35ca) | ||||
| #define MTK_HIA_DATA_WIDTH(x)		(((x) >> 25) & GENMASK(1, 0)) | ||||
| #define MTK_HIA_DMA_LENGTH(x)		(((x) >> 20) & GENMASK(4, 0)) | ||||
| #define MTK_CDR_STAT_CLR		GENMASK(4, 0) | ||||
| #define MTK_RDR_STAT_CLR		GENMASK(7, 0) | ||||
|  | ||||
| #define MTK_AIC_INT_MSK			GENMASK(5, 0) | ||||
| #define MTK_AIC_VER_MSK			(GENMASK(15, 0) | GENMASK(27, 20)) | ||||
| #define MTK_AIC_VER11			0x011036c9 | ||||
| #define MTK_AIC_VER12			0x012036c9 | ||||
| #define MTK_AIC_G_CLR			GENMASK(30, 20) | ||||
|  | ||||
| /** | ||||
|  * EIP97 is an integrated security subsystem to accelerate cryptographic | ||||
|  * functions and protocols to offload the host processor. | ||||
|  * Some important hardware modules are briefly introduced below: | ||||
|  * | ||||
|  * Host Interface Adapter(HIA) - the main interface between the host | ||||
|  * system and the hardware subsystem. It is responsible for attaching | ||||
|  * processing engine to the specific host bus interface and provides a | ||||
|  * standardized software view for off loading tasks to the engine. | ||||
|  * | ||||
|  * Command Descriptor Ring Manager(CDR Manager) - keeps track of how many | ||||
|  * CD the host has prepared in the CDR. It monitors the fill level of its | ||||
|  * CD-FIFO and if there's sufficient space for the next block of descriptors, | ||||
|  * then it fires off a DMA request to fetch a block of CDs. | ||||
|  * | ||||
|  * Data fetch engine(DFE) - It is responsible for parsing the CD and | ||||
|  * setting up the required control and packet data DMA transfers from | ||||
|  * system memory to the processing engine. | ||||
|  * | ||||
|  * Result Descriptor Ring Manager(RDR Manager) - same as CDR Manager, | ||||
|  * but target is result descriptors, Moreover, it also handles the RD | ||||
|  * updates under control of the DSE. For each packet data segment | ||||
|  * processed, the DSE triggers the RDR Manager to write the updated RD. | ||||
|  * If triggered to update, the RDR Manager sets up a DMA operation to | ||||
|  * copy the RD from the DSE to the correct location in the RDR. | ||||
|  * | ||||
|  * Data Store Engine(DSE) - It is responsible for parsing the prepared RD | ||||
|  * and setting up the required control and packet data DMA transfers from | ||||
|  * the processing engine to system memory. | ||||
|  * | ||||
|  * Advanced Interrupt Controllers(AICs) - receive interrupt request signals | ||||
|  * from various sources and combine them into one interrupt output. | ||||
|  * The AICs are used by: | ||||
|  * - One for the HIA global and processing engine interrupts. | ||||
|  * - The others for the descriptor ring interrupts. | ||||
|  */ | ||||
|  | ||||
| /* Cryptographic engine capabilities */ | ||||
| struct mtk_sys_cap { | ||||
| 	/* host interface adapter */ | ||||
| 	u32 hia_ver; | ||||
| 	u32 hia_opt; | ||||
| 	/* packet engine */ | ||||
| 	u32 pkt_eng_opt; | ||||
| 	/* global hardware */ | ||||
| 	u32 hw_opt; | ||||
| }; | ||||
|  | ||||
| static void mtk_desc_ring_link(struct mtk_cryp *cryp, u32 mask) | ||||
| { | ||||
| 	/* Assign rings to DFE/DSE thread and enable it */ | ||||
| 	writel(MTK_DFSE_THR_CTRL_EN | mask, cryp->base + DFE_THR_CTRL); | ||||
| 	writel(MTK_DFSE_THR_CTRL_EN | mask, cryp->base + DSE_THR_CTRL); | ||||
| } | ||||
|  | ||||
| static void mtk_dfe_dse_buf_setup(struct mtk_cryp *cryp, | ||||
| 				  struct mtk_sys_cap *cap) | ||||
| { | ||||
| 	u32 width = MTK_HIA_DATA_WIDTH(cap->hia_opt) + 2; | ||||
| 	u32 len = MTK_HIA_DMA_LENGTH(cap->hia_opt) - 1; | ||||
| 	u32 ipbuf = min((u32)MTK_IN_DBUF_SIZE(cap->hw_opt) + width, len); | ||||
| 	u32 opbuf = min((u32)MTK_OUT_DBUF_SIZE(cap->hw_opt) + width, len); | ||||
| 	u32 itbuf = min((u32)MTK_IN_TBUF_SIZE(cap->hw_opt) + width, len); | ||||
|  | ||||
| 	writel(MTK_DFSE_MIN_DATA(ipbuf - 1) | | ||||
| 	       MTK_DFSE_MAX_DATA(ipbuf) | | ||||
| 	       MTK_DFE_MIN_CTRL(itbuf - 1) | | ||||
| 	       MTK_DFE_MAX_CTRL(itbuf), | ||||
| 	       cryp->base + DFE_CFG); | ||||
|  | ||||
| 	writel(MTK_DFSE_MIN_DATA(opbuf - 1) | | ||||
| 	       MTK_DFSE_MAX_DATA(opbuf), | ||||
| 	       cryp->base + DSE_CFG); | ||||
|  | ||||
| 	writel(MTK_IN_BUF_MIN_THRESH(ipbuf - 1) | | ||||
| 	       MTK_IN_BUF_MAX_THRESH(ipbuf), | ||||
| 	       cryp->base + PE_IN_DBUF_THRESH); | ||||
|  | ||||
| 	writel(MTK_IN_BUF_MIN_THRESH(itbuf - 1) | | ||||
| 	       MTK_IN_BUF_MAX_THRESH(itbuf), | ||||
| 	       cryp->base + PE_IN_TBUF_THRESH); | ||||
|  | ||||
| 	writel(MTK_OUT_BUF_MIN_THRESH(opbuf - 1) | | ||||
| 	       MTK_OUT_BUF_MAX_THRESH(opbuf), | ||||
| 	       cryp->base + PE_OUT_DBUF_THRESH); | ||||
|  | ||||
| 	writel(0, cryp->base + PE_OUT_TBUF_THRESH); | ||||
| 	writel(0, cryp->base + PE_OUT_BUF_CTRL); | ||||
| } | ||||
|  | ||||
| static int mtk_dfe_dse_state_check(struct mtk_cryp *cryp) | ||||
| { | ||||
| 	int ret = -EINVAL; | ||||
| 	u32 val; | ||||
|  | ||||
| 	/* Check for completion of all DMA transfers */ | ||||
| 	val = readl(cryp->base + DFE_THR_STAT); | ||||
| 	if (MTK_DFSE_RING_ID(val) == MTK_DFSE_IDLE) { | ||||
| 		val = readl(cryp->base + DSE_THR_STAT); | ||||
| 		if (MTK_DFSE_RING_ID(val) == MTK_DFSE_IDLE) | ||||
| 			ret = 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!ret) { | ||||
| 		/* Take DFE/DSE thread out of reset */ | ||||
| 		writel(0, cryp->base + DFE_THR_CTRL); | ||||
| 		writel(0, cryp->base + DSE_THR_CTRL); | ||||
| 	} else { | ||||
| 		return -EBUSY; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int mtk_dfe_dse_reset(struct mtk_cryp *cryp) | ||||
| { | ||||
| 	int err; | ||||
|  | ||||
| 	/* Reset DSE/DFE and correct system priorities for all rings. */ | ||||
| 	writel(MTK_DFSE_THR_CTRL_RESET, cryp->base + DFE_THR_CTRL); | ||||
| 	writel(0, cryp->base + DFE_PRIO_0); | ||||
| 	writel(0, cryp->base + DFE_PRIO_1); | ||||
| 	writel(0, cryp->base + DFE_PRIO_2); | ||||
| 	writel(0, cryp->base + DFE_PRIO_3); | ||||
|  | ||||
| 	writel(MTK_DFSE_THR_CTRL_RESET, cryp->base + DSE_THR_CTRL); | ||||
| 	writel(0, cryp->base + DSE_PRIO_0); | ||||
| 	writel(0, cryp->base + DSE_PRIO_1); | ||||
| 	writel(0, cryp->base + DSE_PRIO_2); | ||||
| 	writel(0, cryp->base + DSE_PRIO_3); | ||||
|  | ||||
| 	err = mtk_dfe_dse_state_check(cryp); | ||||
| 	if (err) | ||||
| 		return err; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void mtk_cmd_desc_ring_setup(struct mtk_cryp *cryp, | ||||
| 				    int i, struct mtk_sys_cap *cap) | ||||
| { | ||||
| 	/* Full descriptor that fits FIFO minus one */ | ||||
| 	u32 count = | ||||
| 		((1 << MTK_CMD_FIFO_SIZE(cap->hia_opt)) / MTK_DESC_SZ) - 1; | ||||
|  | ||||
| 	/* Temporarily disable external triggering */ | ||||
| 	writel(0, cryp->base + CDR_CFG(i)); | ||||
|  | ||||
| 	/* Clear CDR count */ | ||||
| 	writel(MTK_CNT_RST, cryp->base + CDR_PREP_COUNT(i)); | ||||
| 	writel(MTK_CNT_RST, cryp->base + CDR_PROC_COUNT(i)); | ||||
|  | ||||
| 	writel(0, cryp->base + CDR_PREP_PNTR(i)); | ||||
| 	writel(0, cryp->base + CDR_PROC_PNTR(i)); | ||||
| 	writel(0, cryp->base + CDR_DMA_CFG(i)); | ||||
|  | ||||
| 	/* Configure CDR host address space */ | ||||
| 	writel(0, cryp->base + CDR_BASE_ADDR_HI(i)); | ||||
| 	writel(cryp->ring[i]->cmd_dma, cryp->base + CDR_BASE_ADDR_LO(i)); | ||||
|  | ||||
| 	writel(MTK_DESC_RING_SZ, cryp->base + CDR_RING_SIZE(i)); | ||||
|  | ||||
| 	/* Clear and disable all CDR interrupts */ | ||||
| 	writel(MTK_CDR_STAT_CLR, cryp->base + CDR_STAT(i)); | ||||
|  | ||||
| 	/* | ||||
| 	 * Set command descriptor offset and enable additional | ||||
| 	 * token present in descriptor. | ||||
| 	 */ | ||||
| 	writel(MTK_DESC_SIZE(MTK_DESC_SZ) | | ||||
| 		   MTK_DESC_OFFSET(MTK_DESC_OFF) | | ||||
| 	       MTK_DESC_ATP_PRESENT, | ||||
| 	       cryp->base + CDR_DESC_SIZE(i)); | ||||
|  | ||||
| 	writel(MTK_DESC_FETCH_SIZE(count * MTK_DESC_OFF) | | ||||
| 		   MTK_DESC_FETCH_THRESH(count * MTK_DESC_SZ), | ||||
| 		   cryp->base + CDR_CFG(i)); | ||||
| } | ||||
|  | ||||
| static void mtk_res_desc_ring_setup(struct mtk_cryp *cryp, | ||||
| 				    int i, struct mtk_sys_cap *cap) | ||||
| { | ||||
| 	u32 rndup = 2; | ||||
| 	u32 count = ((1 << MTK_RES_FIFO_SIZE(cap->hia_opt)) / rndup) - 1; | ||||
|  | ||||
| 	/* Temporarily disable external triggering */ | ||||
| 	writel(0, cryp->base + RDR_CFG(i)); | ||||
|  | ||||
| 	/* Clear RDR count */ | ||||
| 	writel(MTK_CNT_RST, cryp->base + RDR_PREP_COUNT(i)); | ||||
| 	writel(MTK_CNT_RST, cryp->base + RDR_PROC_COUNT(i)); | ||||
|  | ||||
| 	writel(0, cryp->base + RDR_PREP_PNTR(i)); | ||||
| 	writel(0, cryp->base + RDR_PROC_PNTR(i)); | ||||
| 	writel(0, cryp->base + RDR_DMA_CFG(i)); | ||||
|  | ||||
| 	/* Configure RDR host address space */ | ||||
| 	writel(0, cryp->base + RDR_BASE_ADDR_HI(i)); | ||||
| 	writel(cryp->ring[i]->res_dma, cryp->base + RDR_BASE_ADDR_LO(i)); | ||||
|  | ||||
| 	writel(MTK_DESC_RING_SZ, cryp->base + RDR_RING_SIZE(i)); | ||||
| 	writel(MTK_RDR_STAT_CLR, cryp->base + RDR_STAT(i)); | ||||
|  | ||||
| 	/* | ||||
| 	 * RDR manager generates update interrupts on a per-completed-packet, | ||||
| 	 * and the rd_proc_thresh_irq interrupt is fired when proc_pkt_count | ||||
| 	 * for the RDR exceeds the number of packets. | ||||
| 	 */ | ||||
| 	writel(MTK_RDR_PROC_THRESH | MTK_RDR_PROC_MODE, | ||||
| 	       cryp->base + RDR_THRESH(i)); | ||||
|  | ||||
| 	/* | ||||
| 	 * Configure a threshold and time-out value for the processed | ||||
| 	 * result descriptors (or complete packets) that are written to | ||||
| 	 * the RDR. | ||||
| 	 */ | ||||
| 	writel(MTK_DESC_SIZE(MTK_DESC_SZ) | MTK_DESC_OFFSET(MTK_DESC_OFF), | ||||
| 	       cryp->base + RDR_DESC_SIZE(i)); | ||||
|  | ||||
| 	/* | ||||
| 	 * Configure HIA fetch size and fetch threshold that are used to | ||||
| 	 * fetch blocks of multiple descriptors. | ||||
| 	 */ | ||||
| 	writel(MTK_DESC_FETCH_SIZE(count * MTK_DESC_OFF) | | ||||
| 	       MTK_DESC_FETCH_THRESH(count * rndup) | | ||||
| 	       MTK_DESC_OVL_IRQ_EN, | ||||
| 		   cryp->base + RDR_CFG(i)); | ||||
| } | ||||
|  | ||||
| static int mtk_packet_engine_setup(struct mtk_cryp *cryp) | ||||
| { | ||||
| 	struct mtk_sys_cap cap; | ||||
| 	int i, err; | ||||
| 	u32 val; | ||||
|  | ||||
| 	cap.hia_ver = readl(cryp->base + HIA_VERSION); | ||||
| 	cap.hia_opt = readl(cryp->base + HIA_OPTIONS); | ||||
| 	cap.hw_opt = readl(cryp->base + EIP97_OPTIONS); | ||||
|  | ||||
| 	if (!(((u16)cap.hia_ver) == MTK_HIA_SIGNATURE)) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	/* Configure endianness conversion method for master (DMA) interface */ | ||||
| 	writel(0, cryp->base + EIP97_MST_CTRL); | ||||
|  | ||||
| 	/* Set HIA burst size */ | ||||
| 	val = readl(cryp->base + HIA_MST_CTRL); | ||||
| 	val &= ~MTK_BURST_SIZE_MSK; | ||||
| 	val |= MTK_BURST_SIZE(5); | ||||
| 	writel(val, cryp->base + HIA_MST_CTRL); | ||||
|  | ||||
| 	err = mtk_dfe_dse_reset(cryp); | ||||
| 	if (err) { | ||||
| 		dev_err(cryp->dev, "Failed to reset DFE and DSE.\n"); | ||||
| 		return err; | ||||
| 	} | ||||
|  | ||||
| 	mtk_dfe_dse_buf_setup(cryp, &cap); | ||||
|  | ||||
| 	/* Enable the 4 rings for the packet engines. */ | ||||
| 	mtk_desc_ring_link(cryp, 0xf); | ||||
|  | ||||
| 	for (i = 0; i < MTK_RING_MAX; i++) { | ||||
| 		mtk_cmd_desc_ring_setup(cryp, i, &cap); | ||||
| 		mtk_res_desc_ring_setup(cryp, i, &cap); | ||||
| 	} | ||||
|  | ||||
| 	writel(MTK_PE_TK_LOC_AVL | MTK_PE_PROC_HELD | MTK_PE_TK_TIMEOUT_EN, | ||||
| 	       cryp->base + PE_TOKEN_CTRL_STAT); | ||||
|  | ||||
| 	/* Clear all pending interrupts */ | ||||
| 	writel(MTK_AIC_G_CLR, cryp->base + AIC_G_ACK); | ||||
| 	writel(MTK_PE_INPUT_DMA_ERR | MTK_PE_OUTPUT_DMA_ERR | | ||||
| 	       MTK_PE_PKT_PORC_ERR | MTK_PE_PKT_TIMEOUT | | ||||
| 	       MTK_PE_FATAL_ERR | MTK_PE_INPUT_DMA_ERR_EN | | ||||
| 	       MTK_PE_OUTPUT_DMA_ERR_EN | MTK_PE_PKT_PORC_ERR_EN | | ||||
| 	       MTK_PE_PKT_TIMEOUT_EN | MTK_PE_FATAL_ERR_EN | | ||||
| 	       MTK_PE_INT_OUT_EN, | ||||
| 	       cryp->base + PE_INTERRUPT_CTRL_STAT); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int mtk_aic_cap_check(struct mtk_cryp *cryp, int hw) | ||||
| { | ||||
| 	u32 val; | ||||
|  | ||||
| 	if (hw == MTK_RING_MAX) | ||||
| 		val = readl(cryp->base + AIC_G_VERSION); | ||||
| 	else | ||||
| 		val = readl(cryp->base + AIC_VERSION(hw)); | ||||
|  | ||||
| 	val &= MTK_AIC_VER_MSK; | ||||
| 	if (val != MTK_AIC_VER11 && val != MTK_AIC_VER12) | ||||
| 		return -ENXIO; | ||||
|  | ||||
| 	if (hw == MTK_RING_MAX) | ||||
| 		val = readl(cryp->base + AIC_G_OPTIONS); | ||||
| 	else | ||||
| 		val = readl(cryp->base + AIC_OPTIONS(hw)); | ||||
|  | ||||
| 	val &= MTK_AIC_INT_MSK; | ||||
| 	if (!val || val > 32) | ||||
| 		return -ENXIO; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int mtk_aic_init(struct mtk_cryp *cryp, int hw) | ||||
| { | ||||
| 	int err; | ||||
|  | ||||
| 	err = mtk_aic_cap_check(cryp, hw); | ||||
| 	if (err) | ||||
| 		return err; | ||||
|  | ||||
| 	/* Disable all interrupts and set initial configuration */ | ||||
| 	if (hw == MTK_RING_MAX) { | ||||
| 		writel(0, cryp->base + AIC_G_ENABLE_CTRL); | ||||
| 		writel(0, cryp->base + AIC_G_POL_CTRL); | ||||
| 		writel(0, cryp->base + AIC_G_TYPE_CTRL); | ||||
| 		writel(0, cryp->base + AIC_G_ENABLE_SET); | ||||
| 	} else { | ||||
| 		writel(0, cryp->base + AIC_ENABLE_CTRL(hw)); | ||||
| 		writel(0, cryp->base + AIC_POL_CTRL(hw)); | ||||
| 		writel(0, cryp->base + AIC_TYPE_CTRL(hw)); | ||||
| 		writel(0, cryp->base + AIC_ENABLE_SET(hw)); | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int mtk_accelerator_init(struct mtk_cryp *cryp) | ||||
| { | ||||
| 	int i, err; | ||||
|  | ||||
| 	/* Initialize advanced interrupt controller(AIC) */ | ||||
| 	for (i = 0; i < MTK_IRQ_NUM; i++) { | ||||
| 		err = mtk_aic_init(cryp, i); | ||||
| 		if (err) { | ||||
| 			dev_err(cryp->dev, "Failed to initialize AIC.\n"); | ||||
| 			return err; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* Initialize packet engine */ | ||||
| 	err = mtk_packet_engine_setup(cryp); | ||||
| 	if (err) { | ||||
| 		dev_err(cryp->dev, "Failed to configure packet engine.\n"); | ||||
| 		return err; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void mtk_desc_dma_free(struct mtk_cryp *cryp) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
| 	for (i = 0; i < MTK_RING_MAX; i++) { | ||||
| 		dma_free_coherent(cryp->dev, MTK_DESC_RING_SZ, | ||||
| 				  cryp->ring[i]->res_base, | ||||
| 				  cryp->ring[i]->res_dma); | ||||
| 		dma_free_coherent(cryp->dev, MTK_DESC_RING_SZ, | ||||
| 				  cryp->ring[i]->cmd_base, | ||||
| 				  cryp->ring[i]->cmd_dma); | ||||
| 		kfree(cryp->ring[i]); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static int mtk_desc_ring_alloc(struct mtk_cryp *cryp) | ||||
| { | ||||
| 	struct mtk_ring **ring = cryp->ring; | ||||
| 	int i, err = ENOMEM; | ||||
|  | ||||
| 	for (i = 0; i < MTK_RING_MAX; i++) { | ||||
| 		ring[i] = kzalloc(sizeof(**ring), GFP_KERNEL); | ||||
| 		if (!ring[i]) | ||||
| 			goto err_cleanup; | ||||
|  | ||||
| 		ring[i]->cmd_base = dma_zalloc_coherent(cryp->dev, | ||||
| 					   MTK_DESC_RING_SZ, | ||||
| 					   &ring[i]->cmd_dma, | ||||
| 					   GFP_KERNEL); | ||||
| 		if (!ring[i]->cmd_base) | ||||
| 			goto err_cleanup; | ||||
|  | ||||
| 		ring[i]->res_base = dma_zalloc_coherent(cryp->dev, | ||||
| 					   MTK_DESC_RING_SZ, | ||||
| 					   &ring[i]->res_dma, | ||||
| 					   GFP_KERNEL); | ||||
| 		if (!ring[i]->res_base) | ||||
| 			goto err_cleanup; | ||||
|  | ||||
| 		ring[i]->cmd_next = ring[i]->cmd_base; | ||||
| 		ring[i]->res_next = ring[i]->res_base; | ||||
| 	} | ||||
| 	return 0; | ||||
|  | ||||
| err_cleanup: | ||||
| 	for (; i--; ) { | ||||
| 		dma_free_coherent(cryp->dev, MTK_DESC_RING_SZ, | ||||
| 				  ring[i]->res_base, ring[i]->res_dma); | ||||
| 		dma_free_coherent(cryp->dev, MTK_DESC_RING_SZ, | ||||
| 				  ring[i]->cmd_base, ring[i]->cmd_dma); | ||||
| 		kfree(ring[i]); | ||||
| 	} | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
| static int mtk_crypto_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||||
| 	struct mtk_cryp *cryp; | ||||
| 	int i, err; | ||||
|  | ||||
| 	cryp = devm_kzalloc(&pdev->dev, sizeof(*cryp), GFP_KERNEL); | ||||
| 	if (!cryp) | ||||
| 		return -ENOMEM; | ||||
|  | ||||
| 	cryp->base = devm_ioremap_resource(&pdev->dev, res); | ||||
| 	if (IS_ERR(cryp->base)) | ||||
| 		return PTR_ERR(cryp->base); | ||||
|  | ||||
| 	for (i = 0; i < MTK_IRQ_NUM; i++) { | ||||
| 		cryp->irq[i] = platform_get_irq(pdev, i); | ||||
| 		if (cryp->irq[i] < 0) { | ||||
| 			dev_err(cryp->dev, "no IRQ:%d resource info\n", i); | ||||
| 			return -ENXIO; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	cryp->clk_ethif = devm_clk_get(&pdev->dev, "ethif"); | ||||
| 	cryp->clk_cryp = devm_clk_get(&pdev->dev, "cryp"); | ||||
| 	if (IS_ERR(cryp->clk_ethif) || IS_ERR(cryp->clk_cryp)) | ||||
| 		return -EPROBE_DEFER; | ||||
|  | ||||
| 	cryp->dev = &pdev->dev; | ||||
| 	pm_runtime_enable(cryp->dev); | ||||
| 	pm_runtime_get_sync(cryp->dev); | ||||
|  | ||||
| 	err = clk_prepare_enable(cryp->clk_ethif); | ||||
| 	if (err) | ||||
| 		goto err_clk_ethif; | ||||
|  | ||||
| 	err = clk_prepare_enable(cryp->clk_cryp); | ||||
| 	if (err) | ||||
| 		goto err_clk_cryp; | ||||
|  | ||||
| 	/* Allocate four command/result descriptor rings */ | ||||
| 	err = mtk_desc_ring_alloc(cryp); | ||||
| 	if (err) { | ||||
| 		dev_err(cryp->dev, "Unable to allocate descriptor rings.\n"); | ||||
| 		goto err_resource; | ||||
| 	} | ||||
|  | ||||
| 	/* Initialize hardware modules */ | ||||
| 	err = mtk_accelerator_init(cryp); | ||||
| 	if (err) { | ||||
| 		dev_err(cryp->dev, "Failed to initialize cryptographic engine.\n"); | ||||
| 		goto err_engine; | ||||
| 	} | ||||
|  | ||||
| 	err = mtk_cipher_alg_register(cryp); | ||||
| 	if (err) { | ||||
| 		dev_err(cryp->dev, "Unable to register cipher algorithm.\n"); | ||||
| 		goto err_cipher; | ||||
| 	} | ||||
|  | ||||
| 	err = mtk_hash_alg_register(cryp); | ||||
| 	if (err) { | ||||
| 		dev_err(cryp->dev, "Unable to register hash algorithm.\n"); | ||||
| 		goto err_hash; | ||||
| 	} | ||||
|  | ||||
| 	platform_set_drvdata(pdev, cryp); | ||||
| 	return 0; | ||||
|  | ||||
| err_hash: | ||||
| 	mtk_cipher_alg_release(cryp); | ||||
| err_cipher: | ||||
| 	mtk_dfe_dse_reset(cryp); | ||||
| err_engine: | ||||
| 	mtk_desc_dma_free(cryp); | ||||
| err_resource: | ||||
| 	clk_disable_unprepare(cryp->clk_cryp); | ||||
| err_clk_cryp: | ||||
| 	clk_disable_unprepare(cryp->clk_ethif); | ||||
| err_clk_ethif: | ||||
| 	pm_runtime_put_sync(cryp->dev); | ||||
| 	pm_runtime_disable(cryp->dev); | ||||
|  | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
| static int mtk_crypto_remove(struct platform_device *pdev) | ||||
| { | ||||
| 	struct mtk_cryp *cryp = platform_get_drvdata(pdev); | ||||
|  | ||||
| 	mtk_hash_alg_release(cryp); | ||||
| 	mtk_cipher_alg_release(cryp); | ||||
| 	mtk_desc_dma_free(cryp); | ||||
|  | ||||
| 	clk_disable_unprepare(cryp->clk_cryp); | ||||
| 	clk_disable_unprepare(cryp->clk_ethif); | ||||
|  | ||||
| 	pm_runtime_put_sync(cryp->dev); | ||||
| 	pm_runtime_disable(cryp->dev); | ||||
| 	platform_set_drvdata(pdev, NULL); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static const struct of_device_id of_crypto_id[] = { | ||||
| 	{ .compatible = "mediatek,eip97-crypto" }, | ||||
| 	{}, | ||||
| }; | ||||
| MODULE_DEVICE_TABLE(of, of_crypto_id); | ||||
|  | ||||
| static struct platform_driver mtk_crypto_driver = { | ||||
| 	.probe = mtk_crypto_probe, | ||||
| 	.remove = mtk_crypto_remove, | ||||
| 	.driver = { | ||||
| 		   .name = "mtk-crypto", | ||||
| 		   .owner = THIS_MODULE, | ||||
| 		   .of_match_table = of_crypto_id, | ||||
| 	}, | ||||
| }; | ||||
| module_platform_driver(mtk_crypto_driver); | ||||
|  | ||||
| MODULE_LICENSE("GPL"); | ||||
| MODULE_AUTHOR("Ryder Lee <ryder.lee@mediatek.com>"); | ||||
| MODULE_DESCRIPTION("Cryptographic accelerator driver for EIP97"); | ||||
| @@ -1,237 +0,0 @@ | ||||
| /* | ||||
|  * Driver for EIP97 cryptographic accelerator. | ||||
|  * | ||||
|  * Copyright (c) 2016 Ryder Lee <ryder.lee@mediatek.com> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #ifndef __MTK_PLATFORM_H_ | ||||
| #define __MTK_PLATFORM_H_ | ||||
|  | ||||
| #include <crypto/algapi.h> | ||||
| #include <crypto/internal/aead.h> | ||||
| #include <crypto/internal/hash.h> | ||||
| #include <crypto/scatterwalk.h> | ||||
| #include <crypto/skcipher.h> | ||||
| #include <linux/crypto.h> | ||||
| #include <linux/dma-mapping.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <linux/scatterlist.h> | ||||
| #include "mtk-regs.h" | ||||
|  | ||||
| #define MTK_RDR_PROC_THRESH	BIT(0) | ||||
| #define MTK_RDR_PROC_MODE	BIT(23) | ||||
| #define MTK_CNT_RST		BIT(31) | ||||
| #define MTK_IRQ_RDR0		BIT(1) | ||||
| #define MTK_IRQ_RDR1		BIT(3) | ||||
| #define MTK_IRQ_RDR2		BIT(5) | ||||
| #define MTK_IRQ_RDR3		BIT(7) | ||||
|  | ||||
| #define SIZE_IN_WORDS(x)	((x) >> 2) | ||||
|  | ||||
| /** | ||||
|  * Ring 0/1 are used by AES encrypt and decrypt. | ||||
|  * Ring 2/3 are used by SHA. | ||||
|  */ | ||||
| enum { | ||||
| 	MTK_RING0, | ||||
| 	MTK_RING1, | ||||
| 	MTK_RING2, | ||||
| 	MTK_RING3, | ||||
| 	MTK_RING_MAX | ||||
| }; | ||||
|  | ||||
| #define MTK_REC_NUM		(MTK_RING_MAX / 2) | ||||
| #define MTK_IRQ_NUM		5 | ||||
|  | ||||
| /** | ||||
|  * struct mtk_desc - DMA descriptor | ||||
|  * @hdr:	the descriptor control header | ||||
|  * @buf:	DMA address of input buffer segment | ||||
|  * @ct:		DMA address of command token that control operation flow | ||||
|  * @ct_hdr:	the command token control header | ||||
|  * @tag:	the user-defined field | ||||
|  * @tfm:	DMA address of transform state | ||||
|  * @bound:	align descriptors offset boundary | ||||
|  * | ||||
|  * Structure passed to the crypto engine to describe where source | ||||
|  * data needs to be fetched and how it needs to be processed. | ||||
|  */ | ||||
| struct mtk_desc { | ||||
| 	__le32 hdr; | ||||
| 	__le32 buf; | ||||
| 	__le32 ct; | ||||
| 	__le32 ct_hdr; | ||||
| 	__le32 tag; | ||||
| 	__le32 tfm; | ||||
| 	__le32 bound[2]; | ||||
| }; | ||||
|  | ||||
| #define MTK_DESC_NUM		512 | ||||
| #define MTK_DESC_OFF		SIZE_IN_WORDS(sizeof(struct mtk_desc)) | ||||
| #define MTK_DESC_SZ		(MTK_DESC_OFF - 2) | ||||
| #define MTK_DESC_RING_SZ	((sizeof(struct mtk_desc) * MTK_DESC_NUM)) | ||||
| #define MTK_DESC_CNT(x)		((MTK_DESC_OFF * (x)) << 2) | ||||
| #define MTK_DESC_LAST		cpu_to_le32(BIT(22)) | ||||
| #define MTK_DESC_FIRST		cpu_to_le32(BIT(23)) | ||||
| #define MTK_DESC_BUF_LEN(x)	cpu_to_le32(x) | ||||
| #define MTK_DESC_CT_LEN(x)	cpu_to_le32((x) << 24) | ||||
|  | ||||
| /** | ||||
|  * struct mtk_ring - Descriptor ring | ||||
|  * @cmd_base:	pointer to command descriptor ring base | ||||
|  * @cmd_next:	pointer to the next command descriptor | ||||
|  * @cmd_dma:	DMA address of command descriptor ring | ||||
|  * @res_base:	pointer to result descriptor ring base | ||||
|  * @res_next:	pointer to the next result descriptor | ||||
|  * @res_prev:	pointer to the previous result descriptor | ||||
|  * @res_dma:	DMA address of result descriptor ring | ||||
|  * | ||||
|  * A descriptor ring is a circular buffer that is used to manage | ||||
|  * one or more descriptors. There are two type of descriptor rings; | ||||
|  * the command descriptor ring and result descriptor ring. | ||||
|  */ | ||||
| struct mtk_ring { | ||||
| 	struct mtk_desc *cmd_base; | ||||
| 	struct mtk_desc *cmd_next; | ||||
| 	dma_addr_t cmd_dma; | ||||
| 	struct mtk_desc *res_base; | ||||
| 	struct mtk_desc *res_next; | ||||
| 	struct mtk_desc *res_prev; | ||||
| 	dma_addr_t res_dma; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * struct mtk_aes_dma - Structure that holds sg list info | ||||
|  * @sg:		pointer to scatter-gather list | ||||
|  * @nents:	number of entries in the sg list | ||||
|  * @remainder:	remainder of sg list | ||||
|  * @sg_len:	number of entries in the sg mapped list | ||||
|  */ | ||||
| struct mtk_aes_dma { | ||||
| 	struct scatterlist *sg; | ||||
| 	int nents; | ||||
| 	u32 remainder; | ||||
| 	u32 sg_len; | ||||
| }; | ||||
|  | ||||
| struct mtk_aes_base_ctx; | ||||
| struct mtk_aes_rec; | ||||
| struct mtk_cryp; | ||||
|  | ||||
| typedef int (*mtk_aes_fn)(struct mtk_cryp *cryp, struct mtk_aes_rec *aes); | ||||
|  | ||||
| /** | ||||
|  * struct mtk_aes_rec - AES operation record | ||||
|  * @cryp:	pointer to Cryptographic device | ||||
|  * @queue:	crypto request queue | ||||
|  * @areq:	pointer to async request | ||||
|  * @done_task:	the tasklet is use in AES interrupt | ||||
|  * @queue_task:	the tasklet is used to dequeue request | ||||
|  * @ctx:	pointer to current context | ||||
|  * @src:	the structure that holds source sg list info | ||||
|  * @dst:	the structure that holds destination sg list info | ||||
|  * @aligned_sg:	the scatter list is use to alignment | ||||
|  * @real_dst:	pointer to the destination sg list | ||||
|  * @resume:	pointer to resume function | ||||
|  * @total:	request buffer length | ||||
|  * @buf:	pointer to page buffer | ||||
|  * @id:		the current use of ring | ||||
|  * @flags:	it's describing AES operation state | ||||
|  * @lock:	the async queue lock | ||||
|  * | ||||
|  * Structure used to record AES execution state. | ||||
|  */ | ||||
| struct mtk_aes_rec { | ||||
| 	struct mtk_cryp *cryp; | ||||
| 	struct crypto_queue queue; | ||||
| 	struct crypto_async_request *areq; | ||||
| 	struct tasklet_struct done_task; | ||||
| 	struct tasklet_struct queue_task; | ||||
| 	struct mtk_aes_base_ctx *ctx; | ||||
| 	struct mtk_aes_dma src; | ||||
| 	struct mtk_aes_dma dst; | ||||
|  | ||||
| 	struct scatterlist aligned_sg; | ||||
| 	struct scatterlist *real_dst; | ||||
|  | ||||
| 	mtk_aes_fn resume; | ||||
|  | ||||
| 	size_t total; | ||||
| 	void *buf; | ||||
|  | ||||
| 	u8 id; | ||||
| 	unsigned long flags; | ||||
| 	/* queue lock */ | ||||
| 	spinlock_t lock; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * struct mtk_sha_rec - SHA operation record | ||||
|  * @cryp:	pointer to Cryptographic device | ||||
|  * @queue:	crypto request queue | ||||
|  * @req:	pointer to ahash request | ||||
|  * @done_task:	the tasklet is use in SHA interrupt | ||||
|  * @queue_task:	the tasklet is used to dequeue request | ||||
|  * @id:		the current use of ring | ||||
|  * @flags:	it's describing SHA operation state | ||||
|  * @lock:	the async queue lock | ||||
|  * | ||||
|  * Structure used to record SHA execution state. | ||||
|  */ | ||||
| struct mtk_sha_rec { | ||||
| 	struct mtk_cryp *cryp; | ||||
| 	struct crypto_queue queue; | ||||
| 	struct ahash_request *req; | ||||
| 	struct tasklet_struct done_task; | ||||
| 	struct tasklet_struct queue_task; | ||||
|  | ||||
| 	u8 id; | ||||
| 	unsigned long flags; | ||||
| 	/* queue lock */ | ||||
| 	spinlock_t lock; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * struct mtk_cryp - Cryptographic device | ||||
|  * @base:	pointer to mapped register I/O base | ||||
|  * @dev:	pointer to device | ||||
|  * @clk_ethif:	pointer to ethif clock | ||||
|  * @clk_cryp:	pointer to crypto clock | ||||
|  * @irq:	global system and rings IRQ | ||||
|  * @ring:	pointer to descriptor rings | ||||
|  * @aes:	pointer to operation record of AES | ||||
|  * @sha:	pointer to operation record of SHA | ||||
|  * @aes_list:	device list of AES | ||||
|  * @sha_list:	device list of SHA | ||||
|  * @rec:	it's used to select SHA record for tfm | ||||
|  * | ||||
|  * Structure storing cryptographic device information. | ||||
|  */ | ||||
| struct mtk_cryp { | ||||
| 	void __iomem *base; | ||||
| 	struct device *dev; | ||||
| 	struct clk *clk_ethif; | ||||
| 	struct clk *clk_cryp; | ||||
| 	int irq[MTK_IRQ_NUM]; | ||||
|  | ||||
| 	struct mtk_ring *ring[MTK_RING_MAX]; | ||||
| 	struct mtk_aes_rec *aes[MTK_REC_NUM]; | ||||
| 	struct mtk_sha_rec *sha[MTK_REC_NUM]; | ||||
|  | ||||
| 	struct list_head aes_list; | ||||
| 	struct list_head sha_list; | ||||
|  | ||||
| 	bool rec; | ||||
| }; | ||||
|  | ||||
| int mtk_cipher_alg_register(struct mtk_cryp *cryp); | ||||
| void mtk_cipher_alg_release(struct mtk_cryp *cryp); | ||||
| int mtk_hash_alg_register(struct mtk_cryp *cryp); | ||||
| void mtk_hash_alg_release(struct mtk_cryp *cryp); | ||||
|  | ||||
| #endif /* __MTK_PLATFORM_H_ */ | ||||
| @@ -1,194 +0,0 @@ | ||||
| /* | ||||
|  * Support for MediaTek cryptographic accelerator. | ||||
|  * | ||||
|  * Copyright (c) 2016 MediaTek Inc. | ||||
|  * Author: Ryder Lee <ryder.lee@mediatek.com> | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #ifndef __MTK_REGS_H__ | ||||
| #define __MTK_REGS_H__ | ||||
|  | ||||
| /* HIA, Command Descriptor Ring Manager */ | ||||
| #define CDR_BASE_ADDR_LO(x)		(0x0 + ((x) << 12)) | ||||
| #define CDR_BASE_ADDR_HI(x)		(0x4 + ((x) << 12)) | ||||
| #define CDR_DATA_BASE_ADDR_LO(x)	(0x8 + ((x) << 12)) | ||||
| #define CDR_DATA_BASE_ADDR_HI(x)	(0xC + ((x) << 12)) | ||||
| #define CDR_ACD_BASE_ADDR_LO(x)		(0x10 + ((x) << 12)) | ||||
| #define CDR_ACD_BASE_ADDR_HI(x)		(0x14 + ((x) << 12)) | ||||
| #define CDR_RING_SIZE(x)		(0x18 + ((x) << 12)) | ||||
| #define CDR_DESC_SIZE(x)		(0x1C + ((x) << 12)) | ||||
| #define CDR_CFG(x)			(0x20 + ((x) << 12)) | ||||
| #define CDR_DMA_CFG(x)			(0x24 + ((x) << 12)) | ||||
| #define CDR_THRESH(x)			(0x28 + ((x) << 12)) | ||||
| #define CDR_PREP_COUNT(x)		(0x2C + ((x) << 12)) | ||||
| #define CDR_PROC_COUNT(x)		(0x30 + ((x) << 12)) | ||||
| #define CDR_PREP_PNTR(x)		(0x34 + ((x) << 12)) | ||||
| #define CDR_PROC_PNTR(x)		(0x38 + ((x) << 12)) | ||||
| #define CDR_STAT(x)			(0x3C + ((x) << 12)) | ||||
|  | ||||
| /* HIA, Result Descriptor Ring Manager */ | ||||
| #define RDR_BASE_ADDR_LO(x)		(0x800 + ((x) << 12)) | ||||
| #define RDR_BASE_ADDR_HI(x)		(0x804 + ((x) << 12)) | ||||
| #define RDR_DATA_BASE_ADDR_LO(x)	(0x808 + ((x) << 12)) | ||||
| #define RDR_DATA_BASE_ADDR_HI(x)	(0x80C + ((x) << 12)) | ||||
| #define RDR_ACD_BASE_ADDR_LO(x)		(0x810 + ((x) << 12)) | ||||
| #define RDR_ACD_BASE_ADDR_HI(x)		(0x814 + ((x) << 12)) | ||||
| #define RDR_RING_SIZE(x)		(0x818 + ((x) << 12)) | ||||
| #define RDR_DESC_SIZE(x)		(0x81C + ((x) << 12)) | ||||
| #define RDR_CFG(x)			(0x820 + ((x) << 12)) | ||||
| #define RDR_DMA_CFG(x)			(0x824 + ((x) << 12)) | ||||
| #define RDR_THRESH(x)			(0x828 + ((x) << 12)) | ||||
| #define RDR_PREP_COUNT(x)		(0x82C + ((x) << 12)) | ||||
| #define RDR_PROC_COUNT(x)		(0x830 + ((x) << 12)) | ||||
| #define RDR_PREP_PNTR(x)		(0x834 + ((x) << 12)) | ||||
| #define RDR_PROC_PNTR(x)		(0x838 + ((x) << 12)) | ||||
| #define RDR_STAT(x)			(0x83C + ((x) << 12)) | ||||
|  | ||||
| /* HIA, Ring AIC */ | ||||
| #define AIC_POL_CTRL(x)			(0xE000 - ((x) << 12)) | ||||
| #define	AIC_TYPE_CTRL(x)		(0xE004 - ((x) << 12)) | ||||
| #define	AIC_ENABLE_CTRL(x)		(0xE008 - ((x) << 12)) | ||||
| #define	AIC_RAW_STAL(x)			(0xE00C - ((x) << 12)) | ||||
| #define	AIC_ENABLE_SET(x)		(0xE00C - ((x) << 12)) | ||||
| #define	AIC_ENABLED_STAT(x)		(0xE010 - ((x) << 12)) | ||||
| #define	AIC_ACK(x)			(0xE010 - ((x) << 12)) | ||||
| #define	AIC_ENABLE_CLR(x)		(0xE014 - ((x) << 12)) | ||||
| #define	AIC_OPTIONS(x)			(0xE018 - ((x) << 12)) | ||||
| #define	AIC_VERSION(x)			(0xE01C - ((x) << 12)) | ||||
|  | ||||
| /* HIA, Global AIC */ | ||||
| #define AIC_G_POL_CTRL			0xF800 | ||||
| #define AIC_G_TYPE_CTRL			0xF804 | ||||
| #define AIC_G_ENABLE_CTRL		0xF808 | ||||
| #define AIC_G_RAW_STAT			0xF80C | ||||
| #define AIC_G_ENABLE_SET		0xF80C | ||||
| #define AIC_G_ENABLED_STAT		0xF810 | ||||
| #define AIC_G_ACK			0xF810 | ||||
| #define AIC_G_ENABLE_CLR		0xF814 | ||||
| #define AIC_G_OPTIONS			0xF818 | ||||
| #define AIC_G_VERSION			0xF81C | ||||
|  | ||||
| /* HIA, Data Fetch Engine */ | ||||
| #define DFE_CFG				0xF000 | ||||
| #define DFE_PRIO_0			0xF010 | ||||
| #define DFE_PRIO_1			0xF014 | ||||
| #define DFE_PRIO_2			0xF018 | ||||
| #define DFE_PRIO_3			0xF01C | ||||
|  | ||||
| /* HIA, Data Fetch Engine access monitoring for CDR */ | ||||
| #define DFE_RING_REGION_LO(x)		(0xF080 + ((x) << 3)) | ||||
| #define DFE_RING_REGION_HI(x)		(0xF084 + ((x) << 3)) | ||||
|  | ||||
| /* HIA, Data Fetch Engine thread control and status for thread */ | ||||
| #define DFE_THR_CTRL			0xF200 | ||||
| #define DFE_THR_STAT			0xF204 | ||||
| #define DFE_THR_DESC_CTRL		0xF208 | ||||
| #define DFE_THR_DESC_DPTR_LO		0xF210 | ||||
| #define DFE_THR_DESC_DPTR_HI		0xF214 | ||||
| #define DFE_THR_DESC_ACDPTR_LO		0xF218 | ||||
| #define DFE_THR_DESC_ACDPTR_HI		0xF21C | ||||
|  | ||||
| /* HIA, Data Store Engine */ | ||||
| #define DSE_CFG				0xF400 | ||||
| #define DSE_PRIO_0			0xF410 | ||||
| #define DSE_PRIO_1			0xF414 | ||||
| #define DSE_PRIO_2			0xF418 | ||||
| #define DSE_PRIO_3			0xF41C | ||||
|  | ||||
| /* HIA, Data Store Engine access monitoring for RDR */ | ||||
| #define DSE_RING_REGION_LO(x)		(0xF480 + ((x) << 3)) | ||||
| #define DSE_RING_REGION_HI(x)		(0xF484 + ((x) << 3)) | ||||
|  | ||||
| /* HIA, Data Store Engine thread control and status for thread */ | ||||
| #define DSE_THR_CTRL			0xF600 | ||||
| #define DSE_THR_STAT			0xF604 | ||||
| #define DSE_THR_DESC_CTRL		0xF608 | ||||
| #define DSE_THR_DESC_DPTR_LO		0xF610 | ||||
| #define DSE_THR_DESC_DPTR_HI		0xF614 | ||||
| #define DSE_THR_DESC_S_DPTR_LO		0xF618 | ||||
| #define DSE_THR_DESC_S_DPTR_HI		0xF61C | ||||
| #define DSE_THR_ERROR_STAT		0xF620 | ||||
|  | ||||
| /* HIA Global */ | ||||
| #define HIA_MST_CTRL			0xFFF4 | ||||
| #define HIA_OPTIONS			0xFFF8 | ||||
| #define HIA_VERSION			0xFFFC | ||||
|  | ||||
| /* Processing Engine Input Side, Processing Engine */ | ||||
| #define PE_IN_DBUF_THRESH		0x10000 | ||||
| #define PE_IN_TBUF_THRESH		0x10100 | ||||
|  | ||||
| /* Packet Engine Configuration / Status Registers */ | ||||
| #define PE_TOKEN_CTRL_STAT		0x11000 | ||||
| #define PE_FUNCTION_EN			0x11004 | ||||
| #define PE_CONTEXT_CTRL			0x11008 | ||||
| #define PE_INTERRUPT_CTRL_STAT		0x11010 | ||||
| #define PE_CONTEXT_STAT			0x1100C | ||||
| #define PE_OUT_TRANS_CTRL_STAT		0x11018 | ||||
| #define PE_OUT_BUF_CTRL			0x1101C | ||||
|  | ||||
| /* Packet Engine PRNG Registers */ | ||||
| #define PE_PRNG_STAT			0x11040 | ||||
| #define PE_PRNG_CTRL			0x11044 | ||||
| #define PE_PRNG_SEED_L			0x11048 | ||||
| #define PE_PRNG_SEED_H			0x1104C | ||||
| #define PE_PRNG_KEY_0_L			0x11050 | ||||
| #define PE_PRNG_KEY_0_H			0x11054 | ||||
| #define PE_PRNG_KEY_1_L			0x11058 | ||||
| #define PE_PRNG_KEY_1_H			0x1105C | ||||
| #define PE_PRNG_RES_0			0x11060 | ||||
| #define PE_PRNG_RES_1			0x11064 | ||||
| #define PE_PRNG_RES_2			0x11068 | ||||
| #define PE_PRNG_RES_3			0x1106C | ||||
| #define PE_PRNG_LFSR_L			0x11070 | ||||
| #define PE_PRNG_LFSR_H			0x11074 | ||||
|  | ||||
| /* Packet Engine AIC */ | ||||
| #define PE_EIP96_AIC_POL_CTRL		0x113C0 | ||||
| #define PE_EIP96_AIC_TYPE_CTRL		0x113C4 | ||||
| #define PE_EIP96_AIC_ENABLE_CTRL	0x113C8 | ||||
| #define PE_EIP96_AIC_RAW_STAT		0x113CC | ||||
| #define PE_EIP96_AIC_ENABLE_SET		0x113CC | ||||
| #define PE_EIP96_AIC_ENABLED_STAT	0x113D0 | ||||
| #define PE_EIP96_AIC_ACK		0x113D0 | ||||
| #define PE_EIP96_AIC_ENABLE_CLR		0x113D4 | ||||
| #define PE_EIP96_AIC_OPTIONS		0x113D8 | ||||
| #define PE_EIP96_AIC_VERSION		0x113DC | ||||
|  | ||||
| /* Packet Engine Options & Version Registers */ | ||||
| #define PE_EIP96_OPTIONS		0x113F8 | ||||
| #define PE_EIP96_VERSION		0x113FC | ||||
|  | ||||
| /* Processing Engine Output Side */ | ||||
| #define PE_OUT_DBUF_THRESH		0x11C00 | ||||
| #define PE_OUT_TBUF_THRESH		0x11D00 | ||||
|  | ||||
| /* Processing Engine Local AIC */ | ||||
| #define PE_AIC_POL_CTRL			0x11F00 | ||||
| #define PE_AIC_TYPE_CTRL		0x11F04 | ||||
| #define PE_AIC_ENABLE_CTRL		0x11F08 | ||||
| #define PE_AIC_RAW_STAT			0x11F0C | ||||
| #define PE_AIC_ENABLE_SET		0x11F0C | ||||
| #define PE_AIC_ENABLED_STAT		0x11F10 | ||||
| #define PE_AIC_ENABLE_CLR		0x11F14 | ||||
| #define PE_AIC_OPTIONS			0x11F18 | ||||
| #define PE_AIC_VERSION			0x11F1C | ||||
|  | ||||
| /* Processing Engine General Configuration and Version */ | ||||
| #define PE_IN_FLIGHT			0x11FF0 | ||||
| #define PE_OPTIONS			0x11FF8 | ||||
| #define PE_VERSION			0x11FFC | ||||
|  | ||||
| /* EIP-97 - Global */ | ||||
| #define EIP97_CLOCK_STATE		0x1FFE4 | ||||
| #define EIP97_FORCE_CLOCK_ON		0x1FFE8 | ||||
| #define EIP97_FORCE_CLOCK_OFF		0x1FFEC | ||||
| #define EIP97_MST_CTRL			0x1FFF4 | ||||
| #define EIP97_OPTIONS			0x1FFF8 | ||||
| #define EIP97_VERSION			0x1FFFC | ||||
| #endif /* __MTK_REGS_H__ */ | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -21,25 +21,12 @@ endif | ||||
| endef | ||||
|  | ||||
| COMPAT_BPI-R2:=bananapi,bpi-r2 | ||||
| COMPAT_EMMC:=mediatek,mt7623-rfb-emmc | ||||
| COMPAT_NAND:=mediatek,mt7623-rfb-nand | ||||
| COMPAT_NAND_EPHY:=mediatek,mt7623-rfb-nand-ephy | ||||
| COMPAT_EMMC:=mediatek,mt7623a-rfb-emmc | ||||
|  | ||||
| define Image/Build/squashfs | ||||
| 	$(call prepare_generic_squashfs,$(KDIR)/root.squashfs) | ||||
| 	$(CP) $(KDIR)/root.squashfs $(BIN_DIR)/$(IMG_PREFIX)-root.squashfs | ||||
|  | ||||
| 	$(call Image/Build/SysupgradeCombined,mt7623n-bananapi-bpi-r2,squashfs,$$(COMPAT_EMMC)) | ||||
| 	$(call Image/Build/SysupgradeCombined,mt7623-eMMC,squashfs,$$(COMPAT_BPI-R2)) | ||||
|  | ||||
| 	$(call Image/BuilduImage,mt7623-NAND) | ||||
| 	$(call Image/BuilduImage,mt7623-NAND-ePHY) | ||||
| ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),) | ||||
| 	$(call Image/BuilduImage,mt7623-NAND,-initramfs) | ||||
| 	$(call Image/BuilduImage,mt7623-NAND-ePHY,-initramfs) | ||||
| 	$(CP) $(KDIR)/uImage-mt7623-NAND-initramfs $(BIN_DIR)/$(IMG_PREFIX)-uImage-NAND-initramfs | ||||
| 	$(CP) $(KDIR)/uImage-mt7623-NAND-ePHY-initramfs $(BIN_DIR)/$(IMG_PREFIX)-uImage-NAND-ePHY-initramfs | ||||
| endif | ||||
| 	$(call Image/Build/SysupgradeNAND,mt7623-NAND,$(1),$(KDIR)/uImage-mt7623-NAND,$$(COMPAT_NAND)) | ||||
| 	$(call Image/Build/SysupgradeNAND,mt7623-NAND-ePHY,$(1),$(KDIR)/uImage-mt7623-NAND-ePHY,$$(COMPAT_NAND_EPHY)) | ||||
| 	$(call Image/Build/SysupgradeCombined,mt7623n-bananapi-bpi-r2,squashfs,$$(COMPAT_BPI-R2)) | ||||
| 	$(call Image/Build/SysupgradeCombined,mt7623a-rfb-emmc,squashfs,$$(COMPAT_EMMC)) | ||||
| endef | ||||
|   | ||||
| @@ -1,14 +0,0 @@ | ||||
| define KernelPackage/mediatek_hnat | ||||
|   SUBMENU:=Network Devices | ||||
|   TITLE:=MT7623 HNAT | ||||
|   DEPENDS:=@TARGET_mediatek +kmod-nf-conntrack | ||||
|   KCONFIG:= CONFIG_NET_MEDIATEK_HNAT=y | ||||
|   FILES:= \ | ||||
| 	$(LINUX_DIR)/drivers/net/ethernet/mediatek/mtk_hnat/mtkhnat.ko | ||||
| endef | ||||
|  | ||||
| define KernelPackage/mediatek_hnat/description | ||||
|   Kernel modules for MediaTek HW NAT offloading | ||||
| endef | ||||
|  | ||||
| $(eval $(call KernelPackage,mediatek_hnat)) | ||||
| @@ -14,23 +14,16 @@ Acked-by: Philipp Zabel <p.zabel@pengutronix.de> | ||||
|  drivers/clk/mediatek/clk-mt2701.c | 4 ++++ | ||||
|  1 file changed, 4 insertions(+) | ||||
| 
 | ||||
| --- a/drivers/clk/mediatek/clk-mt2701.c
 | ||||
| +++ b/drivers/clk/mediatek/clk-mt2701.c
 | ||||
| @@ -665,6 +665,8 @@ static void __init mtk_infrasys_init(str
 | ||||
| Index: linux-4.14.11/drivers/clk/mediatek/clk-mt2701.c
 | ||||
| ===================================================================
 | ||||
| --- linux-4.14.11.orig/drivers/clk/mediatek/clk-mt2701.c
 | ||||
| +++ linux-4.14.11/drivers/clk/mediatek/clk-mt2701.c
 | ||||
| @@ -771,6 +771,8 @@ static void mtk_infrasys_init_early(stru
 | ||||
|  	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); | ||||
|   | ||||
|  CLK_OF_DECLARE_DRIVER(mtk_infra, "mediatek,mt2701-infracfg", | ||||
|  			mtk_infrasys_init_early); | ||||
| @@ -16,9 +16,11 @@ Signed-off-by: John Crispin <john@phrozen.org> | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 +++++++++++++++++------------ | ||||
|  1 file changed, 21 insertions(+), 14 deletions(-) | ||||
| 
 | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | ||||
| @@ -710,7 +710,16 @@ static int mtk_tx_map(struct sk_buff *sk
 | ||||
| Index: linux-4.14.11/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | ||||
| ===================================================================
 | ||||
| --- linux-4.14.11.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | ||||
| +++ linux-4.14.11/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | ||||
| @@ -779,7 +779,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))); | ||||
|   | ||||
| @@ -36,7 +38,7 @@ Signed-off-by: John Crispin <john@phrozen.org> | ||||
|  	skb_tx_timestamp(skb); | ||||
|   | ||||
|  	ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2); | ||||
| @@ -1002,21 +1011,18 @@ static int mtk_poll_tx(struct mtk_eth *e
 | ||||
| @@ -1076,20 +1085,17 @@ static int mtk_poll_tx(struct mtk_eth *e
 | ||||
|  	struct mtk_tx_dma *desc; | ||||
|  	struct sk_buff *skb; | ||||
|  	struct mtk_tx_buf *tx_buf; | ||||
| @@ -45,7 +47,6 @@ Signed-off-by: John Crispin <john@phrozen.org> | ||||
| +	int total = 0, done = 0;
 | ||||
| +	unsigned int bytes = 0;
 | ||||
|  	u32 cpu, dma; | ||||
|  	static int condition; | ||||
| -	int total = 0, i;
 | ||||
| -
 | ||||
| -	memset(done, 0, sizeof(done));
 | ||||
| @@ -58,12 +59,12 @@ Signed-off-by: John Crispin <john@phrozen.org> | ||||
|  	desc = mtk_qdma_phys_to_virt(ring, cpu); | ||||
|   | ||||
| -	while ((cpu != dma) && budget) {
 | ||||
| +	while ((cpu != dma) && done < budget) {
 | ||||
| +	while ((cpu != dma) && (done < budget)) {
 | ||||
|  		u32 next_cpu = desc->txd2; | ||||
|  		int mac = 0; | ||||
|   | ||||
| @@ -1035,9 +1041,8 @@ static int mtk_poll_tx(struct mtk_eth *e
 | ||||
|  		} | ||||
| @@ -1106,9 +1112,8 @@ static int mtk_poll_tx(struct mtk_eth *e
 | ||||
|  			break; | ||||
|   | ||||
|  		if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) { | ||||
| -			bytes[mac] += skb->len;
 | ||||
| @@ -74,7 +75,7 @@ Signed-off-by: John Crispin <john@phrozen.org> | ||||
|  		} | ||||
|  		mtk_tx_unmap(eth, tx_buf); | ||||
|   | ||||
| @@ -1049,11 +1054,13 @@ static int mtk_poll_tx(struct mtk_eth *e
 | ||||
| @@ -1120,11 +1125,13 @@ static int mtk_poll_tx(struct mtk_eth *e
 | ||||
|   | ||||
|  	mtk_w32(eth, cpu, MTK_QTX_CRX_PTR); | ||||
|   | ||||
| @@ -10,9 +10,11 @@ Signed-off-by: John Crispin <john@phrozen.org> | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +++ | ||||
|  2 files changed, 8 insertions(+) | ||||
| 
 | ||||
| --- a/drivers/net/dsa/mt7530.c
 | ||||
| +++ b/drivers/net/dsa/mt7530.c
 | ||||
| @@ -629,6 +629,11 @@ mt7530_setup(struct dsa_switch *ds)
 | ||||
| Index: linux-4.14.11/drivers/net/dsa/mt7530.c
 | ||||
| ===================================================================
 | ||||
| --- linux-4.14.11.orig/drivers/net/dsa/mt7530.c
 | ||||
| +++ linux-4.14.11/drivers/net/dsa/mt7530.c
 | ||||
| @@ -991,6 +991,11 @@ mt7530_setup(struct dsa_switch *ds)
 | ||||
|  	val = mt7530_read(priv, MT7530_MHWTRAP); | ||||
|  	val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS; | ||||
|  	val |= MHWTRAP_MANUAL; | ||||
| @@ -24,15 +26,3 @@ Signed-off-by: John Crispin <john@phrozen.org> | ||||
|  	mt7530_write(priv, MT7530_MHWTRAP, val); | ||||
|   | ||||
|  	/* Enable and reset MIB counters */ | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | ||||
| @@ -221,6 +221,9 @@ static void mtk_phy_link_adjust(struct n
 | ||||
|  		netif_carrier_on(dev); | ||||
|  	else | ||||
|  		netif_carrier_off(dev); | ||||
| +
 | ||||
| +	if (!of_phy_is_fixed_link(mac->of_node))
 | ||||
| +		phy_print_status(dev->phydev);
 | ||||
|  } | ||||
|   | ||||
|  static int mtk_phy_connect_node(struct mtk_eth *eth, struct mtk_mac *mac, | ||||
							
								
								
									
										278
									
								
								target/linux/mediatek/patches-4.14/0033-dsa-multi-cpu.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										278
									
								
								target/linux/mediatek/patches-4.14/0033-dsa-multi-cpu.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,278 @@ | ||||
| Index: linux-4.14.14/drivers/net/dsa/mt7530.c | ||||
| =================================================================== | ||||
| --- linux-4.14.14.orig/drivers/net/dsa/mt7530.c | ||||
| +++ linux-4.14.14/drivers/net/dsa/mt7530.c | ||||
| @@ -670,6 +670,9 @@ static int | ||||
|  mt7530_cpu_port_enable(struct mt7530_priv *priv, | ||||
|  		       int port) | ||||
|  { | ||||
| +	u8 port_mask = 0; | ||||
| +	int i; | ||||
| + | ||||
|  	/* Enable Mediatek header mode on the cpu port */ | ||||
|  	mt7530_write(priv, MT7530_PVC_P(port), | ||||
|  		     PORT_SPEC_TAG); | ||||
| @@ -686,8 +689,12 @@ mt7530_cpu_port_enable(struct mt7530_pri | ||||
|  	/* CPU port gets connected to all user ports of | ||||
|  	 * the switch | ||||
|  	 */ | ||||
| +	for (i = 0; i < MT7530_NUM_PORTS; i++) | ||||
| +		if ((priv->ds->enabled_port_mask & BIT(i)) && | ||||
| +		    (dsa_port_upstream_port(priv->ds, i) == port)) | ||||
| +			port_mask |= BIT(i); | ||||
|  	mt7530_write(priv, MT7530_PCR_P(port), | ||||
| -		     PCR_MATRIX(priv->ds->enabled_port_mask)); | ||||
| +		     PCR_MATRIX(port_mask)); | ||||
|   | ||||
|  	return 0; | ||||
|  } | ||||
| @@ -697,6 +704,7 @@ mt7530_port_enable(struct dsa_switch *ds | ||||
|  		   struct phy_device *phy) | ||||
|  { | ||||
|  	struct mt7530_priv *priv = ds->priv; | ||||
| +	u8 upstream = dsa_port_upstream_port(ds, port); | ||||
|   | ||||
|  	mutex_lock(&priv->reg_mutex); | ||||
|   | ||||
| @@ -707,7 +715,7 @@ mt7530_port_enable(struct dsa_switch *ds | ||||
|  	 * restore the port matrix if the port is the member of a certain | ||||
|  	 * bridge. | ||||
|  	 */ | ||||
| -	priv->ports[port].pm |= PCR_MATRIX(BIT(MT7530_CPU_PORT)); | ||||
| +	priv->ports[port].pm |= PCR_MATRIX(BIT(upstream)); | ||||
|  	priv->ports[port].enable = true; | ||||
|  	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, | ||||
|  		   priv->ports[port].pm); | ||||
| @@ -770,7 +778,8 @@ mt7530_port_bridge_join(struct dsa_switc | ||||
|  			struct net_device *bridge) | ||||
|  { | ||||
|  	struct mt7530_priv *priv = ds->priv; | ||||
| -	u32 port_bitmap = BIT(MT7530_CPU_PORT); | ||||
| +	u8 upstream = dsa_port_upstream_port(ds, port); | ||||
| +	u32 port_bitmap = BIT(upstream); | ||||
|  	int i; | ||||
|   | ||||
|  	mutex_lock(&priv->reg_mutex); | ||||
| @@ -808,6 +817,7 @@ mt7530_port_bridge_leave(struct dsa_swit | ||||
|  			 struct net_device *bridge) | ||||
|  { | ||||
|  	struct mt7530_priv *priv = ds->priv; | ||||
| +	u8 upstream = dsa_port_upstream_port(ds, port); | ||||
|  	int i; | ||||
|   | ||||
|  	mutex_lock(&priv->reg_mutex); | ||||
| @@ -832,8 +842,8 @@ mt7530_port_bridge_leave(struct dsa_swit | ||||
|  	 */ | ||||
|  	if (priv->ports[port].enable) | ||||
|  		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, | ||||
| -			   PCR_MATRIX(BIT(MT7530_CPU_PORT))); | ||||
| -	priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT)); | ||||
| +			   PCR_MATRIX(BIT(upstream))); | ||||
| +	priv->ports[port].pm = PCR_MATRIX(BIT(upstream)); | ||||
|   | ||||
|  	mutex_unlock(&priv->reg_mutex); | ||||
|  } | ||||
| @@ -908,15 +918,7 @@ err: | ||||
|  static enum dsa_tag_protocol | ||||
|  mtk_get_tag_protocol(struct dsa_switch *ds) | ||||
|  { | ||||
| -	struct mt7530_priv *priv = ds->priv; | ||||
| - | ||||
| -	if (!dsa_is_cpu_port(ds, MT7530_CPU_PORT)) { | ||||
| -		dev_warn(priv->dev, | ||||
| -			 "port not matched with tagging CPU port\n"); | ||||
| -		return DSA_TAG_PROTO_NONE; | ||||
| -	} else { | ||||
| -		return DSA_TAG_PROTO_MTK; | ||||
| -	} | ||||
| +	return DSA_TAG_PROTO_MTK; | ||||
|  } | ||||
|   | ||||
|  static int | ||||
| @@ -989,7 +991,7 @@ mt7530_setup(struct dsa_switch *ds) | ||||
|   | ||||
|  	/* Enable Port 6 only; P5 as GMAC5 which currently is not supported */ | ||||
|  	val = mt7530_read(priv, MT7530_MHWTRAP); | ||||
| -	val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS; | ||||
| +	val &= ~MHWTRAP_P5_DIS & ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS; | ||||
|  	val |= MHWTRAP_MANUAL; | ||||
|  	if (!dsa_is_cpu_port(ds, 5)) { | ||||
|  		val |= MHWTRAP_P5_DIS; | ||||
| Index: linux-4.14.14/include/net/dsa.h | ||||
| =================================================================== | ||||
| --- linux-4.14.14.orig/include/net/dsa.h | ||||
| +++ linux-4.14.14/include/net/dsa.h | ||||
| @@ -185,6 +185,10 @@ struct dsa_port { | ||||
|  	u8			stp_state; | ||||
|  	struct net_device	*bridge_dev; | ||||
|  	struct devlink_port	devlink_port; | ||||
| + | ||||
| +	struct net_device	*ethernet; | ||||
| +	int			upstream; | ||||
| + | ||||
|  	/* | ||||
|  	 * Original copy of the master netdev ethtool_ops | ||||
|  	 */ | ||||
| @@ -266,6 +270,11 @@ static inline bool dsa_is_normal_port(st | ||||
|  	return !dsa_is_cpu_port(ds, p) && !dsa_is_dsa_port(ds, p); | ||||
|  } | ||||
|   | ||||
| +static inline bool dsa_is_upstream_port(struct dsa_switch *ds, int p) | ||||
| +{ | ||||
| +	return dsa_is_cpu_port(ds, p) || dsa_is_dsa_port(ds, p); | ||||
| +} | ||||
| + | ||||
|  static inline u8 dsa_upstream_port(struct dsa_switch *ds) | ||||
|  { | ||||
|  	struct dsa_switch_tree *dst = ds->dst; | ||||
| @@ -282,6 +291,18 @@ static inline u8 dsa_upstream_port(struc | ||||
|  		return ds->rtable[dst->cpu_dp->ds->index]; | ||||
|  } | ||||
|   | ||||
| +static inline u8 dsa_port_upstream_port(struct dsa_switch *ds, int port) | ||||
| +{ | ||||
| +	/* | ||||
| +	 * If this port has a specific upstream cpu port, use it, | ||||
| +	 * otherwise use the switch default. | ||||
| +	 */ | ||||
| +	if (ds->ports[port].upstream) | ||||
| +		return ds->ports[port].upstream; | ||||
| +	else | ||||
| +		return dsa_upstream_port(ds); | ||||
| +} | ||||
| + | ||||
|  typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid, | ||||
|  			      bool is_static, void *data); | ||||
|  struct dsa_switch_ops { | ||||
| Index: linux-4.14.14/net/dsa/dsa2.c | ||||
| =================================================================== | ||||
| --- linux-4.14.14.orig/net/dsa/dsa2.c | ||||
| +++ linux-4.14.14/net/dsa/dsa2.c | ||||
| @@ -253,6 +253,8 @@ static int dsa_cpu_port_apply(struct dsa | ||||
|  	memset(&port->devlink_port, 0, sizeof(port->devlink_port)); | ||||
|  	err = devlink_port_register(ds->devlink, &port->devlink_port, | ||||
|  				    port->index); | ||||
| +	if (port->netdev) | ||||
| +		port->netdev->dsa_ptr = ds->dst; | ||||
|  	return err; | ||||
|  } | ||||
|   | ||||
| @@ -262,6 +264,12 @@ static void dsa_cpu_port_unapply(struct | ||||
|  	dsa_cpu_dsa_destroy(port); | ||||
|  	port->ds->cpu_port_mask &= ~BIT(port->index); | ||||
|   | ||||
| +	if (port->netdev) | ||||
| +		port->netdev->dsa_ptr = NULL; | ||||
| +	if (port->ethernet) { | ||||
| +		dev_put(port->ethernet); | ||||
| +		port->ethernet = NULL; | ||||
| +	} | ||||
|  } | ||||
|   | ||||
|  static int dsa_user_port_apply(struct dsa_port *port) | ||||
| @@ -505,10 +513,9 @@ static int dsa_cpu_parse(struct dsa_port | ||||
|  		dev_put(ethernet_dev); | ||||
|  	} | ||||
|   | ||||
| -	if (!dst->cpu_dp) { | ||||
| +	if (!dst->cpu_dp) | ||||
|  		dst->cpu_dp = port; | ||||
| -		dst->cpu_dp->netdev = ethernet_dev; | ||||
| -	} | ||||
| +	port->netdev = ethernet_dev; | ||||
|   | ||||
|  	/* Initialize cpu_port_mask now for drv->setup() | ||||
|  	 * to have access to a correct value, just like what | ||||
| @@ -526,6 +533,29 @@ static int dsa_cpu_parse(struct dsa_port | ||||
|   | ||||
|  	dst->rcv = dst->tag_ops->rcv; | ||||
|   | ||||
| +	dev_hold(ethernet_dev); | ||||
| +	ds->ports[index].ethernet = ethernet_dev; | ||||
| +	ds->cpu_port_mask |= BIT(index); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int dsa_user_parse(struct dsa_port *port, u32 index, | ||||
| +			  struct dsa_switch *ds) | ||||
| +{ | ||||
| +	struct device_node *cpu_port; | ||||
| +	const unsigned int *cpu_port_reg; | ||||
| +	int cpu_port_index; | ||||
| + | ||||
| +	cpu_port = of_parse_phandle(port->dn, "cpu", 0); | ||||
| +	if (cpu_port) { | ||||
| +		cpu_port_reg = of_get_property(cpu_port, "reg", NULL); | ||||
| +		if (!cpu_port_reg) | ||||
| +			return -EINVAL; | ||||
| +		cpu_port_index = be32_to_cpup(cpu_port_reg); | ||||
| +		ds->ports[index].upstream = cpu_port_index; | ||||
| +	} | ||||
| + | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| @@ -533,7 +563,7 @@ static int dsa_ds_parse(struct dsa_switc | ||||
|  { | ||||
|  	struct dsa_port *port; | ||||
|  	u32 index; | ||||
| -	int err; | ||||
| +	int err = 0; | ||||
|   | ||||
|  	for (index = 0; index < ds->num_ports; index++) { | ||||
|  		port = &ds->ports[index]; | ||||
| @@ -546,6 +576,9 @@ static int dsa_ds_parse(struct dsa_switc | ||||
|  			if (err) | ||||
|  				return err; | ||||
|  		} else { | ||||
| +			err = dsa_user_parse(port, index, ds); | ||||
| +			if (err) | ||||
| +				return err; | ||||
|  			/* Initialize enabled_port_mask now for drv->setup() | ||||
|  			 * to have access to a correct value, just like what | ||||
|  			 * net/dsa/dsa.c::dsa_switch_setup_one does. | ||||
| Index: linux-4.14.14/net/dsa/dsa_priv.h | ||||
| =================================================================== | ||||
| --- linux-4.14.14.orig/net/dsa/dsa_priv.h | ||||
| +++ linux-4.14.14/net/dsa/dsa_priv.h | ||||
| @@ -91,6 +91,8 @@ struct dsa_slave_priv { | ||||
|   | ||||
|  	/* TC context */ | ||||
|  	struct list_head	mall_tc_list; | ||||
| + | ||||
| +	struct net_device       *master; | ||||
|  }; | ||||
|   | ||||
|  /* dsa.c */ | ||||
| @@ -177,6 +179,9 @@ extern const struct dsa_device_ops trail | ||||
|   | ||||
|  static inline struct net_device *dsa_master_netdev(struct dsa_slave_priv *p) | ||||
|  { | ||||
| +	if (p->master) | ||||
| +		return p->master; | ||||
| + | ||||
|  	return p->dp->cpu_dp->netdev; | ||||
|  } | ||||
|   | ||||
| Index: linux-4.14.14/net/dsa/slave.c | ||||
| =================================================================== | ||||
| --- linux-4.14.14.orig/net/dsa/slave.c | ||||
| +++ linux-4.14.14/net/dsa/slave.c | ||||
| @@ -1257,7 +1257,7 @@ int dsa_slave_create(struct dsa_port *po | ||||
|  	int ret; | ||||
|   | ||||
|  	cpu_dp = ds->dst->cpu_dp; | ||||
| -	master = cpu_dp->netdev; | ||||
| +	master = ds->ports[port->upstream].ethernet; | ||||
|   | ||||
|  	if (!ds->num_tx_queues) | ||||
|  		ds->num_tx_queues = 1; | ||||
| @@ -1295,6 +1295,7 @@ int dsa_slave_create(struct dsa_port *po | ||||
|  	p->dp = port; | ||||
|  	INIT_LIST_HEAD(&p->mall_tc_list); | ||||
|  	p->xmit = dst->tag_ops->xmit; | ||||
| +	p->master = master; | ||||
|   | ||||
|  	p->old_pause = -1; | ||||
|  	p->old_link = -1; | ||||
| @@ -8,9 +8,11 @@ Signed-off-by: John Crispin <john@phrozen.org> | ||||
|  drivers/net/dsa/mt7530.c | 23 +++++++++++++++-------- | ||||
|  1 file changed, 15 insertions(+), 8 deletions(-) | ||||
| 
 | ||||
| --- a/drivers/net/dsa/mt7530.c
 | ||||
| +++ b/drivers/net/dsa/mt7530.c
 | ||||
| @@ -1035,10 +1035,10 @@ static struct dsa_switch_ops mt7530_swit
 | ||||
| Index: linux-4.14.12/drivers/net/dsa/mt7530.c
 | ||||
| ===================================================================
 | ||||
| --- linux-4.14.12.orig/drivers/net/dsa/mt7530.c
 | ||||
| +++ linux-4.14.12/drivers/net/dsa/mt7530.c
 | ||||
| @@ -1049,10 +1049,10 @@ static const struct dsa_switch_ops mt753
 | ||||
|  }; | ||||
|   | ||||
|  static int | ||||
| @@ -23,7 +25,7 @@ Signed-off-by: John Crispin <john@phrozen.org> | ||||
|   | ||||
|  	dn = mdiodev->dev.of_node; | ||||
|   | ||||
| @@ -1086,7 +1086,12 @@ mt7530_probe(struct mdio_device *mdiodev
 | ||||
| @@ -1100,7 +1100,12 @@ mt7530_probe(struct mdio_device *mdiodev
 | ||||
|  		} | ||||
|  	} | ||||
|   | ||||
| @@ -36,9 +38,9 @@ Signed-off-by: John Crispin <john@phrozen.org> | ||||
| +		return -EPROBE_DEFER;
 | ||||
|  	priv->dev = &mdiodev->dev; | ||||
|  	priv->ds->priv = priv; | ||||
|  	priv->ds->dev = &mdiodev->dev; | ||||
| @@ -1098,8 +1103,8 @@ mt7530_probe(struct mdio_device *mdiodev
 | ||||
|  	return dsa_register_switch(priv->ds, priv->ds->dev->of_node); | ||||
|  	priv->ds->ops = &mt7530_switch_ops; | ||||
| @@ -1110,8 +1115,8 @@ mt7530_probe(struct mdio_device *mdiodev
 | ||||
|  	return dsa_register_switch(priv->ds); | ||||
|  } | ||||
|   | ||||
| -static void
 | ||||
| @@ -48,7 +50,7 @@ Signed-off-by: John Crispin <john@phrozen.org> | ||||
|  { | ||||
|  	struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); | ||||
|  	int ret = 0; | ||||
| @@ -1116,6 +1121,8 @@ mt7530_remove(struct mdio_device *mdiode
 | ||||
| @@ -1128,6 +1133,8 @@ mt7530_remove(struct mdio_device *mdiode
 | ||||
|   | ||||
|  	dsa_unregister_switch(priv->ds); | ||||
|  	mutex_destroy(&priv->reg_mutex); | ||||
| @@ -57,7 +59,7 @@ Signed-off-by: John Crispin <john@phrozen.org> | ||||
|  } | ||||
|   | ||||
|  static const struct of_device_id mt7530_of_match[] = { | ||||
| @@ -1123,16 +1130,16 @@ static const struct of_device_id mt7530_
 | ||||
| @@ -1135,16 +1142,16 @@ static const struct of_device_id mt7530_
 | ||||
|  	{ /* sentinel */ }, | ||||
|  }; | ||||
|   | ||||
| @@ -0,0 +1,23 @@ | ||||
| From 6e081074df96bf3762c2e6438c383f11a56b0a7e Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Thu, 10 Aug 2017 15:58:04 +0200 | ||||
| Subject: [PATCH 46/57] net: mediatek: add irq delay | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 ++++++- | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++++- | ||||
|  2 files changed, 13 insertions(+), 2 deletions(-) | ||||
|  | ||||
| Index: linux-4.14.11/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| =================================================================== | ||||
| --- linux-4.14.11.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| +++ linux-4.14.11/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| @@ -1994,6 +1994,7 @@ static int mtk_hw_init(struct mtk_eth *e | ||||
|   | ||||
|  	/* enable interrupt delay for RX */ | ||||
|  	mtk_w32(eth, MTK_PDMA_DELAY_RX_DELAY, MTK_PDMA_DELAY_INT); | ||||
| +	//mtk_w32(eth, MTK_PDMA_DELAY_RX_DELAY, MTK_QDMA_DELAY_INT); | ||||
|   | ||||
|  	/* disable delay and normal interrupt */ | ||||
|  	mtk_w32(eth, 0, MTK_QDMA_DELAY_INT); | ||||
							
								
								
									
										48
									
								
								target/linux/mediatek/patches-4.14/0063-atomic-sleep.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								target/linux/mediatek/patches-4.14/0063-atomic-sleep.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| Index: linux-4.14.12/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| =================================================================== | ||||
| --- linux-4.14.12.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| +++ linux-4.14.12/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| @@ -409,6 +409,7 @@ static int mtk_mdio_init(struct mtk_eth | ||||
|   | ||||
|  	snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%s", mii_np->name); | ||||
|  	ret = of_mdiobus_register(eth->mii_bus, mii_np); | ||||
| +printk("%s:%s[%d]%d %p\n", __FILE__, __func__, __LINE__, ret, eth->mii_bus); | ||||
|   | ||||
|  err_put_node: | ||||
|  	of_node_put(mii_np); | ||||
| @@ -1472,7 +1473,10 @@ static void mtk_hwlro_rx_uninit(struct m | ||||
|  	for (i = 0; i < 10; i++) { | ||||
|  		val = mtk_r32(eth, MTK_PDMA_LRO_CTRL_DW0); | ||||
|  		if (val & MTK_LRO_RING_RELINQUISH_DONE) { | ||||
| -			msleep(20); | ||||
| +			if (in_atomic()) | ||||
| +				mdelay(20); | ||||
| +			else | ||||
| +				msleep(20); | ||||
|  			continue; | ||||
|  		} | ||||
|  		break; | ||||
| @@ -1868,7 +1872,10 @@ static void mtk_stop_dma(struct mtk_eth | ||||
|  	for (i = 0; i < 10; i++) { | ||||
|  		val = mtk_r32(eth, glo_cfg); | ||||
|  		if (val & (MTK_TX_DMA_BUSY | MTK_RX_DMA_BUSY)) { | ||||
| -			msleep(20); | ||||
| +			if (in_atomic()) | ||||
| +				mdelay(20); | ||||
| +			else | ||||
| +				msleep(20); | ||||
|  			continue; | ||||
|  		} | ||||
|  		break; | ||||
| @@ -1906,7 +1913,10 @@ static void ethsys_reset(struct mtk_eth | ||||
|  			   reset_bits, | ||||
|  			   reset_bits); | ||||
|   | ||||
| -	usleep_range(1000, 1100); | ||||
| +	if (in_atomic()) | ||||
| +		udelay(1000); | ||||
| +	else | ||||
| +		usleep_range(1000, 1100); | ||||
|  	regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, | ||||
|  			   reset_bits, | ||||
|  			   ~reset_bits); | ||||
							
								
								
									
										597
									
								
								target/linux/mediatek/patches-4.14/0064-dts.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										597
									
								
								target/linux/mediatek/patches-4.14/0064-dts.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,597 @@ | ||||
| Index: linux-4.14.18/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | ||||
| =================================================================== | ||||
| --- linux-4.14.18.orig/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | ||||
| +++ linux-4.14.18/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | ||||
| @@ -21,6 +21,10 @@ | ||||
|  		stdout-path = "serial2:115200n8"; | ||||
|  	}; | ||||
|   | ||||
| +	memory { | ||||
| +		reg = <0 0x80000000 0 0x20000000>; | ||||
| +	}; | ||||
| + | ||||
|  	cpus { | ||||
|  		cpu@0 { | ||||
|  			proc-supply = <&mt6323_vproc_reg>; | ||||
| @@ -84,6 +88,10 @@ | ||||
|  	memory@80000000 { | ||||
|  		reg = <0 0x80000000 0 0x40000000>; | ||||
|  	}; | ||||
| + | ||||
| +	mt7530: switch@0 { | ||||
| +		compatible = "mediatek,mt7530"; | ||||
| +	}; | ||||
|  }; | ||||
|   | ||||
|  &cir { | ||||
| @@ -111,11 +119,24 @@ | ||||
|  		}; | ||||
|  	}; | ||||
|   | ||||
| +	gmac1: mac@1 { | ||||
| +		compatible = "mediatek,eth-mac"; | ||||
| +		reg = <1>; | ||||
| +		phy-mode = "rgmii"; | ||||
| + | ||||
| +		fixed-link { | ||||
| +			speed = <1000>; | ||||
| +			full-duplex; | ||||
| +			pause; | ||||
| +		}; | ||||
| +	}; | ||||
| + | ||||
|  	mdio: mdio-bus { | ||||
|  		#address-cells = <1>; | ||||
|  		#size-cells = <0>; | ||||
| - | ||||
| -		switch@0 { | ||||
| +	}; | ||||
| +}; | ||||
| +		&mt7530 { | ||||
|  			compatible = "mediatek,mt7530"; | ||||
|  			#address-cells = <1>; | ||||
|  			#size-cells = <0>; | ||||
| @@ -125,6 +146,8 @@ | ||||
|  			core-supply = <&mt6323_vpa_reg>; | ||||
|  			io-supply = <&mt6323_vemc3v3_reg>; | ||||
|   | ||||
| +			dsa,mii-bus = <&mdio>; | ||||
| + | ||||
|  			ports { | ||||
|  				#address-cells = <1>; | ||||
|  				#size-cells = <0>; | ||||
| @@ -133,29 +156,46 @@ | ||||
|  				port@0 { | ||||
|  					reg = <0>; | ||||
|  					label = "wan"; | ||||
| +					cpu = <&cpu_port1>; | ||||
|  				}; | ||||
|   | ||||
|  				port@1 { | ||||
|  					reg = <1>; | ||||
|  					label = "lan0"; | ||||
| +					cpu = <&cpu_port0>; | ||||
|  				}; | ||||
|   | ||||
|  				port@2 { | ||||
|  					reg = <2>; | ||||
|  					label = "lan1"; | ||||
| +					cpu = <&cpu_port0>; | ||||
|  				}; | ||||
|   | ||||
|  				port@3 { | ||||
|  					reg = <3>; | ||||
|  					label = "lan2"; | ||||
| +					cpu = <&cpu_port0>; | ||||
|  				}; | ||||
|   | ||||
|  				port@4 { | ||||
|  					reg = <4>; | ||||
|  					label = "lan3"; | ||||
| +					cpu = <&cpu_port0>; | ||||
|  				}; | ||||
|   | ||||
| -				port@6 { | ||||
| +				cpu_port1: port@5 { | ||||
| +					reg = <5>; | ||||
| +					label = "cpu"; | ||||
| +					ethernet = <&gmac1>; | ||||
| +					phy-mode = "rgmii"; | ||||
| + | ||||
| +					fixed-link { | ||||
| +						speed = <1000>; | ||||
| +						full-duplex; | ||||
| +					}; | ||||
| +				}; | ||||
| + | ||||
| +				cpu_port0: port@6 { | ||||
|  					reg = <6>; | ||||
|  					label = "cpu"; | ||||
|  					ethernet = <&gmac0>; | ||||
| @@ -168,8 +208,6 @@ | ||||
|  				}; | ||||
|  			}; | ||||
|  		}; | ||||
| -	}; | ||||
| -}; | ||||
|   | ||||
|  &i2c0 { | ||||
|  	pinctrl-names = "default"; | ||||
| Index: linux-4.14.18/arch/arm/boot/dts/Makefile | ||||
| =================================================================== | ||||
| --- linux-4.14.18.orig/arch/arm/boot/dts/Makefile | ||||
| +++ linux-4.14.18/arch/arm/boot/dts/Makefile | ||||
| @@ -1061,6 +1061,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ | ||||
|  	mt6580-evbp1.dtb \ | ||||
|  	mt6589-aquaris5.dtb \ | ||||
|  	mt6592-evb.dtb \ | ||||
| +	mt7623a-rfb-emmc.dtb \ | ||||
|  	mt7623n-rfb-nand.dtb \ | ||||
|  	mt7623n-bananapi-bpi-r2.dtb \ | ||||
|  	mt8127-moose.dtb \ | ||||
| Index: linux-4.14.18/arch/arm/boot/dts/mt7623a-rfb-emmc.dts | ||||
| =================================================================== | ||||
| --- /dev/null | ||||
| +++ linux-4.14.18/arch/arm/boot/dts/mt7623a-rfb-emmc.dts | ||||
| @@ -0,0 +1,449 @@ | ||||
| +/* | ||||
| + * Copyright 2017 Sean Wang <sean.wang@mediatek.com> | ||||
| + * | ||||
| + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) | ||||
| + */ | ||||
| + | ||||
| +/dts-v1/; | ||||
| +#include <dt-bindings/input/input.h> | ||||
| +#include "mt7623.dtsi" | ||||
| +#include "mt6323.dtsi" | ||||
| + | ||||
| +/ { | ||||
| +	model = "MediaTek MT7623N NAND reference board"; | ||||
| +	compatible = "mediatek,mt7623a-rfb-emmc", "mediatek,mt7623"; | ||||
| + | ||||
| +	aliases { | ||||
| +		serial2 = &uart2; | ||||
| +	}; | ||||
| + | ||||
| +	chosen { | ||||
| +		bootargs = "earlyprintk 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"; | ||||
| + | ||||
| +		stdout-path = "serial2:115200n8"; | ||||
| +	}; | ||||
| + | ||||
| +	memory { | ||||
| +		reg = <0 0x80000000 0 0x20000000>; | ||||
| +	}; | ||||
| + | ||||
| +	cpus { | ||||
| +		cpu@0 { | ||||
| +			proc-supply = <&mt6323_vproc_reg>; | ||||
| +		}; | ||||
| + | ||||
| +		cpu@1 { | ||||
| +			proc-supply = <&mt6323_vproc_reg>; | ||||
| +		}; | ||||
| + | ||||
| +		cpu@2 { | ||||
| +			proc-supply = <&mt6323_vproc_reg>; | ||||
| +		}; | ||||
| + | ||||
| +		cpu@3 { | ||||
| +			proc-supply = <&mt6323_vproc_reg>; | ||||
| +		}; | ||||
| +	}; | ||||
| + | ||||
| +	memory@80000000 { | ||||
| +		reg = <0 0x80000000 0 0x40000000>; | ||||
| +	}; | ||||
| + | ||||
| +	mt7530: switch@0 { | ||||
| +		compatible = "mediatek,mt7530"; | ||||
| +		#address-cells = <1>; | ||||
| +		#size-cells = <0>; | ||||
| +	}; | ||||
| +}; | ||||
| + | ||||
| +&crypto { | ||||
| +	status = "okay"; | ||||
| +}; | ||||
| + | ||||
| +ð { | ||||
| +	status = "okay"; | ||||
| + | ||||
| +	gmac0: mac@0 { | ||||
| +		compatible = "mediatek,eth-mac"; | ||||
| +		reg = <0>; | ||||
| +		phy-mode = "trgmii"; | ||||
| + | ||||
| +		fixed-link { | ||||
| +			speed = <1000>; | ||||
| +			full-duplex; | ||||
| +			pause; | ||||
| +		}; | ||||
| +	}; | ||||
| + | ||||
| +	gmac1: mac@1 { | ||||
| +		compatible = "mediatek,eth-mac"; | ||||
| +		reg = <1>; | ||||
| +		phy-mode = "rgmiii-rxid"; | ||||
| +		phy-handle = <&phy5>; | ||||
| +	}; | ||||
| + | ||||
| +	mdio: mdio-bus { | ||||
| +		#address-cells = <1>; | ||||
| +		#size-cells = <0>; | ||||
| +		phy5: ethernet-phy@5 { | ||||
| +			reg = <5>; | ||||
| +			phy-mode = "rgmii-rxid"; | ||||
| +		}; | ||||
| +	}; | ||||
| +}; | ||||
| + | ||||
| +&mt7530 { | ||||
| +	compatible = "mediatek,mt7530"; | ||||
| +	#address-cells = <1>; | ||||
| +	#size-cells = <0>; | ||||
| +	reg = <0>; | ||||
| +	pinctrl-names = "default"; | ||||
| +	mediatek,mcm; | ||||
| +	resets = <ðsys 2>; | ||||
| +	reset-names = "mcm"; | ||||
| +	core-supply = <&mt6323_vpa_reg>; | ||||
| +	io-supply = <&mt6323_vemc3v3_reg>; | ||||
| + | ||||
| +	dsa,mii-bus = <&mdio>; | ||||
| + | ||||
| +	ports { | ||||
| +		#address-cells = <1>; | ||||
| +		#size-cells = <0>; | ||||
| +		reg = <0>; | ||||
| + | ||||
| +		port@0 { | ||||
| +			reg = <0>; | ||||
| +			label = "lan0"; | ||||
| +			cpu = <&cpu_port0>; | ||||
| +		}; | ||||
| + | ||||
| +		port@1 { | ||||
| +			reg = <1>; | ||||
| +			label = "lan1"; | ||||
| +			cpu = <&cpu_port0>; | ||||
| +		}; | ||||
| + | ||||
| +		port@2 { | ||||
| +			reg = <2>; | ||||
| +			label = "lan2"; | ||||
| +			cpu = <&cpu_port0>; | ||||
| +		}; | ||||
| + | ||||
| +		port@3 { | ||||
| +			reg = <3>; | ||||
| +			label = "lan3"; | ||||
| +			cpu = <&cpu_port0>; | ||||
| +		}; | ||||
| + | ||||
| +		cpu_port0: port@6 { | ||||
| +			reg = <6>; | ||||
| +			label = "cpu"; | ||||
| +			ethernet = <&gmac0>; | ||||
| +			phy-mode = "trgmii"; | ||||
| + | ||||
| +			fixed-link { | ||||
| +				speed = <1000>; | ||||
| +				full-duplex; | ||||
| +			}; | ||||
| +		}; | ||||
| +	}; | ||||
| +}; | ||||
| + | ||||
| +&i2c0 { | ||||
| +	pinctrl-names = "default"; | ||||
| +	pinctrl-0 = <&i2c0_pins_a>; | ||||
| +	status = "okay"; | ||||
| +}; | ||||
| + | ||||
| +&i2c1 { | ||||
| +	pinctrl-names = "default"; | ||||
| +	pinctrl-0 = <&i2c1_pins_a>; | ||||
| +	status = "okay"; | ||||
| +}; | ||||
| + | ||||
| +&mmc0 { | ||||
| +	pinctrl-names = "default", "state_uhs"; | ||||
| +	pinctrl-0 = <&mmc0_pins_default>; | ||||
| +	pinctrl-1 = <&mmc0_pins_uhs>; | ||||
| +	status = "okay"; | ||||
| +	bus-width = <8>; | ||||
| +	max-frequency = <50000000>; | ||||
| +	cap-mmc-highspeed; | ||||
| +	vmmc-supply = <&mt6323_vemc3v3_reg>; | ||||
| +	vqmmc-supply = <&mt6323_vio18_reg>; | ||||
| +	non-removable; | ||||
| +}; | ||||
| + | ||||
| +&mmc1 { | ||||
| +	pinctrl-names = "default", "state_uhs"; | ||||
| +	pinctrl-0 = <&mmc1_pins_default>; | ||||
| +	pinctrl-1 = <&mmc1_pins_uhs>; | ||||
| +	status = "okay"; | ||||
| +	bus-width = <4>; | ||||
| +	max-frequency = <50000000>; | ||||
| +	cap-sd-highspeed; | ||||
| +	cd-gpios = <&pio 261 0>; | ||||
| +	vmmc-supply = <&mt6323_vmch_reg>; | ||||
| +	vqmmc-supply = <&mt6323_vio18_reg>; | ||||
| +}; | ||||
| + | ||||
| +&pio { | ||||
| +	cir_pins_a:cir@0 { | ||||
| +		pins_cir { | ||||
| +			pinmux = <MT7623_PIN_46_IR_FUNC_IR>; | ||||
| +			bias-disable; | ||||
| +		}; | ||||
| +	}; | ||||
| + | ||||
| +	i2c0_pins_a: i2c@0 { | ||||
| +		pins_i2c0 { | ||||
| +			pinmux = <MT7623_PIN_75_SDA0_FUNC_SDA0>, | ||||
| +				 <MT7623_PIN_76_SCL0_FUNC_SCL0>; | ||||
| +			bias-disable; | ||||
| +		}; | ||||
| +	}; | ||||
| + | ||||
| +	i2c1_pins_a: i2c@1 { | ||||
| +		pin_i2c1 { | ||||
| +			pinmux = <MT7623_PIN_57_SDA1_FUNC_SDA1>, | ||||
| +				 <MT7623_PIN_58_SCL1_FUNC_SCL1>; | ||||
| +			bias-disable; | ||||
| +		}; | ||||
| +	}; | ||||
| + | ||||
| +	i2s0_pins_a: i2s@0 { | ||||
| +		pin_i2s0 { | ||||
| +			pinmux = <MT7623_PIN_49_I2S0_DATA_FUNC_I2S0_DATA>, | ||||
| +				 <MT7623_PIN_72_I2S0_DATA_IN_FUNC_I2S0_DATA_IN>, | ||||
| +				 <MT7623_PIN_73_I2S0_LRCK_FUNC_I2S0_LRCK>, | ||||
| +				 <MT7623_PIN_74_I2S0_BCK_FUNC_I2S0_BCK>, | ||||
| +				 <MT7623_PIN_126_I2S0_MCLK_FUNC_I2S0_MCLK>; | ||||
| +			drive-strength = <MTK_DRIVE_12mA>; | ||||
| +			bias-pull-down; | ||||
| +		}; | ||||
| +	}; | ||||
| + | ||||
| +	i2s1_pins_a: i2s@1 { | ||||
| +		pin_i2s1 { | ||||
| +			pinmux = <MT7623_PIN_33_I2S1_DATA_FUNC_I2S1_DATA>, | ||||
| +				 <MT7623_PIN_34_I2S1_DATA_IN_FUNC_I2S1_DATA_IN>, | ||||
| +				 <MT7623_PIN_35_I2S1_BCK_FUNC_I2S1_BCK>, | ||||
| +				 <MT7623_PIN_36_I2S1_LRCK_FUNC_I2S1_LRCK>, | ||||
| +				 <MT7623_PIN_37_I2S1_MCLK_FUNC_I2S1_MCLK>; | ||||
| +			drive-strength = <MTK_DRIVE_12mA>; | ||||
| +			bias-pull-down; | ||||
| +		}; | ||||
| +	}; | ||||
| + | ||||
| +	mmc0_pins_default: mmc0default { | ||||
| +		pins_cmd_dat { | ||||
| +			pinmux = <MT7623_PIN_111_MSDC0_DAT7_FUNC_MSDC0_DAT7>, | ||||
| +				 <MT7623_PIN_112_MSDC0_DAT6_FUNC_MSDC0_DAT6>, | ||||
| +				 <MT7623_PIN_113_MSDC0_DAT5_FUNC_MSDC0_DAT5>, | ||||
| +				 <MT7623_PIN_114_MSDC0_DAT4_FUNC_MSDC0_DAT4>, | ||||
| +				 <MT7623_PIN_118_MSDC0_DAT3_FUNC_MSDC0_DAT3>, | ||||
| +				 <MT7623_PIN_119_MSDC0_DAT2_FUNC_MSDC0_DAT2>, | ||||
| +				 <MT7623_PIN_120_MSDC0_DAT1_FUNC_MSDC0_DAT1>, | ||||
| +				 <MT7623_PIN_121_MSDC0_DAT0_FUNC_MSDC0_DAT0>, | ||||
| +				 <MT7623_PIN_116_MSDC0_CMD_FUNC_MSDC0_CMD>; | ||||
| +			input-enable; | ||||
| +			bias-pull-up; | ||||
| +		}; | ||||
| + | ||||
| +		pins_clk { | ||||
| +			pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_MSDC0_CLK>; | ||||
| +			bias-pull-down; | ||||
| +		}; | ||||
| + | ||||
| +		pins_rst { | ||||
| +			pinmux = <MT7623_PIN_115_MSDC0_RSTB_FUNC_MSDC0_RSTB>; | ||||
| +			bias-pull-up; | ||||
| +		}; | ||||
| +	}; | ||||
| + | ||||
| +	mmc0_pins_uhs: mmc0 { | ||||
| +		pins_cmd_dat { | ||||
| +			pinmux = <MT7623_PIN_111_MSDC0_DAT7_FUNC_MSDC0_DAT7>, | ||||
| +				 <MT7623_PIN_112_MSDC0_DAT6_FUNC_MSDC0_DAT6>, | ||||
| +				 <MT7623_PIN_113_MSDC0_DAT5_FUNC_MSDC0_DAT5>, | ||||
| +				 <MT7623_PIN_114_MSDC0_DAT4_FUNC_MSDC0_DAT4>, | ||||
| +				 <MT7623_PIN_118_MSDC0_DAT3_FUNC_MSDC0_DAT3>, | ||||
| +				 <MT7623_PIN_119_MSDC0_DAT2_FUNC_MSDC0_DAT2>, | ||||
| +				 <MT7623_PIN_120_MSDC0_DAT1_FUNC_MSDC0_DAT1>, | ||||
| +				 <MT7623_PIN_121_MSDC0_DAT0_FUNC_MSDC0_DAT0>, | ||||
| +				 <MT7623_PIN_116_MSDC0_CMD_FUNC_MSDC0_CMD>; | ||||
| +			input-enable; | ||||
| +			drive-strength = <MTK_DRIVE_2mA>; | ||||
| +			bias-pull-up = <MTK_PUPD_SET_R1R0_01>; | ||||
| +		}; | ||||
| + | ||||
| +		pins_clk { | ||||
| +			pinmux = <MT7623_PIN_117_MSDC0_CLK_FUNC_MSDC0_CLK>; | ||||
| +			drive-strength = <MTK_DRIVE_2mA>; | ||||
| +			bias-pull-down = <MTK_PUPD_SET_R1R0_01>; | ||||
| +		}; | ||||
| + | ||||
| +		pins_rst { | ||||
| +			pinmux = <MT7623_PIN_115_MSDC0_RSTB_FUNC_MSDC0_RSTB>; | ||||
| +			bias-pull-up; | ||||
| +		}; | ||||
| +	}; | ||||
| + | ||||
| +	mmc1_pins_default: mmc1default { | ||||
| +		pins_cmd_dat { | ||||
| +			pinmux = <MT7623_PIN_107_MSDC1_DAT0_FUNC_MSDC1_DAT0>, | ||||
| +				 <MT7623_PIN_108_MSDC1_DAT1_FUNC_MSDC1_DAT1>, | ||||
| +				 <MT7623_PIN_109_MSDC1_DAT2_FUNC_MSDC1_DAT2>, | ||||
| +				 <MT7623_PIN_110_MSDC1_DAT3_FUNC_MSDC1_DAT3>, | ||||
| +				 <MT7623_PIN_105_MSDC1_CMD_FUNC_MSDC1_CMD>; | ||||
| +			input-enable; | ||||
| +			drive-strength = <MTK_DRIVE_4mA>; | ||||
| +			bias-pull-up = <MTK_PUPD_SET_R1R0_10>; | ||||
| +		}; | ||||
| + | ||||
| +		pins_clk { | ||||
| +			pinmux = <MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK>; | ||||
| +			bias-pull-down; | ||||
| +			drive-strength = <MTK_DRIVE_4mA>; | ||||
| +		}; | ||||
| + | ||||
| +		pins_wp { | ||||
| +			pinmux = <MT7623_PIN_29_EINT7_FUNC_MSDC1_WP>; | ||||
| +			input-enable; | ||||
| +			bias-pull-up; | ||||
| +		}; | ||||
| + | ||||
| +		pins_insert { | ||||
| +			pinmux = <MT7623_PIN_261_MSDC1_INS_FUNC_GPIO261>; | ||||
| +			bias-pull-up; | ||||
| +		}; | ||||
| +	}; | ||||
| + | ||||
| +	mmc1_pins_uhs: mmc1 { | ||||
| +		pins_cmd_dat { | ||||
| +			pinmux = <MT7623_PIN_107_MSDC1_DAT0_FUNC_MSDC1_DAT0>, | ||||
| +				 <MT7623_PIN_108_MSDC1_DAT1_FUNC_MSDC1_DAT1>, | ||||
| +				 <MT7623_PIN_109_MSDC1_DAT2_FUNC_MSDC1_DAT2>, | ||||
| +				 <MT7623_PIN_110_MSDC1_DAT3_FUNC_MSDC1_DAT3>, | ||||
| +				 <MT7623_PIN_105_MSDC1_CMD_FUNC_MSDC1_CMD>; | ||||
| +			input-enable; | ||||
| +			drive-strength = <MTK_DRIVE_4mA>; | ||||
| +			bias-pull-up = <MTK_PUPD_SET_R1R0_10>; | ||||
| +		}; | ||||
| + | ||||
| +		pins_clk { | ||||
| +			pinmux = <MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK>; | ||||
| +			drive-strength = <MTK_DRIVE_4mA>; | ||||
| +			bias-pull-down = <MTK_PUPD_SET_R1R0_10>; | ||||
| +		}; | ||||
| +	}; | ||||
| + | ||||
| +	pwm_pins_a: pwm@0 { | ||||
| +		pins_pwm { | ||||
| +			pinmux = <MT7623_PIN_203_PWM0_FUNC_PWM0>, | ||||
| +				 <MT7623_PIN_204_PWM1_FUNC_PWM1>, | ||||
| +				 <MT7623_PIN_205_PWM2_FUNC_PWM2>, | ||||
| +				 <MT7623_PIN_206_PWM3_FUNC_PWM3>, | ||||
| +				 <MT7623_PIN_207_PWM4_FUNC_PWM4>; | ||||
| +		}; | ||||
| +	}; | ||||
| + | ||||
| +	spi0_pins_a: spi@0 { | ||||
| +		pins_spi { | ||||
| +			pinmux = <MT7623_PIN_53_SPI0_CSN_FUNC_SPI0_CS>, | ||||
| +				<MT7623_PIN_54_SPI0_CK_FUNC_SPI0_CK>, | ||||
| +				<MT7623_PIN_55_SPI0_MI_FUNC_SPI0_MI>, | ||||
| +				<MT7623_PIN_56_SPI0_MO_FUNC_SPI0_MO>; | ||||
| +			bias-disable; | ||||
| +		}; | ||||
| +	}; | ||||
| + | ||||
| +	uart0_pins_a: uart@0 { | ||||
| +		pins_dat { | ||||
| +			pinmux = <MT7623_PIN_79_URXD0_FUNC_URXD0>, | ||||
| +				 <MT7623_PIN_80_UTXD0_FUNC_UTXD0>; | ||||
| +		}; | ||||
| +	}; | ||||
| + | ||||
| +	uart1_pins_a: uart@1 { | ||||
| +		pins_dat { | ||||
| +			pinmux = <MT7623_PIN_81_URXD1_FUNC_URXD1>, | ||||
| +				 <MT7623_PIN_82_UTXD1_FUNC_UTXD1>; | ||||
| +		}; | ||||
| +	}; | ||||
| +}; | ||||
| + | ||||
| +&pwm { | ||||
| +	pinctrl-names = "default"; | ||||
| +	pinctrl-0 = <&pwm_pins_a>; | ||||
| +	status = "okay"; | ||||
| +}; | ||||
| + | ||||
| +&pwrap { | ||||
| +	mt6323 { | ||||
| +		mt6323led: led { | ||||
| +			compatible = "mediatek,mt6323-led"; | ||||
| +			#address-cells = <1>; | ||||
| +			#size-cells = <0>; | ||||
| + | ||||
| +			led@0 { | ||||
| +				reg = <0>; | ||||
| +				label = "bpi-r2:isink:green"; | ||||
| +				default-state = "off"; | ||||
| +			}; | ||||
| + | ||||
| +			led@1 { | ||||
| +				reg = <1>; | ||||
| +				label = "bpi-r2:isink:red"; | ||||
| +				default-state = "off"; | ||||
| +			}; | ||||
| + | ||||
| +			led@2 { | ||||
| +				reg = <2>; | ||||
| +				label = "bpi-r2:isink:blue"; | ||||
| +				default-state = "off"; | ||||
| +			}; | ||||
| +		}; | ||||
| +	}; | ||||
| +}; | ||||
| + | ||||
| +&spi0 { | ||||
| +	pinctrl-names = "default"; | ||||
| +	pinctrl-0 = <&spi0_pins_a>; | ||||
| +	status = "okay"; | ||||
| +}; | ||||
| + | ||||
| +&uart0 { | ||||
| +	pinctrl-names = "default"; | ||||
| +	pinctrl-0 = <&uart0_pins_a>; | ||||
| +	status = "disabled"; | ||||
| +}; | ||||
| + | ||||
| +&uart1 { | ||||
| +	pinctrl-names = "default"; | ||||
| +	pinctrl-0 = <&uart1_pins_a>; | ||||
| +	status = "disabled"; | ||||
| +}; | ||||
| + | ||||
| +&uart2 { | ||||
| +	status = "okay"; | ||||
| +}; | ||||
| + | ||||
| +&usb1 { | ||||
| +	vusb33-supply = <&mt6323_vusb_reg>; | ||||
| +	status = "okay"; | ||||
| +}; | ||||
| + | ||||
| +&usb2 { | ||||
| +	vusb33-supply = <&mt6323_vusb_reg>; | ||||
| +	status = "okay"; | ||||
| +}; | ||||
| + | ||||
| +&u3phy1 { | ||||
| +	status = "okay"; | ||||
| +}; | ||||
| + | ||||
| +&u3phy2 { | ||||
| +	status = "okay"; | ||||
| +}; | ||||
| + | ||||
| Index: linux-4.14.18/arch/arm/boot/dts/mt7623.dtsi | ||||
| =================================================================== | ||||
| --- linux-4.14.18.orig/arch/arm/boot/dts/mt7623.dtsi | ||||
| +++ linux-4.14.18/arch/arm/boot/dts/mt7623.dtsi | ||||
| @@ -753,6 +753,7 @@ | ||||
|  			     "syscon"; | ||||
|  		reg = <0 0x1b000000 0 0x1000>; | ||||
|  		#clock-cells = <1>; | ||||
| +		#reset-cells = <1>; | ||||
|  	}; | ||||
|   | ||||
|  	eth: ethernet@1b100000 { | ||||
| @@ -1,23 +0,0 @@ | ||||
| From 9fdcf63545855f3a6f82dee109510f4735e861c8 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Thu, 10 Aug 2017 15:54:13 +0200 | ||||
| Subject: [PATCH 01/57] arch: arm: add dts build code | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  arch/arm/boot/dts/Makefile | 3 +++ | ||||
|  1 file changed, 3 insertions(+) | ||||
|  | ||||
| --- a/arch/arm/boot/dts/Makefile | ||||
| +++ b/arch/arm/boot/dts/Makefile | ||||
| @@ -950,6 +950,10 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ | ||||
|  	mt6589-aquaris5.dtb \ | ||||
|  	mt6592-evb.dtb \ | ||||
|  	mt7623-evb.dtb \ | ||||
| +	mt7623-eMMC.dtb \ | ||||
| +	mt7623-NAND.dtb \ | ||||
| +	mt7623-NAND-ePHY.dtb \ | ||||
| +	mt7623n-bananapi-bpi-r2.dtb \ | ||||
|  	mt8127-moose.dtb \ | ||||
|  	mt8135-evbp1.dtb | ||||
|  dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb | ||||
| @@ -1,154 +0,0 @@ | ||||
| From ad2d4df46d8ef6a7aab20f0b668fa7db5257cbea Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <blogic@openwrt.org> | ||||
| Date: Wed, 6 Jan 2016 21:55:10 +0100 | ||||
| Subject: [PATCH 02/57] dt-bindings: add MediaTek PCIe binding documentation | ||||
|  | ||||
| Signed-off-by: John Crispin <blogic@openwrt.org> | ||||
| --- | ||||
|  .../devicetree/bindings/pci/mediatek-pcie.txt      | 140 +++++++++++++++++++++ | ||||
|  1 file changed, 140 insertions(+) | ||||
|  create mode 100644 Documentation/devicetree/bindings/pci/mediatek-pcie.txt | ||||
|  | ||||
| --- /dev/null | ||||
| +++ b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt | ||||
| @@ -0,0 +1,140 @@ | ||||
| +Mediatek PCIe controller | ||||
| + | ||||
| +Required properties: | ||||
| +- compatible: Should be one of: | ||||
| +	- "mediatek,mt2701-pcie" | ||||
| +	- "mediatek,mt7623-pcie" | ||||
| +- device_type: Must be "pci" | ||||
| +- reg: A list of physical base address and length for each set of controller | ||||
| +  registers. A list of register ranges to use. Must contain an | ||||
| +    entry for each entry in the reg-names property. | ||||
| +- reg-names: Must include the following entries: | ||||
| +  "pcie": PCIe registers | ||||
| +  "pcie phy0": PCIe PHY0 registers | ||||
| +  "pcie phy1": PCIe PHY0 registers | ||||
| +  "pcie phy2": PCIe PHY0 registers | ||||
| +- interrupts: A list of interrupt outputs of the controller. Must contain an | ||||
| +  entry for each entry in the interrupt-names property. | ||||
| +- interrupt-names: Must include the following entries: | ||||
| +  "pcie0": The interrupt that is asserted for port0 | ||||
| +  "pcie1": The interrupt that is asserted for port1 | ||||
| +  "pcie2": The interrupt that is asserted for port2 | ||||
| +- bus-range: Range of bus numbers associated with this controller | ||||
| +- #address-cells: Address representation for root ports (must be 3) | ||||
| +- #size-cells: Size representation for root ports (must be 2) | ||||
| +- ranges: Describes the translation of addresses for root ports and standard | ||||
| +  PCI regions. The entries must be 6 cells each. | ||||
| +  Please refer to the standard PCI bus binding document for a more detailed | ||||
| +  explanation. | ||||
| +- #interrupt-cells: Size representation for interrupts (must be 1) | ||||
| +- clocks: Must contain an entry for each entry in clock-names. | ||||
| +  See ../clocks/clock-bindings.txt for details. | ||||
| +- clock-names: Must include the following entries: | ||||
| +  - pcie0 | ||||
| +  - pcie1 | ||||
| +  - pcie2 | ||||
| +- resets: Must contain an entry for each entry in reset-names. | ||||
| +  See ../reset/reset.txt for details. | ||||
| +- reset-names: Must include the following entries: | ||||
| +  - pcie0 | ||||
| +  - pcie1 | ||||
| +  - pcie2 | ||||
| +- mediatek,hifsys: Must contain a phandle to the HIFSYS syscon range. | ||||
| +Root ports are defined as subnodes of the PCIe controller node. | ||||
| + | ||||
| +Required properties: | ||||
| +- device_type: Must be "pci" | ||||
| +- assigned-addresses: Address and size of the port configuration registers | ||||
| +- reg: PCI bus address of the root port | ||||
| +- #address-cells: Must be 3 | ||||
| +- #size-cells: Must be 2 | ||||
| +- ranges: Sub-ranges distributed from the PCIe controller node. An empty | ||||
| +  property is sufficient. | ||||
| + | ||||
| +Example: | ||||
| + | ||||
| +SoC DTSI: | ||||
| + | ||||
| +	hifsys: clock-controller@1a000000 { | ||||
| +		compatible = "mediatek,mt7623-hifsys", | ||||
| +			     "mediatek,mt2701-hifsys", | ||||
| +			     "syscon"; | ||||
| +		reg = <0 0x1a000000 0 0x1000>; | ||||
| +		#clock-cells = <1>; | ||||
| +		#reset-cells = <1>; | ||||
| +	}; | ||||
| + | ||||
| +	pcie-controller@1a140000 { | ||||
| +		compatible = "mediatek,mt7623-pcie"; | ||||
| +		device_type = "pci"; | ||||
| +		reg = <0 0x1a140000 0 0x8000>, /* PCI-Express registers */ | ||||
| +		      <0 0x1a149000 0 0x1000>, /* PCI-Express PHY0 */ | ||||
| +		      <0 0x1a14a000 0 0x1000>, /* PCI-Express PHY1 */ | ||||
| +		      <0 0x1a244000 0 0x1000>; /* PCI-Express PHY2 */ | ||||
| +		reg-names = "pcie", "pcie phy0", "pcie phy1", "pcie phy2"; | ||||
| +		interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>, | ||||
| +			     <GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>, | ||||
| +			     <GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; | ||||
| +		interrupt-names = "pcie0", "pcie1", "pcie2"; | ||||
| +		clocks = <&topckgen CLK_TOP_ETHIF_SEL>; | ||||
| +		clock-names = "pcie"; | ||||
| +		power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; | ||||
| +		resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>, | ||||
| +			 <&hifsys MT2701_HIFSYS_PCIE1_RST>, | ||||
| +			 <&hifsys MT2701_HIFSYS_PCIE2_RST>; | ||||
| +		reset-names = "pcie0", "pice1", "pcie2"; | ||||
| + | ||||
| +		bus-range = <0x00 0xff>; | ||||
| +		#address-cells = <3>; | ||||
| +		#size-cells = <2>; | ||||
| + | ||||
| +                mediatek,hifsys = <&hifsys>; | ||||
| + | ||||
| +		ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000 /* io space */ | ||||
| +			  0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* pci memory */ | ||||
| + | ||||
| +		status = "disabled"; | ||||
| + | ||||
| +		pcie@1,0 { | ||||
| +			device_type = "pci"; | ||||
| +			reg = <0x0800 0 0 0 0>; | ||||
| + | ||||
| +			#address-cells = <3>; | ||||
| +			#size-cells = <2>; | ||||
| +			ranges; | ||||
| + | ||||
| +			status = "disabled"; | ||||
| +		}; | ||||
| + | ||||
| +		pcie@2,0{ | ||||
| +			device_type = "pci"; | ||||
| +			reg = <0x1000 0 0 0 0>; | ||||
| + | ||||
| +			#address-cells = <3>; | ||||
| +			#size-cells = <2>; | ||||
| +			ranges; | ||||
| + | ||||
| +			status = "disabled"; | ||||
| +		}; | ||||
| + | ||||
| +		pcie@3,0{ | ||||
| +			device_type = "pci"; | ||||
| +			reg = <0x1800 0 0 0 0>; | ||||
| + | ||||
| +			#address-cells = <3>; | ||||
| +			#size-cells = <2>; | ||||
| +			ranges; | ||||
| + | ||||
| +			status = "disabled"; | ||||
| +		}; | ||||
| +	}; | ||||
| + | ||||
| +Board DTS: | ||||
| + | ||||
| +	pcie-controller { | ||||
| +		status = "okay"; | ||||
| + | ||||
| +		pci@1,0 { | ||||
| +			status = "okay"; | ||||
| +		}; | ||||
| +	}; | ||||
| @@ -1,698 +0,0 @@ | ||||
| From 950bd9b0691dd10209c333086a6bdda0108ed3a8 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <blogic@openwrt.org> | ||||
| Date: Tue, 5 Jan 2016 20:20:04 +0100 | ||||
| Subject: [PATCH 03/57] PCI: mediatek: add support for PCIe found on | ||||
|  MT7623/MT2701 | ||||
|  | ||||
| Add PCIe controller support on MediaTek MT2701/MT7623. The driver supports | ||||
| a single Root complex (RC) with 3 Root Ports. The SoCs supports a Gen2 | ||||
| 1-lan Link on each port. | ||||
|  | ||||
| Signed-off-by: John Crispin <blogic@openwrt.org> | ||||
| --- | ||||
|  arch/arm/mach-mediatek/Kconfig   |   1 + | ||||
|  drivers/pci/host/Kconfig         |  11 + | ||||
|  drivers/pci/host/Makefile        |   1 + | ||||
|  drivers/pci/host/pcie-mediatek.c | 641 +++++++++++++++++++++++++++++++++++++++ | ||||
|  4 files changed, 654 insertions(+) | ||||
|  create mode 100644 drivers/pci/host/pcie-mediatek.c | ||||
|  | ||||
| --- a/arch/arm/mach-mediatek/Kconfig | ||||
| +++ b/arch/arm/mach-mediatek/Kconfig | ||||
| @@ -25,6 +25,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 | ||||
| @@ -301,4 +301,15 @@ config VMD | ||||
|  	  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_ARMADA_8K) += pcie-arm | ||||
|  obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o | ||||
|  obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o | ||||
|  obj-$(CONFIG_VMD) += vmd.o | ||||
| +obj-$(CONFIG_PCIE_MTK) += pcie-mediatek.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/pci/host/pcie-mediatek.c | ||||
| @@ -0,0 +1,641 @@ | ||||
| +/* | ||||
| + *  Mediatek MT2701/MT7623 SoC PCIE support | ||||
| + * | ||||
| + *  Copyright (C) 2015 Mediatek | ||||
| + *  Copyright (C) 2015 Ziv Huang <ziv.huang@mediatek.com> | ||||
| + *  Copyright (C) 2015 John Crispin <blogic@openwrt.org> | ||||
| + * | ||||
| + *  This program is free software; you can redistribute it and/or modify it | ||||
| + *  under the terms of the GNU General Public License version 2 as published | ||||
| + *  by the Free Software Foundation. | ||||
| + */ | ||||
| + | ||||
| +#include <linux/kernel.h> | ||||
| +#include <linux/pci.h> | ||||
| +#include <linux/ioport.h> | ||||
| +#include <linux/interrupt.h> | ||||
| +#include <linux/spinlock.h> | ||||
| +#include <linux/init.h> | ||||
| +#include <linux/device.h> | ||||
| +#include <linux/io.h> | ||||
| +#include <linux/delay.h> | ||||
| +#include <asm/irq.h> | ||||
| +#include <asm/mach/pci.h> | ||||
| +#include <linux/module.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/of_address.h> | ||||
| +#include <linux/of_pci.h> | ||||
| +#include <linux/of_platform.h> | ||||
| +#include <linux/of_irq.h> | ||||
| +#include <linux/reset.h> | ||||
| +#include <linux/platform_device.h> | ||||
| +#include <linux/regulator/consumer.h> | ||||
| +#include <linux/pm_runtime.h> | ||||
| +#include <linux/clk.h> | ||||
| +#include <linux/regmap.h> | ||||
| +#include <linux/mfd/syscon.h> | ||||
| + | ||||
| +#define MEMORY_BASE			0x80000000 | ||||
| + | ||||
| +/* PCIE Registers */ | ||||
| +#define PCICFG				0x00 | ||||
| +#define PCIINT				0x08 | ||||
| +#define PCIENA				0x0c | ||||
| +#define CFGADDR				0x20 | ||||
| +#define CFGDATA				0x24 | ||||
| +#define MEMBASE				0x28 | ||||
| +#define IOBASE				0x2c | ||||
| + | ||||
| +/* per Port Registers */ | ||||
| +#define BAR0SETUP			0x10 | ||||
| +#define IMBASEBAR0			0x18 | ||||
| +#define PCIE_CLASS			0x34 | ||||
| +#define PCIE_SISTAT			0x50 | ||||
| + | ||||
| +#define MTK_PCIE_HIGH_PERF		BIT(14) | ||||
| +#define PCIEP0_BASE			0x2000 | ||||
| +#define PCIEP1_BASE			0x3000 | ||||
| +#define PCIEP2_BASE			0x4000 | ||||
| + | ||||
| +#define PHY_P0_CTL			0x9000 | ||||
| +#define PHY_P1_CTL			0xa000 | ||||
| +#define PHY_P2_CTL			0x4000 | ||||
| + | ||||
| +#define RSTCTL_PCIE0_RST		BIT(24) | ||||
| +#define RSTCTL_PCIE1_RST		BIT(25) | ||||
| +#define RSTCTL_PCIE2_RST		BIT(26) | ||||
| + | ||||
| +#define HIFSYS_SYSCFG1			0x14 | ||||
| +#define HIFSYS_SYSCFG1_PHY2_MASK	(0x3 << 20) | ||||
| + | ||||
| +#define MTK_PHY_CLK			0xb00 | ||||
| +#define MTK_PHY_CLKDRV_OFFSET		BIT(2) | ||||
| +#define MTK_PHY_CLKDRV_OFFSET_MASK	0xe | ||||
| +#define MTK_PHY_PLL			0xb04 | ||||
| +#define MTK_PHY_CLKDRV_AMP		BIT(30) | ||||
| +#define MTK_PHY_CLKDRV_AMP_MASK		0xe0000000 | ||||
| +#define MTK_PHY_REFCLK_SEL		0xc00 | ||||
| +#define MTK_PHY_XTAL_EXT_EN		(BIT(17) | BIT(12)) | ||||
| +#define MTK_PHY_XTAL_EXT_EN_MASK	0x33000 | ||||
| +#define MTK_PHY_PLL_BC			0xc08 | ||||
| +#define MTK_PHY_PLL_BC_PE2H		0xc0 | ||||
| +#define MTK_PHY_PLL_BC_PE2H_MASK	0x380000 | ||||
| +#define MTK_PHY_PLL_IC			0xc0c | ||||
| +#define MTK_PHY_PLL_IC_BR_PE2H		BIT(28) | ||||
| +#define MTK_PHY_PLL_IC_BR_PE2H_MASK	0x30000000 | ||||
| +#define MTK_PHY_PLL_IC_PE2H		BIT(12) | ||||
| +#define MTK_PHY_PLL_IC_PE2H_MASK	0xf000 | ||||
| +#define MTK_PHY_PLL_IR			0xc10 | ||||
| +#define MTK_PHY_PLL_IR_PE2H		BIT(17) | ||||
| +#define MTK_PHY_PLL_IR_PE2H_MASK	0xf0000 | ||||
| +#define MTK_PHY_PLL_BP			0xc14 | ||||
| +#define MTK_PHY_PLL_BP_PE2H		(BIT(19) | BIT(17)) | ||||
| +#define MTK_PHY_PLL_BP_PE2H_MASK	0xf0000 | ||||
| +#define MTK_PHY_SSC_DELTA1		0xc3c | ||||
| +#define MTK_PHY_SSC_DELTA1_PE2H		(0x3c << 16) | ||||
| +#define MTK_PHY_SSC_DELTA1_PE2H_MASK	0xffff0000 | ||||
| +#define MTK_PHY_SSC_DELTA		0xc48 | ||||
| +#define MTK_PHY_SSC_DELTA_PE2H		0x36 | ||||
| +#define MTK_PHY_SSC_DELTA_PE2H_MASK	0xffff | ||||
| + | ||||
| +#define MAX_PORT_NUM			3 | ||||
| + | ||||
| +struct mtk_pcie_port { | ||||
| +	int id; | ||||
| +	int enable; | ||||
| +	int irq; | ||||
| +	u32 link; | ||||
| +	void __iomem *phy_base; | ||||
| +	struct reset_control *rstc; | ||||
| +}; | ||||
| + | ||||
| +#define mtk_foreach_port(pcie, p)			\ | ||||
| +		for ((p) = pcie->port;	\ | ||||
| +		     (p) != &pcie->port[MAX_PORT_NUM]; (p)++) | ||||
| + | ||||
| +struct mtk_pcie { | ||||
| +	struct device *dev; | ||||
| +	void __iomem *pcie_base; | ||||
| +	struct regmap *hifsys; | ||||
| + | ||||
| +	struct resource io; | ||||
| +	struct resource pio; | ||||
| +	struct resource mem; | ||||
| +	struct resource prefetch; | ||||
| +	struct resource busn; | ||||
| + | ||||
| +	u32 io_bus_addr; | ||||
| +	u32 mem_bus_addr; | ||||
| + | ||||
| +	struct clk *clk; | ||||
| + | ||||
| +	struct mtk_pcie_port port[MAX_PORT_NUM]; | ||||
| +	int pcie_card_link; | ||||
| +}; | ||||
| + | ||||
| +static struct mtk_pcie_port_data { | ||||
| +	u32 base; | ||||
| +	u32 perst_n; | ||||
| +	u32 interrupt_en; | ||||
| +} mtk_pcie_port_data[MAX_PORT_NUM] = { | ||||
| +	{ PCIEP0_BASE, BIT(1), BIT(20) }, | ||||
| +	{ PCIEP1_BASE, BIT(2), BIT(21) }, | ||||
| +	{ PCIEP2_BASE, BIT(3), BIT(22) }, | ||||
| +}; | ||||
| + | ||||
| +static const struct mtk_phy_init { | ||||
| +	uint32_t reg; | ||||
| +	uint32_t mask; | ||||
| +	uint32_t val; | ||||
| +} mtk_phy_init[] = { | ||||
| +	{ MTK_PHY_REFCLK_SEL, MTK_PHY_XTAL_EXT_EN_MASK, MTK_PHY_XTAL_EXT_EN }, | ||||
| +	{ MTK_PHY_PLL, MTK_PHY_CLKDRV_AMP_MASK, MTK_PHY_CLKDRV_AMP }, | ||||
| +	{ MTK_PHY_CLK, MTK_PHY_CLKDRV_OFFSET_MASK, MTK_PHY_CLKDRV_OFFSET }, | ||||
| +	{ MTK_PHY_SSC_DELTA1, MTK_PHY_SSC_DELTA1_PE2H_MASK, MTK_PHY_SSC_DELTA1_PE2H }, | ||||
| +	{ MTK_PHY_SSC_DELTA, MTK_PHY_SSC_DELTA_PE2H_MASK, MTK_PHY_SSC_DELTA_PE2H }, | ||||
| +	{ MTK_PHY_PLL_IC, MTK_PHY_PLL_IC_BR_PE2H_MASK, MTK_PHY_PLL_IC_BR_PE2H }, | ||||
| +	{ MTK_PHY_PLL_BC, MTK_PHY_PLL_BC_PE2H_MASK, MTK_PHY_PLL_BC_PE2H }, | ||||
| +	{ MTK_PHY_PLL_IR, MTK_PHY_PLL_IR_PE2H_MASK, MTK_PHY_PLL_IR_PE2H }, | ||||
| +	{ MTK_PHY_PLL_IC, MTK_PHY_PLL_IC_PE2H_MASK, MTK_PHY_PLL_IC_PE2H }, | ||||
| +	{ MTK_PHY_PLL_BP, MTK_PHY_PLL_BP_PE2H_MASK, MTK_PHY_PLL_BP_PE2H }, | ||||
| +}; | ||||
| + | ||||
| +static struct mtk_pcie *sys_to_pcie(struct pci_sys_data *sys) | ||||
| +{ | ||||
| +	return sys->private_data; | ||||
| +} | ||||
| + | ||||
| +static void pcie_w32(struct mtk_pcie *pcie, u32 val, unsigned reg) | ||||
| +{ | ||||
| +	iowrite32(val, pcie->pcie_base + reg); | ||||
| +} | ||||
| + | ||||
| +static u32 pcie_r32(struct mtk_pcie *pcie, unsigned reg) | ||||
| +{ | ||||
| +	return ioread32(pcie->pcie_base + reg); | ||||
| +} | ||||
| + | ||||
| +static void pcie_m32(struct mtk_pcie *pcie, u32 mask, u32 val, unsigned reg) | ||||
| +{ | ||||
| +	u32 v = pcie_r32(pcie, reg); | ||||
| + | ||||
| +	v &= mask; | ||||
| +	v |= val; | ||||
| +	pcie_w32(pcie, v, reg); | ||||
| +} | ||||
| + | ||||
| +static int pcie_config_read(struct pci_bus *bus, unsigned int devfn, int where, | ||||
| +			    int size, u32 *val) | ||||
| +{ | ||||
| +	struct mtk_pcie *pcie = sys_to_pcie(bus->sysdata); | ||||
| +	unsigned int slot = PCI_SLOT(devfn); | ||||
| +	u8 func = PCI_FUNC(devfn); | ||||
| +	u32 address; | ||||
| +	u32 data; | ||||
| +	u32 num = 0; | ||||
| + | ||||
| +	if (bus) | ||||
| +		num = bus->number; | ||||
| + | ||||
| +	address = (((where & 0xf00) >> 8) << 24) | | ||||
| +		  (num << 16) | | ||||
| +		  (slot << 11) | | ||||
| +		  (func << 8) | | ||||
| +		  (where & 0xfc); | ||||
| + | ||||
| +	pcie_w32(pcie, address, CFGADDR); | ||||
| +	data = pcie_r32(pcie, CFGDATA); | ||||
| + | ||||
| +	switch (size) { | ||||
| +	case 1: | ||||
| +		*val = (data >> ((where & 3) << 3)) & 0xff; | ||||
| +		break; | ||||
| +	case 2: | ||||
| +		*val = (data >> ((where & 3) << 3)) & 0xffff; | ||||
| +		break; | ||||
| +	case 4: | ||||
| +		*val = data; | ||||
| +		break; | ||||
| +	} | ||||
| + | ||||
| +	return PCIBIOS_SUCCESSFUL; | ||||
| +} | ||||
| + | ||||
| +static int pcie_config_write(struct pci_bus *bus, unsigned int devfn, int where, | ||||
| +			     int size, u32 val) | ||||
| +{ | ||||
| +	struct mtk_pcie *pcie = sys_to_pcie(bus->sysdata); | ||||
| +	unsigned int slot = PCI_SLOT(devfn); | ||||
| +	u8 func = PCI_FUNC(devfn); | ||||
| +	u32 address; | ||||
| +	u32 data; | ||||
| +	u32 num = 0; | ||||
| + | ||||
| +	if (bus) | ||||
| +		num = bus->number; | ||||
| + | ||||
| +	address = (((where & 0xf00) >> 8) << 24) | | ||||
| +		  (num << 16) | (slot << 11) | (func << 8) | (where & 0xfc); | ||||
| +	pcie_w32(pcie, address, CFGADDR); | ||||
| +	data = pcie_r32(pcie, CFGDATA); | ||||
| + | ||||
| +	switch (size) { | ||||
| +	case 1: | ||||
| +		data = (data & ~(0xff << ((where & 3) << 3))) | | ||||
| +		       (val << ((where & 3) << 3)); | ||||
| +		break; | ||||
| +	case 2: | ||||
| +		data = (data & ~(0xffff << ((where & 3) << 3))) | | ||||
| +		       (val << ((where & 3) << 3)); | ||||
| +		break; | ||||
| +	case 4: | ||||
| +		data = val; | ||||
| +		break; | ||||
| +	} | ||||
| +	pcie_w32(pcie, data, CFGDATA); | ||||
| + | ||||
| +	return PCIBIOS_SUCCESSFUL; | ||||
| +} | ||||
| + | ||||
| +static struct pci_ops mtk_pcie_ops = { | ||||
| +	.read   = pcie_config_read, | ||||
| +	.write  = pcie_config_write, | ||||
| +}; | ||||
| + | ||||
| +static int __init mtk_pcie_setup(int nr, struct pci_sys_data *sys) | ||||
| +{ | ||||
| +	struct mtk_pcie *pcie = sys_to_pcie(sys); | ||||
| + | ||||
| +	request_resource(&ioport_resource, &pcie->pio); | ||||
| +	request_resource(&iomem_resource, &pcie->mem); | ||||
| + | ||||
| +	pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset); | ||||
| +	pci_add_resource_offset(&sys->resources, &pcie->pio, sys->io_offset); | ||||
| +	pci_add_resource(&sys->resources, &pcie->busn); | ||||
| + | ||||
| +	return 1; | ||||
| +} | ||||
| + | ||||
| +static struct pci_bus * __init mtk_pcie_scan_bus(int nr, | ||||
| +						struct pci_sys_data *sys) | ||||
| +{ | ||||
| +	struct mtk_pcie *pcie = sys_to_pcie(sys); | ||||
| +	struct pci_bus *bus; | ||||
| + | ||||
| +	bus = pci_create_root_bus(pcie->dev, sys->busnr, &mtk_pcie_ops, sys, | ||||
| +				  &sys->resources); | ||||
| +	if (!bus) | ||||
| +		return NULL; | ||||
| + | ||||
| +	pci_scan_child_bus(bus); | ||||
| + | ||||
| +	return bus; | ||||
| +} | ||||
| + | ||||
| +static int __init mtk_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||||
| +{ | ||||
| +	struct mtk_pcie *pcie = sys_to_pcie(dev->bus->sysdata); | ||||
| +	struct mtk_pcie_port *port; | ||||
| +	int irq = -1; | ||||
| + | ||||
| +	mtk_foreach_port(pcie, port) | ||||
| +		if (port->id == slot) | ||||
| +			irq = port->irq; | ||||
| + | ||||
| +	return irq; | ||||
| +} | ||||
| + | ||||
| +static void mtk_pcie_configure_phy(struct mtk_pcie *pcie, | ||||
| +				   struct mtk_pcie_port *port) | ||||
| +{ | ||||
| +	int i; | ||||
| + | ||||
| +	for (i = 0; i < ARRAY_SIZE(mtk_phy_init); i++) { | ||||
| +		void __iomem *phy_addr = port->phy_base + mtk_phy_init[i].reg; | ||||
| +		u32 val = ioread32(phy_addr); | ||||
| + | ||||
| +		val &= ~mtk_phy_init[i].mask; | ||||
| +		val |= mtk_phy_init[i].val; | ||||
| +		iowrite32(val, phy_addr); | ||||
| +	} | ||||
| +	usleep_range(5000, 6000); | ||||
| +} | ||||
| + | ||||
| +static void mtk_pcie_configure_rc(struct mtk_pcie *pcie, | ||||
| +				  struct mtk_pcie_port *port, | ||||
| +				  struct pci_bus *bus) | ||||
| +{ | ||||
| +	u32 val = 0; | ||||
| + | ||||
| +	pcie_config_write(bus, | ||||
| +			  port->id << 3, | ||||
| +			  PCI_BASE_ADDRESS_0, 4, MEMORY_BASE); | ||||
| + | ||||
| +	pcie_config_read(bus, | ||||
| +			 port->id << 3, PCI_BASE_ADDRESS_0, 4, &val); | ||||
| + | ||||
| +	/* Configure RC Credit */ | ||||
| +	pcie_config_read(bus, port->id << 3, 0x73c, 4, &val); | ||||
| +	val &= ~(0x9fff) << 16; | ||||
| +	val |= 0x806c << 16; | ||||
| +	pcie_config_write(bus, port->id << 3, 0x73c, 4, val); | ||||
| + | ||||
| +	/* Configure RC FTS number */ | ||||
| +	pcie_config_read(bus, port->id << 3, 0x70c, 4, &val); | ||||
| +	val &= ~(0xff3) << 8; | ||||
| +	val |= 0x50 << 8; | ||||
| +	pcie_config_write(bus, port->id << 3, 0x70c, 4, val); | ||||
| +} | ||||
| + | ||||
| +static int mtk_pcie_preinit(struct mtk_pcie *pcie) | ||||
| +{ | ||||
| +	struct mtk_pcie_port *port; | ||||
| +	u32 val = 0; | ||||
| +	struct pci_bus bus; | ||||
| +	struct pci_sys_data sys; | ||||
| + | ||||
| +	memset(&bus, 0, sizeof(bus)); | ||||
| +	memset(&sys, 0, sizeof(sys)); | ||||
| +	bus.sysdata = (void *)&sys; | ||||
| +	sys.private_data = (void *)pcie; | ||||
| + | ||||
| +	pcibios_min_io = 0; | ||||
| +	pcibios_min_mem = 0; | ||||
| + | ||||
| +	/* The PHY on Port 2 is shared with USB */ | ||||
| +	if (pcie->port[2].enable) | ||||
| +		regmap_update_bits(pcie->hifsys, HIFSYS_SYSCFG1, | ||||
| +				   HIFSYS_SYSCFG1_PHY2_MASK, 0x0); | ||||
| + | ||||
| +	/* PCIe RC Reset */ | ||||
| +	mtk_foreach_port(pcie, port) | ||||
| +		if (port->enable) | ||||
| +			reset_control_assert(port->rstc); | ||||
| +	usleep_range(1000, 2000); | ||||
| +	mtk_foreach_port(pcie, port) | ||||
| +		if (port->enable) | ||||
| +			reset_control_deassert(port->rstc); | ||||
| +	usleep_range(1000, 2000); | ||||
| + | ||||
| +	/* Configure PCIe PHY */ | ||||
| +	mtk_foreach_port(pcie, port) | ||||
| +		if (port->enable) | ||||
| +			mtk_pcie_configure_phy(pcie, port); | ||||
| + | ||||
| +	/* PCIe EP reset */ | ||||
| +	val = 0; | ||||
| +	mtk_foreach_port(pcie, port) | ||||
| +		if (port->enable) | ||||
| +			val |= mtk_pcie_port_data[port->id].perst_n; | ||||
| +	pcie_w32(pcie, pcie_r32(pcie, PCICFG) | val, PCICFG); | ||||
| +	usleep_range(1000, 2000); | ||||
| +	pcie_w32(pcie, pcie_r32(pcie, PCICFG) & ~val, PCICFG); | ||||
| +	usleep_range(1000, 2000); | ||||
| +	msleep(100); | ||||
| + | ||||
| +	/* check the link status */ | ||||
| +	val = 0; | ||||
| +	mtk_foreach_port(pcie, port) { | ||||
| +		if (port->enable) { | ||||
| +			u32 base = mtk_pcie_port_data[port->id].base; | ||||
| + | ||||
| +			if ((pcie_r32(pcie, base + PCIE_SISTAT) & 0x1)) | ||||
| +				port->link = 1; | ||||
| +			else | ||||
| +				reset_control_assert(port->rstc); | ||||
| +		} | ||||
| +	} | ||||
| + | ||||
| +	mtk_foreach_port(pcie, port) | ||||
| +		if (port->link) | ||||
| +			pcie->pcie_card_link++; | ||||
| + | ||||
| +	if (!pcie->pcie_card_link) | ||||
| +		return -ENODEV; | ||||
| + | ||||
| +	pcie_w32(pcie, pcie->mem_bus_addr, MEMBASE); | ||||
| +	pcie_w32(pcie, pcie->io_bus_addr, IOBASE); | ||||
| + | ||||
| +	mtk_foreach_port(pcie, port) { | ||||
| +		if (port->link) { | ||||
| +			u32 base = mtk_pcie_port_data[port->id].base; | ||||
| +			u32 inte = mtk_pcie_port_data[port->id].interrupt_en; | ||||
| + | ||||
| +			pcie_m32(pcie, 0, inte, PCIENA); | ||||
| +			pcie_w32(pcie, 0x7fff0001, base + BAR0SETUP); | ||||
| +			pcie_w32(pcie, MEMORY_BASE, base + IMBASEBAR0); | ||||
| +			pcie_w32(pcie, 0x06040001, base + PCIE_CLASS); | ||||
| +		} | ||||
| +	} | ||||
| + | ||||
| +	mtk_foreach_port(pcie, port) | ||||
| +		if (port->link) | ||||
| +			mtk_pcie_configure_rc(pcie, port, &bus); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int mtk_pcie_parse_dt(struct mtk_pcie *pcie) | ||||
| +{ | ||||
| +	struct device_node *np = pcie->dev->of_node, *port; | ||||
| +	struct of_pci_range_parser parser; | ||||
| +	struct of_pci_range range; | ||||
| +	struct resource res; | ||||
| +	int err; | ||||
| + | ||||
| +	pcie->hifsys = syscon_regmap_lookup_by_phandle(np, "mediatek,hifsys"); | ||||
| +	if (IS_ERR(pcie->hifsys)) { | ||||
| +		dev_err(pcie->dev, "missing \"mediatek,hifsys\" phandle\n"); | ||||
| +		return PTR_ERR(pcie->hifsys); | ||||
| +	} | ||||
| + | ||||
| +	if (of_pci_range_parser_init(&parser, np)) { | ||||
| +		dev_err(pcie->dev, "missing \"ranges\" property\n"); | ||||
| +		return -EINVAL; | ||||
| +	} | ||||
| + | ||||
| +	for_each_of_pci_range(&parser, &range) { | ||||
| +		err = of_pci_range_to_resource(&range, np, &res); | ||||
| +		if (err < 0) { | ||||
| +			dev_err(pcie->dev, "failed to read resource range\n"); | ||||
| +			return err; | ||||
| +		} | ||||
| + | ||||
| +		switch (res.flags & IORESOURCE_TYPE_BITS) { | ||||
| +		case IORESOURCE_IO: | ||||
| +			memcpy(&pcie->pio, &res, sizeof(res)); | ||||
| +			pcie->pio.start = (resource_size_t)range.pci_addr; | ||||
| +			pcie->pio.end = (resource_size_t) | ||||
| +					(range.pci_addr + range.size - 1); | ||||
| +			pcie->io_bus_addr = (resource_size_t)range.cpu_addr; | ||||
| +			break; | ||||
| + | ||||
| +		case IORESOURCE_MEM: | ||||
| +			if (res.flags & IORESOURCE_PREFETCH) { | ||||
| +				memcpy(&pcie->prefetch, &res, sizeof(res)); | ||||
| +				pcie->prefetch.name = "prefetchable"; | ||||
| +				pcie->prefetch.start = | ||||
| +					(resource_size_t)range.pci_addr; | ||||
| +				pcie->prefetch.end = (resource_size_t) | ||||
| +					(range.pci_addr + range.size - 1); | ||||
| +			} else { | ||||
| +				memcpy(&pcie->mem, &res, sizeof(res)); | ||||
| +				pcie->mem.name = "non-prefetchable"; | ||||
| +				pcie->mem.start = (resource_size_t) | ||||
| +					range.pci_addr; | ||||
| +				pcie->prefetch.end = (resource_size_t) | ||||
| +					(range.pci_addr + range.size - 1); | ||||
| +				pcie->mem_bus_addr = (resource_size_t) | ||||
| +					range.cpu_addr; | ||||
| +			} | ||||
| +			break; | ||||
| +		} | ||||
| +	} | ||||
| + | ||||
| +	err = of_pci_parse_bus_range(np, &pcie->busn); | ||||
| +	if (err < 0) { | ||||
| +		dev_err(pcie->dev, "failed to parse ranges property: %d\n", | ||||
| +			err); | ||||
| +		pcie->busn.name = np->name; | ||||
| +		pcie->busn.start = 0; | ||||
| +		pcie->busn.end = 0xff; | ||||
| +		pcie->busn.flags = IORESOURCE_BUS; | ||||
| +	} | ||||
| + | ||||
| +	/* parse root ports */ | ||||
| +	for_each_child_of_node(np, port) { | ||||
| +		unsigned int index; | ||||
| +		char rst[] = "pcie0"; | ||||
| + | ||||
| +		err = of_pci_get_devfn(port); | ||||
| +		if (err < 0) { | ||||
| +			dev_err(pcie->dev, "failed to parse address: %d\n", | ||||
| +				err); | ||||
| +			return err; | ||||
| +		} | ||||
| + | ||||
| +		index = PCI_SLOT(err); | ||||
| +		if (index > MAX_PORT_NUM) { | ||||
| +			dev_err(pcie->dev, "invalid port number: %d\n", index); | ||||
| +			continue; | ||||
| +		} | ||||
| +		index--; | ||||
| +		pcie->port[index].id = index; | ||||
| + | ||||
| +		if (!of_device_is_available(port)) | ||||
| +			continue; | ||||
| + | ||||
| +		rst[4] += index; | ||||
| +		pcie->port[index].rstc = devm_reset_control_get(pcie->dev, | ||||
| +								   rst); | ||||
| +		if (!IS_ERR(pcie->port[index].rstc)) | ||||
| +			pcie->port[index].enable = 1; | ||||
| +	} | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int mtk_pcie_get_resources(struct mtk_pcie *pcie) | ||||
| +{ | ||||
| +	struct platform_device *pdev = to_platform_device(pcie->dev); | ||||
| +	struct mtk_pcie_port *port; | ||||
| +	struct resource *res; | ||||
| + | ||||
| +	pcie->clk = devm_clk_get(&pdev->dev, "pcie"); | ||||
| +	if (IS_ERR(pcie->clk)) { | ||||
| +		dev_err(&pdev->dev, "Failed to get pcie clk\n"); | ||||
| +		return PTR_ERR(pcie->clk); | ||||
| +	} | ||||
| + | ||||
| +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||||
| +	pcie->pcie_base = devm_ioremap_resource(&pdev->dev, res); | ||||
| +	if (IS_ERR(pcie->pcie_base)) { | ||||
| +		dev_err(&pdev->dev, "Failed to get pcie range\n"); | ||||
| +		return PTR_ERR(pcie->pcie_base); | ||||
| +	} | ||||
| + | ||||
| +	mtk_foreach_port(pcie, port) { | ||||
| +		if (!port->enable) | ||||
| +			continue; | ||||
| +		res = platform_get_resource(pdev, IORESOURCE_MEM, port->id + 1); | ||||
| +		port->phy_base = devm_ioremap_resource(&pdev->dev, res); | ||||
| +		if (IS_ERR(port->phy_base)) { | ||||
| +			dev_err(&pdev->dev, "Failed to get pcie phy%d range %p\n", | ||||
| +				port->id, port->phy_base); | ||||
| +			return PTR_ERR(port->phy_base); | ||||
| +		} | ||||
| +		port->irq = platform_get_irq(pdev, port->id); | ||||
| +	} | ||||
| + | ||||
| +	return clk_prepare_enable(pcie->clk); | ||||
| +} | ||||
| + | ||||
| +static int mtk_pcie_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct mtk_pcie *pcie; | ||||
| +	struct hw_pci hw; | ||||
| +	int ret; | ||||
| + | ||||
| +	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL); | ||||
| +	if (!pcie) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	pcie->dev = &pdev->dev; | ||||
| +	ret = mtk_pcie_parse_dt(pcie); | ||||
| +	if (ret < 0) | ||||
| +		return ret; | ||||
| + | ||||
| +	pm_runtime_enable(&pdev->dev); | ||||
| +	pm_runtime_get_sync(&pdev->dev); | ||||
| + | ||||
| +	ret = mtk_pcie_get_resources(pcie); | ||||
| +	if (ret < 0) { | ||||
| +		dev_err(&pdev->dev, "failed to request resources: %d\n", ret); | ||||
| +		goto err_out; | ||||
| +	} | ||||
| + | ||||
| +	ret = mtk_pcie_preinit(pcie); | ||||
| +	if (ret) | ||||
| +		return ret; | ||||
| + | ||||
| +	memset(&hw, 0, sizeof(hw)); | ||||
| +	hw.nr_controllers = 1; | ||||
| +	hw.private_data = (void **)&pcie; | ||||
| +	hw.setup = mtk_pcie_setup; | ||||
| +	hw.map_irq = mtk_pcie_map_irq; | ||||
| +	hw.scan = mtk_pcie_scan_bus; | ||||
| + | ||||
| +	pci_common_init_dev(pcie->dev, &hw); | ||||
| +	platform_set_drvdata(pdev, pcie); | ||||
| + | ||||
| +	return 0; | ||||
| + | ||||
| +err_out: | ||||
| +	clk_disable_unprepare(pcie->clk); | ||||
| +	pm_runtime_put_sync(&pdev->dev); | ||||
| +	pm_runtime_disable(&pdev->dev); | ||||
| + | ||||
| +	return ret; | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id mtk_pcie_ids[] = { | ||||
| +	{ .compatible = "mediatek,mt2701-pcie" }, | ||||
| +	{ .compatible = "mediatek,mt7623-pcie" }, | ||||
| +	{}, | ||||
| +}; | ||||
| +MODULE_DEVICE_TABLE(of, mtk_pcie_ids); | ||||
| + | ||||
| +static struct platform_driver mtk_pcie_driver = { | ||||
| +	.probe = mtk_pcie_probe, | ||||
| +	.driver = { | ||||
| +		.name = "mediatek-pcie", | ||||
| +		.owner = THIS_MODULE, | ||||
| +		.of_match_table = of_match_ptr(mtk_pcie_ids), | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +static int __init mtk_pcie_init(void) | ||||
| +{ | ||||
| +	return platform_driver_register(&mtk_pcie_driver); | ||||
| +} | ||||
| + | ||||
| +module_init(mtk_pcie_init); | ||||
| @@ -1,75 +0,0 @@ | ||||
| From 2f47c01fe3015f4c649849ddffe04f12a122abe2 Mon Sep 17 00:00:00 2001 | ||||
| From: Shunli Wang <shunli.wang@mediatek.com> | ||||
| Date: Thu, 20 Oct 2016 16:56:37 +0800 | ||||
| Subject: [PATCH 04/57] soc: mediatek: Add MT2701 power dt-bindings | ||||
|  | ||||
| Add power dt-bindings for MT2701. | ||||
|  | ||||
| Signed-off-by: Shunli Wang <shunli.wang@mediatek.com> | ||||
| Signed-off-by: James Liao <jamesjj.liao@mediatek.com> | ||||
| Acked-by: Rob Herring <robh@kernel.org> | ||||
| Reviewed-by: Kevin Hilman <khilman@baylibre.com> | ||||
| Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com> | ||||
| --- | ||||
|  .../devicetree/bindings/soc/mediatek/scpsys.txt    | 13 ++++++----- | ||||
|  include/dt-bindings/power/mt2701-power.h           | 26 ++++++++++++++++++++++ | ||||
|  2 files changed, 34 insertions(+), 5 deletions(-) | ||||
|  create mode 100644 include/dt-bindings/power/mt2701-power.h | ||||
|  | ||||
| --- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt | ||||
| +++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt | ||||
| @@ -9,17 +9,20 @@ domain control. | ||||
|   | ||||
|  The driver implements the Generic PM domain bindings described in | ||||
|  power/power_domain.txt. It provides the power domains defined in | ||||
| -include/dt-bindings/power/mt8173-power.h. | ||||
| +include/dt-bindings/power/mt8173-power.h and mt2701-power.h. | ||||
|   | ||||
|  Required properties: | ||||
| -- compatible: Must be "mediatek,mt8173-scpsys" | ||||
| +- compatible: Should be one of: | ||||
| +	- "mediatek,mt2701-scpsys" | ||||
| +	- "mediatek,mt8173-scpsys" | ||||
|  - #power-domain-cells: Must be 1 | ||||
|  - reg: Address range of the SCPSYS unit | ||||
|  - infracfg: must contain a phandle to the infracfg controller | ||||
|  - clock, clock-names: clocks according to the common clock binding. | ||||
| -                      The clocks needed "mm", "mfg", "venc" and "venc_lt". | ||||
| -		      These are the clocks which hardware needs to be enabled | ||||
| -		      before enabling certain power domains. | ||||
| +                      These are clocks which hardware needs to be | ||||
| +                      enabled before enabling certain power domains. | ||||
| +	Required clocks for MT2701: "mm", "mfg", "ethif" | ||||
| +	Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt" | ||||
|   | ||||
|  Optional properties: | ||||
|  - vdec-supply: Power supply for the vdec power domain | ||||
| --- /dev/null | ||||
| +++ b/include/dt-bindings/power/mt2701-power.h | ||||
| @@ -0,0 +1,26 @@ | ||||
| +/* | ||||
| + * 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_IFR_MSC	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 | ||||
| + | ||||
| +#endif /* _DT_BINDINGS_POWER_MT2701_POWER_H */ | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,29 +0,0 @@ | ||||
| From 60c14df3cc898b6b03d66ec725f9705bf431b677 Mon Sep 17 00:00:00 2001 | ||||
| From: Erin Lo <erin.lo@mediatek.com> | ||||
| Date: Mon, 28 Dec 2015 15:09:02 +0800 | ||||
| Subject: [PATCH 07/57] ARM: mediatek: Add MT2701 config options for mediatek | ||||
|  SoCs. | ||||
|  | ||||
| The upcoming MTK pinctrl driver have a big pin table for each SoC | ||||
| and we don't want to bloat the kernel binary if we don't need it. | ||||
| Add config options so we can build for one SoC only. Add MT2701. | ||||
|  | ||||
| Signed-off-by: Erin Lo <erin.lo@mediatek.com> | ||||
| Acked-by: Linus Walleij <linus.walleij@linaro.org> | ||||
| --- | ||||
|  arch/arm/mach-mediatek/Kconfig | 4 ++++ | ||||
|  1 file changed, 4 insertions(+) | ||||
|  | ||||
| --- a/arch/arm/mach-mediatek/Kconfig | ||||
| +++ b/arch/arm/mach-mediatek/Kconfig | ||||
| @@ -14,6 +14,10 @@ config MACH_MT2701 | ||||
|  	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 | ||||
| @@ -1,487 +0,0 @@ | ||||
| From b5a1e520d8039c242b2157b511f684ce464d6e21 Mon Sep 17 00:00:00 2001 | ||||
| From: James Liao <jamesjj.liao@mediatek.com> | ||||
| Date: Thu, 20 Oct 2016 16:56:35 +0800 | ||||
| Subject: [PATCH 08/57] soc: mediatek: Refine scpsys to support multiple | ||||
|  platform | ||||
|  | ||||
| Refine scpsys driver common code to support multiple SoC / platform. | ||||
|  | ||||
| Signed-off-by: James Liao <jamesjj.liao@mediatek.com> | ||||
| Reviewed-by: Kevin Hilman <khilman@baylibre.com> | ||||
| Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com> | ||||
| --- | ||||
|  drivers/soc/mediatek/mtk-scpsys.c | 348 +++++++++++++++++++++++--------------- | ||||
|  1 file changed, 210 insertions(+), 138 deletions(-) | ||||
|  | ||||
| --- a/drivers/soc/mediatek/mtk-scpsys.c | ||||
| +++ b/drivers/soc/mediatek/mtk-scpsys.c | ||||
| @@ -11,17 +11,15 @@ | ||||
|   * GNU General Public License for more details. | ||||
|   */ | ||||
|  #include <linux/clk.h> | ||||
| -#include <linux/delay.h> | ||||
| +#include <linux/init.h> | ||||
|  #include <linux/io.h> | ||||
| -#include <linux/kernel.h> | ||||
|  #include <linux/mfd/syscon.h> | ||||
| -#include <linux/init.h> | ||||
|  #include <linux/of_device.h> | ||||
|  #include <linux/platform_device.h> | ||||
|  #include <linux/pm_domain.h> | ||||
| -#include <linux/regmap.h> | ||||
| -#include <linux/soc/mediatek/infracfg.h> | ||||
|  #include <linux/regulator/consumer.h> | ||||
| +#include <linux/soc/mediatek/infracfg.h> | ||||
| + | ||||
|  #include <dt-bindings/power/mt8173-power.h> | ||||
|   | ||||
|  #define SPM_VDE_PWR_CON			0x0210 | ||||
| @@ -34,6 +32,7 @@ | ||||
|  #define SPM_MFG_2D_PWR_CON		0x02c0 | ||||
|  #define SPM_MFG_ASYNC_PWR_CON		0x02c4 | ||||
|  #define SPM_USB_PWR_CON			0x02cc | ||||
| + | ||||
|  #define SPM_PWR_STATUS			0x060c | ||||
|  #define SPM_PWR_STATUS_2ND		0x0610 | ||||
|   | ||||
| @@ -55,12 +54,21 @@ | ||||
|  #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, | ||||
| +	CLK_NONE, | ||||
| +	CLK_MM, | ||||
| +	CLK_MFG, | ||||
| +	CLK_VENC, | ||||
| +	CLK_VENC_LT, | ||||
| +	CLK_MAX, | ||||
| +}; | ||||
| + | ||||
| +static const char * const clk_names[] = { | ||||
| +	NULL, | ||||
| +	"mm", | ||||
| +	"mfg", | ||||
| +	"venc", | ||||
| +	"venc_lt", | ||||
| +	NULL, | ||||
|  }; | ||||
|   | ||||
|  #define MAX_CLKS	2 | ||||
| @@ -76,98 +84,6 @@ struct scp_domain_data { | ||||
|  	bool active_wakeup; | ||||
|  }; | ||||
|   | ||||
| -static const struct scp_domain_data scp_domain_data[] = { | ||||
| -	[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 { | ||||
| @@ -179,7 +95,7 @@ struct scp_domain { | ||||
|  }; | ||||
|   | ||||
|  struct scp { | ||||
| -	struct scp_domain domains[NUM_DOMAINS]; | ||||
| +	struct scp_domain *domains; | ||||
|  	struct genpd_onecell_data pd_data; | ||||
|  	struct device *dev; | ||||
|  	void __iomem *base; | ||||
| @@ -408,57 +324,55 @@ static bool scpsys_active_wakeup(struct | ||||
|  	return scpd->data->active_wakeup; | ||||
|  } | ||||
|   | ||||
| -static int scpsys_probe(struct platform_device *pdev) | ||||
| +static void init_clks(struct platform_device *pdev, struct clk **clk) | ||||
| +{ | ||||
| +	int i; | ||||
| + | ||||
| +	for (i = CLK_NONE + 1; i < CLK_MAX; i++) | ||||
| +		clk[i] = devm_clk_get(&pdev->dev, clk_names[i]); | ||||
| +} | ||||
| + | ||||
| +static 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); | ||||
| +		return ERR_CAST(scp->base); | ||||
| + | ||||
| +	scp->domains = devm_kzalloc(&pdev->dev, | ||||
| +				sizeof(*scp->domains) * num, GFP_KERNEL); | ||||
| +	if (!scp->domains) | ||||
| +		return ERR_PTR(-ENOMEM); | ||||
|   | ||||
|  	pd_data = &scp->pd_data; | ||||
|   | ||||
|  	pd_data->domains = devm_kzalloc(&pdev->dev, | ||||
| -			sizeof(*pd_data->domains) * NUM_DOMAINS, GFP_KERNEL); | ||||
| +			sizeof(*pd_data->domains) * num, 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_PTR(-ENOMEM); | ||||
|   | ||||
|  	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); | ||||
|  	} | ||||
|   | ||||
| -	for (i = 0; i < NUM_DOMAINS; i++) { | ||||
| +	for (i = 0; i < num; i++) { | ||||
|  		struct scp_domain *scpd = &scp->domains[i]; | ||||
|  		const struct scp_domain_data *data = &scp_domain_data[i]; | ||||
|   | ||||
| @@ -467,13 +381,15 @@ static int scpsys_probe(struct platform_ | ||||
|  			if (PTR_ERR(scpd->supply) == -ENODEV) | ||||
|  				scpd->supply = NULL; | ||||
|  			else | ||||
| -				return PTR_ERR(scpd->supply); | ||||
| +				return ERR_CAST(scpd->supply); | ||||
|  		} | ||||
|  	} | ||||
|   | ||||
| -	pd_data->num_domains = NUM_DOMAINS; | ||||
| +	pd_data->num_domains = num; | ||||
| + | ||||
| +	init_clks(pdev, clk); | ||||
|   | ||||
| -	for (i = 0; i < NUM_DOMAINS; i++) { | ||||
| +	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]; | ||||
| @@ -482,13 +398,37 @@ static int scpsys_probe(struct platform_ | ||||
|  		scpd->scp = scp; | ||||
|   | ||||
|  		scpd->data = data; | ||||
| -		for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) | ||||
| -			scpd->clk[j] = clk[data->clk_id[j]]; | ||||
| + | ||||
| +		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; | ||||
| +		} | ||||
|   | ||||
|  		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; | ||||
| +} | ||||
| + | ||||
| +static 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 | ||||
| @@ -507,6 +447,123 @@ static int scpsys_probe(struct platform_ | ||||
|  	 * valid. | ||||
|  	 */ | ||||
|   | ||||
| +	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); | ||||
| +} | ||||
| + | ||||
| +/* | ||||
| + * MT8173 power domain support | ||||
| + */ | ||||
| + | ||||
| +static const struct scp_domain_data scp_domain_data_mt8173[] = { | ||||
| +	[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_MT8173	ARRAY_SIZE(scp_domain_data_mt8173) | ||||
| + | ||||
| +static int __init scpsys_probe_mt8173(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct scp *scp; | ||||
| +	struct genpd_onecell_data *pd_data; | ||||
| +	int ret; | ||||
| + | ||||
| +	scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173); | ||||
| +	if (IS_ERR(scp)) | ||||
| +		return PTR_ERR(scp); | ||||
| + | ||||
| +	mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT8173); | ||||
| + | ||||
| +	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)) | ||||
| @@ -517,21 +574,36 @@ static int scpsys_probe(struct platform_ | ||||
|  	if (ret && IS_ENABLED(CONFIG_PM)) | ||||
|  		dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); | ||||
|   | ||||
| -	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; | ||||
|  } | ||||
|   | ||||
| +/* | ||||
| + * scpsys driver init | ||||
| + */ | ||||
| + | ||||
|  static const struct of_device_id of_scpsys_match_tbl[] = { | ||||
|  	{ | ||||
|  		.compatible = "mediatek,mt8173-scpsys", | ||||
| +		.data = scpsys_probe_mt8173, | ||||
|  	}, { | ||||
|  		/* sentinel */ | ||||
|  	} | ||||
|  }; | ||||
|   | ||||
| +static int scpsys_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	int (*probe)(struct platform_device *); | ||||
| +	const struct of_device_id *of_id; | ||||
| + | ||||
| +	of_id = of_match_node(of_scpsys_match_tbl, pdev->dev.of_node); | ||||
| +	if (!of_id || !of_id->data) | ||||
| +		return -EINVAL; | ||||
| + | ||||
| +	probe = of_id->data; | ||||
| + | ||||
| +	return probe(pdev); | ||||
| +} | ||||
| + | ||||
|  static struct platform_driver scpsys_drv = { | ||||
|  	.probe = scpsys_probe, | ||||
|  	.driver = { | ||||
| @@ -1,194 +0,0 @@ | ||||
| From fb9f97e047f5a831a54cd61529b8cfdc4d413bb6 Mon Sep 17 00:00:00 2001 | ||||
| From: Shunli Wang <shunli.wang@mediatek.com> | ||||
| Date: Thu, 20 Oct 2016 16:56:38 +0800 | ||||
| Subject: [PATCH 09/57] soc: mediatek: Add MT2701 scpsys driver | ||||
|  | ||||
| Add scpsys driver for MT2701. | ||||
|  | ||||
| mtk-scpsys now supports MT8173 (arm64) and MT2701 (arm). So it should | ||||
| be enabled on both arm64 and arm platforms. | ||||
|  | ||||
| Signed-off-by: Shunli Wang <shunli.wang@mediatek.com> | ||||
| Signed-off-by: James Liao <jamesjj.liao@mediatek.com> | ||||
| Reviewed-by: Kevin Hilman <khilman@baylibre.com> | ||||
| Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com> | ||||
| --- | ||||
|  drivers/soc/mediatek/Kconfig      |   2 +- | ||||
|  drivers/soc/mediatek/mtk-scpsys.c | 108 +++++++++++++++++++++++++++++++++++++- | ||||
|  2 files changed, 108 insertions(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/soc/mediatek/Kconfig | ||||
| +++ b/drivers/soc/mediatek/Kconfig | ||||
| @@ -23,7 +23,7 @@ config MTK_PMIC_WRAP | ||||
|  config MTK_SCPSYS | ||||
|  	bool "MediaTek SCPSYS Support" | ||||
|  	depends on ARCH_MEDIATEK || COMPILE_TEST | ||||
| -	default ARM64 && ARCH_MEDIATEK | ||||
| +	default ARCH_MEDIATEK | ||||
|  	select REGMAP | ||||
|  	select MTK_INFRACFG | ||||
|  	select PM_GENERIC_DOMAINS if PM | ||||
| --- a/drivers/soc/mediatek/mtk-scpsys.c | ||||
| +++ b/drivers/soc/mediatek/mtk-scpsys.c | ||||
| @@ -20,6 +20,7 @@ | ||||
|  #include <linux/regulator/consumer.h> | ||||
|  #include <linux/soc/mediatek/infracfg.h> | ||||
|   | ||||
| +#include <dt-bindings/power/mt2701-power.h> | ||||
|  #include <dt-bindings/power/mt8173-power.h> | ||||
|   | ||||
|  #define SPM_VDE_PWR_CON			0x0210 | ||||
| @@ -27,8 +28,13 @@ | ||||
|  #define SPM_VEN_PWR_CON			0x0230 | ||||
|  #define SPM_ISP_PWR_CON			0x0238 | ||||
|  #define SPM_DIS_PWR_CON			0x023c | ||||
| +#define SPM_CONN_PWR_CON		0x0280 | ||||
|  #define SPM_VEN2_PWR_CON		0x0298 | ||||
| -#define SPM_AUDIO_PWR_CON		0x029c | ||||
| +#define SPM_AUDIO_PWR_CON		0x029c	/* MT8173 */ | ||||
| +#define SPM_BDP_PWR_CON			0x029c	/* MT2701 */ | ||||
| +#define SPM_ETH_PWR_CON			0x02a0 | ||||
| +#define SPM_HIF_PWR_CON			0x02a4 | ||||
| +#define SPM_IFR_MSC_PWR_CON		0x02a8 | ||||
|  #define SPM_MFG_2D_PWR_CON		0x02c0 | ||||
|  #define SPM_MFG_ASYNC_PWR_CON		0x02c4 | ||||
|  #define SPM_USB_PWR_CON			0x02cc | ||||
| @@ -42,10 +48,15 @@ | ||||
|  #define PWR_ON_2ND_BIT			BIT(3) | ||||
|  #define PWR_CLK_DIS_BIT			BIT(4) | ||||
|   | ||||
| +#define PWR_STATUS_CONN			BIT(1) | ||||
|  #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_BDP			BIT(14) | ||||
| +#define PWR_STATUS_ETH			BIT(15) | ||||
| +#define PWR_STATUS_HIF			BIT(16) | ||||
| +#define PWR_STATUS_IFR_MSC		BIT(17) | ||||
|  #define PWR_STATUS_VENC_LT		BIT(20) | ||||
|  #define PWR_STATUS_VENC			BIT(21) | ||||
|  #define PWR_STATUS_MFG_2D		BIT(22) | ||||
| @@ -59,6 +70,7 @@ enum clk_id { | ||||
|  	CLK_MFG, | ||||
|  	CLK_VENC, | ||||
|  	CLK_VENC_LT, | ||||
| +	CLK_ETHIF, | ||||
|  	CLK_MAX, | ||||
|  }; | ||||
|   | ||||
| @@ -68,6 +80,7 @@ static const char * const clk_names[] = | ||||
|  	"mfg", | ||||
|  	"venc", | ||||
|  	"venc_lt", | ||||
| +	"ethif", | ||||
|  	NULL, | ||||
|  }; | ||||
|   | ||||
| @@ -455,6 +468,96 @@ static void mtk_register_power_domains(s | ||||
|  } | ||||
|   | ||||
|  /* | ||||
| + * MT2701 power domain support | ||||
| + */ | ||||
| + | ||||
| +static const struct scp_domain_data scp_domain_data_mt2701[] = { | ||||
| +	[MT2701_POWER_DOMAIN_CONN] = { | ||||
| +		.name = "conn", | ||||
| +		.sta_mask = PWR_STATUS_CONN, | ||||
| +		.ctl_offs = SPM_CONN_PWR_CON, | ||||
| +		.bus_prot_mask = 0x0104, | ||||
| +		.clk_id = {CLK_NONE}, | ||||
| +		.active_wakeup = true, | ||||
| +	}, | ||||
| +	[MT2701_POWER_DOMAIN_DISP] = { | ||||
| +		.name = "disp", | ||||
| +		.sta_mask = PWR_STATUS_DISP, | ||||
| +		.ctl_offs = SPM_DIS_PWR_CON, | ||||
| +		.sram_pdn_bits = GENMASK(11, 8), | ||||
| +		.clk_id = {CLK_MM}, | ||||
| +		.bus_prot_mask = 0x0002, | ||||
| +		.active_wakeup = true, | ||||
| +	}, | ||||
| +	[MT2701_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}, | ||||
| +		.active_wakeup = true, | ||||
| +	}, | ||||
| +	[MT2701_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}, | ||||
| +		.active_wakeup = true, | ||||
| +	}, | ||||
| +	[MT2701_POWER_DOMAIN_BDP] = { | ||||
| +		.name = "bdp", | ||||
| +		.sta_mask = PWR_STATUS_BDP, | ||||
| +		.ctl_offs = SPM_BDP_PWR_CON, | ||||
| +		.sram_pdn_bits = GENMASK(11, 8), | ||||
| +		.clk_id = {CLK_NONE}, | ||||
| +		.active_wakeup = true, | ||||
| +	}, | ||||
| +	[MT2701_POWER_DOMAIN_ETH] = { | ||||
| +		.name = "eth", | ||||
| +		.sta_mask = PWR_STATUS_ETH, | ||||
| +		.ctl_offs = SPM_ETH_PWR_CON, | ||||
| +		.sram_pdn_bits = GENMASK(11, 8), | ||||
| +		.sram_pdn_ack_bits = GENMASK(15, 12), | ||||
| +		.clk_id = {CLK_ETHIF}, | ||||
| +		.active_wakeup = true, | ||||
| +	}, | ||||
| +	[MT2701_POWER_DOMAIN_HIF] = { | ||||
| +		.name = "hif", | ||||
| +		.sta_mask = PWR_STATUS_HIF, | ||||
| +		.ctl_offs = SPM_HIF_PWR_CON, | ||||
| +		.sram_pdn_bits = GENMASK(11, 8), | ||||
| +		.sram_pdn_ack_bits = GENMASK(15, 12), | ||||
| +		.clk_id = {CLK_ETHIF}, | ||||
| +		.active_wakeup = true, | ||||
| +	}, | ||||
| +	[MT2701_POWER_DOMAIN_IFR_MSC] = { | ||||
| +		.name = "ifr_msc", | ||||
| +		.sta_mask = PWR_STATUS_IFR_MSC, | ||||
| +		.ctl_offs = SPM_IFR_MSC_PWR_CON, | ||||
| +		.clk_id = {CLK_NONE}, | ||||
| +		.active_wakeup = true, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +#define NUM_DOMAINS_MT2701	ARRAY_SIZE(scp_domain_data_mt2701) | ||||
| + | ||||
| +static int __init scpsys_probe_mt2701(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct scp *scp; | ||||
| + | ||||
| +	scp = init_scp(pdev, scp_domain_data_mt2701, NUM_DOMAINS_MT2701); | ||||
| +	if (IS_ERR(scp)) | ||||
| +		return PTR_ERR(scp); | ||||
| + | ||||
| +	mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT2701); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +/* | ||||
|   * MT8173 power domain support | ||||
|   */ | ||||
|   | ||||
| @@ -583,6 +686,9 @@ static int __init scpsys_probe_mt8173(st | ||||
|   | ||||
|  static const struct of_device_id of_scpsys_match_tbl[] = { | ||||
|  	{ | ||||
| +		.compatible = "mediatek,mt2701-scpsys", | ||||
| +		.data = scpsys_probe_mt2701, | ||||
| +	}, { | ||||
|  		.compatible = "mediatek,mt8173-scpsys", | ||||
|  		.data = scpsys_probe_mt8173, | ||||
|  	}, { | ||||
| @@ -1,30 +0,0 @@ | ||||
| From 600e2bd5c3019f31e90ec876f4efb6c209cf0d73 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <blogic@openwrt.org> | ||||
| Date: Wed, 6 Jan 2016 20:06:49 +0100 | ||||
| Subject: [PATCH 10/57] clk: add hifsys reset | ||||
|  | ||||
| Hi, | ||||
|  | ||||
| small patch to add hifsys reset bits. Maybe you could add it to the next | ||||
| version of your patch series. i have teste scpsys and clk on mt7623 today | ||||
| and it works well. | ||||
|  | ||||
| thanks, | ||||
| 	John | ||||
|  | ||||
| Signed-off-by: John Crispin <blogic@openwrt.org> | ||||
| --- | ||||
|  drivers/clk/mediatek/clk-mt2701.c | 2 ++ | ||||
|  1 file changed, 2 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); | ||||
|   | ||||
| @@ -1,20 +0,0 @@ | ||||
| From 1e889b3d38ab5fb425762da57313b4cc8fc2f165 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <blogic@openwrt.org> | ||||
| Date: Sun, 21 Feb 2016 13:52:12 +0100 | ||||
| Subject: [PATCH 11/57] scpsys: various fixes | ||||
|  | ||||
| --- | ||||
|  drivers/clk/mediatek/clk-mt2701.c | 2 ++ | ||||
|  1 file changed, 2 insertions(+) | ||||
|  | ||||
| --- 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); | ||||
|   | ||||
| @@ -1,69 +0,0 @@ | ||||
| From 03bead9276653dc842f6970250bc7eba41faf777 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <blogic@openwrt.org> | ||||
| Date: Thu, 31 Mar 2016 06:46:51 +0200 | ||||
| Subject: [PATCH 13/57] clk: mediatek: enable critical clocks | ||||
|  | ||||
| Signed-off-by: John Crispin <blogic@openwrt.org> | ||||
| --- | ||||
|  drivers/clk/mediatek/clk-mt2701.c | 22 ++++++++++++++++++++-- | ||||
|  1 file changed, 20 insertions(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/clk/mediatek/clk-mt2701.c | ||||
| +++ b/drivers/clk/mediatek/clk-mt2701.c | ||||
| @@ -573,6 +573,20 @@ static const struct mtk_gate top_clks[] | ||||
|  	GATE_TOP_AUD(CLK_TOP_AUD_I2S6_MCLK, "aud_i2s6_mclk", "aud_k6_src_div", 28), | ||||
|  }; | ||||
|   | ||||
| +static struct clk_onecell_data *mt7623_top_clk_data __initdata; | ||||
| +static struct clk_onecell_data *mt7623_pll_clk_data __initdata; | ||||
| + | ||||
| +static void __init mtk_clk_enable_critical(void) | ||||
| +{ | ||||
| +	if (!mt7623_top_clk_data || !mt7623_pll_clk_data) | ||||
| +		return; | ||||
| + | ||||
| +	clk_prepare_enable(mt7623_pll_clk_data->clks[CLK_APMIXED_ARMPLL]); | ||||
| +	clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_MEM_SEL]); | ||||
| +	clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_DDRPHYCFG_SEL]); | ||||
| +	clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_RTC_SEL]); | ||||
| +} | ||||
| + | ||||
|  static void __init mtk_topckgen_init(struct device_node *node) | ||||
|  { | ||||
|  	struct clk_onecell_data *clk_data; | ||||
| @@ -585,7 +599,7 @@ static void __init mtk_topckgen_init(str | ||||
|  		return; | ||||
|  	} | ||||
|   | ||||
| -	clk_data = mtk_alloc_clk_data(CLK_TOP_NR); | ||||
| +	mt7623_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR); | ||||
|   | ||||
|  	mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), | ||||
|  								clk_data); | ||||
| @@ -606,6 +620,8 @@ static void __init mtk_topckgen_init(str | ||||
|  	if (r) | ||||
|  		pr_err("%s(): could not register clock provider: %d\n", | ||||
|  			__func__, r); | ||||
| + | ||||
| +	mtk_clk_enable_critical(); | ||||
|  } | ||||
|  CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt2701-topckgen", mtk_topckgen_init); | ||||
|   | ||||
| @@ -1202,7 +1218,7 @@ static void __init mtk_apmixedsys_init(s | ||||
|  	struct clk_onecell_data *clk_data; | ||||
|  	int r; | ||||
|   | ||||
| -	clk_data = mtk_alloc_clk_data(ARRAY_SIZE(apmixed_plls)); | ||||
| +	mt7623_pll_clk_data = clk_data = mtk_alloc_clk_data(ARRAY_SIZE(apmixed_plls)); | ||||
|  	if (!clk_data) | ||||
|  		return; | ||||
|   | ||||
| @@ -1213,6 +1229,8 @@ static void __init mtk_apmixedsys_init(s | ||||
|  	if (r) | ||||
|  		pr_err("%s(): could not register clock provider: %d\n", | ||||
|  			__func__, r); | ||||
| + | ||||
| +	mtk_clk_enable_critical(); | ||||
|  } | ||||
|  CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt2701-apmixedsys", | ||||
|  							mtk_apmixedsys_init); | ||||
| @@ -1,287 +0,0 @@ | ||||
| From 3a947321d72af191ee87a390295c661c876cc6f4 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <blogic@openwrt.org> | ||||
| Date: Thu, 31 Mar 2016 02:26:37 +0200 | ||||
| Subject: [PATCH 14/57] clk: mediatek: Export CPU mux clocks for CPU frequency | ||||
|  control | ||||
|  | ||||
| This patch adds CPU mux clocks which are used by Mediatek cpufreq driver | ||||
| for intermediate clock source switching. | ||||
|  | ||||
| Signed-off-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org> | ||||
| --- | ||||
|  drivers/clk/mediatek/Makefile          |   2 +- | ||||
|  drivers/clk/mediatek/clk-cpumux.c      | 127 +++++++++++++++++++++++++++++++++ | ||||
|  drivers/clk/mediatek/clk-cpumux.h      |  22 ++++++ | ||||
|  drivers/clk/mediatek/clk-mt2701.c      |   8 +++ | ||||
|  drivers/clk/mediatek/clk-mt8173.c      |  23 ++++++ | ||||
|  include/dt-bindings/clock/mt2701-clk.h |   3 +- | ||||
|  include/dt-bindings/clock/mt8173-clk.h |   4 +- | ||||
|  7 files changed, 186 insertions(+), 3 deletions(-) | ||||
|  create mode 100644 drivers/clk/mediatek/clk-cpumux.c | ||||
|  create mode 100644 drivers/clk/mediatek/clk-cpumux.h | ||||
|  | ||||
| --- a/drivers/clk/mediatek/Makefile | ||||
| +++ b/drivers/clk/mediatek/Makefile | ||||
| @@ -1,4 +1,4 @@ | ||||
| -obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o | ||||
| +obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o | ||||
|  obj-$(CONFIG_RESET_CONTROLLER) += reset.o | ||||
|  obj-$(CONFIG_COMMON_CLK_MT2701) += clk-mt2701.o | ||||
|  obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/clk/mediatek/clk-cpumux.c | ||||
| @@ -0,0 +1,127 @@ | ||||
| +/* | ||||
| + * Copyright (c) 2015 Linaro Ltd. | ||||
| + * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org> | ||||
| + * | ||||
| + * This program is free software; you can redistribute it and/or modify | ||||
| + * it under the terms of the GNU General Public License version 2 as | ||||
| + * published by the Free Software Foundation. | ||||
| + * | ||||
| + * This program is distributed in the hope that it will be useful, | ||||
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| + * GNU General Public License for more details. | ||||
| + */ | ||||
| + | ||||
| +#include <linux/clk-provider.h> | ||||
| +#include <linux/mfd/syscon.h> | ||||
| +#include <linux/slab.h> | ||||
| + | ||||
| +#include "clk-mtk.h" | ||||
| +#include "clk-cpumux.h" | ||||
| + | ||||
| +struct mtk_clk_cpumux { | ||||
| +	struct clk_hw	hw; | ||||
| +	struct regmap	*regmap; | ||||
| +	u32		reg; | ||||
| +	u32		mask; | ||||
| +	u8		shift; | ||||
| +}; | ||||
| + | ||||
| +static inline struct mtk_clk_cpumux *to_mtk_clk_mux(struct clk_hw *_hw) | ||||
| +{ | ||||
| +	return container_of(_hw, struct mtk_clk_cpumux, hw); | ||||
| +} | ||||
| + | ||||
| +static u8 clk_cpumux_get_parent(struct clk_hw *hw) | ||||
| +{ | ||||
| +	struct mtk_clk_cpumux *mux = to_mtk_clk_mux(hw); | ||||
| +	int num_parents = clk_hw_get_num_parents(hw); | ||||
| +	unsigned int val; | ||||
| + | ||||
| +	regmap_read(mux->regmap, mux->reg, &val); | ||||
| + | ||||
| +	val >>= mux->shift; | ||||
| +	val &= mux->mask; | ||||
| + | ||||
| +	if (val >= num_parents) | ||||
| +		return -EINVAL; | ||||
| + | ||||
| +	return val; | ||||
| +} | ||||
| + | ||||
| +static int clk_cpumux_set_parent(struct clk_hw *hw, u8 index) | ||||
| +{ | ||||
| +	struct mtk_clk_cpumux *mux = to_mtk_clk_mux(hw); | ||||
| +	u32 mask, val; | ||||
| + | ||||
| +	val = index << mux->shift; | ||||
| +	mask = mux->mask << mux->shift; | ||||
| + | ||||
| +	return regmap_update_bits(mux->regmap, mux->reg, mask, val); | ||||
| +} | ||||
| + | ||||
| +static const struct clk_ops clk_cpumux_ops = { | ||||
| +	.get_parent = clk_cpumux_get_parent, | ||||
| +	.set_parent = clk_cpumux_set_parent, | ||||
| +}; | ||||
| + | ||||
| +static struct clk __init *mtk_clk_register_cpumux(const struct mtk_composite *mux, | ||||
| +					   struct regmap *regmap) | ||||
| +{ | ||||
| +	struct mtk_clk_cpumux *cpumux; | ||||
| +	struct clk *clk; | ||||
| +	struct clk_init_data init; | ||||
| + | ||||
| +	cpumux = kzalloc(sizeof(*cpumux), GFP_KERNEL); | ||||
| +	if (!cpumux) | ||||
| +		return ERR_PTR(-ENOMEM); | ||||
| + | ||||
| +	init.name = mux->name; | ||||
| +	init.ops = &clk_cpumux_ops; | ||||
| +	init.parent_names = mux->parent_names; | ||||
| +	init.num_parents = mux->num_parents; | ||||
| +	init.flags = mux->flags; | ||||
| + | ||||
| +	cpumux->reg = mux->mux_reg; | ||||
| +	cpumux->shift = mux->mux_shift; | ||||
| +	cpumux->mask = BIT(mux->mux_width) - 1; | ||||
| +	cpumux->regmap = regmap; | ||||
| +	cpumux->hw.init = &init; | ||||
| + | ||||
| +	clk = clk_register(NULL, &cpumux->hw); | ||||
| +	if (IS_ERR(clk)) | ||||
| +		kfree(cpumux); | ||||
| + | ||||
| +	return clk; | ||||
| +} | ||||
| + | ||||
| +int __init mtk_clk_register_cpumuxes(struct device_node *node, | ||||
| +			      const struct mtk_composite *clks, int num, | ||||
| +			      struct clk_onecell_data *clk_data) | ||||
| +{ | ||||
| +	int i; | ||||
| +	struct clk *clk; | ||||
| +	struct regmap *regmap; | ||||
| + | ||||
| +	regmap = syscon_node_to_regmap(node); | ||||
| +	if (IS_ERR(regmap)) { | ||||
| +		pr_err("Cannot find regmap for %s: %ld\n", node->full_name, | ||||
| +		       PTR_ERR(regmap)); | ||||
| +		return PTR_ERR(regmap); | ||||
| +	} | ||||
| + | ||||
| +	for (i = 0; i < num; i++) { | ||||
| +		const struct mtk_composite *mux = &clks[i]; | ||||
| + | ||||
| +		clk = mtk_clk_register_cpumux(mux, regmap); | ||||
| +		if (IS_ERR(clk)) { | ||||
| +			pr_err("Failed to register clk %s: %ld\n", | ||||
| +			       mux->name, PTR_ERR(clk)); | ||||
| +			continue; | ||||
| +		} | ||||
| + | ||||
| +		clk_data->clks[mux->id] = clk; | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| --- /dev/null | ||||
| +++ b/drivers/clk/mediatek/clk-cpumux.h | ||||
| @@ -0,0 +1,22 @@ | ||||
| +/* | ||||
| + * Copyright (c) 2015 Linaro Ltd. | ||||
| + * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org> | ||||
| + * | ||||
| + * This program is free software; you can redistribute it and/or modify | ||||
| + * it under the terms of the GNU General Public License version 2 as | ||||
| + * published by the Free Software Foundation. | ||||
| + * | ||||
| + * This program is distributed in the hope that it will be useful, | ||||
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| + * GNU General Public License for more details. | ||||
| + */ | ||||
| + | ||||
| +#ifndef __DRV_CLK_CPUMUX_H | ||||
| +#define __DRV_CLK_CPUMUX_H | ||||
| + | ||||
| +int mtk_clk_register_cpumuxes(struct device_node *node, | ||||
| +			      const struct mtk_composite *clks, int num, | ||||
| +			      struct clk_onecell_data *clk_data); | ||||
| + | ||||
| +#endif /* __DRV_CLK_CPUMUX_H */ | ||||
| --- a/drivers/clk/mediatek/clk-mt2701.c | ||||
| +++ b/drivers/clk/mediatek/clk-mt2701.c | ||||
| @@ -18,6 +18,7 @@ | ||||
|   | ||||
|  #include "clk-mtk.h" | ||||
|  #include "clk-gate.h" | ||||
| +#include "clk-cpumux.h" | ||||
|   | ||||
|  #include <dt-bindings/clock/mt2701-clk.h> | ||||
|   | ||||
| @@ -465,6 +466,10 @@ static const char * const cpu_parents[] | ||||
|  	"mmpll" | ||||
|  }; | ||||
|   | ||||
| +static const struct mtk_composite cpu_muxes[] __initconst = { | ||||
| +	MUX(CLK_INFRA_CPUSEL, "infra_cpu_sel", cpu_parents, 0x0000, 2, 2), | ||||
| +}; | ||||
| + | ||||
|  static const struct mtk_composite top_muxes[] __initconst = { | ||||
|  	MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, | ||||
|  		0x0040, 0, 3, INVALID_MUX_GATE_BIT), | ||||
| @@ -677,6 +682,9 @@ static void __init mtk_infrasys_init(str | ||||
|  	mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs), | ||||
|  						clk_data); | ||||
|   | ||||
| +	mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes), | ||||
| +						clk_data); | ||||
| + | ||||
|  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||||
|  	if (r) | ||||
|  		pr_err("%s(): could not register clock provider: %d\n", | ||||
| --- a/drivers/clk/mediatek/clk-mt8173.c | ||||
| +++ b/drivers/clk/mediatek/clk-mt8173.c | ||||
| @@ -18,6 +18,7 @@ | ||||
|   | ||||
|  #include "clk-mtk.h" | ||||
|  #include "clk-gate.h" | ||||
| +#include "clk-cpumux.h" | ||||
|   | ||||
|  #include <dt-bindings/clock/mt8173-clk.h> | ||||
|   | ||||
| @@ -525,6 +526,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), | ||||
| @@ -948,6 +968,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 | ||||
| @@ -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 */ | ||||
|   | ||||
| @@ -1,433 +0,0 @@ | ||||
| From 8aa2c6c4d8b20c0e9c69b15db4a0039d33f8b365 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <blogic@openwrt.org> | ||||
| Date: Wed, 30 Mar 2016 23:48:53 +0200 | ||||
| Subject: [PATCH 15/57] cpufreq: mediatek: add driver | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/cpufreq/Kconfig.arm      |   9 + | ||||
|  drivers/cpufreq/Makefile         |   1 + | ||||
|  drivers/cpufreq/mt7623-cpufreq.c | 389 +++++++++++++++++++++++++++++++++++++++ | ||||
|  3 files changed, 399 insertions(+) | ||||
|  create mode 100644 drivers/cpufreq/mt7623-cpufreq.c | ||||
|  | ||||
| --- a/drivers/cpufreq/Kconfig.arm | ||||
| +++ b/drivers/cpufreq/Kconfig.arm | ||||
| @@ -74,6 +74,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 | ||||
|  	tristate "Mediatek MT8173 CPUFreq support" | ||||
|  	depends on ARCH_MEDIATEK && REGULATOR | ||||
| --- a/drivers/cpufreq/Makefile | ||||
| +++ b/drivers/cpufreq/Makefile | ||||
| @@ -58,6 +58,7 @@ obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ)	+= hi | ||||
|  obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)		+= imx6q-cpufreq.o | ||||
|  obj-$(CONFIG_ARM_INTEGRATOR)		+= integrator-cpufreq.o | ||||
|  obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ)	+= kirkwood-cpufreq.o | ||||
| +obj-$(CONFIG_ARM_MT7623_CPUFREQ)	+= mt7623-cpufreq.o | ||||
|  obj-$(CONFIG_ARM_MT8173_CPUFREQ)	+= mt8173-cpufreq.o | ||||
|  obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)	+= omap-cpufreq.o | ||||
|  obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)	+= pxa2xx-cpufreq.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/cpufreq/mt7623-cpufreq.c | ||||
| @@ -0,0 +1,389 @@ | ||||
| +/* | ||||
| + * Copyright (c) 2015 Linaro Ltd. | ||||
| + * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org> | ||||
| + * | ||||
| + * This program is free software; you can redistribute it and/or modify | ||||
| + * it under the terms of the GNU General Public License version 2 as | ||||
| + * published by the Free Software Foundation. | ||||
| + * | ||||
| + * This program is distributed in the hope that it will be useful, | ||||
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| + * GNU General Public License for more details. | ||||
| + */ | ||||
| + | ||||
| +#include <linux/clk.h> | ||||
| +#include <linux/cpu.h> | ||||
| +#include <linux/cpu_cooling.h> | ||||
| +#include <linux/cpufreq.h> | ||||
| +#include <linux/cpumask.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/platform_device.h> | ||||
| +#include <linux/pm_opp.h> | ||||
| +#include <linux/regulator/consumer.h> | ||||
| +#include <linux/slab.h> | ||||
| +#include <linux/thermal.h> | ||||
| + | ||||
| +#define VOLT_TOL		(10000) | ||||
| + | ||||
| +/* | ||||
| + * When scaling the clock frequency of a CPU clock domain, the clock source | ||||
| + * needs to be switched to another stable PLL clock temporarily until | ||||
| + * the original PLL becomes stable at target frequency. | ||||
| + */ | ||||
| +struct mtk_cpu_dvfs_info { | ||||
| +	struct device *cpu_dev; | ||||
| +	struct regulator *proc_reg; | ||||
| +	struct clk *cpu_clk; | ||||
| +	struct clk *inter_clk; | ||||
| +	struct thermal_cooling_device *cdev; | ||||
| +	int intermediate_voltage; | ||||
| +}; | ||||
| + | ||||
| +static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc) | ||||
| +{ | ||||
| +	return regulator_set_voltage(info->proc_reg, vproc, | ||||
| +				     vproc + VOLT_TOL); | ||||
| +} | ||||
| + | ||||
| +static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, | ||||
| +				  unsigned int index) | ||||
| +{ | ||||
| +	struct cpufreq_frequency_table *freq_table = policy->freq_table; | ||||
| +	struct clk *cpu_clk = policy->clk; | ||||
| +	struct clk *armpll = clk_get_parent(cpu_clk); | ||||
| +	struct mtk_cpu_dvfs_info *info = policy->driver_data; | ||||
| +	struct device *cpu_dev = info->cpu_dev; | ||||
| +	struct dev_pm_opp *opp; | ||||
| +	long freq_hz, old_freq_hz; | ||||
| +	int vproc, old_vproc, inter_vproc, target_vproc, ret; | ||||
| + | ||||
| +	inter_vproc = info->intermediate_voltage; | ||||
| + | ||||
| +	old_freq_hz = clk_get_rate(cpu_clk); | ||||
| +	old_vproc = regulator_get_voltage(info->proc_reg); | ||||
| + | ||||
| +	freq_hz = freq_table[index].frequency * 1000; | ||||
| + | ||||
| +	rcu_read_lock(); | ||||
| +	opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz); | ||||
| +	if (IS_ERR(opp)) { | ||||
| +		rcu_read_unlock(); | ||||
| +		pr_err("cpu%d: failed to find OPP for %ld\n", | ||||
| +		       policy->cpu, freq_hz); | ||||
| +		return PTR_ERR(opp); | ||||
| +	} | ||||
| +	vproc = dev_pm_opp_get_voltage(opp); | ||||
| +	rcu_read_unlock(); | ||||
| + | ||||
| +	/* | ||||
| +	 * If the new voltage or the intermediate voltage is higher than the | ||||
| +	 * current voltage, scale up voltage first. | ||||
| +	 */ | ||||
| +	target_vproc = (inter_vproc > vproc) ? inter_vproc : vproc; | ||||
| +	if (old_vproc < target_vproc) { | ||||
| +		ret = mtk_cpufreq_set_voltage(info, target_vproc); | ||||
| +		if (ret) { | ||||
| +			pr_err("cpu%d: failed to scale up voltage!\n", | ||||
| +			       policy->cpu); | ||||
| +			mtk_cpufreq_set_voltage(info, old_vproc); | ||||
| +			return ret; | ||||
| +		} | ||||
| +	} | ||||
| + | ||||
| +	/* Reparent the CPU clock to intermediate clock. */ | ||||
| +	ret = clk_set_parent(cpu_clk, info->inter_clk); | ||||
| +	if (ret) { | ||||
| +		pr_err("cpu%d: failed to re-parent cpu clock!\n", | ||||
| +		       policy->cpu); | ||||
| +		mtk_cpufreq_set_voltage(info, old_vproc); | ||||
| +		WARN_ON(1); | ||||
| +		return ret; | ||||
| +	} | ||||
| + | ||||
| +	/* Set the original PLL to target rate. */ | ||||
| +	ret = clk_set_rate(armpll, freq_hz); | ||||
| +	if (ret) { | ||||
| +		pr_err("cpu%d: failed to scale cpu clock rate!\n", | ||||
| +		       policy->cpu); | ||||
| +		clk_set_parent(cpu_clk, armpll); | ||||
| +		mtk_cpufreq_set_voltage(info, old_vproc); | ||||
| +		return ret; | ||||
| +	} | ||||
| + | ||||
| +	/* Set parent of CPU clock back to the original PLL. */ | ||||
| +	ret = clk_set_parent(cpu_clk, armpll); | ||||
| +	if (ret) { | ||||
| +		pr_err("cpu%d: failed to re-parent cpu clock!\n", | ||||
| +		       policy->cpu); | ||||
| +		mtk_cpufreq_set_voltage(info, inter_vproc); | ||||
| +		WARN_ON(1); | ||||
| +		return ret; | ||||
| +	} | ||||
| + | ||||
| +	/* | ||||
| +	 * If the new voltage is lower than the intermediate voltage or the | ||||
| +	 * original voltage, scale down to the new voltage. | ||||
| +	 */ | ||||
| +	if (vproc < inter_vproc || vproc < old_vproc) { | ||||
| +		ret = mtk_cpufreq_set_voltage(info, vproc); | ||||
| +		if (ret) { | ||||
| +			pr_err("cpu%d: failed to scale down voltage!\n", | ||||
| +			       policy->cpu); | ||||
| +			clk_set_parent(cpu_clk, info->inter_clk); | ||||
| +			clk_set_rate(armpll, old_freq_hz); | ||||
| +			clk_set_parent(cpu_clk, armpll); | ||||
| +			return ret; | ||||
| +		} | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static void mtk_cpufreq_ready(struct cpufreq_policy *policy) | ||||
| +{ | ||||
| +	struct mtk_cpu_dvfs_info *info = policy->driver_data; | ||||
| +	struct device_node *np = of_node_get(info->cpu_dev->of_node); | ||||
| + | ||||
| +	if (WARN_ON(!np)) | ||||
| +		return; | ||||
| + | ||||
| +	if (of_find_property(np, "#cooling-cells", NULL)) { | ||||
| +		info->cdev = of_cpufreq_cooling_register(np, | ||||
| +							 policy->related_cpus); | ||||
| + | ||||
| +		if (IS_ERR(info->cdev)) { | ||||
| +			dev_err(info->cpu_dev, | ||||
| +				"running cpufreq without cooling device: %ld\n", | ||||
| +				PTR_ERR(info->cdev)); | ||||
| + | ||||
| +			info->cdev = NULL; | ||||
| +		} | ||||
| +	} | ||||
| + | ||||
| +	of_node_put(np); | ||||
| +} | ||||
| + | ||||
| +static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) | ||||
| +{ | ||||
| +	struct device *cpu_dev; | ||||
| +	struct regulator *proc_reg = ERR_PTR(-ENODEV); | ||||
| +	struct clk *cpu_clk = ERR_PTR(-ENODEV); | ||||
| +	struct clk *inter_clk = ERR_PTR(-ENODEV); | ||||
| +	struct dev_pm_opp *opp; | ||||
| +	unsigned long rate; | ||||
| +	int ret; | ||||
| + | ||||
| +	cpu_dev = get_cpu_device(cpu); | ||||
| +	if (!cpu_dev) { | ||||
| +		pr_err("failed to get cpu%d device\n", cpu); | ||||
| +		return -ENODEV; | ||||
| +	} | ||||
| + | ||||
| +	cpu_clk = clk_get(cpu_dev, "cpu"); | ||||
| +	if (IS_ERR(cpu_clk)) { | ||||
| +		if (PTR_ERR(cpu_clk) == -EPROBE_DEFER) | ||||
| +			pr_warn("cpu clk for cpu%d not ready, retry.\n", cpu); | ||||
| +		else | ||||
| +			pr_err("failed to get cpu clk for cpu%d\n", cpu); | ||||
| + | ||||
| +		ret = PTR_ERR(cpu_clk); | ||||
| +		return ret; | ||||
| +	} | ||||
| + | ||||
| +	inter_clk = clk_get(cpu_dev, "intermediate"); | ||||
| +	if (IS_ERR(inter_clk)) { | ||||
| +		if (PTR_ERR(inter_clk) == -EPROBE_DEFER) | ||||
| +			pr_warn("intermediate clk for cpu%d not ready, retry.\n", | ||||
| +				cpu); | ||||
| +		else | ||||
| +			pr_err("failed to get intermediate clk for cpu%d\n", | ||||
| +			       cpu); | ||||
| + | ||||
| +		ret = PTR_ERR(inter_clk); | ||||
| +		goto out_free_resources; | ||||
| +	} | ||||
| + | ||||
| +	proc_reg = regulator_get_exclusive(cpu_dev, "proc"); | ||||
| +	if (IS_ERR(proc_reg)) { | ||||
| +		if (PTR_ERR(proc_reg) == -EPROBE_DEFER) | ||||
| +			pr_warn("proc regulator for cpu%d not ready, retry.\n", | ||||
| +				cpu); | ||||
| +		else | ||||
| +			pr_err("failed to get proc regulator for cpu%d\n", | ||||
| +			       cpu); | ||||
| + | ||||
| +		ret = PTR_ERR(proc_reg); | ||||
| +		goto out_free_resources; | ||||
| +	} | ||||
| + | ||||
| +	ret = dev_pm_opp_of_add_table(cpu_dev); | ||||
| +	if (ret) { | ||||
| +		pr_warn("no OPP table for cpu%d\n", cpu); | ||||
| +		goto out_free_resources; | ||||
| +	} | ||||
| + | ||||
| +	/* Search a safe voltage for intermediate frequency. */ | ||||
| +	rate = clk_get_rate(inter_clk); | ||||
| +	rcu_read_lock(); | ||||
| +	opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate); | ||||
| +	if (IS_ERR(opp)) { | ||||
| +		rcu_read_unlock(); | ||||
| +		pr_err("failed to get intermediate opp for cpu%d\n", cpu); | ||||
| +		ret = PTR_ERR(opp); | ||||
| +		goto out_free_opp_table; | ||||
| +	} | ||||
| +	info->intermediate_voltage = dev_pm_opp_get_voltage(opp); | ||||
| +	rcu_read_unlock(); | ||||
| + | ||||
| +	info->cpu_dev = cpu_dev; | ||||
| +	info->proc_reg = proc_reg; | ||||
| +	info->cpu_clk = cpu_clk; | ||||
| +	info->inter_clk = inter_clk; | ||||
| + | ||||
| +	return 0; | ||||
| + | ||||
| +out_free_opp_table: | ||||
| +	dev_pm_opp_of_remove_table(cpu_dev); | ||||
| + | ||||
| +out_free_resources: | ||||
| +	if (!IS_ERR(proc_reg)) | ||||
| +		regulator_put(proc_reg); | ||||
| +	if (!IS_ERR(cpu_clk)) | ||||
| +		clk_put(cpu_clk); | ||||
| +	if (!IS_ERR(inter_clk)) | ||||
| +		clk_put(inter_clk); | ||||
| + | ||||
| +	return ret; | ||||
| +} | ||||
| + | ||||
| +static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info) | ||||
| +{ | ||||
| +	if (!IS_ERR(info->proc_reg)) | ||||
| +		regulator_put(info->proc_reg); | ||||
| +	if (!IS_ERR(info->cpu_clk)) | ||||
| +		clk_put(info->cpu_clk); | ||||
| +	if (!IS_ERR(info->inter_clk)) | ||||
| +		clk_put(info->inter_clk); | ||||
| + | ||||
| +	dev_pm_opp_of_remove_table(info->cpu_dev); | ||||
| +} | ||||
| + | ||||
| +static int mtk_cpufreq_init(struct cpufreq_policy *policy) | ||||
| +{ | ||||
| +	struct mtk_cpu_dvfs_info *info; | ||||
| +	struct cpufreq_frequency_table *freq_table; | ||||
| +	int ret; | ||||
| + | ||||
| +	info = kzalloc(sizeof(*info), GFP_KERNEL); | ||||
| +	if (!info) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	ret = mtk_cpu_dvfs_info_init(info, policy->cpu); | ||||
| +	if (ret) { | ||||
| +		pr_err("%s failed to initialize dvfs info for cpu%d\n", | ||||
| +		       __func__, policy->cpu); | ||||
| +		goto out_free_dvfs_info; | ||||
| +	} | ||||
| + | ||||
| +	ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table); | ||||
| +	if (ret) { | ||||
| +		pr_err("failed to init cpufreq table for cpu%d: %d\n", | ||||
| +		       policy->cpu, ret); | ||||
| +		goto out_release_dvfs_info; | ||||
| +	} | ||||
| + | ||||
| +	ret = cpufreq_table_validate_and_show(policy, freq_table); | ||||
| +	if (ret) { | ||||
| +		pr_err("%s: invalid frequency table: %d\n", __func__, ret); | ||||
| +		goto out_free_cpufreq_table; | ||||
| +	} | ||||
| + | ||||
| +	/* CPUs in the same cluster share a clock and power domain. */ | ||||
| +	cpumask_setall(policy->cpus); | ||||
| +	policy->driver_data = info; | ||||
| +	policy->clk = info->cpu_clk; | ||||
| + | ||||
| +	return 0; | ||||
| + | ||||
| +out_free_cpufreq_table: | ||||
| +	dev_pm_opp_free_cpufreq_table(info->cpu_dev, &freq_table); | ||||
| + | ||||
| +out_release_dvfs_info: | ||||
| +	mtk_cpu_dvfs_info_release(info); | ||||
| + | ||||
| +out_free_dvfs_info: | ||||
| +	kfree(info); | ||||
| + | ||||
| +	return ret; | ||||
| +} | ||||
| + | ||||
| +static int mtk_cpufreq_exit(struct cpufreq_policy *policy) | ||||
| +{ | ||||
| +	struct mtk_cpu_dvfs_info *info = policy->driver_data; | ||||
| + | ||||
| +	cpufreq_cooling_unregister(info->cdev); | ||||
| +	dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table); | ||||
| +	mtk_cpu_dvfs_info_release(info); | ||||
| +	kfree(info); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static struct cpufreq_driver mt7623_cpufreq_driver = { | ||||
| +	.flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, | ||||
| +	.verify = cpufreq_generic_frequency_table_verify, | ||||
| +	.target_index = mtk_cpufreq_set_target, | ||||
| +	.get = cpufreq_generic_get, | ||||
| +	.init = mtk_cpufreq_init, | ||||
| +	.exit = mtk_cpufreq_exit, | ||||
| +	.ready = mtk_cpufreq_ready, | ||||
| +	.name = "mtk-cpufreq", | ||||
| +	.attr = cpufreq_generic_attr, | ||||
| +}; | ||||
| + | ||||
| +static int mt7623_cpufreq_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	int ret; | ||||
| + | ||||
| +	ret = cpufreq_register_driver(&mt7623_cpufreq_driver); | ||||
| +	if (ret) | ||||
| +		pr_err("failed to register mtk cpufreq driver\n"); | ||||
| + | ||||
| +	return ret; | ||||
| +} | ||||
| + | ||||
| +static struct platform_driver mt7623_cpufreq_platdrv = { | ||||
| +	.driver = { | ||||
| +		.name	= "mt7623-cpufreq", | ||||
| +	}, | ||||
| +	.probe		= mt7623_cpufreq_probe, | ||||
| +}; | ||||
| + | ||||
| +static int mt7623_cpufreq_driver_init(void) | ||||
| +{ | ||||
| +	struct platform_device *pdev; | ||||
| +	int err; | ||||
| + | ||||
| +	if (!of_machine_is_compatible("mediatek,mt7623")) | ||||
| +		return -ENODEV; | ||||
| + | ||||
| +	err = platform_driver_register(&mt7623_cpufreq_platdrv); | ||||
| +	if (err) | ||||
| +		return err; | ||||
| + | ||||
| +	/* | ||||
| +	 * Since there's no place to hold device registration code and no | ||||
| +	 * device tree based way to match cpufreq driver yet, both the driver | ||||
| +	 * and the device registration codes are put here to handle defer | ||||
| +	 * probing. | ||||
| +	 */ | ||||
| +	pdev = platform_device_register_simple("mt7623-cpufreq", -1, NULL, 0); | ||||
| +	if (IS_ERR(pdev)) { | ||||
| +		pr_err("failed to register mtk-cpufreq platform device\n"); | ||||
| +		return PTR_ERR(pdev); | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| +device_initcall(mt7623_cpufreq_driver_init); | ||||
| @@ -1,274 +0,0 @@ | ||||
| From 201be68268eddb1568c41780a62868cc1666a2de Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Fri, 6 May 2016 02:55:48 +0200 | ||||
| Subject: [PATCH 16/57] pwm: add pwm-mediatek | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/pwm/Kconfig        |   9 ++ | ||||
|  drivers/pwm/Makefile       |   1 + | ||||
|  drivers/pwm/pwm-mediatek.c | 230 +++++++++++++++++++++++++++++++++++++++++++++ | ||||
|  3 files changed, 240 insertions(+) | ||||
|  create mode 100644 drivers/pwm/pwm-mediatek.c | ||||
|  | ||||
| --- a/drivers/pwm/Kconfig | ||||
| +++ b/drivers/pwm/Kconfig | ||||
| @@ -282,6 +282,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 | ||||
| @@ -25,6 +25,7 @@ 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_MESON)		+= pwm-meson.o | ||||
| +obj-$(CONFIG_PWM_MEDIATEK)	+= pwm-mediatek.o | ||||
|  obj-$(CONFIG_PWM_MTK_DISP)	+= pwm-mtk-disp.o | ||||
|  obj-$(CONFIG_PWM_MXS)		+= pwm-mxs.o | ||||
|  obj-$(CONFIG_PWM_OMAP_DMTIMER)	+= pwm-omap-dmtimer.o | ||||
| --- /dev/null | ||||
| +++ b/drivers/pwm/pwm-mediatek.c | ||||
| @@ -0,0 +1,230 @@ | ||||
| +/* | ||||
| + * Mediatek Pulse Width Modulator driver | ||||
| + * | ||||
| + * Copyright (C) 2015 John Crispin <blogic@openwrt.org> | ||||
| + * | ||||
| + * This file is licensed under the terms of the GNU General Public | ||||
| + * License version 2. This program is licensed "as is" without any | ||||
| + * warranty of any kind, whether express or implied. | ||||
| + */ | ||||
| + | ||||
| +#include <linux/err.h> | ||||
| +#include <linux/io.h> | ||||
| +#include <linux/ioport.h> | ||||
| +#include <linux/kernel.h> | ||||
| +#include <linux/module.h> | ||||
| +#include <linux/clk.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/platform_device.h> | ||||
| +#include <linux/pwm.h> | ||||
| +#include <linux/slab.h> | ||||
| +#include <linux/types.h> | ||||
| + | ||||
| +#define NUM_PWM		5 | ||||
| + | ||||
| +/* PWM registers and bits definitions */ | ||||
| +#define PWMCON			0x00 | ||||
| +#define PWMHDUR			0x04 | ||||
| +#define PWMLDUR			0x08 | ||||
| +#define PWMGDUR			0x0c | ||||
| +#define PWMWAVENUM		0x28 | ||||
| +#define PWMDWIDTH		0x2c | ||||
| +#define PWMTHRES		0x30 | ||||
| + | ||||
| +/** | ||||
| + * struct mtk_pwm_chip - struct representing pwm chip | ||||
| + * | ||||
| + * @mmio_base: base address of pwm chip | ||||
| + * @chip: linux pwm chip representation | ||||
| + */ | ||||
| +struct mtk_pwm_chip { | ||||
| +	void __iomem *mmio_base; | ||||
| +	struct pwm_chip chip; | ||||
| +	struct clk *clk_top; | ||||
| +	struct clk *clk_main; | ||||
| +	struct clk *clk_pwm[NUM_PWM]; | ||||
| +}; | ||||
| + | ||||
| +static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip) | ||||
| +{ | ||||
| +	return container_of(chip, struct mtk_pwm_chip, chip); | ||||
| +} | ||||
| + | ||||
| +static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num, | ||||
| +				  unsigned long offset) | ||||
| +{ | ||||
| +	return ioread32(chip->mmio_base + 0x10 + (num * 0x40) + offset); | ||||
| +} | ||||
| + | ||||
| +static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip, | ||||
| +				    unsigned int num, unsigned long offset, | ||||
| +				    unsigned long val) | ||||
| +{ | ||||
| +	iowrite32(val, chip->mmio_base + 0x10 + (num * 0x40) + offset); | ||||
| +} | ||||
| + | ||||
| +static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | ||||
| +			    int duty_ns, int period_ns) | ||||
| +{ | ||||
| +	struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); | ||||
| +	u32 resolution = 100 / 4; | ||||
| +	u32 clkdiv = 0; | ||||
| + | ||||
| +	resolution = 1000000000 / (clk_get_rate(pc->clk_pwm[pwm->hwpwm])); | ||||
| + | ||||
| +	while (period_ns / resolution  > 8191) { | ||||
| +		clkdiv++; | ||||
| +		resolution *= 2; | ||||
| +	} | ||||
| + | ||||
| +	if (clkdiv > 7) | ||||
| +		return -1; | ||||
| + | ||||
| +	mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | BIT(3) | clkdiv); | ||||
| +	mtk_pwm_writel(pc, pwm->hwpwm, PWMDWIDTH, period_ns / resolution); | ||||
| +	mtk_pwm_writel(pc, pwm->hwpwm, PWMTHRES, duty_ns / resolution); | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int mtk_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) | ||||
| +{ | ||||
| +	struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); | ||||
| +	u32 val; | ||||
| +	int ret; | ||||
| + | ||||
| +	ret = clk_prepare(pc->clk_pwm[pwm->hwpwm]); | ||||
| +	if (ret < 0) | ||||
| +		return ret; | ||||
| + | ||||
| +	val = ioread32(pc->mmio_base); | ||||
| +	val |= BIT(pwm->hwpwm); | ||||
| +	iowrite32(val, pc->mmio_base); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static void mtk_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) | ||||
| +{ | ||||
| +	struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip); | ||||
| +	u32 val; | ||||
| + | ||||
| +	val = ioread32(pc->mmio_base); | ||||
| +	val &= ~BIT(pwm->hwpwm); | ||||
| +	iowrite32(val, pc->mmio_base); | ||||
| +        clk_unprepare(pc->clk_pwm[pwm->hwpwm]); | ||||
| +} | ||||
| + | ||||
| +static const struct pwm_ops mtk_pwm_ops = { | ||||
| +	.config = mtk_pwm_config, | ||||
| +	.enable = mtk_pwm_enable, | ||||
| +	.disable = mtk_pwm_disable, | ||||
| +	.owner = THIS_MODULE, | ||||
| +}; | ||||
| + | ||||
| +static int mtk_pwm_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct mtk_pwm_chip *pc; | ||||
| +	struct resource *r; | ||||
| +	int ret; | ||||
| + | ||||
| +	pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); | ||||
| +	if (!pc) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||||
| +	pc->mmio_base = devm_ioremap_resource(&pdev->dev, r); | ||||
| +	if (IS_ERR(pc->mmio_base)) | ||||
| +		return PTR_ERR(pc->mmio_base); | ||||
| + | ||||
| +	pc->clk_main = devm_clk_get(&pdev->dev, "main"); | ||||
| +        if (IS_ERR(pc->clk_main)) | ||||
| +		return PTR_ERR(pc->clk_main); | ||||
| + | ||||
| +	pc->clk_top = devm_clk_get(&pdev->dev, "top"); | ||||
| +        if (IS_ERR(pc->clk_top)) | ||||
| +		return PTR_ERR(pc->clk_top); | ||||
| + | ||||
| +	pc->clk_pwm[0] = devm_clk_get(&pdev->dev, "pwm1"); | ||||
| +        if (IS_ERR(pc->clk_pwm[0])) | ||||
| +		return PTR_ERR(pc->clk_pwm[0]); | ||||
| + | ||||
| +	pc->clk_pwm[1] = devm_clk_get(&pdev->dev, "pwm2"); | ||||
| +        if (IS_ERR(pc->clk_pwm[1])) | ||||
| +		return PTR_ERR(pc->clk_pwm[1]); | ||||
| + | ||||
| +	pc->clk_pwm[2] = devm_clk_get(&pdev->dev, "pwm3"); | ||||
| +        if (IS_ERR(pc->clk_pwm[2])) | ||||
| +		return PTR_ERR(pc->clk_pwm[2]); | ||||
| + | ||||
| +	pc->clk_pwm[3] = devm_clk_get(&pdev->dev, "pwm4"); | ||||
| +        if (IS_ERR(pc->clk_pwm[3])) | ||||
| +		return PTR_ERR(pc->clk_pwm[3]); | ||||
| + | ||||
| +	pc->clk_pwm[4] = devm_clk_get(&pdev->dev, "pwm5"); | ||||
| +        if (IS_ERR(pc->clk_pwm[4])) | ||||
| +		return PTR_ERR(pc->clk_pwm[4]); | ||||
| + | ||||
| +	ret = clk_prepare(pc->clk_top); | ||||
| +        if (ret < 0) | ||||
| +		return ret; | ||||
| + | ||||
| +	ret = clk_prepare(pc->clk_main); | ||||
| +	if (ret < 0) | ||||
| +		goto disable_clk_top; | ||||
| + | ||||
| +	platform_set_drvdata(pdev, pc); | ||||
| + | ||||
| +	pc->chip.dev = &pdev->dev; | ||||
| +	pc->chip.ops = &mtk_pwm_ops; | ||||
| +	pc->chip.base = -1; | ||||
| +	pc->chip.npwm = NUM_PWM; | ||||
| + | ||||
| +	ret = pwmchip_add(&pc->chip); | ||||
| +	if (ret < 0) { | ||||
| +		dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); | ||||
| +		goto disable_clk_main; | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| + | ||||
| +disable_clk_main: | ||||
| +	clk_unprepare(pc->clk_main); | ||||
| +disable_clk_top: | ||||
| +	clk_unprepare(pc->clk_top); | ||||
| + | ||||
| +	return ret; | ||||
| +} | ||||
| + | ||||
| +static int mtk_pwm_remove(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct mtk_pwm_chip *pc = platform_get_drvdata(pdev); | ||||
| +	int i; | ||||
| + | ||||
| +	for (i = 0; i < NUM_PWM; i++) | ||||
| +		pwm_disable(&pc->chip.pwms[i]); | ||||
| + | ||||
| +	return pwmchip_remove(&pc->chip); | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id mtk_pwm_of_match[] = { | ||||
| +	{ .compatible = "mediatek,mt7623-pwm" }, | ||||
| +	{ } | ||||
| +}; | ||||
| + | ||||
| +MODULE_DEVICE_TABLE(of, mtk_pwm_of_match); | ||||
| + | ||||
| +static struct platform_driver mtk_pwm_driver = { | ||||
| +	.driver = { | ||||
| +		.name = "mtk-pwm", | ||||
| +		.owner = THIS_MODULE, | ||||
| +		.of_match_table = mtk_pwm_of_match, | ||||
| +	}, | ||||
| +	.probe = mtk_pwm_probe, | ||||
| +	.remove = mtk_pwm_remove, | ||||
| +}; | ||||
| + | ||||
| +module_platform_driver(mtk_pwm_driver); | ||||
| + | ||||
| +MODULE_LICENSE("GPL"); | ||||
| +MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); | ||||
| +MODULE_ALIAS("platform:mtk-pwm"); | ||||
| @@ -1,27 +0,0 @@ | ||||
| From 2b866d69f6198701457d29c5886c0ad7865c785f Mon Sep 17 00:00:00 2001 | ||||
| From: Sean Wang <sean.wang@mediatek.com> | ||||
| Date: Sat, 25 Feb 2017 02:47:21 +0800 | ||||
| Subject: [PATCH 17/57] mfd: mt6397: Add MT6323 LED support into MT6397 driver | ||||
|  | ||||
| Add compatible string as "mt6323-led" that will make | ||||
| the OF core spawn child devices for the LED subnode | ||||
| of that MT6323 MFD device. | ||||
|  | ||||
| Signed-off-by: Sean Wang <sean.wang@mediatek.com> | ||||
| --- | ||||
|  drivers/mfd/mt6397-core.c | 4 ++++ | ||||
|  1 file changed, 4 insertions(+) | ||||
|  | ||||
| --- a/drivers/mfd/mt6397-core.c | ||||
| +++ b/drivers/mfd/mt6397-core.c | ||||
| @@ -48,6 +48,10 @@ static const struct mfd_cell mt6323_devs | ||||
|  		.name = "mt6323-regulator", | ||||
|  		.of_compatible = "mediatek,mt6323-regulator" | ||||
|  	}, | ||||
| +	{ | ||||
| +		.name = "mt6323-led", | ||||
| +		.of_compatible = "mediatek,mt6323-led" | ||||
| +	}, | ||||
|  }; | ||||
|   | ||||
|  static const struct mfd_cell mt6397_devs[] = { | ||||
| @@ -1,78 +0,0 @@ | ||||
| From 424ca23e68b043ce26d6981839ca825ef8637aba Mon Sep 17 00:00:00 2001 | ||||
| From: Sean Wang <sean.wang@mediatek.com> | ||||
| Date: Mon, 20 Mar 2017 14:47:24 +0800 | ||||
| Subject: [PATCH 18/57] dt-bindings: leds: Add document bindings for | ||||
|  leds-mt6323 | ||||
|  | ||||
| This patch adds documentation for devicetree bindings for LED support on | ||||
| MT6323 PMIC. | ||||
|  | ||||
| Signed-off-by: Sean Wang <sean.wang@mediatek.com> | ||||
| --- | ||||
|  .../devicetree/bindings/leds/leds-mt6323.txt       | 60 ++++++++++++++++++++++ | ||||
|  1 file changed, 60 insertions(+) | ||||
|  create mode 100644 Documentation/devicetree/bindings/leds/leds-mt6323.txt | ||||
|  | ||||
| --- /dev/null | ||||
| +++ b/Documentation/devicetree/bindings/leds/leds-mt6323.txt | ||||
| @@ -0,0 +1,60 @@ | ||||
| +Device Tree Bindings for LED support on MT6323 PMIC | ||||
| + | ||||
| +MT6323 LED controller is subfunction provided by MT6323 PMIC, so the LED | ||||
| +controllers are defined as the subnode of the function node provided by MT6323 | ||||
| +PMIC controller that is being defined as one kind of Muti-Function Device (MFD) | ||||
| +using shared bus called PMIC wrapper for each subfunction to access remote | ||||
| +MT6323 PMIC hardware. | ||||
| + | ||||
| +For MT6323 MFD bindings see: | ||||
| +Documentation/devicetree/bindings/mfd/mt6397.txt | ||||
| +For MediaTek PMIC wrapper bindings see: | ||||
| +Documentation/devicetree/bindings/soc/mediatek/pwrap.txt | ||||
| + | ||||
| +Required properties: | ||||
| +- compatible : Must be "mediatek,mt6323-led" | ||||
| +- address-cells : Must be 1 | ||||
| +- size-cells : Must be 0 | ||||
| + | ||||
| +Each led is represented as a child node of the mediatek,mt6323-led that | ||||
| +describes the initial behavior for each LED physically and currently only four | ||||
| +LED child nodes can be supported. | ||||
| + | ||||
| +Required properties for the LED child node: | ||||
| +- reg : LED channel number (0..3) | ||||
| + | ||||
| +Optional properties for the LED child node: | ||||
| +- label : See Documentation/devicetree/bindings/leds/common.txt | ||||
| +- linux,default-trigger : See Documentation/devicetree/bindings/leds/common.txt | ||||
| +- default-state: See Documentation/devicetree/bindings/leds/common.txt | ||||
| + | ||||
| +Example: | ||||
| + | ||||
| +	mt6323: pmic { | ||||
| +		compatible = "mediatek,mt6323"; | ||||
| + | ||||
| +		... | ||||
| + | ||||
| +		mt6323led: leds { | ||||
| +			compatible = "mediatek,mt6323-led"; | ||||
| +			#address-cells = <1>; | ||||
| +			#size-cells = <0>; | ||||
| + | ||||
| +			led@0 { | ||||
| +				reg = <0>; | ||||
| +				label = "LED0"; | ||||
| +				linux,default-trigger = "timer"; | ||||
| +				default-state = "on"; | ||||
| +			}; | ||||
| +			led@1 { | ||||
| +				reg = <1>; | ||||
| +				label = "LED1"; | ||||
| +				default-state = "off"; | ||||
| +			}; | ||||
| +			led@2 { | ||||
| +				reg = <2>; | ||||
| +				label = "LED2"; | ||||
| +				default-state = "on"; | ||||
| +			}; | ||||
| +		}; | ||||
| +	}; | ||||
| @@ -1,24 +0,0 @@ | ||||
| From 7c137e4b83f32a67ccf6b39fa455aca71980a21f Mon Sep 17 00:00:00 2001 | ||||
| From: Sean Wang <sean.wang@mediatek.com> | ||||
| Date: Mon, 20 Mar 2017 14:47:25 +0800 | ||||
| Subject: [PATCH 19/57] dt-bindings: mfd: Add the description for LED as the | ||||
|  sub module | ||||
|  | ||||
| This patch adds description for LED as the sub-module on MT6397/MT6323 | ||||
| multifunction device. | ||||
|  | ||||
| Signed-off-by: Sean Wang <sean.wang@mediatek.com> | ||||
| --- | ||||
|  Documentation/devicetree/bindings/mfd/mt6397.txt | 1 + | ||||
|  1 file changed, 1 insertion(+) | ||||
|  | ||||
| --- a/Documentation/devicetree/bindings/mfd/mt6397.txt | ||||
| +++ b/Documentation/devicetree/bindings/mfd/mt6397.txt | ||||
| @@ -6,6 +6,7 @@ MT6397/MT6323 is a multifunction device | ||||
|  - Audio codec | ||||
|  - GPIO | ||||
|  - Clock | ||||
| +- LED | ||||
|   | ||||
|  It is interfaced to host controller using SPI interface by a proprietary hardware | ||||
|  called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap. | ||||
| @@ -1,539 +0,0 @@ | ||||
| From e482f9590f2e831c68bcf85e3f9f4c88bbd3329f Mon Sep 17 00:00:00 2001 | ||||
| From: Sean Wang <sean.wang@mediatek.com> | ||||
| Date: Mon, 20 Mar 2017 14:47:26 +0800 | ||||
| Subject: [PATCH 20/57] leds: Add LED support for MT6323 PMIC | ||||
|  | ||||
| MT6323 PMIC is a multi-function device that includes LED function. | ||||
| It allows attaching up to 4 LEDs which can either be on, off or dimmed | ||||
| and/or blinked with the controller. | ||||
|  | ||||
| Signed-off-by: Sean Wang <sean.wang@mediatek.com> | ||||
| Reviewed-by: Jacek Anaszewski <jacek.anaszewski@gmail.com> | ||||
| --- | ||||
|  drivers/leds/Kconfig       |   8 + | ||||
|  drivers/leds/leds-mt6323.c | 502 +++++++++++++++++++++++++++++++++++++++++++++ | ||||
|  2 files changed, 510 insertions(+) | ||||
|  create mode 100644 drivers/leds/leds-mt6323.c | ||||
|  | ||||
| --- a/drivers/leds/Kconfig | ||||
| +++ b/drivers/leds/Kconfig | ||||
| @@ -117,6 +117,14 @@ config LEDS_MIKROTIK_RB532 | ||||
|  	  This option enables support for the so called "User LED" of | ||||
|  	  Mikrotik's Routerboard 532. | ||||
|   | ||||
| +config LEDS_MT6323 | ||||
| +	tristate "LED Support for Mediatek MT6323 PMIC" | ||||
| +	depends on LEDS_CLASS | ||||
| +	depends on MFD_MT6397 | ||||
| +	help | ||||
| +	  This option enables support for on-chip LED drivers found on | ||||
| +	  Mediatek MT6323 PMIC. | ||||
| + | ||||
|  config LEDS_S3C24XX | ||||
|  	tristate "LED Support for Samsung S3C24XX GPIO LEDs" | ||||
|  	depends on LEDS_CLASS | ||||
| --- /dev/null | ||||
| +++ b/drivers/leds/leds-mt6323.c | ||||
| @@ -0,0 +1,502 @@ | ||||
| +/* | ||||
| + * LED driver for Mediatek MT6323 PMIC | ||||
| + * | ||||
| + * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.com> | ||||
| + * | ||||
| + * This program is free software; you can redistribute it and/or | ||||
| + * modify it under the terms of the GNU General Public License 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. | ||||
| + */ | ||||
| +#include <linux/kernel.h> | ||||
| +#include <linux/leds.h> | ||||
| +#include <linux/mfd/mt6323/registers.h> | ||||
| +#include <linux/mfd/mt6397/core.h> | ||||
| +#include <linux/module.h> | ||||
| +#include <linux/of.h> | ||||
| +#include <linux/platform_device.h> | ||||
| +#include <linux/regmap.h> | ||||
| + | ||||
| +/* | ||||
| + * Register field for MT6323_TOP_CKPDN0 to enable | ||||
| + * 32K clock common for LED device. | ||||
| + */ | ||||
| +#define MT6323_RG_DRV_32K_CK_PDN	BIT(11) | ||||
| +#define MT6323_RG_DRV_32K_CK_PDN_MASK	BIT(11) | ||||
| + | ||||
| +/* | ||||
| + * Register field for MT6323_TOP_CKPDN2 to enable | ||||
| + * individual clock for LED device. | ||||
| + */ | ||||
| +#define MT6323_RG_ISINK_CK_PDN(i)	BIT(i) | ||||
| +#define MT6323_RG_ISINK_CK_PDN_MASK(i)	BIT(i) | ||||
| + | ||||
| +/* | ||||
| + * Register field for MT6323_TOP_CKCON1 to select | ||||
| + * clock source. | ||||
| + */ | ||||
| +#define MT6323_RG_ISINK_CK_SEL_MASK(i)	(BIT(10) << (i)) | ||||
| + | ||||
| +/* | ||||
| + * Register for MT6323_ISINK_CON0 to setup the | ||||
| + * duty cycle of the blink. | ||||
| + */ | ||||
| +#define MT6323_ISINK_CON0(i)		(MT6323_ISINK0_CON0 + 0x8 * (i)) | ||||
| +#define MT6323_ISINK_DIM_DUTY_MASK	(0x1f << 8) | ||||
| +#define MT6323_ISINK_DIM_DUTY(i)	(((i) << 8) & \ | ||||
| +					MT6323_ISINK_DIM_DUTY_MASK) | ||||
| + | ||||
| +/* Register to setup the period of the blink. */ | ||||
| +#define MT6323_ISINK_CON1(i)		(MT6323_ISINK0_CON1 + 0x8 * (i)) | ||||
| +#define MT6323_ISINK_DIM_FSEL_MASK	(0xffff) | ||||
| +#define MT6323_ISINK_DIM_FSEL(i)	((i) & MT6323_ISINK_DIM_FSEL_MASK) | ||||
| + | ||||
| +/* Register to control the brightness. */ | ||||
| +#define MT6323_ISINK_CON2(i)		(MT6323_ISINK0_CON2 + 0x8 * (i)) | ||||
| +#define MT6323_ISINK_CH_STEP_SHIFT	12 | ||||
| +#define MT6323_ISINK_CH_STEP_MASK	(0x7 << 12) | ||||
| +#define MT6323_ISINK_CH_STEP(i)		(((i) << 12) & \ | ||||
| +					MT6323_ISINK_CH_STEP_MASK) | ||||
| +#define MT6323_ISINK_SFSTR0_TC_MASK	(0x3 << 1) | ||||
| +#define MT6323_ISINK_SFSTR0_TC(i)	(((i) << 1) & \ | ||||
| +					MT6323_ISINK_SFSTR0_TC_MASK) | ||||
| +#define MT6323_ISINK_SFSTR0_EN_MASK	BIT(0) | ||||
| +#define MT6323_ISINK_SFSTR0_EN		BIT(0) | ||||
| + | ||||
| +/* Register to LED channel enablement. */ | ||||
| +#define MT6323_ISINK_CH_EN_MASK(i)	BIT(i) | ||||
| +#define MT6323_ISINK_CH_EN(i)		BIT(i) | ||||
| + | ||||
| +#define MT6323_MAX_PERIOD		10000 | ||||
| +#define MT6323_MAX_LEDS			4 | ||||
| +#define MT6323_MAX_BRIGHTNESS		6 | ||||
| +#define MT6323_UNIT_DUTY		3125 | ||||
| +#define MT6323_CAL_HW_DUTY(o, p)	DIV_ROUND_CLOSEST((o) * 100000ul,\ | ||||
| +					(p) * MT6323_UNIT_DUTY) | ||||
| + | ||||
| +struct mt6323_leds; | ||||
| + | ||||
| +/** | ||||
| + * struct mt6323_led - state container for the LED device | ||||
| + * @id:			the identifier in MT6323 LED device | ||||
| + * @parent:		the pointer to MT6323 LED controller | ||||
| + * @cdev:		LED class device for this LED device | ||||
| + * @current_brightness: current state of the LED device | ||||
| + */ | ||||
| +struct mt6323_led { | ||||
| +	int			id; | ||||
| +	struct mt6323_leds	*parent; | ||||
| +	struct led_classdev	cdev; | ||||
| +	enum led_brightness	current_brightness; | ||||
| +}; | ||||
| + | ||||
| +/** | ||||
| + * struct mt6323_leds -	state container for holding LED controller | ||||
| + *			of the driver | ||||
| + * @dev:		the device pointer | ||||
| + * @hw:			the underlying hardware providing shared | ||||
| + *			bus for the register operations | ||||
| + * @lock:		the lock among process context | ||||
| + * @led:		the array that contains the state of individual | ||||
| + *			LED device | ||||
| + */ | ||||
| +struct mt6323_leds { | ||||
| +	struct device		*dev; | ||||
| +	struct mt6397_chip	*hw; | ||||
| +	/* protect among process context */ | ||||
| +	struct mutex		lock; | ||||
| +	struct mt6323_led	*led[MT6323_MAX_LEDS]; | ||||
| +}; | ||||
| + | ||||
| +static int mt6323_led_hw_brightness(struct led_classdev *cdev, | ||||
| +				    enum led_brightness brightness) | ||||
| +{ | ||||
| +	struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev); | ||||
| +	struct mt6323_leds *leds = led->parent; | ||||
| +	struct regmap *regmap = leds->hw->regmap; | ||||
| +	u32 con2_mask = 0, con2_val = 0; | ||||
| +	int ret; | ||||
| + | ||||
| +	/* | ||||
| +	 * Setup current output for the corresponding | ||||
| +	 * brightness level. | ||||
| +	 */ | ||||
| +	con2_mask |= MT6323_ISINK_CH_STEP_MASK | | ||||
| +		     MT6323_ISINK_SFSTR0_TC_MASK | | ||||
| +		     MT6323_ISINK_SFSTR0_EN_MASK; | ||||
| +	con2_val |=  MT6323_ISINK_CH_STEP(brightness - 1) | | ||||
| +		     MT6323_ISINK_SFSTR0_TC(2) | | ||||
| +		     MT6323_ISINK_SFSTR0_EN; | ||||
| + | ||||
| +	ret = regmap_update_bits(regmap, MT6323_ISINK_CON2(led->id), | ||||
| +				 con2_mask, con2_val); | ||||
| +	return ret; | ||||
| +} | ||||
| + | ||||
| +static int mt6323_led_hw_off(struct led_classdev *cdev) | ||||
| +{ | ||||
| +	struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev); | ||||
| +	struct mt6323_leds *leds = led->parent; | ||||
| +	struct regmap *regmap = leds->hw->regmap; | ||||
| +	unsigned int status; | ||||
| +	int ret; | ||||
| + | ||||
| +	status = MT6323_ISINK_CH_EN(led->id); | ||||
| +	ret = regmap_update_bits(regmap, MT6323_ISINK_EN_CTRL, | ||||
| +				 MT6323_ISINK_CH_EN_MASK(led->id), ~status); | ||||
| +	if (ret < 0) | ||||
| +		return ret; | ||||
| + | ||||
| +	usleep_range(100, 300); | ||||
| +	ret = regmap_update_bits(regmap, MT6323_TOP_CKPDN2, | ||||
| +				 MT6323_RG_ISINK_CK_PDN_MASK(led->id), | ||||
| +				 MT6323_RG_ISINK_CK_PDN(led->id)); | ||||
| +	if (ret < 0) | ||||
| +		return ret; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static enum led_brightness | ||||
| +mt6323_get_led_hw_brightness(struct led_classdev *cdev) | ||||
| +{ | ||||
| +	struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev); | ||||
| +	struct mt6323_leds *leds = led->parent; | ||||
| +	struct regmap *regmap = leds->hw->regmap; | ||||
| +	unsigned int status; | ||||
| +	int ret; | ||||
| + | ||||
| +	ret = regmap_read(regmap, MT6323_TOP_CKPDN2, &status); | ||||
| +	if (ret < 0) | ||||
| +		return ret; | ||||
| + | ||||
| +	if (status & MT6323_RG_ISINK_CK_PDN_MASK(led->id)) | ||||
| +		return 0; | ||||
| + | ||||
| +	ret = regmap_read(regmap, MT6323_ISINK_EN_CTRL, &status); | ||||
| +	if (ret < 0) | ||||
| +		return ret; | ||||
| + | ||||
| +	if (!(status & MT6323_ISINK_CH_EN(led->id))) | ||||
| +		return 0; | ||||
| + | ||||
| +	ret = regmap_read(regmap, MT6323_ISINK_CON2(led->id), &status); | ||||
| +	if (ret < 0) | ||||
| +		return ret; | ||||
| + | ||||
| +	return  ((status & MT6323_ISINK_CH_STEP_MASK) | ||||
| +		  >> MT6323_ISINK_CH_STEP_SHIFT) + 1; | ||||
| +} | ||||
| + | ||||
| +static int mt6323_led_hw_on(struct led_classdev *cdev, | ||||
| +			    enum led_brightness brightness) | ||||
| +{ | ||||
| +	struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev); | ||||
| +	struct mt6323_leds *leds = led->parent; | ||||
| +	struct regmap *regmap = leds->hw->regmap; | ||||
| +	unsigned int status; | ||||
| +	int ret; | ||||
| + | ||||
| +	/* | ||||
| +	 * Setup required clock source, enable the corresponding | ||||
| +	 * clock and channel and let work with continuous blink as | ||||
| +	 * the default. | ||||
| +	 */ | ||||
| +	ret = regmap_update_bits(regmap, MT6323_TOP_CKCON1, | ||||
| +				 MT6323_RG_ISINK_CK_SEL_MASK(led->id), 0); | ||||
| +	if (ret < 0) | ||||
| +		return ret; | ||||
| + | ||||
| +	status = MT6323_RG_ISINK_CK_PDN(led->id); | ||||
| +	ret = regmap_update_bits(regmap, MT6323_TOP_CKPDN2, | ||||
| +				 MT6323_RG_ISINK_CK_PDN_MASK(led->id), | ||||
| +				 ~status); | ||||
| +	if (ret < 0) | ||||
| +		return ret; | ||||
| + | ||||
| +	usleep_range(100, 300); | ||||
| + | ||||
| +	ret = regmap_update_bits(regmap, MT6323_ISINK_EN_CTRL, | ||||
| +				 MT6323_ISINK_CH_EN_MASK(led->id), | ||||
| +				 MT6323_ISINK_CH_EN(led->id)); | ||||
| +	if (ret < 0) | ||||
| +		return ret; | ||||
| + | ||||
| +	ret = mt6323_led_hw_brightness(cdev, brightness); | ||||
| +	if (ret < 0) | ||||
| +		return ret; | ||||
| + | ||||
| +	ret = regmap_update_bits(regmap, MT6323_ISINK_CON0(led->id), | ||||
| +				 MT6323_ISINK_DIM_DUTY_MASK, | ||||
| +				 MT6323_ISINK_DIM_DUTY(31)); | ||||
| +	if (ret < 0) | ||||
| +		return ret; | ||||
| + | ||||
| +	ret = regmap_update_bits(regmap, MT6323_ISINK_CON1(led->id), | ||||
| +				 MT6323_ISINK_DIM_FSEL_MASK, | ||||
| +				 MT6323_ISINK_DIM_FSEL(1000)); | ||||
| +	if (ret < 0) | ||||
| +		return ret; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int mt6323_led_set_blink(struct led_classdev *cdev, | ||||
| +				unsigned long *delay_on, | ||||
| +				unsigned long *delay_off) | ||||
| +{ | ||||
| +	struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev); | ||||
| +	struct mt6323_leds *leds = led->parent; | ||||
| +	struct regmap *regmap = leds->hw->regmap; | ||||
| +	unsigned long period; | ||||
| +	u8 duty_hw; | ||||
| +	int ret; | ||||
| + | ||||
| +	/* | ||||
| +	 * Units are in ms, if over the hardware able | ||||
| +	 * to support, fallback into software blink | ||||
| +	 */ | ||||
| +	period = *delay_on + *delay_off; | ||||
| + | ||||
| +	if (period > MT6323_MAX_PERIOD) | ||||
| +		return -EINVAL; | ||||
| + | ||||
| +	/* | ||||
| +	 * LED subsystem requires a default user | ||||
| +	 * friendly blink pattern for the LED so using | ||||
| +	 * 1Hz duty cycle 50% here if without specific | ||||
| +	 * value delay_on and delay off being assigned. | ||||
| +	 */ | ||||
| +	if (!*delay_on && !*delay_off) { | ||||
| +		*delay_on = 500; | ||||
| +		*delay_off = 500; | ||||
| +	} | ||||
| + | ||||
| +	/* | ||||
| +	 * Calculate duty_hw based on the percentage of period during | ||||
| +	 * which the led is ON. | ||||
| +	 */ | ||||
| +	duty_hw = MT6323_CAL_HW_DUTY(*delay_on, period); | ||||
| + | ||||
| +	/* hardware doesn't support zero duty cycle. */ | ||||
| +	if (!duty_hw) | ||||
| +		return -EINVAL; | ||||
| + | ||||
| +	mutex_lock(&leds->lock); | ||||
| +	/* | ||||
| +	 * Set max_brightness as the software blink behavior | ||||
| +	 * when no blink brightness. | ||||
| +	 */ | ||||
| +	if (!led->current_brightness) { | ||||
| +		ret = mt6323_led_hw_on(cdev, cdev->max_brightness); | ||||
| +		if (ret < 0) | ||||
| +			goto out; | ||||
| +		led->current_brightness = cdev->max_brightness; | ||||
| +	} | ||||
| + | ||||
| +	ret = regmap_update_bits(regmap, MT6323_ISINK_CON0(led->id), | ||||
| +				 MT6323_ISINK_DIM_DUTY_MASK, | ||||
| +				 MT6323_ISINK_DIM_DUTY(duty_hw - 1)); | ||||
| +	if (ret < 0) | ||||
| +		goto out; | ||||
| + | ||||
| +	ret = regmap_update_bits(regmap, MT6323_ISINK_CON1(led->id), | ||||
| +				 MT6323_ISINK_DIM_FSEL_MASK, | ||||
| +				 MT6323_ISINK_DIM_FSEL(period - 1)); | ||||
| +out: | ||||
| +	mutex_unlock(&leds->lock); | ||||
| + | ||||
| +	return ret; | ||||
| +} | ||||
| + | ||||
| +static int mt6323_led_set_brightness(struct led_classdev *cdev, | ||||
| +				     enum led_brightness brightness) | ||||
| +{ | ||||
| +	struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev); | ||||
| +	struct mt6323_leds *leds = led->parent; | ||||
| +	int ret; | ||||
| + | ||||
| +	mutex_lock(&leds->lock); | ||||
| + | ||||
| +	if (!led->current_brightness && brightness) { | ||||
| +		ret = mt6323_led_hw_on(cdev, brightness); | ||||
| +		if (ret < 0) | ||||
| +			goto out; | ||||
| +	} else if (brightness) { | ||||
| +		ret = mt6323_led_hw_brightness(cdev, brightness); | ||||
| +		if (ret < 0) | ||||
| +			goto out; | ||||
| +	} else { | ||||
| +		ret = mt6323_led_hw_off(cdev); | ||||
| +		if (ret < 0) | ||||
| +			goto out; | ||||
| +	} | ||||
| + | ||||
| +	led->current_brightness = brightness; | ||||
| +out: | ||||
| +	mutex_unlock(&leds->lock); | ||||
| + | ||||
| +	return ret; | ||||
| +} | ||||
| + | ||||
| +static int mt6323_led_set_dt_default(struct led_classdev *cdev, | ||||
| +				     struct device_node *np) | ||||
| +{ | ||||
| +	struct mt6323_led *led = container_of(cdev, struct mt6323_led, cdev); | ||||
| +	const char *state; | ||||
| +	int ret = 0; | ||||
| + | ||||
| +	led->cdev.name = of_get_property(np, "label", NULL) ? : np->name; | ||||
| +	led->cdev.default_trigger = of_get_property(np, | ||||
| +						    "linux,default-trigger", | ||||
| +						    NULL); | ||||
| + | ||||
| +	state = of_get_property(np, "default-state", NULL); | ||||
| +	if (state) { | ||||
| +		if (!strcmp(state, "keep")) { | ||||
| +			ret = mt6323_get_led_hw_brightness(cdev); | ||||
| +			if (ret < 0) | ||||
| +				return ret; | ||||
| +			led->current_brightness = ret; | ||||
| +			ret = 0; | ||||
| +		} else if (!strcmp(state, "on")) { | ||||
| +			ret = | ||||
| +			mt6323_led_set_brightness(cdev, cdev->max_brightness); | ||||
| +		} else  { | ||||
| +			ret = mt6323_led_set_brightness(cdev, LED_OFF); | ||||
| +		} | ||||
| +	} | ||||
| + | ||||
| +	return ret; | ||||
| +} | ||||
| + | ||||
| +static int mt6323_led_probe(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct device *dev = &pdev->dev; | ||||
| +	struct device_node *np = pdev->dev.of_node; | ||||
| +	struct device_node *child; | ||||
| +	struct mt6397_chip *hw = dev_get_drvdata(pdev->dev.parent); | ||||
| +	struct mt6323_leds *leds; | ||||
| +	struct mt6323_led *led; | ||||
| +	int ret; | ||||
| +	unsigned int status; | ||||
| +	u32 reg; | ||||
| + | ||||
| +	leds = devm_kzalloc(dev, sizeof(*leds), GFP_KERNEL); | ||||
| +	if (!leds) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	platform_set_drvdata(pdev, leds); | ||||
| +	leds->dev = dev; | ||||
| + | ||||
| +	/* | ||||
| +	 * leds->hw points to the underlying bus for the register | ||||
| +	 * controlled. | ||||
| +	 */ | ||||
| +	leds->hw = hw; | ||||
| +	mutex_init(&leds->lock); | ||||
| + | ||||
| +	status = MT6323_RG_DRV_32K_CK_PDN; | ||||
| +	ret = regmap_update_bits(leds->hw->regmap, MT6323_TOP_CKPDN0, | ||||
| +				 MT6323_RG_DRV_32K_CK_PDN_MASK, ~status); | ||||
| +	if (ret < 0) { | ||||
| +		dev_err(leds->dev, | ||||
| +			"Failed to update MT6323_TOP_CKPDN0 Register\n"); | ||||
| +		return ret; | ||||
| +	} | ||||
| + | ||||
| +	for_each_available_child_of_node(np, child) { | ||||
| +		ret = of_property_read_u32(child, "reg", ®); | ||||
| +		if (ret) { | ||||
| +			dev_err(dev, "Failed to read led 'reg' property\n"); | ||||
| +			goto put_child_node; | ||||
| +		} | ||||
| + | ||||
| +		if (reg < 0 || reg > MT6323_MAX_LEDS || leds->led[reg]) { | ||||
| +			dev_err(dev, "Invalid led reg %u\n", reg); | ||||
| +			ret = -EINVAL; | ||||
| +			goto put_child_node; | ||||
| +		} | ||||
| + | ||||
| +		led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL); | ||||
| +		if (!led) { | ||||
| +			ret = -ENOMEM; | ||||
| +			goto put_child_node; | ||||
| +		} | ||||
| + | ||||
| +		leds->led[reg] = led; | ||||
| +		leds->led[reg]->id = reg; | ||||
| +		leds->led[reg]->cdev.max_brightness = MT6323_MAX_BRIGHTNESS; | ||||
| +		leds->led[reg]->cdev.brightness_set_blocking = | ||||
| +					mt6323_led_set_brightness; | ||||
| +		leds->led[reg]->cdev.blink_set = mt6323_led_set_blink; | ||||
| +		leds->led[reg]->cdev.brightness_get = | ||||
| +					mt6323_get_led_hw_brightness; | ||||
| +		leds->led[reg]->parent = leds; | ||||
| + | ||||
| +		ret = mt6323_led_set_dt_default(&leds->led[reg]->cdev, child); | ||||
| +		if (ret < 0) { | ||||
| +			dev_err(leds->dev, | ||||
| +				"Failed to LED set default from devicetree\n"); | ||||
| +			goto put_child_node; | ||||
| +		} | ||||
| + | ||||
| +		ret = devm_led_classdev_register(dev, &leds->led[reg]->cdev); | ||||
| +		if (ret) { | ||||
| +			dev_err(&pdev->dev, "Failed to register LED: %d\n", | ||||
| +				ret); | ||||
| +			goto put_child_node; | ||||
| +		} | ||||
| +		leds->led[reg]->cdev.dev->of_node = child; | ||||
| +	} | ||||
| + | ||||
| +	return 0; | ||||
| + | ||||
| +put_child_node: | ||||
| +	of_node_put(child); | ||||
| +	return ret; | ||||
| +} | ||||
| + | ||||
| +static int mt6323_led_remove(struct platform_device *pdev) | ||||
| +{ | ||||
| +	struct mt6323_leds *leds = platform_get_drvdata(pdev); | ||||
| +	int i; | ||||
| + | ||||
| +	/* Turn the LEDs off on driver removal. */ | ||||
| +	for (i = 0 ; leds->led[i] ; i++) | ||||
| +		mt6323_led_hw_off(&leds->led[i]->cdev); | ||||
| + | ||||
| +	regmap_update_bits(leds->hw->regmap, MT6323_TOP_CKPDN0, | ||||
| +			   MT6323_RG_DRV_32K_CK_PDN_MASK, | ||||
| +			   MT6323_RG_DRV_32K_CK_PDN); | ||||
| + | ||||
| +	mutex_destroy(&leds->lock); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static const struct of_device_id mt6323_led_dt_match[] = { | ||||
| +	{ .compatible = "mediatek,mt6323-led" }, | ||||
| +	{}, | ||||
| +}; | ||||
| +MODULE_DEVICE_TABLE(of, mt6323_led_dt_match); | ||||
| + | ||||
| +static struct platform_driver mt6323_led_driver = { | ||||
| +	.probe		= mt6323_led_probe, | ||||
| +	.remove		= mt6323_led_remove, | ||||
| +	.driver		= { | ||||
| +		.name	= "mt6323-led", | ||||
| +		.of_match_table = mt6323_led_dt_match, | ||||
| +	}, | ||||
| +}; | ||||
| + | ||||
| +module_platform_driver(mt6323_led_driver); | ||||
| + | ||||
| +MODULE_DESCRIPTION("LED driver for Mediatek MT6323 PMIC"); | ||||
| +MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); | ||||
| +MODULE_LICENSE("GPL"); | ||||
| @@ -1,27 +0,0 @@ | ||||
| From 6e81b4fee93c004078465589128ba07b6855be02 Mon Sep 17 00:00:00 2001 | ||||
| From: Sean Wang <sean.wang@mediatek.com> | ||||
| Date: Mon, 20 Mar 2017 14:47:27 +0800 | ||||
| Subject: [PATCH 21/57] mfd: mt6397: Align the placement at which the mfd_cell | ||||
|  of LED is defined | ||||
|  | ||||
| Align the placement as which the mfd_cell of LED is defined as the other | ||||
| members done on the structure. | ||||
|  | ||||
| Signed-off-by: Sean Wang <sean.wang@mediatek.com> | ||||
| Acked-by: Lee Jones <lee.jones@linaro.org> | ||||
| --- | ||||
|  drivers/mfd/mt6397-core.c | 3 +-- | ||||
|  1 file changed, 1 insertion(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/mfd/mt6397-core.c | ||||
| +++ b/drivers/mfd/mt6397-core.c | ||||
| @@ -47,8 +47,7 @@ static const struct mfd_cell mt6323_devs | ||||
|  	{ | ||||
|  		.name = "mt6323-regulator", | ||||
|  		.of_compatible = "mediatek,mt6323-regulator" | ||||
| -	}, | ||||
| -	{ | ||||
| +	}, { | ||||
|  		.name = "mt6323-led", | ||||
|  		.of_compatible = "mediatek,mt6323-led" | ||||
|  	}, | ||||
| @@ -1,32 +0,0 @@ | ||||
| From 453ebd5d6b535388972fcea747025ced3afca5cc Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Thu, 10 Aug 2017 14:47:06 +0200 | ||||
| Subject: [PATCH 22/57] nand: make bootrom work with upstream driver | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/mtd/nand/mtk_nand.c | 6 +++--- | ||||
|  1 file changed, 3 insertions(+), 3 deletions(-) | ||||
|  | ||||
| --- a/drivers/mtd/nand/mtk_nand.c | ||||
| +++ b/drivers/mtd/nand/mtk_nand.c | ||||
| @@ -1073,8 +1073,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; | ||||
|  } | ||||
| @@ -1114,7 +1114,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, | ||||
| @@ -1,81 +0,0 @@ | ||||
| From 4ad0accdfb0941de1440906461c08bee715378d5 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Thu, 10 Aug 2017 15:57:44 +0200 | ||||
| Subject: [PATCH 23/57] rng: add mediatek hw rng | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/char/hw_random/Kconfig  | 14 ++++++++++++++ | ||||
|  drivers/char/hw_random/Makefile |  1 + | ||||
|  drivers/crypto/Kconfig          | 18 ++++++++++++++++++ | ||||
|  drivers/crypto/Makefile         |  1 + | ||||
|  4 files changed, 34 insertions(+) | ||||
|  | ||||
| --- a/drivers/char/hw_random/Kconfig | ||||
| +++ b/drivers/char/hw_random/Kconfig | ||||
| @@ -166,6 +166,20 @@ config HW_RANDOM_IXP4XX | ||||
|   | ||||
|  	  If unsure, say Y. | ||||
|   | ||||
| +config HW_RANDOM_MTK | ||||
| +	tristate "Mediatek Random Number Generator support" | ||||
| +	depends on HW_RANDOM | ||||
| +	depends on ARCH_MEDIATEK || COMPILE_TEST | ||||
| +	default y | ||||
| +	---help--- | ||||
| +	  This driver provides kernel-side support for the Random Number | ||||
| +	  Generator hardware found on Mediatek SoCs. | ||||
| + | ||||
| +	  To compile this driver as a module, choose M here. the | ||||
| +	  module will be called mtk-rng. | ||||
| + | ||||
| +	  If unsure, say Y. | ||||
| + | ||||
|  config HW_RANDOM_OMAP | ||||
|  	tristate "OMAP Random Number Generator support" | ||||
|  	depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS | ||||
| --- a/drivers/char/hw_random/Makefile | ||||
| +++ b/drivers/char/hw_random/Makefile | ||||
| @@ -35,4 +35,5 @@ obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-r | ||||
|  obj-$(CONFIG_HW_RANDOM_STM32) += stm32-rng.o | ||||
|  obj-$(CONFIG_HW_RANDOM_PIC32) += pic32-rng.o | ||||
|  obj-$(CONFIG_HW_RANDOM_MESON) += meson-rng.o | ||||
| +obj-$(CONFIG_HW_RANDOM_MTK)	+= mtk-rng.o | ||||
|  obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o | ||||
| --- a/drivers/crypto/Kconfig | ||||
| +++ b/drivers/crypto/Kconfig | ||||
| @@ -553,6 +553,24 @@ config CRYPTO_DEV_ROCKCHIP | ||||
|  	  This driver interfaces with the hardware crypto accelerator. | ||||
|  	  Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode. | ||||
|   | ||||
| +config CRYPTO_DEV_MEDIATEK | ||||
| +	tristate "MediaTek's EIP97 Cryptographic Engine driver" | ||||
| +	depends on HAS_DMA | ||||
| +	depends on (ARM && ARCH_MEDIATEK) || COMPILE_TEST | ||||
| +	select CRYPTO_AES | ||||
| +	select CRYPTO_AEAD | ||||
| +	select CRYPTO_BLKCIPHER | ||||
| +	select CRYPTO_CTR | ||||
| +	select CRYPTO_SHA1 | ||||
| +	select CRYPTO_SHA256 | ||||
| +	select CRYPTO_SHA512 | ||||
| +	select CRYPTO_HMAC | ||||
| +	help | ||||
| +	  This driver allows you to utilize the hardware crypto accelerator | ||||
| +	  EIP97 which can be found on the MT7623 MT2701, MT8521p, etc .... | ||||
| +	  Select this if you want to use it for AES/SHA1/SHA2 algorithms. | ||||
| + | ||||
| + | ||||
|  source "drivers/crypto/chelsio/Kconfig" | ||||
|   | ||||
|  endif # CRYPTO_HW | ||||
| --- a/drivers/crypto/Makefile | ||||
| +++ b/drivers/crypto/Makefile | ||||
| @@ -10,6 +10,7 @@ obj-$(CONFIG_CRYPTO_DEV_IMGTEC_HASH) += | ||||
|  obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o | ||||
|  obj-$(CONFIG_CRYPTO_DEV_MV_CESA) += mv_cesa.o | ||||
|  obj-$(CONFIG_CRYPTO_DEV_MARVELL_CESA) += marvell/ | ||||
| +obj-$(CONFIG_CRYPTO_DEV_MEDIATEK) += mediatek/ | ||||
|  obj-$(CONFIG_CRYPTO_DEV_MXS_DCP) += mxs-dcp.o | ||||
|  obj-$(CONFIG_CRYPTO_DEV_NIAGARA2) += n2_crypto.o | ||||
|  n2_crypto-y := n2_core.o n2_asm.o | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,110 +0,0 @@ | ||||
| From 3b9b46b5705214b16c5356284ad68be32ae56a26 Mon Sep 17 00:00:00 2001 | ||||
| From: Sean Wang <sean.wang@mediatek.com> | ||||
| Date: Wed, 29 Mar 2017 17:38:19 +0800 | ||||
| Subject: [PATCH 25/57] dt-bindings: net: dsa: add Mediatek MT7530 binding | ||||
|  | ||||
| Add device-tree binding for Mediatek MT7530 switch. | ||||
|  | ||||
| Cc: devicetree@vger.kernel.org | ||||
| Signed-off-by: Sean Wang <sean.wang@mediatek.com> | ||||
| Acked-by: Rob Herring <robh@kernel.org> | ||||
| --- | ||||
|  .../devicetree/bindings/net/dsa/mt7530.txt         | 92 ++++++++++++++++++++++ | ||||
|  1 file changed, 92 insertions(+) | ||||
|  create mode 100644 Documentation/devicetree/bindings/net/dsa/mt7530.txt | ||||
|  | ||||
| --- /dev/null | ||||
| +++ b/Documentation/devicetree/bindings/net/dsa/mt7530.txt | ||||
| @@ -0,0 +1,92 @@ | ||||
| +Mediatek MT7530 Ethernet switch | ||||
| +================================ | ||||
| + | ||||
| +Required properties: | ||||
| + | ||||
| +- compatible: Must be compatible = "mediatek,mt7530"; | ||||
| +- #address-cells: Must be 1. | ||||
| +- #size-cells: Must be 0. | ||||
| +- mediatek,mcm: Boolean; if defined, indicates that either MT7530 is the part | ||||
| +	on multi-chip module belong to MT7623A has or the remotely standalone | ||||
| +	chip as the function MT7623N reference board provided for. | ||||
| +- core-supply: Phandle to the regulator node necessary for the core power. | ||||
| +- io-supply: Phandle to the regulator node necessary for the I/O power. | ||||
| +	See Documentation/devicetree/bindings/regulator/mt6323-regulator.txt | ||||
| +	for details for the regulator setup on these boards. | ||||
| + | ||||
| +If the property mediatek,mcm isn't defined, following property is required | ||||
| + | ||||
| +- reset-gpios: Should be a gpio specifier for a reset line. | ||||
| + | ||||
| +Else, following properties are required | ||||
| + | ||||
| +- resets : Phandle pointing to the system reset controller with | ||||
| +	line index for the ethsys. | ||||
| +- reset-names : Should be set to "mcm". | ||||
| + | ||||
| +Required properties for the child nodes within ports container: | ||||
| + | ||||
| +- reg: Port address described must be 6 for CPU port and from 0 to 5 for | ||||
| +	user ports. | ||||
| +- phy-mode: String, must be either "trgmii" or "rgmii" for port labeled | ||||
| +	 "cpu". | ||||
| + | ||||
| +See Documentation/devicetree/bindings/dsa/dsa.txt for a list of additional | ||||
| +required, optional properties and how the integrated switch subnodes must | ||||
| +be specified. | ||||
| + | ||||
| +Example: | ||||
| + | ||||
| +	&mdio0 { | ||||
| +		switch@0 { | ||||
| +			compatible = "mediatek,mt7530"; | ||||
| +			#address-cells = <1>; | ||||
| +			#size-cells = <0>; | ||||
| +			reg = <0>; | ||||
| + | ||||
| +			core-supply = <&mt6323_vpa_reg>; | ||||
| +			io-supply = <&mt6323_vemc3v3_reg>; | ||||
| +			reset-gpios = <&pio 33 0>; | ||||
| + | ||||
| +			ports { | ||||
| +				#address-cells = <1>; | ||||
| +				#size-cells = <0>; | ||||
| +				reg = <0>; | ||||
| +				port@0 { | ||||
| +					reg = <0>; | ||||
| +					label = "lan0"; | ||||
| +				}; | ||||
| + | ||||
| +				port@1 { | ||||
| +					reg = <1>; | ||||
| +					label = "lan1"; | ||||
| +				}; | ||||
| + | ||||
| +				port@2 { | ||||
| +					reg = <2>; | ||||
| +					label = "lan2"; | ||||
| +				}; | ||||
| + | ||||
| +				port@3 { | ||||
| +					reg = <3>; | ||||
| +					label = "lan3"; | ||||
| +				}; | ||||
| + | ||||
| +				port@4 { | ||||
| +					reg = <4>; | ||||
| +					label = "wan"; | ||||
| +				}; | ||||
| + | ||||
| +				port@6 { | ||||
| +					reg = <6>; | ||||
| +					label = "cpu"; | ||||
| +					ethernet = <&gmac0>; | ||||
| +					phy-mode = "trgmii"; | ||||
| +					fixed-link { | ||||
| +						speed = <1000>; | ||||
| +						full-duplex; | ||||
| +					}; | ||||
| +				}; | ||||
| +			}; | ||||
| +		}; | ||||
| +	}; | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,192 +0,0 @@ | ||||
| From 5c01c03920c63630864d2b8641924a8c7c6cb62f Mon Sep 17 00:00:00 2001 | ||||
| From: Sean Wang <sean.wang@mediatek.com> | ||||
| Date: Wed, 29 Mar 2017 17:38:20 +0800 | ||||
| Subject: [PATCH 28/57] net-next: dsa: add Mediatek tag RX/TX handler | ||||
|  | ||||
| Add the support for the 4-bytes tag for DSA port distinguishing inserted | ||||
| allowing receiving and transmitting the packet via the particular port. | ||||
| The tag is being added after the source MAC address in the ethernet | ||||
| header. | ||||
|  | ||||
| Signed-off-by: Sean Wang <sean.wang@mediatek.com> | ||||
| Signed-off-by: Landen Chao <Landen.Chao@mediatek.com> | ||||
| Reviewed-by: Andrew Lunn <andrew@lunn.ch> | ||||
| Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> | ||||
| --- | ||||
|  include/net/dsa.h  |   1 + | ||||
|  net/dsa/Kconfig    |   2 + | ||||
|  net/dsa/Makefile   |   1 + | ||||
|  net/dsa/dsa.c      |   3 ++ | ||||
|  net/dsa/dsa_priv.h |   3 ++ | ||||
|  net/dsa/tag_mtk.c  | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++ | ||||
|  6 files changed, 127 insertions(+) | ||||
|  create mode 100644 net/dsa/tag_mtk.c | ||||
|  | ||||
| --- a/include/net/dsa.h | ||||
| +++ b/include/net/dsa.h | ||||
| @@ -27,6 +27,7 @@ enum dsa_tag_protocol { | ||||
|  	DSA_TAG_PROTO_EDSA, | ||||
|  	DSA_TAG_PROTO_BRCM, | ||||
|  	DSA_TAG_PROTO_QCA, | ||||
| +	DSA_TAG_PROTO_MTK, | ||||
|  	DSA_TAG_LAST,		/* MUST BE LAST */ | ||||
|  }; | ||||
|   | ||||
| --- a/net/dsa/Kconfig | ||||
| +++ b/net/dsa/Kconfig | ||||
| @@ -42,4 +42,6 @@ config NET_DSA_TAG_TRAILER | ||||
|  config NET_DSA_TAG_QCA | ||||
|  	bool | ||||
|   | ||||
| +config NET_DSA_TAG_MTK | ||||
| +	bool | ||||
|  endif | ||||
| --- a/net/dsa/Makefile | ||||
| +++ b/net/dsa/Makefile | ||||
| @@ -8,3 +8,4 @@ dsa_core-$(CONFIG_NET_DSA_TAG_DSA) += ta | ||||
|  dsa_core-$(CONFIG_NET_DSA_TAG_EDSA) += tag_edsa.o | ||||
|  dsa_core-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o | ||||
|  dsa_core-$(CONFIG_NET_DSA_TAG_QCA) += tag_qca.o | ||||
| +dsa_core-$(CONFIG_NET_DSA_TAG_MTK) += tag_mtk.o | ||||
| --- a/net/dsa/dsa.c | ||||
| +++ b/net/dsa/dsa.c | ||||
| @@ -57,6 +57,9 @@ const struct dsa_device_ops *dsa_device_ | ||||
|  #ifdef CONFIG_NET_DSA_TAG_QCA | ||||
|  	[DSA_TAG_PROTO_QCA] = &qca_netdev_ops, | ||||
|  #endif | ||||
| +#ifdef CONFIG_NET_DSA_TAG_MTK | ||||
| +	[DSA_TAG_PROTO_MTK] = &mtk_netdev_ops, | ||||
| +#endif | ||||
|  	[DSA_TAG_PROTO_NONE] = &none_ops, | ||||
|  }; | ||||
|   | ||||
| --- a/net/dsa/dsa_priv.h | ||||
| +++ b/net/dsa/dsa_priv.h | ||||
| @@ -84,4 +84,7 @@ extern const struct dsa_device_ops brcm_ | ||||
|  /* tag_qca.c */ | ||||
|  extern const struct dsa_device_ops qca_netdev_ops; | ||||
|   | ||||
| +/* tag_mtk.c */ | ||||
| +extern const struct dsa_device_ops mtk_netdev_ops; | ||||
| + | ||||
|  #endif | ||||
| --- /dev/null | ||||
| +++ b/net/dsa/tag_mtk.c | ||||
| @@ -0,0 +1,117 @@ | ||||
| +/* | ||||
| + * Mediatek DSA Tag support | ||||
| + * Copyright (C) 2017 Landen Chao <landen.chao@mediatek.com> | ||||
| + *		      Sean Wang <sean.wang@mediatek.com> | ||||
| + * This program is free software; you can redistribute it and/or modify | ||||
| + * it under the terms of the GNU General Public License version 2 and | ||||
| + * only version 2 as published by the Free Software Foundation. | ||||
| + * | ||||
| + * This program is distributed in the hope that it will be useful, | ||||
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| + * GNU General Public License for more details. | ||||
| + */ | ||||
| + | ||||
| +#include <linux/etherdevice.h> | ||||
| +#include "dsa_priv.h" | ||||
| + | ||||
| +#define MTK_HDR_LEN		4 | ||||
| +#define MTK_HDR_RECV_SOURCE_PORT_MASK	GENMASK(2, 0) | ||||
| +#define MTK_HDR_XMIT_DP_BIT_MASK	GENMASK(5, 0) | ||||
| + | ||||
| +static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, | ||||
| +				    struct net_device *dev) | ||||
| +{ | ||||
| +	struct dsa_slave_priv *p = netdev_priv(dev); | ||||
| +	u8 *mtk_tag; | ||||
| + | ||||
| +	if (skb_cow_head(skb, MTK_HDR_LEN) < 0) | ||||
| +		goto out_free; | ||||
| + | ||||
| +	skb_push(skb, MTK_HDR_LEN); | ||||
| + | ||||
| +	memmove(skb->data, skb->data + MTK_HDR_LEN, 2 * ETH_ALEN); | ||||
| + | ||||
| +	/* Build the tag after the MAC Source Address */ | ||||
| +	mtk_tag = skb->data + 2 * ETH_ALEN; | ||||
| +	mtk_tag[0] = 0; | ||||
| +	mtk_tag[1] = (1 << p->dp->index) & MTK_HDR_XMIT_DP_BIT_MASK; | ||||
| +	mtk_tag[2] = 0; | ||||
| +	mtk_tag[3] = 0; | ||||
| + | ||||
| +	return skb; | ||||
| + | ||||
| +out_free: | ||||
| +	kfree_skb(skb); | ||||
| +	return NULL; | ||||
| +} | ||||
| + | ||||
| +static int mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev, | ||||
| +		       struct packet_type *pt, struct net_device *orig_dev) | ||||
| +{ | ||||
| +	struct dsa_switch_tree *dst = dev->dsa_ptr; | ||||
| +	struct dsa_switch *ds; | ||||
| +	int port; | ||||
| +	__be16 *phdr, hdr; | ||||
| + | ||||
| +	if (unlikely(!dst)) | ||||
| +		goto out_drop; | ||||
| + | ||||
| +	skb = skb_unshare(skb, GFP_ATOMIC); | ||||
| +	if (!skb) | ||||
| +		goto out; | ||||
| + | ||||
| +	if (unlikely(!pskb_may_pull(skb, MTK_HDR_LEN))) | ||||
| +		goto out_drop; | ||||
| + | ||||
| +	/* The MTK header is added by the switch between src addr | ||||
| +	 * and ethertype at this point, skb->data points to 2 bytes | ||||
| +	 * after src addr so header should be 2 bytes right before. | ||||
| +	 */ | ||||
| +	phdr = (__be16 *)(skb->data - 2); | ||||
| +	hdr = ntohs(*phdr); | ||||
| + | ||||
| +	/* Remove MTK tag and recalculate checksum. */ | ||||
| +	skb_pull_rcsum(skb, MTK_HDR_LEN); | ||||
| + | ||||
| +	memmove(skb->data - ETH_HLEN, | ||||
| +		skb->data - ETH_HLEN - MTK_HDR_LEN, | ||||
| +		2 * ETH_ALEN); | ||||
| + | ||||
| +	/* This protocol doesn't support cascading multiple | ||||
| +	 * switches so it's safe to assume the switch is first | ||||
| +	 * in the tree. | ||||
| +	 */ | ||||
| +	ds = dst->ds[0]; | ||||
| +	if (!ds) | ||||
| +		goto out_drop; | ||||
| + | ||||
| +	/* Get source port information */ | ||||
| +	port = (hdr & MTK_HDR_RECV_SOURCE_PORT_MASK); | ||||
| +	if (!ds->ports[port].netdev) | ||||
| +		goto out_drop; | ||||
| + | ||||
| +	/* Update skb & forward the frame accordingly */ | ||||
| +	skb_push(skb, ETH_HLEN); | ||||
| + | ||||
| +	skb->pkt_type = PACKET_HOST; | ||||
| +	skb->dev = ds->ports[port].netdev; | ||||
| +	skb->protocol = eth_type_trans(skb, skb->dev); | ||||
| + | ||||
| +	skb->dev->stats.rx_packets++; | ||||
| +	skb->dev->stats.rx_bytes += skb->len; | ||||
| + | ||||
| +	netif_receive_skb(skb); | ||||
| + | ||||
| +	return 0; | ||||
| + | ||||
| +out_drop: | ||||
| +	kfree_skb(skb); | ||||
| +out: | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +const struct dsa_device_ops mtk_netdev_ops = { | ||||
| +	.xmit	= mtk_tag_xmit, | ||||
| +	.rcv	= mtk_tag_rcv, | ||||
| +}; | ||||
| @@ -1,48 +0,0 @@ | ||||
| From de3c04b820e1d396bf12e88ea87271a84f6fedb7 Mon Sep 17 00:00:00 2001 | ||||
| From: Sean Wang <sean.wang@mediatek.com> | ||||
| Date: Wed, 29 Mar 2017 17:38:21 +0800 | ||||
| Subject: [PATCH 29/57] net-next: ethernet: mediatek: add CDM able to recognize | ||||
|  the tag for DSA | ||||
|  | ||||
| The patch adds the setup for allowing CDM can recognize these packets with | ||||
| carrying port-distinguishing tag. Otherwise, these tagging packets will be | ||||
| handled incorrectly by CDM. The setup is also working out for general | ||||
| untag packets as well. | ||||
|  | ||||
| Signed-off-by: Sean Wang <sean.wang@mediatek.com> | ||||
| Signed-off-by: Landen Chao <Landen.Chao@mediatek.com> | ||||
| Reviewed-by: Andrew Lunn <andrew@lunn.ch> | ||||
| Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> | ||||
| --- | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 ++++++ | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++++ | ||||
|  2 files changed, 10 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| @@ -1864,6 +1864,12 @@ static int mtk_hw_init(struct mtk_eth *e | ||||
|  	val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); | ||||
|  	mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); | ||||
|   | ||||
| +	/* Indicates CDM to parse the MTK special tag from CPU | ||||
| +	 * which also is working out for untag packets. | ||||
| +	 */ | ||||
| +	val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); | ||||
| +	mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); | ||||
| + | ||||
|  	/* Enable RX VLan Offloading */ | ||||
|  	mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); | ||||
|   | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||||
| @@ -74,6 +74,10 @@ | ||||
|  #define MTK_CDMQ_IG_CTRL	0x1400 | ||||
|  #define MTK_CDMQ_STAG_EN	BIT(0) | ||||
|   | ||||
| +/* CDMP Ingress Control Register */ | ||||
| +#define MTK_CDMQ_IG_CTRL	0x1400 | ||||
| +#define MTK_CDMQ_STAG_EN	BIT(0) | ||||
| + | ||||
|  /* CDMP Exgress Control Register */ | ||||
|  #define MTK_CDMP_EG_CTRL	0x404 | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,106 +0,0 @@ | ||||
| From a319687ac18dcc557a88054282508e061ad8495f Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Thu, 10 Aug 2017 14:42:19 +0200 | ||||
| Subject: [PATCH 31/57] net: dsa: dsa api compat | ||||
|  | ||||
| make the latest driver work on the old API | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/net/dsa/mt7530.c | 14 ++++++++------ | ||||
|  drivers/net/dsa/mt7530.h |  2 ++ | ||||
|  net/dsa/tag_mtk.c        |  2 +- | ||||
|  3 files changed, 11 insertions(+), 7 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/dsa/mt7530.c | ||||
| +++ b/drivers/net/dsa/mt7530.c | ||||
| @@ -834,6 +834,7 @@ mt7530_port_bridge_join(struct dsa_switc | ||||
|  	int i; | ||||
|   | ||||
|  	mutex_lock(&priv->reg_mutex); | ||||
| +	priv->bridge_dev[port] = bridge; | ||||
|   | ||||
|  	for (i = 0; i < MT7530_NUM_PORTS; i++) { | ||||
|  		/* Add this port to the port matrix of the other ports in the | ||||
| @@ -841,7 +842,7 @@ mt7530_port_bridge_join(struct dsa_switc | ||||
|  		 * and not being setup until the port becomes enabled. | ||||
|  		 */ | ||||
|  		if (ds->enabled_port_mask & BIT(i) && i != port) { | ||||
| -			if (ds->ports[i].bridge_dev != bridge) | ||||
| +			if (priv->bridge_dev[i] != bridge) | ||||
|  				continue; | ||||
|  			if (priv->ports[i].enable) | ||||
|  				mt7530_set(priv, MT7530_PCR_P(i), | ||||
| @@ -864,8 +865,7 @@ mt7530_port_bridge_join(struct dsa_switc | ||||
|  } | ||||
|   | ||||
|  static void | ||||
| -mt7530_port_bridge_leave(struct dsa_switch *ds, int port, | ||||
| -			 struct net_device *bridge) | ||||
| +mt7530_port_bridge_leave(struct dsa_switch *ds, int port) | ||||
|  { | ||||
|  	struct mt7530_priv *priv = ds->priv; | ||||
|  	int i; | ||||
| @@ -878,7 +878,7 @@ mt7530_port_bridge_leave(struct dsa_swit | ||||
|  		 * is kept and not being setup until the port becomes enabled. | ||||
|  		 */ | ||||
|  		if (ds->enabled_port_mask & BIT(i) && i != port) { | ||||
| -			if (ds->ports[i].bridge_dev != bridge) | ||||
| +			if (priv->bridge_dev[i] != priv->bridge_dev[port]) | ||||
|  				continue; | ||||
|  			if (priv->ports[i].enable) | ||||
|  				mt7530_clear(priv, MT7530_PCR_P(i), | ||||
| @@ -890,6 +890,7 @@ mt7530_port_bridge_leave(struct dsa_swit | ||||
|  	/* Set the cpu port to be the only one in the port matrix of | ||||
|  	 * this port. | ||||
|  	 */ | ||||
| +	priv->bridge_dev[port] = NULL; | ||||
|  	if (priv->ports[port].enable) | ||||
|  		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, | ||||
|  			   PCR_MATRIX(BIT(MT7530_CPU_PORT))); | ||||
| @@ -1033,7 +1034,7 @@ mt7530_probe(struct mdio_device *mdiodev | ||||
|  	if (!priv) | ||||
|  		return -ENOMEM; | ||||
|   | ||||
| -	priv->ds = dsa_switch_alloc(&mdiodev->dev, DSA_MAX_PORTS); | ||||
| +	priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL); | ||||
|  	if (!priv->ds) | ||||
|  		return -ENOMEM; | ||||
|   | ||||
| @@ -1076,12 +1077,13 @@ mt7530_probe(struct mdio_device *mdiodev | ||||
|  	priv->bus = mdiodev->bus; | ||||
|  	priv->dev = &mdiodev->dev; | ||||
|  	priv->ds->priv = priv; | ||||
| +	priv->ds->dev = &mdiodev->dev; | ||||
|  	priv->ds->ops = &mt7530_switch_ops; | ||||
|  	mutex_init(&priv->reg_mutex); | ||||
|  	lpriv = priv; | ||||
|  	dev_set_drvdata(&mdiodev->dev, priv); | ||||
|   | ||||
| -	return dsa_register_switch(priv->ds, &mdiodev->dev); | ||||
| +	return dsa_register_switch(priv->ds, priv->ds->dev->of_node); | ||||
|  } | ||||
|   | ||||
|  static void | ||||
| --- a/drivers/net/dsa/mt7530.h | ||||
| +++ b/drivers/net/dsa/mt7530.h | ||||
| @@ -379,6 +379,8 @@ struct mt7530_priv { | ||||
|  	struct mt7530_port	ports[MT7530_NUM_PORTS]; | ||||
|  	/* protect among processes for registers access*/ | ||||
|  	struct mutex reg_mutex; | ||||
| + | ||||
| +	struct net_device *bridge_dev[MT7530_NUM_PORTS]; | ||||
|  }; | ||||
|   | ||||
|  struct mt7530_hw_stats { | ||||
| --- a/net/dsa/tag_mtk.c | ||||
| +++ b/net/dsa/tag_mtk.c | ||||
| @@ -35,7 +35,7 @@ static struct sk_buff *mtk_tag_xmit(stru | ||||
|  	/* Build the tag after the MAC Source Address */ | ||||
|  	mtk_tag = skb->data + 2 * ETH_ALEN; | ||||
|  	mtk_tag[0] = 0; | ||||
| -	mtk_tag[1] = (1 << p->dp->index) & MTK_HDR_XMIT_DP_BIT_MASK; | ||||
| +	mtk_tag[1] = (1 << p->port) & MTK_HDR_XMIT_DP_BIT_MASK; | ||||
|  	mtk_tag[2] = 0; | ||||
|  	mtk_tag[3] = 0; | ||||
|   | ||||
| @@ -1,272 +0,0 @@ | ||||
| From cce5dd6034ed1651ee25c910edee708e6b84a44a Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Thu, 10 Aug 2017 14:45:08 +0200 | ||||
| Subject: [PATCH 33/57] net: dsa: add multi gmac support | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/net/dsa/mt7530.c | 10 +--------- | ||||
|  include/net/dsa.h        | 21 ++++++++++++++++++++- | ||||
|  net/dsa/dsa2.c           | 40 +++++++++++++++++++++++++++++++++------- | ||||
|  net/dsa/dsa_priv.h       |  1 + | ||||
|  net/dsa/slave.c          | 26 ++++++++++++++++---------- | ||||
|  5 files changed, 71 insertions(+), 27 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/dsa/mt7530.c | ||||
| +++ b/drivers/net/dsa/mt7530.c | ||||
| @@ -996,15 +996,7 @@ err: | ||||
|  static enum dsa_tag_protocol | ||||
|  mtk_get_tag_protocol(struct dsa_switch *ds) | ||||
|  { | ||||
| -	struct mt7530_priv *priv = ds->priv; | ||||
| - | ||||
| -	if (!dsa_is_cpu_port(ds, MT7530_CPU_PORT)) { | ||||
| -		dev_warn(priv->dev, | ||||
| -			 "port not matched with tagging CPU port\n"); | ||||
| -		return DSA_TAG_PROTO_NONE; | ||||
| -	} else { | ||||
| -		return DSA_TAG_PROTO_MTK; | ||||
| -	} | ||||
| +	return DSA_TAG_PROTO_MTK; | ||||
|  } | ||||
|   | ||||
|  static struct dsa_switch_ops mt7530_switch_ops = { | ||||
| --- a/include/net/dsa.h | ||||
| +++ b/include/net/dsa.h | ||||
| @@ -145,6 +145,8 @@ struct dsa_port { | ||||
|  	struct device_node	*dn; | ||||
|  	unsigned int		ageing_time; | ||||
|  	u8			stp_state; | ||||
| +	struct net_device	*ethernet; | ||||
| +	int			upstream; | ||||
|  }; | ||||
|   | ||||
|  struct dsa_switch { | ||||
| @@ -205,7 +207,7 @@ struct dsa_switch { | ||||
|   | ||||
|  static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p) | ||||
|  { | ||||
| -	return !!(ds->index == ds->dst->cpu_switch && p == ds->dst->cpu_port); | ||||
| +	return !!(ds->cpu_port_mask & (1 << p)); | ||||
|  } | ||||
|   | ||||
|  static inline bool dsa_is_dsa_port(struct dsa_switch *ds, int p) | ||||
| @@ -218,6 +220,11 @@ static inline bool dsa_is_port_initializ | ||||
|  	return ds->enabled_port_mask & (1 << p) && ds->ports[p].netdev; | ||||
|  } | ||||
|   | ||||
| +static inline bool dsa_is_upstream_port(struct dsa_switch *ds, int p) | ||||
| +{ | ||||
| +	return dsa_is_cpu_port(ds, p) || dsa_is_dsa_port(ds, p); | ||||
| +} | ||||
| + | ||||
|  static inline u8 dsa_upstream_port(struct dsa_switch *ds) | ||||
|  { | ||||
|  	struct dsa_switch_tree *dst = ds->dst; | ||||
| @@ -234,6 +241,18 @@ static inline u8 dsa_upstream_port(struc | ||||
|  		return ds->rtable[dst->cpu_switch]; | ||||
|  } | ||||
|   | ||||
| +static inline u8 dsa_port_upstream_port(struct dsa_switch *ds, int port) | ||||
| +{ | ||||
| +	/* | ||||
| +	 * If this port has a specific upstream cpu port, use it, | ||||
| +	 * otherwise use the switch default. | ||||
| +	 */ | ||||
| +	if (ds->ports[port].upstream) | ||||
| +		return ds->ports[port].upstream; | ||||
| +	else | ||||
| +		return dsa_upstream_port(ds); | ||||
| +} | ||||
| + | ||||
|  struct switchdev_trans; | ||||
|  struct switchdev_obj; | ||||
|  struct switchdev_obj_port_fdb; | ||||
| --- a/net/dsa/dsa2.c | ||||
| +++ b/net/dsa/dsa2.c | ||||
| @@ -248,8 +248,6 @@ static int dsa_cpu_port_apply(struct dev | ||||
|  		return err; | ||||
|  	} | ||||
|   | ||||
| -	ds->cpu_port_mask |= BIT(index); | ||||
| - | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| @@ -259,6 +257,10 @@ static void dsa_cpu_port_unapply(struct | ||||
|  	dsa_cpu_dsa_destroy(port); | ||||
|  	ds->cpu_port_mask &= ~BIT(index); | ||||
|   | ||||
| +	if (ds->ports[index].ethernet) { | ||||
| +		dev_put(ds->ports[index].ethernet); | ||||
| +		ds->ports[index].ethernet = NULL; | ||||
| +	} | ||||
|  } | ||||
|   | ||||
|  static int dsa_user_port_apply(struct device_node *port, u32 index, | ||||
| @@ -479,6 +481,29 @@ static int dsa_cpu_parse(struct device_n | ||||
|   | ||||
|  	dst->rcv = dst->tag_ops->rcv; | ||||
|   | ||||
| +	dev_hold(ethernet_dev); | ||||
| +	ds->ports[index].ethernet = ethernet_dev; | ||||
| +	ds->cpu_port_mask |= BIT(index); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static int dsa_user_parse(struct device_node *port, u32 index, | ||||
| +			  struct dsa_switch *ds) | ||||
| +{ | ||||
| +	struct device_node *cpu_port; | ||||
| +	const unsigned int *cpu_port_reg; | ||||
| +	int cpu_port_index; | ||||
| + | ||||
| +	cpu_port = of_parse_phandle(port, "cpu", 0); | ||||
| +	if (cpu_port) { | ||||
| +		cpu_port_reg = of_get_property(cpu_port, "reg", NULL); | ||||
| +		if (!cpu_port_reg) | ||||
| +			return -EINVAL; | ||||
| +		cpu_port_index = be32_to_cpup(cpu_port_reg); | ||||
| +		ds->ports[index].upstream = cpu_port_index; | ||||
| +	} | ||||
| + | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| @@ -486,18 +511,19 @@ static int dsa_ds_parse(struct dsa_switc | ||||
|  { | ||||
|  	struct device_node *port; | ||||
|  	u32 index; | ||||
| -	int err; | ||||
| +	int err = 0; | ||||
|   | ||||
|  	for (index = 0; index < DSA_MAX_PORTS; index++) { | ||||
|  		port = ds->ports[index].dn; | ||||
|  		if (!port) | ||||
|  			continue; | ||||
|   | ||||
| -		if (dsa_port_is_cpu(port)) { | ||||
| +		if (dsa_port_is_cpu(port)) | ||||
|  			err = dsa_cpu_parse(port, index, dst, ds); | ||||
| -			if (err) | ||||
| -				return err; | ||||
| -		} | ||||
| +		else if (!dsa_port_is_dsa(port)) | ||||
| +			err = dsa_user_parse(port, index,  ds); | ||||
| +		if (err) | ||||
| +			return err; | ||||
|  	} | ||||
|   | ||||
|  	pr_info("DSA: switch %d %d parsed\n", dst->tree, ds->index); | ||||
| --- a/net/dsa/dsa_priv.h | ||||
| +++ b/net/dsa/dsa_priv.h | ||||
| @@ -43,6 +43,7 @@ struct dsa_slave_priv { | ||||
|  	int			old_duplex; | ||||
|   | ||||
|  	struct net_device	*bridge_dev; | ||||
| +	struct net_device	*master; | ||||
|  #ifdef CONFIG_NET_POLL_CONTROLLER | ||||
|  	struct netpoll		*netpoll; | ||||
|  #endif | ||||
| --- a/net/dsa/slave.c | ||||
| +++ b/net/dsa/slave.c | ||||
| @@ -61,7 +61,7 @@ static int dsa_slave_get_iflink(const st | ||||
|  { | ||||
|  	struct dsa_slave_priv *p = netdev_priv(dev); | ||||
|   | ||||
| -	return p->parent->dst->master_netdev->ifindex; | ||||
| +	return p->master->ifindex; | ||||
|  } | ||||
|   | ||||
|  static inline bool dsa_port_is_bridged(struct dsa_slave_priv *p) | ||||
| @@ -96,7 +96,7 @@ static void dsa_port_set_stp_state(struc | ||||
|  static int dsa_slave_open(struct net_device *dev) | ||||
|  { | ||||
|  	struct dsa_slave_priv *p = netdev_priv(dev); | ||||
| -	struct net_device *master = p->parent->dst->master_netdev; | ||||
| +	struct net_device *master = p->master; | ||||
|  	struct dsa_switch *ds = p->parent; | ||||
|  	u8 stp_state = dsa_port_is_bridged(p) ? | ||||
|  			BR_STATE_BLOCKING : BR_STATE_FORWARDING; | ||||
| @@ -151,7 +151,7 @@ out: | ||||
|  static int dsa_slave_close(struct net_device *dev) | ||||
|  { | ||||
|  	struct dsa_slave_priv *p = netdev_priv(dev); | ||||
| -	struct net_device *master = p->parent->dst->master_netdev; | ||||
| +	struct net_device *master = p->master; | ||||
|  	struct dsa_switch *ds = p->parent; | ||||
|   | ||||
|  	if (p->phy) | ||||
| @@ -178,7 +178,7 @@ static int dsa_slave_close(struct net_de | ||||
|  static void dsa_slave_change_rx_flags(struct net_device *dev, int change) | ||||
|  { | ||||
|  	struct dsa_slave_priv *p = netdev_priv(dev); | ||||
| -	struct net_device *master = p->parent->dst->master_netdev; | ||||
| +	struct net_device *master = p->master; | ||||
|   | ||||
|  	if (change & IFF_ALLMULTI) | ||||
|  		dev_set_allmulti(master, dev->flags & IFF_ALLMULTI ? 1 : -1); | ||||
| @@ -189,7 +189,7 @@ static void dsa_slave_change_rx_flags(st | ||||
|  static void dsa_slave_set_rx_mode(struct net_device *dev) | ||||
|  { | ||||
|  	struct dsa_slave_priv *p = netdev_priv(dev); | ||||
| -	struct net_device *master = p->parent->dst->master_netdev; | ||||
| +	struct net_device *master = p->master; | ||||
|   | ||||
|  	dev_mc_sync(master, dev); | ||||
|  	dev_uc_sync(master, dev); | ||||
| @@ -198,7 +198,7 @@ static void dsa_slave_set_rx_mode(struct | ||||
|  static int dsa_slave_set_mac_address(struct net_device *dev, void *a) | ||||
|  { | ||||
|  	struct dsa_slave_priv *p = netdev_priv(dev); | ||||
| -	struct net_device *master = p->parent->dst->master_netdev; | ||||
| +	struct net_device *master = p->master; | ||||
|  	struct sockaddr *addr = a; | ||||
|  	int err; | ||||
|   | ||||
| @@ -633,7 +633,7 @@ static netdev_tx_t dsa_slave_xmit(struct | ||||
|  	/* Queue the SKB for transmission on the parent interface, but | ||||
|  	 * do not modify its EtherType | ||||
|  	 */ | ||||
| -	nskb->dev = p->parent->dst->master_netdev; | ||||
| +	nskb->dev = p->master; | ||||
|  	dev_queue_xmit(nskb); | ||||
|   | ||||
|  	return NETDEV_TX_OK; | ||||
| @@ -945,7 +945,7 @@ static int dsa_slave_netpoll_setup(struc | ||||
|  { | ||||
|  	struct dsa_slave_priv *p = netdev_priv(dev); | ||||
|  	struct dsa_switch *ds = p->parent; | ||||
| -	struct net_device *master = ds->dst->master_netdev; | ||||
| +	struct net_device *master = p->master; | ||||
|  	struct netpoll *netpoll; | ||||
|  	int err = 0; | ||||
|   | ||||
| @@ -1233,11 +1233,16 @@ int dsa_slave_create(struct dsa_switch * | ||||
|  	struct net_device *master; | ||||
|  	struct net_device *slave_dev; | ||||
|  	struct dsa_slave_priv *p; | ||||
| +	int port_cpu = ds->ports[port].upstream; | ||||
|  	int ret; | ||||
|   | ||||
| -	master = ds->dst->master_netdev; | ||||
| -	if (ds->master_netdev) | ||||
| +	if (port_cpu && ds->ports[port_cpu].ethernet) | ||||
| +		master = ds->ports[port_cpu].ethernet; | ||||
| +	else if (ds->master_netdev) | ||||
|  		master = ds->master_netdev; | ||||
| +	else | ||||
| +		master = ds->dst->master_netdev; | ||||
| +	master->dsa_ptr = (void *)ds->dst; | ||||
|   | ||||
|  	slave_dev = alloc_netdev(sizeof(struct dsa_slave_priv), name, | ||||
|  				 NET_NAME_UNKNOWN, ether_setup); | ||||
| @@ -1263,6 +1268,7 @@ int dsa_slave_create(struct dsa_switch * | ||||
|  	p->parent = ds; | ||||
|  	p->port = port; | ||||
|  	p->xmit = dst->tag_ops->xmit; | ||||
| +	p->master = master; | ||||
|   | ||||
|  	p->old_pause = -1; | ||||
|  	p->old_link = -1; | ||||
| @@ -1,91 +0,0 @@ | ||||
| From dcb751a52b2ee69c16db2fef8f92a96ab13b6bb4 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Thu, 10 Aug 2017 14:45:34 +0200 | ||||
| Subject: [PATCH 34/57] net: dsa: mediatek: add dual gmac support | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/net/dsa/mt7530.c | 22 ++++++++++++++++------ | ||||
|  1 file changed, 16 insertions(+), 6 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/dsa/mt7530.c | ||||
| +++ b/drivers/net/dsa/mt7530.c | ||||
| @@ -627,7 +627,7 @@ mt7530_setup(struct dsa_switch *ds) | ||||
|   | ||||
|  	/* Enable Port 6 only; P5 as GMAC5 which currently is not supported */ | ||||
|  	val = mt7530_read(priv, MT7530_MHWTRAP); | ||||
| -	val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS; | ||||
| +	val &= ~MHWTRAP_P5_DIS & ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS; | ||||
|  	val |= MHWTRAP_MANUAL; | ||||
|  	if (!dsa_is_cpu_port(ds, 5)) { | ||||
|  		val |= MHWTRAP_P5_DIS; | ||||
| @@ -735,6 +735,9 @@ static int | ||||
|  mt7530_cpu_port_enable(struct mt7530_priv *priv, | ||||
|  		       int port) | ||||
|  { | ||||
| +	u8 port_mask = 0; | ||||
| +	int i; | ||||
| + | ||||
|  	/* Enable Mediatek header mode on the cpu port */ | ||||
|  	mt7530_write(priv, MT7530_PVC_P(port), | ||||
|  		     PORT_SPEC_TAG); | ||||
| @@ -751,8 +754,12 @@ mt7530_cpu_port_enable(struct mt7530_pri | ||||
|  	/* CPU port gets connected to all user ports of | ||||
|  	 * the switch | ||||
|  	 */ | ||||
| +	for (i = 0; i < MT7530_NUM_PORTS; i++) | ||||
| +		if ((priv->ds->enabled_port_mask & BIT(i)) && | ||||
| +		    (dsa_port_upstream_port(priv->ds, i) == port)) | ||||
| +			port_mask |= BIT(i); | ||||
|  	mt7530_write(priv, MT7530_PCR_P(port), | ||||
| -		     PCR_MATRIX(priv->ds->enabled_port_mask)); | ||||
| +		     PCR_MATRIX(port_mask)); | ||||
|   | ||||
|  	return 0; | ||||
|  } | ||||
| @@ -762,6 +769,7 @@ mt7530_port_enable(struct dsa_switch *ds | ||||
|  		   struct phy_device *phy) | ||||
|  { | ||||
|  	struct mt7530_priv *priv = ds->priv; | ||||
| +	u8 upstream = dsa_port_upstream_port(ds, port); | ||||
|   | ||||
|  	mutex_lock(&priv->reg_mutex); | ||||
|   | ||||
| @@ -772,7 +780,7 @@ mt7530_port_enable(struct dsa_switch *ds | ||||
|  	 * restore the port matrix if the port is the member of a certain | ||||
|  	 * bridge. | ||||
|  	 */ | ||||
| -	priv->ports[port].pm |= PCR_MATRIX(BIT(MT7530_CPU_PORT)); | ||||
| +	priv->ports[port].pm |= PCR_MATRIX(BIT(upstream)); | ||||
|  	priv->ports[port].enable = true; | ||||
|  	mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, | ||||
|  		   priv->ports[port].pm); | ||||
| @@ -835,7 +843,8 @@ mt7530_port_bridge_join(struct dsa_switc | ||||
|  			struct net_device *bridge) | ||||
|  { | ||||
|  	struct mt7530_priv *priv = ds->priv; | ||||
| -	u32 port_bitmap = BIT(MT7530_CPU_PORT); | ||||
| +	u8 upstream = dsa_port_upstream_port(ds, port); | ||||
| +	u32 port_bitmap = BIT(upstream); | ||||
|  	int i; | ||||
|   | ||||
|  	mutex_lock(&priv->reg_mutex); | ||||
| @@ -873,6 +882,7 @@ static void | ||||
|  mt7530_port_bridge_leave(struct dsa_switch *ds, int port) | ||||
|  { | ||||
|  	struct mt7530_priv *priv = ds->priv; | ||||
| +	u8 upstream = dsa_port_upstream_port(ds, port); | ||||
|  	int i; | ||||
|   | ||||
|  	mutex_lock(&priv->reg_mutex); | ||||
| @@ -898,8 +908,8 @@ mt7530_port_bridge_leave(struct dsa_swit | ||||
|  	priv->bridge_dev[port] = NULL; | ||||
|  	if (priv->ports[port].enable) | ||||
|  		mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, | ||||
| -			   PCR_MATRIX(BIT(MT7530_CPU_PORT))); | ||||
| -	priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT)); | ||||
| +			   PCR_MATRIX(BIT(upstream))); | ||||
| +	priv->ports[port].pm = PCR_MATRIX(BIT(upstream)); | ||||
|   | ||||
|  	mutex_unlock(&priv->reg_mutex); | ||||
|  } | ||||
| @@ -1,25 +0,0 @@ | ||||
| From bf25fbdc7dfb256f267725336e29e232aadd5123 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Fri, 21 Jul 2017 08:43:58 +0200 | ||||
| Subject: [PATCH 36/57] net-next: mediatek: fix typos inside the header file | ||||
|  | ||||
| Trivial patch fixing 2 typos. | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++-- | ||||
|  1 file changed, 2 insertions(+), 2 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||||
| @@ -525,8 +525,8 @@ struct mtk_rx_ring { | ||||
|   * @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 | ||||
| + * @tx_ring:		Pointer to the memory holding info about the TX ring | ||||
| + * @rx_ring:		Pointer to the memory holding info about the RX ring | ||||
|   * @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 | ||||
| @@ -1,128 +0,0 @@ | ||||
| From 047a4e7b17322c1b32d8db32a0df9899cb4963a3 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Fri, 21 Jul 2017 08:48:38 +0200 | ||||
| Subject: [PATCH 37/57] net-next: mediatek: bring up QDMA RX ring 0 | ||||
|  | ||||
| This patch is in peparation for adding HW flow and QoS offloading. For | ||||
| those features to work, the driver needs to bring up the first QDMA RX | ||||
| ring. This ring is used by the PPE offloading HW. | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.c | 38 ++++++++++++++++++++--------- | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.h |  3 +++ | ||||
|  2 files changed, 30 insertions(+), 11 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| @@ -1224,11 +1224,21 @@ static void mtk_tx_clean(struct mtk_eth | ||||
|   | ||||
|  static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag) | ||||
|  { | ||||
| -	struct mtk_rx_ring *ring = ð->rx_ring[ring_no]; | ||||
| +	struct mtk_rx_ring *ring; | ||||
|  	int rx_data_len, rx_dma_size; | ||||
|  	int i; | ||||
| +	u32 offset = 0; | ||||
|   | ||||
| -	if (rx_flag == MTK_RX_FLAGS_HWLRO) { | ||||
| +	if (rx_flag & MTK_RX_FLAGS_QDMA) { | ||||
| +		if (ring_no) | ||||
| +			return -EINVAL; | ||||
| +		ring = ð->rx_ring_qdma; | ||||
| +		offset = 0x1000; | ||||
| +	} else { | ||||
| +		ring = ð->rx_ring[ring_no]; | ||||
| +	} | ||||
| + | ||||
| +	if (rx_flag & MTK_RX_FLAGS_HWLRO) { | ||||
|  		rx_data_len = MTK_MAX_LRO_RX_LENGTH; | ||||
|  		rx_dma_size = MTK_HW_LRO_DMA_SIZE; | ||||
|  	} else { | ||||
| @@ -1276,17 +1286,16 @@ static int mtk_rx_alloc(struct mtk_eth * | ||||
|  	 */ | ||||
|  	wmb(); | ||||
|   | ||||
| -	mtk_w32(eth, ring->phys, MTK_PRX_BASE_PTR_CFG(ring_no)); | ||||
| -	mtk_w32(eth, rx_dma_size, MTK_PRX_MAX_CNT_CFG(ring_no)); | ||||
| -	mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg); | ||||
| -	mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), MTK_PDMA_RST_IDX); | ||||
| +	mtk_w32(eth, ring->phys, MTK_PRX_BASE_PTR_CFG(ring_no) + offset); | ||||
| +	mtk_w32(eth, rx_dma_size, MTK_PRX_MAX_CNT_CFG(ring_no) + offset); | ||||
| +	mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg + offset); | ||||
| +	mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), MTK_PDMA_RST_IDX + offset); | ||||
|   | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| -static void mtk_rx_clean(struct mtk_eth *eth, int ring_no) | ||||
| +static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring) | ||||
|  { | ||||
| -	struct mtk_rx_ring *ring = ð->rx_ring[ring_no]; | ||||
|  	int i; | ||||
|   | ||||
|  	if (ring->data && ring->dma) { | ||||
| @@ -1612,6 +1621,10 @@ static int mtk_dma_init(struct mtk_eth * | ||||
|  	if (err) | ||||
|  		return err; | ||||
|   | ||||
| +	err = mtk_rx_alloc(eth, 0, MTK_RX_FLAGS_QDMA); | ||||
| +	if (err) | ||||
| +		return err; | ||||
| + | ||||
|  	err = mtk_rx_alloc(eth, 0, MTK_RX_FLAGS_NORMAL); | ||||
|  	if (err) | ||||
|  		return err; | ||||
| @@ -1651,12 +1664,13 @@ static void mtk_dma_free(struct mtk_eth | ||||
|  		eth->phy_scratch_ring = 0; | ||||
|  	} | ||||
|  	mtk_tx_clean(eth); | ||||
| -	mtk_rx_clean(eth, 0); | ||||
| +	mtk_rx_clean(eth, ð->rx_ring[0]); | ||||
| +	mtk_rx_clean(eth, ð->rx_ring_qdma); | ||||
|   | ||||
|  	if (eth->hwlro) { | ||||
|  		mtk_hwlro_rx_uninit(eth); | ||||
|  		for (i = 1; i < MTK_MAX_RX_RING_NUM; i++) | ||||
| -			mtk_rx_clean(eth, i); | ||||
| +			mtk_rx_clean(eth, ð->rx_ring[i]); | ||||
|  	} | ||||
|   | ||||
|  	kfree(eth->scratch_head); | ||||
| @@ -1723,7 +1737,9 @@ static int mtk_start_dma(struct mtk_eth | ||||
|   | ||||
|  	mtk_w32(eth, | ||||
|  		MTK_TX_WB_DDONE | MTK_TX_DMA_EN | | ||||
| -		MTK_DMA_SIZE_16DWORDS | MTK_NDP_CO_PRO, | ||||
| +		MTK_DMA_SIZE_16DWORDS | MTK_NDP_CO_PRO | | ||||
| +		MTK_RX_DMA_EN | MTK_RX_2B_OFFSET | | ||||
| +		MTK_RX_BT_32DWORDS, | ||||
|  		MTK_QDMA_GLO_CFG); | ||||
|   | ||||
|  	mtk_w32(eth, | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||||
| @@ -484,6 +484,7 @@ struct mtk_tx_ring { | ||||
|  enum mtk_rx_flags { | ||||
|  	MTK_RX_FLAGS_NORMAL = 0, | ||||
|  	MTK_RX_FLAGS_HWLRO, | ||||
| +	MTK_RX_FLAGS_QDMA, | ||||
|  }; | ||||
|   | ||||
|  /* struct mtk_rx_ring -	This struct holds info describing a RX ring | ||||
| @@ -527,6 +528,7 @@ struct mtk_rx_ring { | ||||
|   * @dma_refcnt:		track how many netdevs are using the DMA engine | ||||
|   * @tx_ring:		Pointer to the memory holding info about the TX ring | ||||
|   * @rx_ring:		Pointer to the memory holding info about the RX ring | ||||
| + * @rx_ring_qdma:	Pointer to the memory holding info about the QDMA RX ring | ||||
|   * @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 | ||||
| @@ -556,6 +558,7 @@ struct mtk_eth { | ||||
|  	atomic_t			dma_refcnt; | ||||
|  	struct mtk_tx_ring		tx_ring; | ||||
|  	struct mtk_rx_ring		rx_ring[MTK_MAX_RX_RING_NUM]; | ||||
| +	struct mtk_rx_ring		rx_ring_qdma; | ||||
|  	struct napi_struct		tx_napi; | ||||
|  	struct napi_struct		rx_napi; | ||||
|  	struct mtk_tx_dma		*scratch_ring; | ||||
| @@ -1,46 +0,0 @@ | ||||
| From b58bf0220f666705e63fe8d361f37c913aee2d8f Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Fri, 21 Jul 2017 09:32:54 +0200 | ||||
| Subject: [PATCH 38/57] net-next: dsa: move struct dsa_device_ops to the global | ||||
|  header file | ||||
|  | ||||
| We need to access this struct from within the flow_dissector to fix | ||||
| dissection for packets coming in on DSA devices. | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  include/net/dsa.h  | 7 +++++++ | ||||
|  net/dsa/dsa_priv.h | 6 ------ | ||||
|  2 files changed, 7 insertions(+), 6 deletions(-) | ||||
|  | ||||
| --- a/include/net/dsa.h | ||||
| +++ b/include/net/dsa.h | ||||
| @@ -88,6 +88,13 @@ struct dsa_platform_data { | ||||
|   | ||||
|  struct packet_type; | ||||
|   | ||||
| +struct dsa_device_ops { | ||||
| +	struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev); | ||||
| +	int sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev, | ||||
| +			       struct packet_type *pt, | ||||
| +			       struct net_device *orig_dev); | ||||
| +}; | ||||
| + | ||||
|  struct dsa_switch_tree { | ||||
|  	struct list_head	list; | ||||
|   | ||||
| --- a/net/dsa/dsa_priv.h | ||||
| +++ b/net/dsa/dsa_priv.h | ||||
| @@ -15,12 +15,6 @@ | ||||
|  #include <linux/netdevice.h> | ||||
|  #include <linux/netpoll.h> | ||||
|   | ||||
| -struct dsa_device_ops { | ||||
| -	struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev); | ||||
| -	int (*rcv)(struct sk_buff *skb, struct net_device *dev, | ||||
| -		   struct packet_type *pt, struct net_device *orig_dev); | ||||
| -}; | ||||
| - | ||||
|  struct dsa_slave_priv { | ||||
|  	struct sk_buff *	(*xmit)(struct sk_buff *skb, | ||||
|  					struct net_device *dev); | ||||
| @@ -1,32 +0,0 @@ | ||||
| From 22e8b65ea4bf8a1fa757137bdcbdefe505fa4044 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Mon, 7 Aug 2017 16:35:43 +0200 | ||||
| Subject: [PATCH 39/57] net-next: dsa: add flow_dissect callback to struct | ||||
|  dsa_device_ops | ||||
|  | ||||
| When the flow dissector first sees packets coming in on a DSA devices the | ||||
| 802.3 header wont be located where the code expects it to be as the tag | ||||
| is still present. Adding this new callback allows a DSA device to provide a | ||||
| new function that the flow_disscetor can use to get the correct offsets | ||||
| for the protocol field and network header offset. | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  include/net/dsa.h | 4 +++- | ||||
|  1 file changed, 3 insertions(+), 1 deletion(-) | ||||
|  | ||||
| --- a/include/net/dsa.h | ||||
| +++ b/include/net/dsa.h | ||||
| @@ -90,9 +90,11 @@ struct packet_type; | ||||
|   | ||||
|  struct dsa_device_ops { | ||||
|  	struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev); | ||||
| -	int sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev, | ||||
| +	int (*rcv)(struct sk_buff *skb, struct net_device *dev, | ||||
|  			       struct packet_type *pt, | ||||
|  			       struct net_device *orig_dev); | ||||
| +	int (*flow_dissect)(const struct sk_buff *skb, __be16 *proto, | ||||
| +			    int *offset); | ||||
|  }; | ||||
|   | ||||
|  struct dsa_switch_tree { | ||||
| @@ -1,39 +0,0 @@ | ||||
| From 9d6806e16e5ea68a49225da1ab065ef0b5d7704b Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Mon, 7 Aug 2017 16:55:56 +0200 | ||||
| Subject: [PATCH 40/57] net-next: tag_mtk: add flow_dissect callback to the ops | ||||
|  struct | ||||
|  | ||||
| The MT7530 inserts the 4 magic header in between the 802.3 address and | ||||
| protocol field. The patch implements the callback that can be called by | ||||
| the flow dissector to figure out the real protocol and offset of the | ||||
| network header. With this patch applied we can properly parse the packet | ||||
| and thus make hashing function properly. | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  net/dsa/tag_mtk.c | 14 ++++++++++++-- | ||||
|  1 file changed, 12 insertions(+), 2 deletions(-) | ||||
|  | ||||
| --- a/net/dsa/tag_mtk.c | ||||
| +++ b/net/dsa/tag_mtk.c | ||||
| @@ -111,7 +111,17 @@ out: | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| +static int mtk_tag_flow_dissect(const struct sk_buff *skb, __be16 *proto, | ||||
| +				int *offset) | ||||
| +{ | ||||
| +	*offset = 4; | ||||
| +	*proto = ((__be16 *)skb->data)[1]; | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
|  const struct dsa_device_ops mtk_netdev_ops = { | ||||
| -	.xmit	= mtk_tag_xmit, | ||||
| -	.rcv	= mtk_tag_rcv, | ||||
| +	.xmit		= mtk_tag_xmit, | ||||
| +	.rcv		= mtk_tag_rcv, | ||||
| +	.flow_dissect	= mtk_tag_flow_dissect, | ||||
|  }; | ||||
| @@ -1,65 +0,0 @@ | ||||
| From 04c825484d6ecdcc8ce09b350235c9077eaca6e3 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Wed, 9 Aug 2017 08:20:21 +0200 | ||||
| Subject: [PATCH 41/57] net-next: dsa: fix flow dissection | ||||
|  | ||||
| RPS and probably other kernel features are currently broken on some if not | ||||
| all DSA devices. The root cause of this is that skb_hash will call the | ||||
| flow_dissector. At this point the skb still contains the magic switch | ||||
| header and the skb->protocol field is not set up to the correct 802.3 | ||||
| value yet. By the time the tag specific code is called, removing the header | ||||
| and =roperly setting the protocol an invalid hash is already set. In the | ||||
| case of the mt7530 this will result in all flows always having the same | ||||
| hash. | ||||
|  | ||||
| This patch makes the flow dissector honour the nh and protocol offset | ||||
| defined by the dsa tag driver thus fixing dissection, hashing and RPS. | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  net/core/flow_dissector.c | 14 +++++++++++++- | ||||
|  1 file changed, 13 insertions(+), 1 deletion(-) | ||||
|  | ||||
| --- a/net/core/flow_dissector.c | ||||
| +++ b/net/core/flow_dissector.c | ||||
| @@ -4,6 +4,7 @@ | ||||
|  #include <linux/ip.h> | ||||
|  #include <linux/ipv6.h> | ||||
|  #include <linux/if_vlan.h> | ||||
| +#include <net/dsa.h> | ||||
|  #include <net/ip.h> | ||||
|  #include <net/ipv6.h> | ||||
|  #include <net/gre.h> | ||||
| @@ -123,13 +124,23 @@ bool __skb_flow_dissect(const struct sk_ | ||||
|  	bool skip_vlan = false; | ||||
|  	u8 ip_proto = 0; | ||||
|  	bool ret; | ||||
| - | ||||
|  	if (!data) { | ||||
|  		data = skb->data; | ||||
|  		proto = skb_vlan_tag_present(skb) ? | ||||
|  			 skb->vlan_proto : skb->protocol; | ||||
|  		nhoff = skb_network_offset(skb); | ||||
|  		hlen = skb_headlen(skb); | ||||
| +		if (unlikely(netdev_uses_dsa(skb->dev))) { | ||||
| +			const struct dsa_device_ops *ops; | ||||
| +			int offset; | ||||
| + | ||||
| +			ops = skb->dev->dsa_ptr->tag_ops; | ||||
| +			if (ops->flow_dissect && | ||||
| +			    !ops->flow_dissect(skb, &proto, &offset)) { | ||||
| +				hlen -= offset; | ||||
| +				nhoff += offset; | ||||
| +			} | ||||
| +		} | ||||
|  	} | ||||
|   | ||||
|  	/* It is ensured by skb_flow_dissector_init() that control key will | ||||
| @@ -162,6 +173,7 @@ again: | ||||
|  	case htons(ETH_P_IP): { | ||||
|  		const struct iphdr *iph; | ||||
|  		struct iphdr _iph; | ||||
| + | ||||
|  ip: | ||||
|  		iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph); | ||||
|  		if (!iph || iph->ihl < 5) | ||||
| @@ -1,56 +0,0 @@ | ||||
| From 6e081074df96bf3762c2e6438c383f11a56b0a7e Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Thu, 10 Aug 2017 15:58:04 +0200 | ||||
| Subject: [PATCH 46/57] net: mediatek: add irq delay | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 ++++++- | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++++- | ||||
|  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 | ||||
| @@ -1904,8 +1904,13 @@ static int mtk_hw_init(struct mtk_eth *e | ||||
|  		mtk_w32(eth, 0, MTK_CDMP_EG_CTRL); | ||||
|   | ||||
|  	/* disable delay and normal interrupt */ | ||||
| -	mtk_w32(eth, 0, MTK_QDMA_DELAY_INT); | ||||
| +#ifdef MTK_IRQ_DLY | ||||
| +	mtk_w32(eth, 0x84048404, MTK_PDMA_DELAY_INT); | ||||
| +	mtk_w32(eth, 0x84048404, MTK_QDMA_DELAY_INT); | ||||
| +#else | ||||
|  	mtk_w32(eth, 0, MTK_PDMA_DELAY_INT); | ||||
| +	mtk_w32(eth, 0, MTK_QDMA_DELAY_INT); | ||||
| +#endif | ||||
|  	mtk_irq_disable(eth, MTK_QDMA_INT_MASK, ~0); | ||||
|  	mtk_irq_disable(eth, MTK_PDMA_INT_MASK, ~0); | ||||
|  	mtk_w32(eth, RST_GL_PSE, MTK_RST_GL); | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||||
| @@ -12,6 +12,8 @@ | ||||
|   *   Copyright (C) 2013-2016 Michael Lee <igvtee@gmail.com> | ||||
|   */ | ||||
|   | ||||
| +#define MTK_IRQ_DLY | ||||
| + | ||||
|  #ifndef MTK_ETH_H | ||||
|  #define MTK_ETH_H | ||||
|   | ||||
| @@ -220,11 +222,15 @@ | ||||
|  #define MTK_TX_DONE_INT2	BIT(2) | ||||
|  #define MTK_TX_DONE_INT1	BIT(1) | ||||
|  #define MTK_TX_DONE_INT0	BIT(0) | ||||
| +#ifdef MTK_IRQ_DLY | ||||
| +#define MTK_RX_DONE_INT		BIT(30) | ||||
| +#define MTK_TX_DONE_INT		BIT(28) | ||||
| +#else | ||||
|  #define MTK_RX_DONE_INT		(MTK_RX_DONE_INT0 | MTK_RX_DONE_INT1 | \ | ||||
|  				 MTK_RX_DONE_INT2 | MTK_RX_DONE_INT3) | ||||
|  #define MTK_TX_DONE_INT		(MTK_TX_DONE_INT0 | MTK_TX_DONE_INT1 | \ | ||||
|  				 MTK_TX_DONE_INT2 | MTK_TX_DONE_INT3) | ||||
| - | ||||
| +#endif | ||||
|  /* QDMA Interrupt grouping registers */ | ||||
|  #define MTK_QDMA_INT_GRP1	0x1a20 | ||||
|  #define MTK_QDMA_INT_GRP2	0x1a24 | ||||
| @@ -1,208 +0,0 @@ | ||||
| From 5afceece38fa30e3c71e7ed9ac62aa70ba8cfbb1 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Fri, 16 Jun 2017 10:00:30 +0200 | ||||
| Subject: [PATCH 47/57] net-next: mediatek: split IRQ register locking into TX | ||||
|  and RX | ||||
|  | ||||
| Originally the driver only utilized the new QDMA engine. The current code | ||||
| still assumes this is the case when locking the IRQ mask register. Since | ||||
| RX now runs on the old style PDMA engine we can add a second lock. This | ||||
| patch reduces the IRQ latency as the TX and RX path no longer need to wait | ||||
| on each other under heavy load. | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.c | 79 ++++++++++++++++++----------- | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.h |  5 +- | ||||
|  2 files changed, 54 insertions(+), 30 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| @@ -372,28 +372,48 @@ static void mtk_mdio_cleanup(struct mtk_ | ||||
|  	mdiobus_unregister(eth->mii_bus); | ||||
|  } | ||||
|   | ||||
| -static inline void mtk_irq_disable(struct mtk_eth *eth, | ||||
| -				   unsigned reg, u32 mask) | ||||
| +static inline void mtk_tx_irq_disable(struct mtk_eth *eth, u32 mask) | ||||
|  { | ||||
|  	unsigned long flags; | ||||
|  	u32 val; | ||||
|   | ||||
| -	spin_lock_irqsave(ð->irq_lock, flags); | ||||
| -	val = mtk_r32(eth, reg); | ||||
| -	mtk_w32(eth, val & ~mask, reg); | ||||
| -	spin_unlock_irqrestore(ð->irq_lock, flags); | ||||
| +	spin_lock_irqsave(ð->tx_irq_lock, flags); | ||||
| +	val = mtk_r32(eth, MTK_QDMA_INT_MASK); | ||||
| +	mtk_w32(eth, val & ~mask, MTK_QDMA_INT_MASK); | ||||
| +	spin_unlock_irqrestore(ð->tx_irq_lock, flags); | ||||
|  } | ||||
|   | ||||
| -static inline void mtk_irq_enable(struct mtk_eth *eth, | ||||
| -				  unsigned reg, u32 mask) | ||||
| +static inline void mtk_tx_irq_enable(struct mtk_eth *eth, u32 mask) | ||||
|  { | ||||
|  	unsigned long flags; | ||||
|  	u32 val; | ||||
|   | ||||
| -	spin_lock_irqsave(ð->irq_lock, flags); | ||||
| -	val = mtk_r32(eth, reg); | ||||
| -	mtk_w32(eth, val | mask, reg); | ||||
| -	spin_unlock_irqrestore(ð->irq_lock, flags); | ||||
| +	spin_lock_irqsave(ð->tx_irq_lock, flags); | ||||
| +	val = mtk_r32(eth, MTK_QDMA_INT_MASK); | ||||
| +	mtk_w32(eth, val | mask, MTK_QDMA_INT_MASK); | ||||
| +	spin_unlock_irqrestore(ð->tx_irq_lock, flags); | ||||
| +} | ||||
| + | ||||
| +static inline void mtk_rx_irq_disable(struct mtk_eth *eth, u32 mask) | ||||
| +{ | ||||
| +	unsigned long flags; | ||||
| +	u32 val; | ||||
| + | ||||
| +	spin_lock_irqsave(ð->rx_irq_lock, flags); | ||||
| +	val = mtk_r32(eth, MTK_PDMA_INT_MASK); | ||||
| +	mtk_w32(eth, val & ~mask, MTK_PDMA_INT_MASK); | ||||
| +	spin_unlock_irqrestore(ð->rx_irq_lock, flags); | ||||
| +} | ||||
| + | ||||
| +static inline void mtk_rx_irq_enable(struct mtk_eth *eth, u32 mask) | ||||
| +{ | ||||
| +	unsigned long flags; | ||||
| +	u32 val; | ||||
| + | ||||
| +	spin_lock_irqsave(ð->rx_irq_lock, flags); | ||||
| +	val = mtk_r32(eth, MTK_PDMA_INT_MASK); | ||||
| +	mtk_w32(eth, val | mask, MTK_PDMA_INT_MASK); | ||||
| +	spin_unlock_irqrestore(ð->rx_irq_lock, flags); | ||||
|  } | ||||
|   | ||||
|  static int mtk_set_mac_address(struct net_device *dev, void *p) | ||||
| @@ -1116,7 +1136,7 @@ static int mtk_napi_tx(struct napi_struc | ||||
|  		return budget; | ||||
|   | ||||
|  	napi_complete(napi); | ||||
| -	mtk_irq_enable(eth, MTK_QDMA_INT_MASK, MTK_TX_DONE_INT); | ||||
| +	mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); | ||||
|   | ||||
|  	return tx_done; | ||||
|  } | ||||
| @@ -1150,7 +1170,7 @@ poll_again: | ||||
|  		goto poll_again; | ||||
|  	} | ||||
|  	napi_complete(napi); | ||||
| -	mtk_irq_enable(eth, MTK_PDMA_INT_MASK, MTK_RX_DONE_INT); | ||||
| +	mtk_rx_irq_enable(eth, MTK_RX_DONE_INT); | ||||
|   | ||||
|  	return rx_done + budget - remain_budget; | ||||
|  } | ||||
| @@ -1699,7 +1719,7 @@ static irqreturn_t mtk_handle_irq_rx(int | ||||
|   | ||||
|  	if (likely(napi_schedule_prep(ð->rx_napi))) { | ||||
|  		__napi_schedule(ð->rx_napi); | ||||
| -		mtk_irq_disable(eth, MTK_PDMA_INT_MASK, MTK_RX_DONE_INT); | ||||
| +		mtk_rx_irq_disable(eth, MTK_RX_DONE_INT); | ||||
|  	} | ||||
|   | ||||
|  	return IRQ_HANDLED; | ||||
| @@ -1711,7 +1731,7 @@ static irqreturn_t mtk_handle_irq_tx(int | ||||
|   | ||||
|  	if (likely(napi_schedule_prep(ð->tx_napi))) { | ||||
|  		__napi_schedule(ð->tx_napi); | ||||
| -		mtk_irq_disable(eth, MTK_QDMA_INT_MASK, MTK_TX_DONE_INT); | ||||
| +		mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); | ||||
|  	} | ||||
|   | ||||
|  	return IRQ_HANDLED; | ||||
| @@ -1723,11 +1743,11 @@ static void mtk_poll_controller(struct n | ||||
|  	struct mtk_mac *mac = netdev_priv(dev); | ||||
|  	struct mtk_eth *eth = mac->hw; | ||||
|   | ||||
| -	mtk_irq_disable(eth, MTK_QDMA_INT_MASK, MTK_TX_DONE_INT); | ||||
| -	mtk_irq_disable(eth, MTK_PDMA_INT_MASK, MTK_RX_DONE_INT); | ||||
| +	mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); | ||||
| +	mtk_rx_irq_disable(eth, MTK_RX_DONE_INT); | ||||
|  	mtk_handle_irq_rx(eth->irq[2], dev); | ||||
| -	mtk_irq_enable(eth, MTK_QDMA_INT_MASK, MTK_TX_DONE_INT); | ||||
| -	mtk_irq_enable(eth, MTK_PDMA_INT_MASK, MTK_RX_DONE_INT); | ||||
| +	mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); | ||||
| +	mtk_rx_irq_enable(eth, MTK_RX_DONE_INT); | ||||
|  } | ||||
|  #endif | ||||
|   | ||||
| @@ -1770,8 +1790,8 @@ static int mtk_open(struct net_device *d | ||||
|   | ||||
|  		napi_enable(ð->tx_napi); | ||||
|  		napi_enable(ð->rx_napi); | ||||
| -		mtk_irq_enable(eth, MTK_QDMA_INT_MASK, MTK_TX_DONE_INT); | ||||
| -		mtk_irq_enable(eth, MTK_PDMA_INT_MASK, MTK_RX_DONE_INT); | ||||
| +		mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); | ||||
| +		mtk_rx_irq_enable(eth, MTK_RX_DONE_INT); | ||||
|  	} | ||||
|  	atomic_inc(ð->dma_refcnt); | ||||
|   | ||||
| @@ -1816,8 +1836,8 @@ static int mtk_stop(struct net_device *d | ||||
|  	if (!atomic_dec_and_test(ð->dma_refcnt)) | ||||
|  		return 0; | ||||
|   | ||||
| -	mtk_irq_disable(eth, MTK_QDMA_INT_MASK, MTK_TX_DONE_INT); | ||||
| -	mtk_irq_disable(eth, MTK_PDMA_INT_MASK, MTK_RX_DONE_INT); | ||||
| +	mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); | ||||
| +	mtk_rx_irq_disable(eth, MTK_RX_DONE_INT); | ||||
|  	napi_disable(ð->tx_napi); | ||||
|  	napi_disable(ð->rx_napi); | ||||
|   | ||||
| @@ -1911,8 +1931,8 @@ static int mtk_hw_init(struct mtk_eth *e | ||||
|  	mtk_w32(eth, 0, MTK_PDMA_DELAY_INT); | ||||
|  	mtk_w32(eth, 0, MTK_QDMA_DELAY_INT); | ||||
|  #endif | ||||
| -	mtk_irq_disable(eth, MTK_QDMA_INT_MASK, ~0); | ||||
| -	mtk_irq_disable(eth, MTK_PDMA_INT_MASK, ~0); | ||||
| +	mtk_tx_irq_disable(eth, ~0); | ||||
| +	mtk_rx_irq_disable(eth, ~0); | ||||
|  	mtk_w32(eth, RST_GL_PSE, MTK_RST_GL); | ||||
|  	mtk_w32(eth, 0, MTK_RST_GL); | ||||
|   | ||||
| @@ -1983,8 +2003,8 @@ static void mtk_uninit(struct net_device | ||||
|  	phy_disconnect(dev->phydev); | ||||
|  	if (of_phy_is_fixed_link(mac->of_node)) | ||||
|  		of_phy_deregister_fixed_link(mac->of_node); | ||||
| -	mtk_irq_disable(eth, MTK_QDMA_INT_MASK, ~0); | ||||
| -	mtk_irq_disable(eth, MTK_PDMA_INT_MASK, ~0); | ||||
| +	mtk_tx_irq_disable(eth, ~0); | ||||
| +	mtk_rx_irq_disable(eth, ~0); | ||||
|  } | ||||
|   | ||||
|  static int mtk_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | ||||
| @@ -2442,7 +2462,8 @@ static int mtk_probe(struct platform_dev | ||||
|  		return PTR_ERR(eth->base); | ||||
|   | ||||
|  	spin_lock_init(ð->page_lock); | ||||
| -	spin_lock_init(ð->irq_lock); | ||||
| +	spin_lock_init(ð->tx_irq_lock); | ||||
| +	spin_lock_init(ð->rx_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 | ||||
| @@ -526,6 +526,8 @@ struct mtk_rx_ring { | ||||
|   * @dev:		The device pointer | ||||
|   * @base:		The mapped register i/o base | ||||
|   * @page_lock:		Make sure that register operations are atomic | ||||
| + * @tx_irq__lock:	Make sure that IRQ register operations are atomic | ||||
| + * @rx_irq__lock:	Make sure that IRQ 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 | ||||
| @@ -555,7 +557,8 @@ struct mtk_eth { | ||||
|  	struct device			*dev; | ||||
|  	void __iomem			*base; | ||||
|  	spinlock_t			page_lock; | ||||
| -	spinlock_t			irq_lock; | ||||
| +	spinlock_t			tx_irq_lock; | ||||
| +	spinlock_t			rx_irq_lock; | ||||
|  	struct net_device		dummy_dev; | ||||
|  	struct net_device		*netdev[MTK_MAX_DEVS]; | ||||
|  	struct mtk_mac			*mac[MTK_MAX_DEVS]; | ||||
| @@ -1,20 +0,0 @@ | ||||
| From 066b30a76a0d13cbd2c0d463f9a1e87efc352679 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Thu, 10 Aug 2017 15:58:46 +0200 | ||||
| Subject: [PATCH 49/57] net: mediatek: add rx queue | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 + | ||||
|  1 file changed, 1 insertion(+) | ||||
|  | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| @@ -1009,6 +1009,7 @@ static int mtk_poll_rx(struct napi_struc | ||||
|  		    RX_DMA_VID(trxd.rxd3)) | ||||
|  			__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), | ||||
|  					       RX_DMA_VID(trxd.rxd3)); | ||||
| +		skb_record_rx_queue(skb, 0); | ||||
|  		napi_gro_receive(napi, skb); | ||||
|   | ||||
|  		ring->data[idx] = new_data; | ||||
| @@ -1,21 +0,0 @@ | ||||
| From 67c4af99af02d86b627a8cde2e99cc4c9699d2ce Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Thu, 10 Aug 2017 15:59:08 +0200 | ||||
| Subject: [PATCH 50/57] net: mediatek: add trgmii clock | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 ++ | ||||
|  1 file changed, 2 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| @@ -1873,6 +1873,8 @@ static int mtk_hw_init(struct mtk_eth *e | ||||
|  	pm_runtime_enable(eth->dev); | ||||
|  	pm_runtime_get_sync(eth->dev); | ||||
|   | ||||
| +	clk_set_rate(eth->clks[MTK_CLK_TRGPLL], 250000000); | ||||
| + | ||||
|  	clk_prepare_enable(eth->clks[MTK_CLK_ETHIF]); | ||||
|  	clk_prepare_enable(eth->clks[MTK_CLK_ESW]); | ||||
|  	clk_prepare_enable(eth->clks[MTK_CLK_GP1]); | ||||
| @@ -1,68 +0,0 @@ | ||||
| From 53eec2c3580e63fdebfc25ae324f30cd8aa4403b Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Thu, 10 Aug 2017 16:00:46 +0200 | ||||
| Subject: [PATCH 53/57] net: dsa: mediatek: add software phy polling | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/net/dsa/mt7530.c | 38 ++++++++++++++++++++++++++++++++++++++ | ||||
|  drivers/net/dsa/mt7530.h |  1 + | ||||
|  2 files changed, 39 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/dsa/mt7530.c | ||||
| +++ b/drivers/net/dsa/mt7530.c | ||||
| @@ -728,6 +728,44 @@ static void mt7530_adjust_link(struct ds | ||||
|  		 * all finished. | ||||
|  		 */ | ||||
|  		mt7623_pad_clk_setup(ds); | ||||
| +	} else { | ||||
| +		u16 lcl_adv = 0, rmt_adv = 0; | ||||
| +		u8 flowctrl; | ||||
| +		u32 mcr = PMCR_USERP_LINK | PMCR_FORCE_MODE; | ||||
| + | ||||
| +		switch (phydev->speed) { | ||||
| +		case SPEED_1000: | ||||
| +			mcr |= PMCR_FORCE_SPEED_1000; | ||||
| +			break; | ||||
| +		case SPEED_100: | ||||
| +			mcr |= PMCR_FORCE_SPEED_100; | ||||
| +			break; | ||||
| +		}; | ||||
| + | ||||
| +		if (phydev->link) | ||||
| +			mcr |= PMCR_FORCE_LNK; | ||||
| + | ||||
| +		if (phydev->duplex) { | ||||
| +			mcr |= PMCR_FORCE_FDX; | ||||
| + | ||||
| +			if (phydev->pause) | ||||
| +				rmt_adv = LPA_PAUSE_CAP; | ||||
| +			if (phydev->asym_pause) | ||||
| +				rmt_adv |= LPA_PAUSE_ASYM; | ||||
| + | ||||
| +			if (phydev->advertising & ADVERTISED_Pause) | ||||
| +				lcl_adv |= ADVERTISE_PAUSE_CAP; | ||||
| +			if (phydev->advertising & ADVERTISED_Asym_Pause) | ||||
| +				lcl_adv |= ADVERTISE_PAUSE_ASYM; | ||||
| + | ||||
| +			flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); | ||||
| + | ||||
| +			if (flowctrl & FLOW_CTRL_TX) | ||||
| +				mcr |= PMCR_TX_FC_EN; | ||||
| +			if (flowctrl & FLOW_CTRL_RX) | ||||
| +				mcr |= PMCR_RX_FC_EN; | ||||
| +		} | ||||
| +		mt7530_write(priv, MT7530_PMCR_P(port), mcr); | ||||
|  	} | ||||
|  } | ||||
|   | ||||
| --- a/drivers/net/dsa/mt7530.h | ||||
| +++ b/drivers/net/dsa/mt7530.h | ||||
| @@ -155,6 +155,7 @@ enum mt7530_stp_state { | ||||
|  #define  PMCR_TX_FC_EN			BIT(5) | ||||
|  #define  PMCR_RX_FC_EN			BIT(4) | ||||
|  #define  PMCR_FORCE_SPEED_1000		BIT(3) | ||||
| +#define  PMCR_FORCE_SPEED_100		BIT(2) | ||||
|  #define  PMCR_FORCE_FDX			BIT(1) | ||||
|  #define  PMCR_FORCE_LNK			BIT(0) | ||||
|  #define  PMCR_COMMON_LINK		(PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \ | ||||
| @@ -1,105 +0,0 @@ | ||||
| From 746bf1c3e561aba396cd40e6540245646461117d Mon Sep 17 00:00:00 2001 | ||||
| From: Sean Wang <sean.wang@mediatek.com> | ||||
| Date: Tue, 4 Jul 2017 11:17:36 +0800 | ||||
| Subject: [PATCH 54/57] net: ethernet: mediatek: fixed deadlock captured by | ||||
|  lockdep | ||||
|  | ||||
| Lockdep found an inconsistent lock state when mtk_get_stats64 is called | ||||
| in user context while NAPI updates MAC statistics in softirq. | ||||
|  | ||||
| Use spin_trylock_bh/spin_unlock_bh fix following lockdep warning. | ||||
|  | ||||
| [   81.321030] WARNING: inconsistent lock state | ||||
| [   81.325266] 4.12.0-rc1-00035-gd9dda65 #32 Not tainted | ||||
| [   81.330273] -------------------------------- | ||||
| [   81.334505] inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. | ||||
| [   81.340464] ksoftirqd/0/7 [HC0[0]:SC1[1]:HE1:SE0] takes: | ||||
| [   81.345731]  (&syncp->seq#2){+.?...}, at: [<c054ba3c>] mtk_handle_status_irq.part.6+0x70/0x84 | ||||
| [   81.354219] {SOFTIRQ-ON-W} state was registered at: | ||||
| [   81.359062]   lock_acquire+0xfc/0x2b0 | ||||
| [   81.362696]   mtk_stats_update_mac+0x60/0x2c0 | ||||
| [   81.367017]   mtk_get_stats64+0x17c/0x18c | ||||
| [   81.370995]   dev_get_stats+0x48/0xbc | ||||
| [   81.374628]   rtnl_fill_stats+0x48/0x128 | ||||
| [   81.378520]   rtnl_fill_ifinfo+0x4ac/0xd1c | ||||
| [   81.382584]   rtmsg_ifinfo_build_skb+0x7c/0xe0 | ||||
| [   81.386991]   rtmsg_ifinfo.part.5+0x24/0x54 | ||||
| [   81.391139]   rtmsg_ifinfo+0x24/0x28 | ||||
| [   81.394685]   __dev_notify_flags+0xa4/0xac | ||||
| [   81.398749]   dev_change_flags+0x50/0x58 | ||||
| [   81.402640]   devinet_ioctl+0x768/0x85c | ||||
| [   81.406444]   inet_ioctl+0x1a4/0x1d0 | ||||
| [   81.409990]   sock_ioctl+0x16c/0x33c | ||||
| [   81.413538]   do_vfs_ioctl+0xb4/0xa34 | ||||
| [   81.417169]   SyS_ioctl+0x44/0x6c | ||||
| [   81.420458]   ret_fast_syscall+0x0/0x1c | ||||
| [   81.424260] irq event stamp: 3354692 | ||||
| [   81.427806] hardirqs last  enabled at (3354692): [<c0678168>] net_rx_action+0xc0/0x504 | ||||
| [   81.435660] hardirqs last disabled at (3354691): [<c0678134>] net_rx_action+0x8c/0x504 | ||||
| [   81.443515] softirqs last  enabled at (3354106): [<c0101944>] __do_softirq+0x4b4/0x614 | ||||
| [   81.451370] softirqs last disabled at (3354109): [<c012f0c4>] run_ksoftirqd+0x44/0x80 | ||||
| [   81.459134] | ||||
| [   81.459134] other info that might help us debug this: | ||||
| [   81.465608]  Possible unsafe locking scenario: | ||||
| [   81.465608] | ||||
| [   81.471478]        CPU0 | ||||
| [   81.473900]        ---- | ||||
| [   81.476321]   lock(&syncp->seq#2); | ||||
| [   81.479701]   <Interrupt> | ||||
| [   81.482294]     lock(&syncp->seq#2); | ||||
| [   81.485847] | ||||
| [   81.485847]  *** DEADLOCK *** | ||||
| [   81.485847] | ||||
| [   81.491720] 1 lock held by ksoftirqd/0/7: | ||||
| [   81.495693]  #0:  (&(&mac->hw_stats->stats_lock)->rlock){+.+...}, at: [<c054ba14>] mtk_handle_status_irq.part.6+0x48/0x84 | ||||
| [   81.506579] | ||||
| [   81.506579] stack backtrace: | ||||
| [   81.510904] CPU: 0 PID: 7 Comm: ksoftirqd/0 Not tainted 4.12.0-rc1-00035-gd9dda65 #32 | ||||
| [   81.518668] Hardware name: Mediatek Cortex-A7 (Device Tree) | ||||
| [   81.524208] [<c0113dc4>] (unwind_backtrace) from [<c010e3f0>] (show_stack+0x20/0x24) | ||||
| [   81.531899] [<c010e3f0>] (show_stack) from [<c03f9c64>] (dump_stack+0xb4/0xe0) | ||||
| [   81.539072] [<c03f9c64>] (dump_stack) from [<c017e970>] (print_usage_bug+0x234/0x2e0) | ||||
| [   81.546846] [<c017e970>] (print_usage_bug) from [<c017f058>] (mark_lock+0x63c/0x7bc) | ||||
| [   81.554532] [<c017f058>] (mark_lock) from [<c017fe90>] (__lock_acquire+0x654/0x1bfc) | ||||
| [   81.562217] [<c017fe90>] (__lock_acquire) from [<c0181d04>] (lock_acquire+0xfc/0x2b0) | ||||
| [   81.569990] [<c0181d04>] (lock_acquire) from [<c054b76c>] (mtk_stats_update_mac+0x60/0x2c0) | ||||
| [   81.578283] [<c054b76c>] (mtk_stats_update_mac) from [<c054ba3c>] (mtk_handle_status_irq.part.6+0x70/0x84) | ||||
| [   81.587865] [<c054ba3c>] (mtk_handle_status_irq.part.6) from [<c054c2b8>] (mtk_napi_tx+0x358/0x37c) | ||||
| [   81.596845] [<c054c2b8>] (mtk_napi_tx) from [<c06782ec>] (net_rx_action+0x244/0x504) | ||||
| [   81.604533] [<c06782ec>] (net_rx_action) from [<c01015c4>] (__do_softirq+0x134/0x614) | ||||
| [   81.612306] [<c01015c4>] (__do_softirq) from [<c012f0c4>] (run_ksoftirqd+0x44/0x80) | ||||
| [   81.619907] [<c012f0c4>] (run_ksoftirqd) from [<c0154680>] (smpboot_thread_fn+0x14c/0x25c) | ||||
| [   81.628110] [<c0154680>] (smpboot_thread_fn) from [<c014f8cc>] (kthread+0x150/0x180) | ||||
| [   81.635798] [<c014f8cc>] (kthread) from [<c0109290>] (ret_from_fork+0x14/0x24) | ||||
|  | ||||
| Signed-off-by: Sean Wang <sean.wang@mediatek.com> | ||||
| --- | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 ++++---- | ||||
|  1 file changed, 4 insertions(+), 4 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| @@ -493,9 +493,9 @@ static struct rtnl_link_stats64 * mtk_ge | ||||
|  	unsigned int start; | ||||
|   | ||||
|  	if (netif_running(dev) && netif_device_present(dev)) { | ||||
| -		if (spin_trylock(&hw_stats->stats_lock)) { | ||||
| +		if (spin_trylock_bh(&hw_stats->stats_lock)) { | ||||
|  			mtk_stats_update_mac(mac); | ||||
| -			spin_unlock(&hw_stats->stats_lock); | ||||
| +			spin_unlock_bh(&hw_stats->stats_lock); | ||||
|  		} | ||||
|  	} | ||||
|   | ||||
| @@ -2229,9 +2229,9 @@ static void mtk_get_ethtool_stats(struct | ||||
|  		return; | ||||
|   | ||||
|  	if (netif_running(dev) && netif_device_present(dev)) { | ||||
| -		if (spin_trylock(&hwstats->stats_lock)) { | ||||
| +		if (spin_trylock_bh(&hwstats->stats_lock)) { | ||||
|  			mtk_stats_update_mac(mac); | ||||
| -			spin_unlock(&hwstats->stats_lock); | ||||
| +			spin_unlock_bh(&hwstats->stats_lock); | ||||
|  		} | ||||
|  	} | ||||
|   | ||||
| @@ -1,31 +0,0 @@ | ||||
| From a3360b3543b9fb833ba691019e396e72293a313f Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Thu, 10 Aug 2017 16:31:45 +0200 | ||||
| Subject: [PATCH 55/57] net: ethernet: mediatek: avoid potential invalid memory | ||||
|  access | ||||
|  | ||||
| Potential dangerous invalid memory might be accessed if invalid mac value | ||||
| reflected from the forward port field in rxd4 caused by possible potential | ||||
| hardware defects. So added a simple sanity checker to avoid the kind of | ||||
| situation happening. | ||||
|  | ||||
| Signed-off-by: Sean Wang <sean.wang@mediatek.com> | ||||
| Acked-by: John Crispin <john@phrozen.org> | ||||
| Signed-off-by: David S. Miller <davem@davemloft.net> | ||||
| --- | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++ | ||||
|  1 file changed, 4 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| @@ -964,6 +964,10 @@ static int mtk_poll_rx(struct napi_struc | ||||
|  			mac--; | ||||
|  		} | ||||
|   | ||||
| +		if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT || | ||||
| +			     !eth->netdev[mac])) | ||||
| +			goto release_desc; | ||||
| + | ||||
|  		netdev = eth->netdev[mac]; | ||||
|   | ||||
|  		if (unlikely(test_bit(MTK_RESETTING, ð->state))) | ||||
| @@ -1,119 +0,0 @@ | ||||
| From 043efc0e619e04661be2b1889382db2fdd378145 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Thu, 10 Aug 2017 16:34:36 +0200 | ||||
| Subject: [PATCH 56/57] net: mediatek: add hw nat support | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/net/ethernet/mediatek/Kconfig       |  7 +++++++ | ||||
|  drivers/net/ethernet/mediatek/Makefile      |  1 + | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.c | 13 +++++++++++++ | ||||
|  net/netfilter/nf_conntrack_proto_tcp.c      | 19 +++++++++++++++++++ | ||||
|  4 files changed, 40 insertions(+) | ||||
|  | ||||
| --- a/drivers/net/ethernet/mediatek/Kconfig | ||||
| +++ b/drivers/net/ethernet/mediatek/Kconfig | ||||
| @@ -14,4 +14,11 @@ config NET_MEDIATEK_SOC | ||||
|  	  This driver supports the gigabit ethernet MACs in the | ||||
|  	  MediaTek MT2701/MT7623 chipset family. | ||||
|   | ||||
| +config NET_MEDIATEK_HNAT | ||||
| +	tristate "MediaTek MT7623 hardware NAT support" | ||||
| +	depends on NET_MEDIATEK_SOC && NF_CONNTRACK && NF_CONNTRACK_IPV4 && IP_NF_NAT && IP_NF_TARGET_MASQUERADE | ||||
| +	---help--- | ||||
| +	  This driver supports the hardwaer NAT in the | ||||
| +	  MediaTek MT2701/MT7623 chipset family. | ||||
| + | ||||
|  endif #NET_VENDOR_MEDIATEK | ||||
| --- a/drivers/net/ethernet/mediatek/Makefile | ||||
| +++ b/drivers/net/ethernet/mediatek/Makefile | ||||
| @@ -3,3 +3,4 @@ | ||||
|  # | ||||
|   | ||||
|  obj-$(CONFIG_NET_MEDIATEK_SOC)			+= mtk_eth_soc.o | ||||
| +obj-$(CONFIG_NET_MEDIATEK_HNAT)			+= mtk_hnat/ | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| @@ -23,6 +23,10 @@ | ||||
|  #include <linux/reset.h> | ||||
|  #include <linux/tcp.h> | ||||
|   | ||||
| +#if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE) | ||||
| +#include "mtk_hnat/nf_hnat_mtk.h" | ||||
| +#endif | ||||
| + | ||||
|  #include "mtk_eth_soc.h" | ||||
|   | ||||
|  static int mtk_msg_level = -1; | ||||
| @@ -649,6 +653,11 @@ static int mtk_tx_map(struct sk_buff *sk | ||||
|  		return -ENOMEM; | ||||
|   | ||||
|  	/* set the forward port */ | ||||
| +#if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE) | ||||
| +	if (HNAT_SKB_CB2(skb)->magic == 0x78681415) | ||||
| +		fport |= 0x4 << TX_DMA_FPORT_SHIFT; | ||||
| +	else | ||||
| +#endif | ||||
|  	fport = (mac->id + 1) << TX_DMA_FPORT_SHIFT; | ||||
|  	txd4 |= fport; | ||||
|   | ||||
| @@ -1013,6 +1022,10 @@ static int mtk_poll_rx(struct napi_struc | ||||
|  		    RX_DMA_VID(trxd.rxd3)) | ||||
|  			__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), | ||||
|  					       RX_DMA_VID(trxd.rxd3)); | ||||
| +#if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE) | ||||
| +		*(u32 *)(skb->head) = trxd.rxd4; | ||||
| +		skb_hnat_alg(skb) = 0; | ||||
| +#endif | ||||
|  		skb_record_rx_queue(skb, 0); | ||||
|  		napi_gro_receive(napi, skb); | ||||
|   | ||||
| --- a/net/netfilter/nf_conntrack_proto_tcp.c | ||||
| +++ b/net/netfilter/nf_conntrack_proto_tcp.c | ||||
| @@ -11,6 +11,7 @@ | ||||
|  #include <linux/types.h> | ||||
|  #include <linux/timer.h> | ||||
|  #include <linux/module.h> | ||||
| +#include <linux/inetdevice.h> | ||||
|  #include <linux/in.h> | ||||
|  #include <linux/tcp.h> | ||||
|  #include <linux/spinlock.h> | ||||
| @@ -19,6 +20,7 @@ | ||||
|  #include <net/ip6_checksum.h> | ||||
|  #include <asm/unaligned.h> | ||||
|   | ||||
| +#include <net/ip.h> | ||||
|  #include <net/tcp.h> | ||||
|   | ||||
|  #include <linux/netfilter.h> | ||||
| @@ -53,6 +55,11 @@ static int nf_ct_tcp_max_retrans __read_ | ||||
|    /* FIXME: Examine ipfilter's timeouts and conntrack transitions more | ||||
|       closely.  They're more complex. --RR */ | ||||
|   | ||||
| +#ifndef IPV4_DEVCONF_DFLT | ||||
| +	#define IPV4_DEVCONF_DFLT(net, attr) \ | ||||
| +	IPV4_DEVCONF((*net->ipv4.devconf_dflt), attr) | ||||
| +#endif | ||||
| + | ||||
|  static const char *const tcp_conntrack_names[] = { | ||||
|  	"NONE", | ||||
|  	"SYN_SENT", | ||||
| @@ -519,6 +526,18 @@ static bool tcp_in_window(const struct n | ||||
|  	if (nf_ct_tcp_no_window_check) | ||||
|  		return true; | ||||
|   | ||||
| +	if (net) { | ||||
| +		if ((net->ipv4.devconf_all && net->ipv4.devconf_dflt && net->ipv6.devconf_all) && | ||||
| +		    net->ipv6.devconf_dflt) { | ||||
| +			if ((IPV4_DEVCONF_DFLT(net, FORWARDING) || | ||||
| +			     IPV4_DEVCONF_ALL(net, FORWARDING)) || | ||||
| +			     (net->ipv6.devconf_all->forwarding || | ||||
| +			      net->ipv6.devconf_dflt->forwarding)) { | ||||
| +				return true; | ||||
| +			} | ||||
| +		} | ||||
| +	} | ||||
| + | ||||
|  	/* | ||||
|  	 * Get the required data from the packet. | ||||
|  	 */ | ||||
| @@ -1,121 +0,0 @@ | ||||
| From 660c13dfbacbf37f090a66a2b14f0c5ce7cbec81 Mon Sep 17 00:00:00 2001 | ||||
| From: John Crispin <john@phrozen.org> | ||||
| Date: Thu, 10 Aug 2017 16:38:27 +0200 | ||||
| Subject: [PATCH 57/57] net: mediatek: add HW QoS support | ||||
|  | ||||
| Signed-off-by: John Crispin <john@phrozen.org> | ||||
| --- | ||||
|  drivers/net/ethernet/mediatek/Kconfig       |  7 ++++ | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.c | 60 ++++++++++++++++++++++++++++- | ||||
|  drivers/net/ethernet/mediatek/mtk_eth_soc.h |  2 +- | ||||
|  3 files changed, 66 insertions(+), 3 deletions(-) | ||||
|  | ||||
| --- a/drivers/net/ethernet/mediatek/Kconfig | ||||
| +++ b/drivers/net/ethernet/mediatek/Kconfig | ||||
| @@ -21,4 +21,11 @@ config NET_MEDIATEK_HNAT | ||||
|  	  This driver supports the hardwaer NAT in the | ||||
|  	  MediaTek MT2701/MT7623 chipset family. | ||||
|   | ||||
| +config NET_MEDIATEK_HW_QOS | ||||
| +	tristate "MediaTek MT7623 hardware QoS support" | ||||
| +	depends on NET_MEDIATEK_SOC | ||||
| +	---help--- | ||||
| +	  This driver supports the hardware QoS in the | ||||
| +	  MediaTek MT2701/MT7623 chipset family. | ||||
| + | ||||
|  endif #NET_VENDOR_MEDIATEK | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| @@ -23,6 +23,17 @@ | ||||
|  #include <linux/reset.h> | ||||
|  #include <linux/tcp.h> | ||||
|   | ||||
| +#if defined(CONFIG_NET_MEDIATEK_HW_QOS) | ||||
| +struct mtk_ioctl_reg { | ||||
| +	unsigned int off; | ||||
| +	unsigned int val; | ||||
| +}; | ||||
| + | ||||
| +#define REG_HQOS_MAX			0x3FFF | ||||
| +#define RAETH_QDMA_REG_READ		0x89F8 | ||||
| +#define RAETH_QDMA_REG_WRITE		0x89F9 | ||||
| +#endif | ||||
| + | ||||
|  #if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE) | ||||
|  #include "mtk_hnat/nf_hnat_mtk.h" | ||||
|  #endif | ||||
| @@ -646,7 +657,7 @@ static int mtk_tx_map(struct sk_buff *sk | ||||
|  	dma_addr_t mapped_addr; | ||||
|  	unsigned int nr_frags; | ||||
|  	int i, n_desc = 1; | ||||
| -	u32 txd4 = 0, fport; | ||||
| +	u32 txd3 = 0, txd4 = 0, fport; | ||||
|   | ||||
|  	itxd = ring->next_free; | ||||
|  	if (itxd == ring->last_free) | ||||
| @@ -675,6 +686,12 @@ static int mtk_tx_map(struct sk_buff *sk | ||||
|  //	if (skb_vlan_tag_present(skb)) | ||||
|  //		txd4 |= TX_DMA_INS_VLAN | skb_vlan_tag_get(skb); | ||||
|   | ||||
| +#ifdef CONFIG_NET_MEDIATEK_HW_QOS | ||||
| +	txd3 |= skb->mark & 0x7; | ||||
| +	if (mac->id) | ||||
| +		txd3 += 8; | ||||
| +#endif | ||||
| + | ||||
|  	mapped_addr = dma_map_single(eth->dev, skb->data, | ||||
|  				     skb_headlen(skb), DMA_TO_DEVICE); | ||||
|  	if (unlikely(dma_mapping_error(eth->dev, mapped_addr))) | ||||
| @@ -718,7 +735,8 @@ 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)); | ||||
| +					       last_frag * TX_DMA_LS0 | | ||||
| +					       txd3)); | ||||
|  			WRITE_ONCE(txd->txd4, fport); | ||||
|   | ||||
|  			tx_buf = mtk_desc_to_tx_buf(ring, txd); | ||||
| @@ -2029,7 +2047,31 @@ static void mtk_uninit(struct net_device | ||||
|   | ||||
|  static int mtk_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | ||||
|  { | ||||
| +#if defined(CONFIG_NET_MEDIATEK_HW_QOS) | ||||
| +	struct mtk_mac *mac = netdev_priv(dev); | ||||
| +	struct mtk_eth *eth = mac->hw; | ||||
| +	struct mtk_ioctl_reg reg; | ||||
| +#endif | ||||
| + | ||||
|  	switch (cmd) { | ||||
| +#if defined(CONFIG_NET_MEDIATEK_HW_QOS) | ||||
| +	case RAETH_QDMA_REG_READ: | ||||
| +		copy_from_user(®, ifr->ifr_data, sizeof(reg)); | ||||
| +		if (reg.off > REG_HQOS_MAX) | ||||
| +			return -EINVAL; | ||||
| +		reg.val = mtk_r32(eth, 0x1800 + reg.off); | ||||
| +//		printk("read reg off:%x val:%x\n", reg.off, reg.val); | ||||
| +		copy_to_user(ifr->ifr_data, ®, sizeof(reg)); | ||||
| +		return 0; | ||||
| + | ||||
| +	case RAETH_QDMA_REG_WRITE: | ||||
| +		copy_from_user(®, ifr->ifr_data, sizeof(reg)); | ||||
| +		if (reg.off > REG_HQOS_MAX) | ||||
| +			return -EINVAL; | ||||
| +		mtk_w32(eth, reg.val, 0x1800 + reg.off); | ||||
| +//		printk("write reg off:%x val:%x\n", reg.off, reg.val); | ||||
| +		return 0; | ||||
| +#endif | ||||
|  	case SIOCGMIIPHY: | ||||
|  	case SIOCGMIIREG: | ||||
|  	case SIOCSMIIREG: | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||||
| @@ -20,7 +20,7 @@ | ||||
|  #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_DMA_SIZE		2048 | ||||
|  #define MTK_NAPI_WEIGHT		64 | ||||
|  #define MTK_MAC_COUNT		2 | ||||
|  #define MTK_RX_ETH_HLEN		(VLAN_ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN) | ||||
| @@ -1,470 +0,0 @@ | ||||
| --- a/drivers/pinctrl/mediatek/Kconfig | ||||
| +++ b/drivers/pinctrl/mediatek/Kconfig | ||||
| @@ -15,12 +15,6 @@ config PINCTRL_MT2701 | ||||
|  	default MACH_MT2701 | ||||
|  	select PINCTRL_MTK | ||||
|   | ||||
| -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,7 +3,6 @@ obj-y				+= pinctrl-mtk-common.o | ||||
|   | ||||
|  # SoC Drivers | ||||
|  obj-$(CONFIG_PINCTRL_MT2701)	+= pinctrl-mt2701.o | ||||
| -obj-$(CONFIG_PINCTRL_MT7623)	+= pinctrl-mt7623.o | ||||
|  obj-$(CONFIG_PINCTRL_MT8135)	+= pinctrl-mt8135.o | ||||
|  obj-$(CONFIG_PINCTRL_MT8127)	+= pinctrl-mt8127.o | ||||
|  obj-$(CONFIG_PINCTRL_MT8173)	+= pinctrl-mt8173.o | ||||
| --- a/drivers/pinctrl/mediatek/pinctrl-mt2701.c | ||||
| +++ b/drivers/pinctrl/mediatek/pinctrl-mt2701.c | ||||
| @@ -565,6 +565,7 @@ static int mt2701_pinctrl_probe(struct p | ||||
|   | ||||
|  static const struct of_device_id mt2701_pctrl_match[] = { | ||||
|  	{ .compatible = "mediatek,mt2701-pinctrl", }, | ||||
| +	{ .compatible = "mediatek,mt7623-pinctrl", }, | ||||
|  	{} | ||||
|  }; | ||||
|  MODULE_DEVICE_TABLE(of, mt2701_pctrl_match); | ||||
| --- a/drivers/pinctrl/mediatek/pinctrl-mt7623.c | ||||
| +++ /dev/null | ||||
| @@ -1,379 +0,0 @@ | ||||
| -/* | ||||
| - * Copyright (c) 2016 John Crispin <blogic@openwrt.org> | ||||
| - * | ||||
| - * This program is free software; you can redistribute it and/or modify | ||||
| - * it under the terms of the GNU General Public License version 2 as | ||||
| - * published by the Free Software Foundation. | ||||
| - * | ||||
| - * This program is distributed in the hope that it will be useful, | ||||
| - * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| - * GNU General Public License for more details. | ||||
| - */ | ||||
| - | ||||
| -#include <dt-bindings/pinctrl/mt65xx.h> | ||||
| -#include <linux/module.h> | ||||
| -#include <linux/of.h> | ||||
| -#include <linux/of_device.h> | ||||
| -#include <linux/platform_device.h> | ||||
| -#include <linux/pinctrl/pinctrl.h> | ||||
| -#include <linux/regmap.h> | ||||
| - | ||||
| -#include "pinctrl-mtk-common.h" | ||||
| -#include "pinctrl-mtk-mt7623.h" | ||||
| - | ||||
| -static const struct mtk_drv_group_desc mt7623_drv_grp[] =  { | ||||
| -	/* 0E4E8SR 4/8/12/16 */ | ||||
| -	MTK_DRV_GRP(4, 16, 1, 2, 4), | ||||
| -	/* 0E2E4SR  2/4/6/8 */ | ||||
| -	MTK_DRV_GRP(2, 8, 1, 2, 2), | ||||
| -	/* E8E4E2  2/4/6/8/10/12/14/16 */ | ||||
| -	MTK_DRV_GRP(2, 16, 0, 2, 2) | ||||
| -}; | ||||
| - | ||||
| -#define DRV_SEL0	0xf50 | ||||
| -#define DRV_SEL1	0xf60 | ||||
| -#define DRV_SEL2	0xf70 | ||||
| -#define DRV_SEL3	0xf80 | ||||
| -#define DRV_SEL4	0xf90 | ||||
| -#define DRV_SEL5	0xfa0 | ||||
| -#define DRV_SEL6	0xfb0 | ||||
| -#define DRV_SEL7	0xfe0 | ||||
| -#define DRV_SEL8	0xfd0 | ||||
| -#define DRV_SEL9	0xff0 | ||||
| -#define DRV_SEL10	0xf00 | ||||
| - | ||||
| -#define MSDC0_CTRL0	0xcc0 | ||||
| -#define MSDC0_CTRL1	0xcd0 | ||||
| -#define MSDC0_CTRL2	0xce0 | ||||
| -#define MSDC0_CTRL3	0xcf0 | ||||
| -#define MSDC0_CTRL4	0xd00 | ||||
| -#define MSDC0_CTRL5	0xd10 | ||||
| -#define MSDC0_CTRL6	0xd20 | ||||
| -#define MSDC1_CTRL0	0xd30 | ||||
| -#define MSDC1_CTRL1	0xd40 | ||||
| -#define MSDC1_CTRL2	0xd50 | ||||
| -#define MSDC1_CTRL3	0xd60 | ||||
| -#define MSDC1_CTRL4	0xd70 | ||||
| -#define MSDC1_CTRL5	0xd80 | ||||
| -#define MSDC1_CTRL6	0xd90 | ||||
| - | ||||
| -#define IES_EN0		0xb20 | ||||
| -#define IES_EN1		0xb30 | ||||
| -#define IES_EN2		0xb40 | ||||
| - | ||||
| -#define SMT_EN0		0xb50 | ||||
| -#define SMT_EN1		0xb60 | ||||
| -#define SMT_EN2		0xb70 | ||||
| - | ||||
| -static const struct mtk_pin_drv_grp mt7623_pin_drv[] = { | ||||
| -	MTK_PIN_DRV_GRP(0, DRV_SEL0, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(1, DRV_SEL0, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(2, DRV_SEL0, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(3, DRV_SEL0, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(4, DRV_SEL0, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(5, DRV_SEL0, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(6, DRV_SEL0, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(7, DRV_SEL0, 4, 1), | ||||
| -	MTK_PIN_DRV_GRP(8, DRV_SEL0, 4, 1), | ||||
| -	MTK_PIN_DRV_GRP(9, DRV_SEL0, 4, 1), | ||||
| -	MTK_PIN_DRV_GRP(10, DRV_SEL0, 8, 1), | ||||
| -	MTK_PIN_DRV_GRP(11, DRV_SEL0, 8, 1), | ||||
| -	MTK_PIN_DRV_GRP(12, DRV_SEL0, 8, 1), | ||||
| -	MTK_PIN_DRV_GRP(13, DRV_SEL0, 8, 1), | ||||
| -	MTK_PIN_DRV_GRP(14, DRV_SEL0, 12, 0), | ||||
| -	MTK_PIN_DRV_GRP(15, DRV_SEL0, 12, 0), | ||||
| -	MTK_PIN_DRV_GRP(18, DRV_SEL1, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(19, DRV_SEL1, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(20, DRV_SEL1, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(21, DRV_SEL1, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(22, DRV_SEL1, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(23, DRV_SEL1, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(24, DRV_SEL1, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(25, DRV_SEL1, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(26, DRV_SEL1, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(27, DRV_SEL1, 12, 0), | ||||
| -	MTK_PIN_DRV_GRP(28, DRV_SEL1, 12, 0), | ||||
| -	MTK_PIN_DRV_GRP(29, DRV_SEL1, 12, 0), | ||||
| -	MTK_PIN_DRV_GRP(33, DRV_SEL2, 0, 0), | ||||
| -	MTK_PIN_DRV_GRP(34, DRV_SEL2, 0, 0), | ||||
| -	MTK_PIN_DRV_GRP(35, DRV_SEL2, 0, 0), | ||||
| -	MTK_PIN_DRV_GRP(36, DRV_SEL2, 0, 0), | ||||
| -	MTK_PIN_DRV_GRP(37, DRV_SEL2, 0, 0), | ||||
| -	MTK_PIN_DRV_GRP(39, DRV_SEL2, 8, 1), | ||||
| -	MTK_PIN_DRV_GRP(40, DRV_SEL2, 8, 1), | ||||
| -	MTK_PIN_DRV_GRP(41, DRV_SEL2, 8, 1), | ||||
| -	MTK_PIN_DRV_GRP(42, DRV_SEL2, 8, 1), | ||||
| -	MTK_PIN_DRV_GRP(43, DRV_SEL2, 12, 0), | ||||
| -	MTK_PIN_DRV_GRP(44, DRV_SEL2, 12, 0), | ||||
| -	MTK_PIN_DRV_GRP(45, DRV_SEL2, 12, 0), | ||||
| -	MTK_PIN_DRV_GRP(47, DRV_SEL3, 0, 0), | ||||
| -	MTK_PIN_DRV_GRP(48, DRV_SEL3, 0, 0), | ||||
| -	MTK_PIN_DRV_GRP(49, DRV_SEL3, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(53, DRV_SEL3, 12, 0), | ||||
| -	MTK_PIN_DRV_GRP(54, DRV_SEL3, 12, 0), | ||||
| -	MTK_PIN_DRV_GRP(55, DRV_SEL3, 12, 0), | ||||
| -	MTK_PIN_DRV_GRP(56, DRV_SEL3, 12, 0), | ||||
| -	MTK_PIN_DRV_GRP(60, DRV_SEL4, 8, 1), | ||||
| -	MTK_PIN_DRV_GRP(61, DRV_SEL4, 8, 1), | ||||
| -	MTK_PIN_DRV_GRP(62, DRV_SEL4, 8, 1), | ||||
| -	MTK_PIN_DRV_GRP(63, DRV_SEL4, 12, 1), | ||||
| -	MTK_PIN_DRV_GRP(64, DRV_SEL4, 12, 1), | ||||
| -	MTK_PIN_DRV_GRP(65, DRV_SEL4, 12, 1), | ||||
| -	MTK_PIN_DRV_GRP(66, DRV_SEL5, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(67, DRV_SEL5, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(68, DRV_SEL5, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(69, DRV_SEL5, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(70, DRV_SEL5, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(71, DRV_SEL5, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(72, DRV_SEL3, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(73, DRV_SEL3, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(74, DRV_SEL3, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(83, DRV_SEL5, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(84, DRV_SEL5, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(105, MSDC1_CTRL1, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(106, MSDC1_CTRL0, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(107, MSDC1_CTRL2, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(108, MSDC1_CTRL2, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(109, MSDC1_CTRL2, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(110, MSDC1_CTRL2, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(111, MSDC0_CTRL2, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(112, MSDC0_CTRL2, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(113, MSDC0_CTRL2, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(114, MSDC0_CTRL2, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(115, MSDC0_CTRL2, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(116, MSDC0_CTRL1, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(117, MSDC0_CTRL0, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(118, MSDC0_CTRL2, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(119, MSDC0_CTRL2, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(120, MSDC0_CTRL2, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(121, MSDC0_CTRL2, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(126, DRV_SEL3, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(199, DRV_SEL0, 4, 1), | ||||
| -	MTK_PIN_DRV_GRP(200, DRV_SEL8, 0, 0), | ||||
| -	MTK_PIN_DRV_GRP(201, DRV_SEL8, 0, 0), | ||||
| -	MTK_PIN_DRV_GRP(203, DRV_SEL8, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(204, DRV_SEL8, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(205, DRV_SEL8, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(206, DRV_SEL8, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(207, DRV_SEL8, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(208, DRV_SEL8, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(209, DRV_SEL8, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(236, DRV_SEL9, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(237, DRV_SEL9, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(238, DRV_SEL9, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(239, DRV_SEL9, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(240, DRV_SEL9, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(241, DRV_SEL9, 4, 0), | ||||
| -	MTK_PIN_DRV_GRP(242, DRV_SEL9, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(243, DRV_SEL9, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(257, MSDC0_CTRL2, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(261, MSDC1_CTRL2, 0, 1), | ||||
| -	MTK_PIN_DRV_GRP(262, DRV_SEL10, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(263, DRV_SEL10, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(264, DRV_SEL10, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(265, DRV_SEL10, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(266, DRV_SEL10, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(267, DRV_SEL10, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(268, DRV_SEL10, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(269, DRV_SEL10, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(270, DRV_SEL10, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(271, DRV_SEL10, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(272, DRV_SEL10, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(274, DRV_SEL10, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(275, DRV_SEL10, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(276, DRV_SEL10, 8, 0), | ||||
| -	MTK_PIN_DRV_GRP(278, DRV_SEL2, 8, 1), | ||||
| -}; | ||||
| - | ||||
| -static const struct mtk_pin_spec_pupd_set_samereg mt7623_spec_pupd[] = { | ||||
| -	MTK_PIN_PUPD_SPEC_SR(105, MSDC1_CTRL1, 8, 9, 10), | ||||
| -	MTK_PIN_PUPD_SPEC_SR(106, MSDC1_CTRL0, 8, 9, 10), | ||||
| -	MTK_PIN_PUPD_SPEC_SR(107, MSDC1_CTRL3, 0, 1, 2), | ||||
| -	MTK_PIN_PUPD_SPEC_SR(108, MSDC1_CTRL3, 4, 5, 6), | ||||
| -	MTK_PIN_PUPD_SPEC_SR(109, MSDC1_CTRL3, 8, 9, 10), | ||||
| -	MTK_PIN_PUPD_SPEC_SR(110, MSDC1_CTRL3, 12, 13, 14), | ||||
| -	MTK_PIN_PUPD_SPEC_SR(111, MSDC0_CTRL4, 12, 13, 14), | ||||
| -	MTK_PIN_PUPD_SPEC_SR(112, MSDC0_CTRL4, 8, 9, 10), | ||||
| -	MTK_PIN_PUPD_SPEC_SR(113, MSDC0_CTRL4, 4, 5, 6), | ||||
| -	MTK_PIN_PUPD_SPEC_SR(114, MSDC0_CTRL4, 0, 1, 2), | ||||
| -	MTK_PIN_PUPD_SPEC_SR(115, MSDC0_CTRL5, 0, 1, 2), | ||||
| -	MTK_PIN_PUPD_SPEC_SR(116, MSDC0_CTRL1, 8, 9, 10), | ||||
| -	MTK_PIN_PUPD_SPEC_SR(117, MSDC0_CTRL0, 8, 9, 10), | ||||
| -	MTK_PIN_PUPD_SPEC_SR(118, MSDC0_CTRL3, 12, 13, 14), | ||||
| -	MTK_PIN_PUPD_SPEC_SR(119, MSDC0_CTRL3, 8, 9, 10), | ||||
| -	MTK_PIN_PUPD_SPEC_SR(120, MSDC0_CTRL3, 4, 5, 6), | ||||
| -	MTK_PIN_PUPD_SPEC_SR(121, MSDC0_CTRL3, 0, 1, 2), | ||||
| -}; | ||||
| - | ||||
| -static int mt7623_spec_pull_set(struct regmap *regmap, unsigned int pin, | ||||
| -		unsigned char align, bool isup, unsigned int r1r0) | ||||
| -{ | ||||
| -	return mtk_pctrl_spec_pull_set_samereg(regmap, mt7623_spec_pupd, | ||||
| -		ARRAY_SIZE(mt7623_spec_pupd), pin, align, isup, r1r0); | ||||
| -} | ||||
| - | ||||
| -static const struct mtk_pin_ies_smt_set mt7623_ies_set[] = { | ||||
| -	MTK_PIN_IES_SMT_SPEC(0, 6, IES_EN0, 0), | ||||
| -	MTK_PIN_IES_SMT_SPEC(7, 9, IES_EN0, 1), | ||||
| -	MTK_PIN_IES_SMT_SPEC(10, 13, IES_EN0, 2), | ||||
| -	MTK_PIN_IES_SMT_SPEC(14, 15, IES_EN0, 3), | ||||
| -	MTK_PIN_IES_SMT_SPEC(18, 21, IES_EN0, 5), | ||||
| -	MTK_PIN_IES_SMT_SPEC(22, 26, IES_EN0, 6), | ||||
| -	MTK_PIN_IES_SMT_SPEC(27, 29, IES_EN0, 7), | ||||
| -	MTK_PIN_IES_SMT_SPEC(33, 37, IES_EN0, 8), | ||||
| -	MTK_PIN_IES_SMT_SPEC(39, 42, IES_EN0, 9), | ||||
| -	MTK_PIN_IES_SMT_SPEC(43, 45, IES_EN0, 10), | ||||
| -	MTK_PIN_IES_SMT_SPEC(47, 48, IES_EN0, 11), | ||||
| -	MTK_PIN_IES_SMT_SPEC(49, 49, IES_EN0, 12), | ||||
| -	MTK_PIN_IES_SMT_SPEC(53, 56, IES_EN0, 14), | ||||
| -	MTK_PIN_IES_SMT_SPEC(60, 62, IES_EN1, 0), | ||||
| -	MTK_PIN_IES_SMT_SPEC(63, 65, IES_EN1, 1), | ||||
| -	MTK_PIN_IES_SMT_SPEC(66, 71, IES_EN1, 2), | ||||
| -	MTK_PIN_IES_SMT_SPEC(72, 74, IES_EN0, 12), | ||||
| -	MTK_PIN_IES_SMT_SPEC(75, 76, IES_EN1, 3), | ||||
| -	MTK_PIN_IES_SMT_SPEC(83, 84, IES_EN1, 2), | ||||
| -	MTK_PIN_IES_SMT_SPEC(105, 121, MSDC1_CTRL1, 4), | ||||
| -	MTK_PIN_IES_SMT_SPEC(122, 125, IES_EN1, 7), | ||||
| -	MTK_PIN_IES_SMT_SPEC(126, 126, IES_EN0, 12), | ||||
| -	MTK_PIN_IES_SMT_SPEC(199, 201, IES_EN0, 1), | ||||
| -	MTK_PIN_IES_SMT_SPEC(203, 207, IES_EN2, 2), | ||||
| -	MTK_PIN_IES_SMT_SPEC(208, 209, IES_EN2, 3), | ||||
| -	MTK_PIN_IES_SMT_SPEC(236, 241, IES_EN2, 6), | ||||
| -	MTK_PIN_IES_SMT_SPEC(242, 243, IES_EN2, 7), | ||||
| -	MTK_PIN_IES_SMT_SPEC(261, 261, MSDC1_CTRL2, 4), | ||||
| -	MTK_PIN_IES_SMT_SPEC(262, 272, IES_EN2, 12), | ||||
| -	MTK_PIN_IES_SMT_SPEC(274, 276, IES_EN2, 12), | ||||
| -	MTK_PIN_IES_SMT_SPEC(278, 278, IES_EN2, 13), | ||||
| -}; | ||||
| - | ||||
| -static const struct mtk_pin_ies_smt_set mt7623_smt_set[] = { | ||||
| -	MTK_PIN_IES_SMT_SPEC(0, 6, SMT_EN0, 0), | ||||
| -	MTK_PIN_IES_SMT_SPEC(7, 9, SMT_EN0, 1), | ||||
| -	MTK_PIN_IES_SMT_SPEC(10, 13, SMT_EN0, 2), | ||||
| -	MTK_PIN_IES_SMT_SPEC(14, 15, SMT_EN0, 3), | ||||
| -	MTK_PIN_IES_SMT_SPEC(18, 21, SMT_EN0, 5), | ||||
| -	MTK_PIN_IES_SMT_SPEC(22, 26, SMT_EN0, 6), | ||||
| -	MTK_PIN_IES_SMT_SPEC(27, 29, SMT_EN0, 7), | ||||
| -	MTK_PIN_IES_SMT_SPEC(33, 37, SMT_EN0, 8), | ||||
| -	MTK_PIN_IES_SMT_SPEC(39, 42, SMT_EN0, 9), | ||||
| -	MTK_PIN_IES_SMT_SPEC(43, 45, SMT_EN0, 10), | ||||
| -	MTK_PIN_IES_SMT_SPEC(47, 48, SMT_EN0, 11), | ||||
| -	MTK_PIN_IES_SMT_SPEC(49, 49, SMT_EN0, 12), | ||||
| -	MTK_PIN_IES_SMT_SPEC(53, 56, SMT_EN0, 14), | ||||
| -	MTK_PIN_IES_SMT_SPEC(60, 62, SMT_EN1, 0), | ||||
| -	MTK_PIN_IES_SMT_SPEC(63, 65, SMT_EN1, 1), | ||||
| -	MTK_PIN_IES_SMT_SPEC(66, 71, SMT_EN1, 2), | ||||
| -	MTK_PIN_IES_SMT_SPEC(72, 74, SMT_EN0, 12), | ||||
| -	MTK_PIN_IES_SMT_SPEC(75, 76, SMT_EN1, 3), | ||||
| -	MTK_PIN_IES_SMT_SPEC(83, 84, SMT_EN1, 2), | ||||
| -	MTK_PIN_IES_SMT_SPEC(105, 106, MSDC1_CTRL1, 11), | ||||
| -	MTK_PIN_IES_SMT_SPEC(107, 107, MSDC1_CTRL3, 3), | ||||
| -	MTK_PIN_IES_SMT_SPEC(108, 108, MSDC1_CTRL3, 7), | ||||
| -	MTK_PIN_IES_SMT_SPEC(109, 109, MSDC1_CTRL3, 11), | ||||
| -	MTK_PIN_IES_SMT_SPEC(110, 111, MSDC1_CTRL3, 15), | ||||
| -	MTK_PIN_IES_SMT_SPEC(112, 112, MSDC0_CTRL4, 11), | ||||
| -	MTK_PIN_IES_SMT_SPEC(113, 113, MSDC0_CTRL4, 7), | ||||
| -	MTK_PIN_IES_SMT_SPEC(114, 115, MSDC0_CTRL4, 3), | ||||
| -	MTK_PIN_IES_SMT_SPEC(116, 117, MSDC0_CTRL1, 11), | ||||
| -	MTK_PIN_IES_SMT_SPEC(118, 118, MSDC0_CTRL3, 15), | ||||
| -	MTK_PIN_IES_SMT_SPEC(119, 119, MSDC0_CTRL3, 11), | ||||
| -	MTK_PIN_IES_SMT_SPEC(120, 120, MSDC0_CTRL3, 7), | ||||
| -	MTK_PIN_IES_SMT_SPEC(121, 121, MSDC0_CTRL3, 3), | ||||
| -	MTK_PIN_IES_SMT_SPEC(122, 125, SMT_EN1, 7), | ||||
| -	MTK_PIN_IES_SMT_SPEC(126, 126, SMT_EN0, 12), | ||||
| -	MTK_PIN_IES_SMT_SPEC(199, 201, SMT_EN0, 1), | ||||
| -	MTK_PIN_IES_SMT_SPEC(203, 207, SMT_EN2, 2), | ||||
| -	MTK_PIN_IES_SMT_SPEC(208, 209, SMT_EN2, 3), | ||||
| -	MTK_PIN_IES_SMT_SPEC(236, 241, SMT_EN2, 6), | ||||
| -	MTK_PIN_IES_SMT_SPEC(242, 243, SMT_EN2, 7), | ||||
| -	MTK_PIN_IES_SMT_SPEC(261, 261, MSDC1_CTRL6, 3), | ||||
| -	MTK_PIN_IES_SMT_SPEC(262, 272, SMT_EN2, 12), | ||||
| -	MTK_PIN_IES_SMT_SPEC(274, 276, SMT_EN2, 12), | ||||
| -	MTK_PIN_IES_SMT_SPEC(278, 278, SMT_EN2, 13), | ||||
| -}; | ||||
| - | ||||
| -static int mt7623_ies_smt_set(struct regmap *regmap, unsigned int pin, | ||||
| -		unsigned char align, int value, enum pin_config_param arg) | ||||
| -{ | ||||
| -	if (arg == PIN_CONFIG_INPUT_ENABLE) | ||||
| -		return mtk_pconf_spec_set_ies_smt_range(regmap, mt7623_ies_set, | ||||
| -			ARRAY_SIZE(mt7623_ies_set), pin, align, value); | ||||
| -	else if (arg == PIN_CONFIG_INPUT_SCHMITT_ENABLE) | ||||
| -		return mtk_pconf_spec_set_ies_smt_range(regmap, mt7623_smt_set, | ||||
| -			ARRAY_SIZE(mt7623_smt_set), pin, align, value); | ||||
| -	return -EINVAL; | ||||
| -} | ||||
| - | ||||
| -static const struct mtk_pinctrl_devdata mt7623_pinctrl_data = { | ||||
| -	.pins = mtk_pins_mt7623, | ||||
| -	.npins = ARRAY_SIZE(mtk_pins_mt7623), | ||||
| -	.grp_desc = mt7623_drv_grp, | ||||
| -	.n_grp_cls = ARRAY_SIZE(mt7623_drv_grp), | ||||
| -	.pin_drv_grp = mt7623_pin_drv, | ||||
| -	.n_pin_drv_grps = ARRAY_SIZE(mt7623_pin_drv), | ||||
| -	.spec_pull_set = mt7623_spec_pull_set, | ||||
| -	.spec_ies_smt_set = mt7623_ies_smt_set, | ||||
| -	.dir_offset = 0x0000, | ||||
| -	.pullen_offset = 0x0150, | ||||
| -	.pullsel_offset = 0x0280, | ||||
| -	.dout_offset = 0x0500, | ||||
| -	.din_offset = 0x0630, | ||||
| -	.pinmux_offset = 0x0760, | ||||
| -	.type1_start = 280, | ||||
| -	.type1_end = 280, | ||||
| -	.port_shf = 4, | ||||
| -	.port_mask = 0x1f, | ||||
| -	.port_align = 4, | ||||
| -	.eint_offsets = { | ||||
| -		.name = "mt7623_eint", | ||||
| -		.stat      = 0x000, | ||||
| -		.ack       = 0x040, | ||||
| -		.mask      = 0x080, | ||||
| -		.mask_set  = 0x0c0, | ||||
| -		.mask_clr  = 0x100, | ||||
| -		.sens      = 0x140, | ||||
| -		.sens_set  = 0x180, | ||||
| -		.sens_clr  = 0x1c0, | ||||
| -		.soft      = 0x200, | ||||
| -		.soft_set  = 0x240, | ||||
| -		.soft_clr  = 0x280, | ||||
| -		.pol       = 0x300, | ||||
| -		.pol_set   = 0x340, | ||||
| -		.pol_clr   = 0x380, | ||||
| -		.dom_en    = 0x400, | ||||
| -		.dbnc_ctrl = 0x500, | ||||
| -		.dbnc_set  = 0x600, | ||||
| -		.dbnc_clr  = 0x700, | ||||
| -		.port_mask = 6, | ||||
| -		.ports     = 6, | ||||
| -	}, | ||||
| -	.ap_num = 169, | ||||
| -	.db_cnt = 16, | ||||
| -}; | ||||
| - | ||||
| -static int mt7623_pinctrl_probe(struct platform_device *pdev) | ||||
| -{ | ||||
| -	return mtk_pctrl_init(pdev, &mt7623_pinctrl_data, NULL); | ||||
| -} | ||||
| - | ||||
| -static const struct of_device_id mt7623_pctrl_match[] = { | ||||
| -	{ .compatible = "mediatek,mt7623-pinctrl", }, | ||||
| -	{} | ||||
| -}; | ||||
| -MODULE_DEVICE_TABLE(of, mt7623_pctrl_match); | ||||
| - | ||||
| -static struct platform_driver mtk_pinctrl_driver = { | ||||
| -	.probe = mt7623_pinctrl_probe, | ||||
| -	.driver = { | ||||
| -		.name = "mediatek-mt7623-pinctrl", | ||||
| -		.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); | ||||
| --- a/include/dt-bindings/pinctrl/mt7623-pinfunc.h | ||||
| +++ b/include/dt-bindings/pinctrl/mt7623-pinfunc.h | ||||
| @@ -185,6 +185,12 @@ | ||||
|  #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_57_SDA1_FUNC_GPIO57 (MTK_PIN_NO(57) | 0) | ||||
| +#define MT7623_PIN_57_SDA1_FUNC_SDA1 (MTK_PIN_NO(57) | 1) | ||||
| + | ||||
| +#define MT7623_PIN_58_SCL1_FUNC_GPIO58 (MTK_PIN_NO(58) | 0) | ||||
| +#define MT7623_PIN_58_SCL1_FUNC_SCL1 (MTK_PIN_NO(58) | 1) | ||||
| + | ||||
|  #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) | ||||
|   | ||||
| @@ -244,6 +250,22 @@ | ||||
|  #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_79_URXD0_FUNC_GPIO79 (MTK_PIN_NO(79) | 0) | ||||
| +#define MT7623_PIN_79_URXD0_FUNC_URXD0 (MTK_PIN_NO(79) | 1) | ||||
| +#define MT7623_PIN_79_URXD0_FUNC_UTXD0 (MTK_PIN_NO(79) | 2) | ||||
| + | ||||
| +#define MT7623_PIN_80_UTXD0_FUNC_GPIO80 (MTK_PIN_NO(80) | 0) | ||||
| +#define MT7623_PIN_80_UTXD0_FUNC_UTXD0 (MTK_PIN_NO(80) | 1) | ||||
| +#define MT7623_PIN_80_UTXD0_FUNC_URXD0 (MTK_PIN_NO(80) | 2) | ||||
| + | ||||
| +#define MT7623_PIN_81_URXD1_FUNC_GPIO81 (MTK_PIN_NO(81) | 0) | ||||
| +#define MT7623_PIN_81_URXD1_FUNC_URXD1 (MTK_PIN_NO(81) | 1) | ||||
| +#define MT7623_PIN_81_URXD1_FUNC_UTXD1 (MTK_PIN_NO(81) | 2) | ||||
| + | ||||
| +#define MT7623_PIN_82_UTXD1_FUNC_GPIO82 (MTK_PIN_NO(82) | 0) | ||||
| +#define MT7623_PIN_82_UTXD1_FUNC_UTXD1 (MTK_PIN_NO(82) | 1) | ||||
| +#define MT7623_PIN_82_UTXD1_FUNC_URXD1 (MTK_PIN_NO(82) | 2) | ||||
| + | ||||
|  #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) | ||||
|   | ||||
| @@ -351,10 +373,10 @@ | ||||
|  #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_123_HTPLG_FUNC_GPIO123 (MTK_PIN_NO(123) | 0) | ||||
| +#define MT7623_PIN_123_HTPLG_FUNC_HTPLG (MTK_PIN_NO(123) | 1) | ||||
| +#define MT7623_PIN_123_HTPLG_FUNC_SCL2 (MTK_PIN_NO(123) | 4) | ||||
| +#define MT7623_PIN_123_HTPLG_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) | ||||
| @@ -1,511 +0,0 @@ | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| @@ -24,6 +24,7 @@ | ||||
|  #include <linux/tcp.h> | ||||
|   | ||||
|  #if defined(CONFIG_NET_MEDIATEK_HW_QOS) | ||||
| + | ||||
|  struct mtk_ioctl_reg { | ||||
|  	unsigned int off; | ||||
|  	unsigned int val; | ||||
| @@ -32,6 +33,13 @@ struct mtk_ioctl_reg { | ||||
|  #define REG_HQOS_MAX			0x3FFF | ||||
|  #define RAETH_QDMA_REG_READ		0x89F8 | ||||
|  #define RAETH_QDMA_REG_WRITE		0x89F9 | ||||
| +#define RAETH_QDMA_QUEUE_MAPPING        0x89FA | ||||
| + | ||||
| +unsigned int M2Q_table[16] = {0}; | ||||
| +unsigned int lan_wan_separate = 0; | ||||
| + | ||||
| +EXPORT_SYMBOL_GPL(M2Q_table); | ||||
| + | ||||
|  #endif | ||||
|   | ||||
|  #if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE) | ||||
| @@ -225,7 +233,7 @@ static void mtk_phy_link_adjust(struct n | ||||
|  		if (flowctrl & FLOW_CTRL_RX) | ||||
|  			mcr |= MAC_MCR_FORCE_RX_FC; | ||||
|   | ||||
| -		netif_dbg(mac->hw, link, dev, "rx pause %s, tx pause %s\n", | ||||
| +		netif_info(mac->hw, link, dev, "rx pause %s, tx pause %s\n", | ||||
|  			  flowctrl & FLOW_CTRL_RX ? "enabled" : "disabled", | ||||
|  			  flowctrl & FLOW_CTRL_TX ? "enabled" : "disabled"); | ||||
|  	} | ||||
| @@ -508,9 +516,9 @@ static struct rtnl_link_stats64 * mtk_ge | ||||
|  	unsigned int start; | ||||
|   | ||||
|  	if (netif_running(dev) && netif_device_present(dev)) { | ||||
| -		if (spin_trylock_bh(&hw_stats->stats_lock)) { | ||||
| +		if (spin_trylock(&hw_stats->stats_lock)) { | ||||
|  			mtk_stats_update_mac(mac); | ||||
| -			spin_unlock_bh(&hw_stats->stats_lock); | ||||
| +			spin_unlock(&hw_stats->stats_lock); | ||||
|  		} | ||||
|  	} | ||||
|   | ||||
| @@ -690,6 +698,7 @@ static int mtk_tx_map(struct sk_buff *sk | ||||
|  	txd3 |= skb->mark & 0x7; | ||||
|  	if (mac->id) | ||||
|  		txd3 += 8; | ||||
| +	txd3 = 0; | ||||
|  #endif | ||||
|   | ||||
|  	mapped_addr = dma_map_single(eth->dev, skb->data, | ||||
| @@ -760,16 +769,7 @@ 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))); | ||||
|   | ||||
| -	/* 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); | ||||
| -	} | ||||
| - | ||||
| +	netdev_sent_queue(dev, skb->len); | ||||
|  	skb_tx_timestamp(skb); | ||||
|   | ||||
|  	ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2); | ||||
| @@ -980,20 +980,9 @@ static int mtk_poll_rx(struct napi_struc | ||||
|  		if (!(trxd.rxd2 & RX_DMA_DONE)) | ||||
|  			break; | ||||
|   | ||||
| -		/* find out which mac the packet comes from. If the special tag is | ||||
| -		 * we can assume that the traffic is coming from the builtin mt7530 | ||||
| -		 * and the DSA driver has loaded. FPORT will be the physical switch | ||||
| -		 * port in this case rather than the FE forward port id. */ | ||||
| -		if (!(trxd.rxd4 & RX_DMA_SP_TAG)) { | ||||
| -			/* values start at 1 */ | ||||
| -			mac = (trxd.rxd4 >> RX_DMA_FPORT_SHIFT) & | ||||
| -			      RX_DMA_FPORT_MASK; | ||||
| -			mac--; | ||||
| -		} | ||||
| - | ||||
| -		if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT || | ||||
| -			     !eth->netdev[mac])) | ||||
| -			goto release_desc; | ||||
| +		/* find out which mac the packet come from. values start at 1 */ | ||||
| +		mac = (trxd.rxd4 >> 22) & 0x1; | ||||
| +		mac = (mac + 1) % 2; | ||||
|   | ||||
|  		netdev = eth->netdev[mac]; | ||||
|   | ||||
| @@ -1017,6 +1006,9 @@ static int mtk_poll_rx(struct napi_struc | ||||
|  		} | ||||
|   | ||||
|  		/* receive data */ | ||||
| +		if (mac < 0 || mac > 2) | ||||
| +			mac = 0; | ||||
| + | ||||
|  		skb = build_skb(data, ring->frag_size); | ||||
|  		if (unlikely(!skb)) { | ||||
|  			skb_free_frag(new_data); | ||||
| @@ -1076,18 +1068,21 @@ 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 = 0; | ||||
| -	unsigned int bytes = 0; | ||||
| +	unsigned int done[MTK_MAX_DEVS]; | ||||
| +	unsigned int bytes[MTK_MAX_DEVS]; | ||||
|  	u32 cpu, dma; | ||||
|  	static int condition; | ||||
| -	int i; | ||||
| +	int total = 0, 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) && done < budget) { | ||||
| +	while ((cpu != dma) && budget) { | ||||
|  		u32 next_cpu = desc->txd2; | ||||
|  		int mac = 0; | ||||
|   | ||||
| @@ -1106,8 +1101,9 @@ static int mtk_poll_tx(struct mtk_eth *e | ||||
|  		} | ||||
|   | ||||
|  		if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) { | ||||
| -			bytes += skb->len; | ||||
| -			done++; | ||||
| +			bytes[mac] += skb->len; | ||||
| +			done[mac]++; | ||||
| +			budget--; | ||||
|  		} | ||||
|  		mtk_tx_unmap(eth, tx_buf); | ||||
|   | ||||
| @@ -1119,13 +1115,11 @@ 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]) | ||||
| +		if (!eth->netdev[i] || !done[i]) | ||||
|  			continue; | ||||
| -		netdev_completed_queue(eth->netdev[i], done, bytes); | ||||
| +		netdev_completed_queue(eth->netdev[i], done[i], bytes[i]); | ||||
| +		total += done[i]; | ||||
|  	} | ||||
|   | ||||
|  	if (mtk_queue_stopped(eth) && | ||||
| @@ -1286,21 +1280,11 @@ static void mtk_tx_clean(struct mtk_eth | ||||
|   | ||||
|  static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag) | ||||
|  { | ||||
| -	struct mtk_rx_ring *ring; | ||||
| +	struct mtk_rx_ring *ring = ð->rx_ring[ring_no]; | ||||
|  	int rx_data_len, rx_dma_size; | ||||
|  	int i; | ||||
| -	u32 offset = 0; | ||||
| - | ||||
| -	if (rx_flag & MTK_RX_FLAGS_QDMA) { | ||||
| -		if (ring_no) | ||||
| -			return -EINVAL; | ||||
| -		ring = ð->rx_ring_qdma; | ||||
| -		offset = 0x1000; | ||||
| -	} else { | ||||
| -		ring = ð->rx_ring[ring_no]; | ||||
| -	} | ||||
|   | ||||
| -	if (rx_flag & MTK_RX_FLAGS_HWLRO) { | ||||
| +	if (rx_flag == MTK_RX_FLAGS_HWLRO) { | ||||
|  		rx_data_len = MTK_MAX_LRO_RX_LENGTH; | ||||
|  		rx_dma_size = MTK_HW_LRO_DMA_SIZE; | ||||
|  	} else { | ||||
| @@ -1348,16 +1332,104 @@ static int mtk_rx_alloc(struct mtk_eth * | ||||
|  	 */ | ||||
|  	wmb(); | ||||
|   | ||||
| -	mtk_w32(eth, ring->phys, MTK_PRX_BASE_PTR_CFG(ring_no) + offset); | ||||
| -	mtk_w32(eth, rx_dma_size, MTK_PRX_MAX_CNT_CFG(ring_no) + offset); | ||||
| -	mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg + offset); | ||||
| -	mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), MTK_PDMA_RST_IDX + offset); | ||||
| +	mtk_w32(eth, ring->phys, MTK_PRX_BASE_PTR_CFG(ring_no)); | ||||
| +	mtk_w32(eth, rx_dma_size, MTK_PRX_MAX_CNT_CFG(ring_no)); | ||||
| +	mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg); | ||||
| +	mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), MTK_PDMA_RST_IDX); | ||||
|   | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| -static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring) | ||||
| +static int mtk_rx_alloc_qdma(struct mtk_eth *eth, int rx_flag) | ||||
|  { | ||||
| +	struct mtk_rx_ring *ring = ð->rx_ring_qdma; | ||||
| +	int rx_data_len, rx_dma_size; | ||||
| +	int i; | ||||
| + | ||||
| +	rx_data_len = ETH_DATA_LEN; | ||||
| +	rx_dma_size = MTK_DMA_SIZE; | ||||
| + | ||||
| +	ring->frag_size = mtk_max_frag_size(rx_data_len); | ||||
| +	ring->buf_size = mtk_max_buf_size(ring->frag_size); | ||||
| +	ring->data = kcalloc(rx_dma_size, sizeof(*ring->data), | ||||
| +			     GFP_KERNEL); | ||||
| +	if (!ring->data) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	for (i = 0; i < rx_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, | ||||
| +				       rx_dma_size * sizeof(*ring->dma), | ||||
| +				       &ring->phys, | ||||
| +				       GFP_ATOMIC | __GFP_ZERO); | ||||
| +	if (!ring->dma) | ||||
| +		return -ENOMEM; | ||||
| + | ||||
| +	for (i = 0; i < rx_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->dma_size = rx_dma_size; | ||||
| +	ring->calc_idx_update = false; | ||||
| +	ring->calc_idx = rx_dma_size - 1; | ||||
| +	ring->crx_idx_reg = MTK_QRX_CRX_IDX_CFG(0); | ||||
| +	/* make sure that all changes to the dma ring are flushed before we | ||||
| +	 * continue | ||||
| +	 */ | ||||
| +	wmb(); | ||||
| + | ||||
| +	mtk_w32(eth, ring->phys, MTK_QRX_BASE_PTR_CFG(0)); | ||||
| +	mtk_w32(eth, rx_dma_size, MTK_QRX_MAX_CNT_CFG(0)); | ||||
| +	mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg); | ||||
| +	mtk_w32(eth, MTK_PST_DRX_IDX_CFG(0), MTK_QDMA_RST_IDX); | ||||
| + | ||||
| +	return 0; | ||||
| +} | ||||
| + | ||||
| +static void mtk_rx_clean(struct mtk_eth *eth, int ring_no) | ||||
| +{ | ||||
| +	struct mtk_rx_ring *ring = ð->rx_ring[ring_no]; | ||||
| +	int i; | ||||
| + | ||||
| +	if (ring->data && ring->dma) { | ||||
| +		for (i = 0; i < ring->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, | ||||
| +				  ring->dma_size * sizeof(*ring->dma), | ||||
| +				  ring->dma, | ||||
| +				  ring->phys); | ||||
| +		ring->dma = NULL; | ||||
| +	} | ||||
| +} | ||||
| + | ||||
| +static void mtk_rx_clean_qdma(struct mtk_eth *eth) | ||||
| +{ | ||||
| +	struct mtk_rx_ring *ring = ð->rx_ring_qdma; | ||||
|  	int i; | ||||
|   | ||||
|  	if (ring->data && ring->dma) { | ||||
| @@ -1683,7 +1755,7 @@ static int mtk_dma_init(struct mtk_eth * | ||||
|  	if (err) | ||||
|  		return err; | ||||
|   | ||||
| -	err = mtk_rx_alloc(eth, 0, MTK_RX_FLAGS_QDMA); | ||||
| +	err = mtk_rx_alloc_qdma(eth, MTK_RX_FLAGS_NORMAL); | ||||
|  	if (err) | ||||
|  		return err; | ||||
|   | ||||
| @@ -1702,6 +1774,7 @@ static int mtk_dma_init(struct mtk_eth * | ||||
|  			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); | ||||
| @@ -1726,13 +1799,13 @@ static void mtk_dma_free(struct mtk_eth | ||||
|  		eth->phy_scratch_ring = 0; | ||||
|  	} | ||||
|  	mtk_tx_clean(eth); | ||||
| -	mtk_rx_clean(eth, ð->rx_ring[0]); | ||||
| -	mtk_rx_clean(eth, ð->rx_ring_qdma); | ||||
| +	mtk_rx_clean(eth, 0); | ||||
| +	mtk_rx_clean_qdma(eth); | ||||
|   | ||||
|  	if (eth->hwlro) { | ||||
|  		mtk_hwlro_rx_uninit(eth); | ||||
|  		for (i = 1; i < MTK_MAX_RX_RING_NUM; i++) | ||||
| -			mtk_rx_clean(eth, ð->rx_ring[i]); | ||||
| +			mtk_rx_clean(eth, i); | ||||
|  	} | ||||
|   | ||||
|  	kfree(eth->scratch_head); | ||||
| @@ -1947,20 +2020,14 @@ static int mtk_hw_init(struct mtk_eth *e | ||||
|  	val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); | ||||
|  	mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); | ||||
|   | ||||
| -	/* Indicates CDM to parse the MTK special tag from CPU | ||||
| -	 * which also is working out for untag packets. | ||||
| -	 */ | ||||
| -	val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); | ||||
| -	mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); | ||||
| -	val = mtk_r32(eth, MTK_CDMP_IG_CTRL); | ||||
| -	mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); | ||||
| - | ||||
|  	/* Enable RX VLan Offloading */ | ||||
|  	if (MTK_HW_FEATURES & NETIF_F_HW_VLAN_CTAG_RX) | ||||
|  		mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); | ||||
|  	else | ||||
|  		mtk_w32(eth, 0, MTK_CDMP_EG_CTRL); | ||||
|   | ||||
| +	mtk_w32(eth, 0x81000001, MTK_CDMP_IG_CTRL); | ||||
| + | ||||
|  	/* disable delay and normal interrupt */ | ||||
|  #ifdef MTK_IRQ_DLY | ||||
|  	mtk_w32(eth, 0x84048404, MTK_PDMA_DELAY_INT); | ||||
| @@ -1990,6 +2057,9 @@ static int mtk_hw_init(struct mtk_eth *e | ||||
|  		/* Enable RX checksum */ | ||||
|  		val |= MTK_GDMA_ICS_EN | MTK_GDMA_TCS_EN | MTK_GDMA_UCS_EN; | ||||
|   | ||||
| +		if (!i) | ||||
| +			val |= BIT(24); | ||||
| + | ||||
|  		/* setup the mac dma */ | ||||
|  		mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i)); | ||||
|  	} | ||||
| @@ -2069,7 +2139,18 @@ static int mtk_do_ioctl(struct net_devic | ||||
|  		if (reg.off > REG_HQOS_MAX) | ||||
|  			return -EINVAL; | ||||
|  		mtk_w32(eth, reg.val, 0x1800 + reg.off); | ||||
| -//		printk("write reg off:%x val:%x\n", reg.off, reg.val); | ||||
| +		printk("write reg off:%x val:%x\n", reg.off, reg.val); | ||||
| +		return 0; | ||||
| + | ||||
| +	case RAETH_QDMA_QUEUE_MAPPING: | ||||
| +		copy_from_user(®, ifr->ifr_data, sizeof(reg)); | ||||
| +		if ((reg.off & 0x100) == 0x100) { | ||||
| +			lan_wan_separate = 1; | ||||
| +			reg.off &= 0xff; | ||||
| +		} else { | ||||
| +			lan_wan_separate = 0; | ||||
| +		} | ||||
| +		M2Q_table[reg.off] = reg.val; | ||||
|  		return 0; | ||||
|  #endif | ||||
|  	case SIOCGMIIPHY: | ||||
| @@ -2288,9 +2369,9 @@ static void mtk_get_ethtool_stats(struct | ||||
|  		return; | ||||
|   | ||||
|  	if (netif_running(dev) && netif_device_present(dev)) { | ||||
| -		if (spin_trylock_bh(&hwstats->stats_lock)) { | ||||
| +		if (spin_trylock(&hwstats->stats_lock)) { | ||||
|  			mtk_stats_update_mac(mac); | ||||
| -			spin_unlock_bh(&hwstats->stats_lock); | ||||
| +			spin_unlock(&hwstats->stats_lock); | ||||
|  		} | ||||
|  	} | ||||
|   | ||||
| @@ -2443,7 +2524,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 = 30 * HZ; | ||||
| +	eth->netdev[id]->watchdog_timeo = 15 * HZ; | ||||
|  	eth->netdev[id]->netdev_ops = &mtk_netdev_ops; | ||||
|  	eth->netdev[id]->base_addr = (unsigned long)eth->base; | ||||
|   | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||||
| @@ -80,7 +80,6 @@ | ||||
|   | ||||
|  /* CDMP Ingress Control Register */ | ||||
|  #define MTK_CDMP_IG_CTRL	0x400 | ||||
| -#define MTK_CDMP_STAG_EN	BIT(0) | ||||
|   | ||||
|  /* CDMP Exgress Control Register */ | ||||
|  #define MTK_CDMP_EG_CTRL	0x404 | ||||
| @@ -91,12 +90,27 @@ | ||||
|  #define MTK_GDMA_TCS_EN		BIT(21) | ||||
|  #define MTK_GDMA_UCS_EN		BIT(20) | ||||
|   | ||||
| +/* GDMA Ingress Control Register */ | ||||
| +#define MTK_GDMA1_IG_CTRL(x)	(0x500 + (x * 0x1000)) | ||||
| + | ||||
|  /* 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 RX Base Pointer Register */ | ||||
| +#define MTK_QRX_BASE_PTR0	0x1900 | ||||
| +#define MTK_QRX_BASE_PTR_CFG(x)	(MTK_QRX_BASE_PTR0 + (x * 0x10)) | ||||
| + | ||||
| +/* QDMA RX Maximum Count Register */ | ||||
| +#define MTK_QRX_MAX_CNT0	0x1904 | ||||
| +#define MTK_QRX_MAX_CNT_CFG(x)	(MTK_QRX_MAX_CNT0 + (x * 0x10)) | ||||
| + | ||||
| +/* QDMA RX CPU Pointer Register */ | ||||
| +#define MTK_QRX_CRX_IDX0	0x1908 | ||||
| +#define MTK_QRX_CRX_IDX_CFG(x)	(MTK_QRX_CRX_IDX0 + (x * 0x10)) | ||||
| + | ||||
|  /* PDMA RX Base Pointer Register */ | ||||
|  #define MTK_PRX_BASE_PTR0	0x900 | ||||
|  #define MTK_PRX_BASE_PTR_CFG(x)	(MTK_PRX_BASE_PTR0 + (x * 0x10)) | ||||
| @@ -240,7 +254,10 @@ | ||||
|  #define MTK_QDMA_INT_MASK	0x1A1C | ||||
|   | ||||
|  /* QDMA Interrupt Mask Register */ | ||||
| +#define MTK_QDMA_HRED1		0x1A40 | ||||
|  #define MTK_QDMA_HRED2		0x1A44 | ||||
| +#define MTK_QDMA_SRED1		0x1A48 | ||||
| +#define MTK_QDMA_SRED2		0x1A4c | ||||
|   | ||||
|  /* QDMA TX Forward CPU Pointer Register */ | ||||
|  #define MTK_QTX_CTX_PTR		0x1B00 | ||||
| @@ -275,6 +292,7 @@ | ||||
|  #define TX_DMA_TSO		BIT(28) | ||||
|  #define TX_DMA_FPORT_SHIFT	25 | ||||
|  #define TX_DMA_FPORT_MASK	0x7 | ||||
| +#define TX_DMA_VQID0		BIT(17) | ||||
|  #define TX_DMA_INS_VLAN		BIT(16) | ||||
|   | ||||
|  /* QDMA descriptor txd3 */ | ||||
| @@ -294,7 +312,6 @@ | ||||
|   | ||||
|  /* QDMA descriptor rxd4 */ | ||||
|  #define RX_DMA_L4_VALID		BIT(24) | ||||
| -#define RX_DMA_SP_TAG		BIT(22) | ||||
|  #define RX_DMA_FPORT_SHIFT	19 | ||||
|  #define RX_DMA_FPORT_MASK	0x7 | ||||
|   | ||||
| @@ -310,6 +327,7 @@ | ||||
|   | ||||
|  /* Mac control registers */ | ||||
|  #define MTK_MAC_MCR(x)		(0x10100 + (x * 0x100)) | ||||
| +#define MTK_MAC_MSR(x)		(0x10108 + (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) | ||||
| @@ -495,7 +513,6 @@ struct mtk_tx_ring { | ||||
|  enum mtk_rx_flags { | ||||
|  	MTK_RX_FLAGS_NORMAL = 0, | ||||
|  	MTK_RX_FLAGS_HWLRO, | ||||
| -	MTK_RX_FLAGS_QDMA, | ||||
|  }; | ||||
|   | ||||
|  /* struct mtk_rx_ring -	This struct holds info describing a RX ring | ||||
| @@ -539,9 +556,9 @@ struct mtk_rx_ring { | ||||
|   * @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 memory holding info about the TX ring | ||||
| - * @rx_ring:		Pointer to the memory holding info about the RX ring | ||||
| - * @rx_ring_qdma:	Pointer to the memory holding info about the QDMA RX ring | ||||
| + * @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_ring_qdma:	Pointer to the memore holding info about the RX ring (QDMA) | ||||
|   * @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 | ||||
| @@ -563,6 +580,7 @@ struct mtk_eth { | ||||
|  	struct net_device		*netdev[MTK_MAX_DEVS]; | ||||
|  	struct mtk_mac			*mac[MTK_MAX_DEVS]; | ||||
|  	int				irq[3]; | ||||
| +	cpumask_t			affinity_mask[3]; | ||||
|  	u32				msg_enable; | ||||
|  	unsigned long			sysclk; | ||||
|  	struct regmap			*ethsys; | ||||
| @@ -615,4 +633,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); | ||||
|   | ||||
| +extern unsigned int M2Q_table[16]; | ||||
| + | ||||
|  #endif /* MTK_ETH_H */ | ||||
| @@ -1,69 +0,0 @@ | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| @@ -851,6 +851,7 @@ static void mtk_stop_queue(struct mtk_et | ||||
|  			continue; | ||||
|  		netif_stop_queue(eth->netdev[i]); | ||||
|  	} | ||||
| +	mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); | ||||
|  } | ||||
|   | ||||
|  static int mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||||
| @@ -1885,6 +1886,19 @@ static int mtk_start_dma(struct mtk_eth | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| +#define NAPI_TIMER_EXPIRE		HZ | ||||
| + | ||||
| +static void napi_timer_handler(unsigned long priv) | ||||
| +{ | ||||
| +	struct mtk_eth *eth = (struct mtk_eth*) priv; | ||||
| + | ||||
| +	mtk_wake_queue(eth); | ||||
| +	mtk_handle_irq_rx(0, eth); | ||||
| +	mtk_handle_irq_tx(0, eth); | ||||
| + | ||||
| +	mod_timer(ð->napi_timer, jiffies + NAPI_TIMER_EXPIRE); | ||||
| +} | ||||
| + | ||||
|  static int mtk_open(struct net_device *dev) | ||||
|  { | ||||
|  	struct mtk_mac *mac = netdev_priv(dev); | ||||
| @@ -1901,6 +1915,9 @@ static int mtk_open(struct net_device *d | ||||
|  		napi_enable(ð->rx_napi); | ||||
|  		mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); | ||||
|  		mtk_rx_irq_enable(eth, MTK_RX_DONE_INT); | ||||
| + | ||||
| +		setup_timer(ð->napi_timer, napi_timer_handler, (unsigned long) eth); | ||||
| +		mod_timer(ð->napi_timer, jiffies + NAPI_TIMER_EXPIRE); | ||||
|  	} | ||||
|  	atomic_inc(ð->dma_refcnt); | ||||
|   | ||||
| @@ -1945,6 +1962,8 @@ static int mtk_stop(struct net_device *d | ||||
|  	if (!atomic_dec_and_test(ð->dma_refcnt)) | ||||
|  		return 0; | ||||
|   | ||||
| +	del_timer(ð->napi_timer); | ||||
| + | ||||
|  	mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); | ||||
|  	mtk_rx_irq_disable(eth, MTK_RX_DONE_INT); | ||||
|  	napi_disable(ð->tx_napi); | ||||
| @@ -2524,7 +2543,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 = 15 * HZ; | ||||
| +	eth->netdev[id]->watchdog_timeo = 30 * HZ; | ||||
|  	eth->netdev[id]->netdev_ops = &mtk_netdev_ops; | ||||
|  	eth->netdev[id]->base_addr = (unsigned long)eth->base; | ||||
|   | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||||
| @@ -601,6 +601,8 @@ struct mtk_eth { | ||||
|  	struct mii_bus			*mii_bus; | ||||
|  	struct work_struct		pending_work; | ||||
|  	unsigned long			state; | ||||
| + | ||||
| +	struct timer_list		napi_timer; | ||||
|  }; | ||||
|   | ||||
|  /* struct mtk_mac -	the structure that holds the info about the MACs of the | ||||
| @@ -1,72 +0,0 @@ | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| @@ -1904,12 +1904,16 @@ static int mtk_open(struct net_device *d | ||||
|  	struct mtk_mac *mac = netdev_priv(dev); | ||||
|  	struct mtk_eth *eth = mac->hw; | ||||
|   | ||||
| +	spin_lock(ð->iface_lock); | ||||
| + | ||||
|  	/* 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) | ||||
| +		if (err) { | ||||
| +			spin_unlock(ð->iface_lock); | ||||
|  			return err; | ||||
| +		} | ||||
|   | ||||
|  		napi_enable(ð->tx_napi); | ||||
|  		napi_enable(ð->rx_napi); | ||||
| @@ -1923,6 +1927,7 @@ static int mtk_open(struct net_device *d | ||||
|   | ||||
|  	phy_start(dev->phydev); | ||||
|  	netif_start_queue(dev); | ||||
| +	spin_unlock(ð->iface_lock); | ||||
|   | ||||
|  	return 0; | ||||
|  } | ||||
| @@ -1955,12 +1960,15 @@ static int mtk_stop(struct net_device *d | ||||
|  	struct mtk_mac *mac = netdev_priv(dev); | ||||
|  	struct mtk_eth *eth = mac->hw; | ||||
|   | ||||
| +	spin_lock(ð->iface_lock); | ||||
|  	netif_tx_disable(dev); | ||||
|  	phy_stop(dev->phydev); | ||||
|   | ||||
|  	/* only shutdown DMA if this is the last user */ | ||||
| -	if (!atomic_dec_and_test(ð->dma_refcnt)) | ||||
| +	if (!atomic_dec_and_test(ð->dma_refcnt)) { | ||||
| +		spin_unlock(ð->iface_lock); | ||||
|  		return 0; | ||||
| +	} | ||||
|   | ||||
|  	del_timer(ð->napi_timer); | ||||
|   | ||||
| @@ -1974,6 +1982,8 @@ static int mtk_stop(struct net_device *d | ||||
|   | ||||
|  	mtk_dma_free(eth); | ||||
|   | ||||
| +	spin_unlock(ð->iface_lock); | ||||
| + | ||||
|  	return 0; | ||||
|  } | ||||
|   | ||||
| @@ -2623,6 +2633,7 @@ static int mtk_probe(struct platform_dev | ||||
|  	if (IS_ERR(eth->base)) | ||||
|  		return PTR_ERR(eth->base); | ||||
|   | ||||
| +	spin_lock_init(ð->iface_lock); | ||||
|  	spin_lock_init(ð->page_lock); | ||||
|  	spin_lock_init(ð->tx_irq_lock); | ||||
|  	spin_lock_init(ð->rx_irq_lock); | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h | ||||
| @@ -573,6 +573,7 @@ struct mtk_rx_ring { | ||||
|  struct mtk_eth { | ||||
|  	struct device			*dev; | ||||
|  	void __iomem			*base; | ||||
| +	spinlock_t			iface_lock; | ||||
|  	spinlock_t			page_lock; | ||||
|  	spinlock_t			tx_irq_lock; | ||||
|  	spinlock_t			rx_irq_lock; | ||||
| @@ -1,38 +0,0 @@ | ||||
| --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c | ||||
| @@ -1533,7 +1533,10 @@ static void mtk_hwlro_rx_uninit(struct m | ||||
|  	for (i = 0; i < 10; i++) { | ||||
|  		val = mtk_r32(eth, MTK_PDMA_LRO_CTRL_DW0); | ||||
|  		if (val & MTK_LRO_RING_RELINQUISH_DONE) { | ||||
| -			msleep(20); | ||||
| +			if (in_atomic()) | ||||
| +				mdelay(20); | ||||
| +			else | ||||
| +				msleep(20); | ||||
|  			continue; | ||||
|  		} | ||||
|  		break; | ||||
| @@ -1951,7 +1954,10 @@ static void mtk_stop_dma(struct mtk_eth | ||||
|  	for (i = 0; i < 10; i++) { | ||||
|  		val = mtk_r32(eth, glo_cfg); | ||||
|  		if (val & (MTK_TX_DMA_BUSY | MTK_RX_DMA_BUSY)) { | ||||
| -			msleep(20); | ||||
| +			if (in_atomic()) | ||||
| +				mdelay(20); | ||||
| +			else | ||||
| +				msleep(20); | ||||
|  			continue; | ||||
|  		} | ||||
|  		break; | ||||
| @@ -1996,7 +2002,10 @@ static void ethsys_reset(struct mtk_eth | ||||
|  			   reset_bits, | ||||
|  			   reset_bits); | ||||
|   | ||||
| -	usleep_range(1000, 1100); | ||||
| +	if (in_atomic()) | ||||
| +		udelay(1000); | ||||
| +	else | ||||
| +		usleep_range(1000, 1100); | ||||
|  	regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, | ||||
|  			   reset_bits, | ||||
|  			   ~reset_bits); | ||||
		Reference in New Issue
	
	Block a user
	 John Crispin
					John Crispin