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:
John Crispin 2018-01-08 15:06:24 +01:00
parent 04d3308b62
commit 7762c07c88
91 changed files with 1482 additions and 19755 deletions

View file

@ -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

View file

@ -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
;;

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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
}

View file

@ -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

View 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

View file

@ -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>,
<&ethsys CLK_ETHSYS_ESW>,
<&ethsys CLK_ETHSYS_GP2>,
<&ethsys 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 = <&ethsys 6>;
reset-names = "eth";
mediatek,ethsys = <&ethsys>;
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 = <&ethsys 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>,
<&ethsys CLK_ETHSYS_CRYPTO>;
clock-names = "ethif","cryp";
power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
};
};

View file

@ -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>;
};
};
};
};

View file

@ -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";
};
&eth {
status = "okay";
};
&gmac1 {
mac-address = [00 11 22 33 44 56];
status = "okay";
};
&gmac2 {
mac-address = [00 11 22 33 44 55];
status = "okay";
phy-handle = <&phy5>;
};
&mdio0 {
switch@0 {
compatible = "mediatek,mt7530";
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&eth_default>;
core-supply = <&mt6323_vpa_reg>;
io-supply = <&mt6323_vemc3v3_reg>;
mediatek,mcm;
resets = <&ethsys 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";
};

View file

@ -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";
};
&eth {
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 = <&eth_default>;
core-supply = <&mt6323_vpa_reg>;
io-supply = <&mt6323_vemc3v3_reg>;
mediatek,mcm;
resets = <&ethsys 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";
};

View file

@ -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 = <&eth_default>;
core-supply = <&mt6323_vpa_reg>;
io-supply = <&mt6323_vemc3v3_reg>;
mediatek,mcm;
resets = <&ethsys 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";
};
&eth {
status = "okay";
};
&gmac1 {
mac-address = [00 11 22 33 44 56];
status = "okay";
};
&gmac2 {
mac-address = [00 11 22 33 44 55];
status = "okay";
phy-handle = <&phy5>;
};
&mdio0 {
phy5: ethernet-phy@5 {
reg = <5>;
phy-mode = "rgmii-rxid";
};
};
&pwm {
pinctrl-names = "default";
pinctrl-0 = <&pwm_pins>;
status = "okay";
};

View file

@ -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";
};*/

View file

@ -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";
};
&eth {
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";
};

View file

@ -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");

View file

@ -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

View file

@ -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");

View file

@ -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_ */

View file

@ -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

View file

@ -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

View file

@ -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))

View file

@ -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);

View file

@ -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);

View file

@ -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,

View 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;

View file

@ -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 */ },
};

View file

@ -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);

View 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);

View 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";
+};
+
+&eth {
+ 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 = <&ethsys 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 {

View file

@ -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

View file

@ -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";
+ };
+ };

View file

@ -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);

View file

@ -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 */

View file

@ -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

View file

@ -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 = {

View file

@ -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,
}, {

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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 */

View file

@ -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);

View file

@ -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");

View file

@ -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[] = {

View file

@ -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";
+ };
+ };
+ };

View file

@ -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.

View file

@ -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", &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");

View file

@ -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"
},

View file

@ -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,

View file

@ -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

View file

@ -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;
+ };
+ };
+ };
+ };
+ };

View file

@ -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,
+};

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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);
}

View file

@ -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

View file

@ -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 = &eth->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 = &eth->rx_ring_qdma;
+ offset = 0x1000;
+ } else {
+ ring = &eth->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 = &eth->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, &eth->rx_ring[0]);
+ mtk_rx_clean(eth, &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, &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;

View file

@ -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);

View file

@ -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 {

View file

@ -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,
};

View file

@ -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)

View file

@ -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

View file

@ -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(&eth->irq_lock, flags);
- val = mtk_r32(eth, reg);
- mtk_w32(eth, val & ~mask, reg);
- spin_unlock_irqrestore(&eth->irq_lock, flags);
+ spin_lock_irqsave(&eth->tx_irq_lock, flags);
+ val = mtk_r32(eth, MTK_QDMA_INT_MASK);
+ mtk_w32(eth, val & ~mask, MTK_QDMA_INT_MASK);
+ spin_unlock_irqrestore(&eth->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(&eth->irq_lock, flags);
- val = mtk_r32(eth, reg);
- mtk_w32(eth, val | mask, reg);
- spin_unlock_irqrestore(&eth->irq_lock, flags);
+ spin_lock_irqsave(&eth->tx_irq_lock, flags);
+ val = mtk_r32(eth, MTK_QDMA_INT_MASK);
+ mtk_w32(eth, val | mask, MTK_QDMA_INT_MASK);
+ spin_unlock_irqrestore(&eth->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(&eth->rx_irq_lock, flags);
+ val = mtk_r32(eth, MTK_PDMA_INT_MASK);
+ mtk_w32(eth, val & ~mask, MTK_PDMA_INT_MASK);
+ spin_unlock_irqrestore(&eth->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(&eth->rx_irq_lock, flags);
+ val = mtk_r32(eth, MTK_PDMA_INT_MASK);
+ mtk_w32(eth, val | mask, MTK_PDMA_INT_MASK);
+ spin_unlock_irqrestore(&eth->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(&eth->rx_napi))) {
__napi_schedule(&eth->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(&eth->tx_napi))) {
__napi_schedule(&eth->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(&eth->tx_napi);
napi_enable(&eth->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(&eth->dma_refcnt);
@@ -1816,8 +1836,8 @@ static int mtk_stop(struct net_device *d
if (!atomic_dec_and_test(&eth->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(&eth->tx_napi);
napi_disable(&eth->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(&eth->page_lock);
- spin_lock_init(&eth->irq_lock);
+ spin_lock_init(&eth->tx_irq_lock);
+ spin_lock_init(&eth->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];

View file

@ -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;

View file

@ -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]);

View file

@ -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 | \

View file

@ -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);
}
}

View file

@ -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, &eth->state)))

View file

@ -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.
*/

View file

@ -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(&reg, 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, &reg, sizeof(reg));
+ return 0;
+
+ case RAETH_QDMA_REG_WRITE:
+ copy_from_user(&reg, 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)

View file

@ -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)

View file

@ -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 = &eth->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 = &eth->rx_ring_qdma;
- offset = 0x1000;
- } else {
- ring = &eth->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 = &eth->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 = &eth->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 = &eth->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, &eth->rx_ring[0]);
- mtk_rx_clean(eth, &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, &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(&reg, 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 */

View file

@ -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(&eth->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(&eth->rx_napi);
mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
mtk_rx_irq_enable(eth, MTK_RX_DONE_INT);
+
+ setup_timer(&eth->napi_timer, napi_timer_handler, (unsigned long) eth);
+ mod_timer(&eth->napi_timer, jiffies + NAPI_TIMER_EXPIRE);
}
atomic_inc(&eth->dma_refcnt);
@@ -1945,6 +1962,8 @@ static int mtk_stop(struct net_device *d
if (!atomic_dec_and_test(&eth->dma_refcnt))
return 0;
+ del_timer(&eth->napi_timer);
+
mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
mtk_rx_irq_disable(eth, MTK_RX_DONE_INT);
napi_disable(&eth->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

View file

@ -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(&eth->iface_lock);
+
/* we run 2 netdevs on the same dma ring so we only bring it up once */
if (!atomic_read(&eth->dma_refcnt)) {
int err = mtk_start_dma(eth);
- if (err)
+ if (err) {
+ spin_unlock(&eth->iface_lock);
return err;
+ }
napi_enable(&eth->tx_napi);
napi_enable(&eth->rx_napi);
@@ -1923,6 +1927,7 @@ static int mtk_open(struct net_device *d
phy_start(dev->phydev);
netif_start_queue(dev);
+ spin_unlock(&eth->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(&eth->iface_lock);
netif_tx_disable(dev);
phy_stop(dev->phydev);
/* only shutdown DMA if this is the last user */
- if (!atomic_dec_and_test(&eth->dma_refcnt))
+ if (!atomic_dec_and_test(&eth->dma_refcnt)) {
+ spin_unlock(&eth->iface_lock);
return 0;
+ }
del_timer(&eth->napi_timer);
@@ -1974,6 +1982,8 @@ static int mtk_stop(struct net_device *d
mtk_dma_free(eth);
+ spin_unlock(&eth->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(&eth->iface_lock);
spin_lock_init(&eth->page_lock);
spin_lock_init(&eth->tx_irq_lock);
spin_lock_init(&eth->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;

View file

@ -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);