mediatek: add support for the new MT7623 Arm SoC
the support is still WIP. next steps are to make the pmic and ethernet work. this is the first commit to make sure nothing gets lost. Signed-off-by: John Crispin <blogic@openwrt.org> SVN-Revision: 47354
This commit is contained in:
parent
12e0d2737f
commit
25afe99b31
20
target/linux/mediatek/Makefile
Normal file
20
target/linux/mediatek/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2015 OpenWrt.org
|
||||
#
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
ARCH:=arm
|
||||
BOARD:=mediatek
|
||||
BOARDNAME:=Mediatek Ralink ARM
|
||||
FEATURES:=squashfs
|
||||
CPU_TYPE:=cortex-a7
|
||||
MAINTAINER:=John Crispin <blogic@openwrt.org>
|
||||
|
||||
KERNEL_PATCHVER:=4.1
|
||||
|
||||
KERNELNAME:=Image dtbs zImage
|
||||
|
||||
include $(INCLUDE_DIR)/target.mk
|
||||
DEFAULT_PACKAGES += \
|
||||
kmod-leds-gpio kmod-gpio-button-hotplug swconfig
|
||||
|
||||
$(eval $(call BuildTarget))
|
3
target/linux/mediatek/base-files.mk
Normal file
3
target/linux/mediatek/base-files.mk
Normal file
@ -0,0 +1,3 @@
|
||||
define Package/base-files/install-target
|
||||
rm -f $(1)/etc/config/network
|
||||
endef
|
3
target/linux/mediatek/base-files/etc/inittab
Normal file
3
target/linux/mediatek/base-files/etc/inittab
Normal file
@ -0,0 +1,3 @@
|
||||
::sysinit:/etc/init.d/rcS S boot
|
||||
::shutdown:/etc/init.d/rcS K shutdown
|
||||
ttyS0::askfirst:/bin/ash --login
|
33
target/linux/mediatek/base-files/lib/mediatek.sh
Normal file
33
target/linux/mediatek/base-files/lib/mediatek.sh
Normal file
@ -0,0 +1,33 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (C) 2015 OpenWrt.org
|
||||
#
|
||||
|
||||
mediatek_board_detect() {
|
||||
local machine
|
||||
local name
|
||||
|
||||
machine=$(cat /proc/device-tree/model)
|
||||
|
||||
case "$machine" in
|
||||
"MediaTek MT7623 Evaluation Board")
|
||||
name="mt7623_evb"
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -z "$name" ] && name="unknown"
|
||||
|
||||
[ -e "/tmp/sysinfo/" ] || mkdir -p "/tmp/sysinfo/"
|
||||
|
||||
echo "$name" > /tmp/sysinfo/board_name
|
||||
echo "$machine" > /tmp/sysinfo/model
|
||||
}
|
||||
|
||||
mediatek_board_name() {
|
||||
local name
|
||||
|
||||
[ -f /tmp/sysinfo/board_name ] && name=$(cat /tmp/sysinfo/board_name)
|
||||
[ -z "$name" ] && name="unknown"
|
||||
|
||||
echo "$name"
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2014 The Linux Foundation. All rights reserved.
|
||||
#
|
||||
|
||||
do_mediatek() {
|
||||
. /lib/mediatek.sh
|
||||
|
||||
mediatek_board_detect
|
||||
}
|
||||
|
||||
boot_hook_add preinit_main do_mediatek
|
430
target/linux/mediatek/config-4.1
Normal file
430
target/linux/mediatek/config-4.1
Normal file
@ -0,0 +1,430 @@
|
||||
# CONFIG_AIO is not set
|
||||
CONFIG_ALIGNMENT_TRAP=y
|
||||
# CONFIG_APM_EMULATION is not set
|
||||
# CONFIG_ARCH_ALPINE is not set
|
||||
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
|
||||
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
|
||||
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
|
||||
CONFIG_ARCH_HAS_SG_CHAIN=y
|
||||
CONFIG_ARCH_HAS_TICK_BROADCAST=y
|
||||
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
|
||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
CONFIG_ARCH_MEDIATEK=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
|
||||
CONFIG_ARCH_MT7623=y
|
||||
CONFIG_ARCH_MULTIPLATFORM=y
|
||||
# CONFIG_ARCH_MULTI_CPU_AUTO is not set
|
||||
CONFIG_ARCH_MULTI_V6_V7=y
|
||||
CONFIG_ARCH_MULTI_V7=y
|
||||
CONFIG_ARCH_NR_GPIO=0
|
||||
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
|
||||
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
|
||||
CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
|
||||
CONFIG_ARCH_SUPPORTS_UPROBES=y
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
|
||||
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
|
||||
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
|
||||
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
|
||||
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ARM_APPENDED_DTB=y
|
||||
CONFIG_ARM_ARCH_TIMER=y
|
||||
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
|
||||
# CONFIG_ARM_ATAG_DTB_COMPAT is not set
|
||||
CONFIG_ARM_CPU_SUSPEND=y
|
||||
# CONFIG_ARM_CPU_TOPOLOGY is not set
|
||||
# CONFIG_ARM_CRYPTO 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_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_AUTO_ZRELADDR=y
|
||||
CONFIG_AVERAGE=y
|
||||
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
|
||||
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
|
||||
CONFIG_BOUNCE=y
|
||||
# CONFIG_CACHE_L2X0 is not set
|
||||
CONFIG_CLEANCACHE=y
|
||||
CONFIG_CLKDEV_LOOKUP=y
|
||||
CONFIG_CLKSRC_MMIO=y
|
||||
CONFIG_CLKSRC_OF=y
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_CMDLINE="earlyprintk console=ttyS0,115200"
|
||||
CONFIG_COMMON_CLK=y
|
||||
CONFIG_COMPACTION=y
|
||||
CONFIG_COREDUMP=y
|
||||
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_HAS_ASID=y
|
||||
# CONFIG_CPU_ICACHE_DISABLE is not set
|
||||
CONFIG_CPU_PABRT_V7=y
|
||||
CONFIG_CPU_PM=y
|
||||
CONFIG_CPU_RMAP=y
|
||||
CONFIG_CPU_TLB_V7=y
|
||||
CONFIG_CPU_V7=y
|
||||
CONFIG_CRC16=y
|
||||
# CONFIG_CRC32_SARWATE is not set
|
||||
CONFIG_CRC32_SLICEBY8=y
|
||||
CONFIG_CROSS_MEMORY_ATTACH=y
|
||||
CONFIG_CRYPTO_HW=y
|
||||
CONFIG_CRYPTO_XZ=y
|
||||
CONFIG_DCACHE_WORD_ACCESS=y
|
||||
CONFIG_DEBUG_BUGVERBOSE=y
|
||||
CONFIG_DEBUG_GPIO=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_LL=y
|
||||
CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
|
||||
# CONFIG_DEBUG_MT6589_UART0 is not set
|
||||
CONFIG_DEBUG_MT8127_UART0=y
|
||||
# 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_DECOMPRESS_GZIP=y
|
||||
CONFIG_DEVMEM=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_DMA_ENGINE=y
|
||||
CONFIG_DMA_OF=y
|
||||
CONFIG_DTC=y
|
||||
# CONFIG_DW_DMAC_PCI is not set
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
CONFIG_ELF_CORE=y
|
||||
CONFIG_ESW_DOUBLE_VLAN_TAG=y
|
||||
CONFIG_FREEZER=y
|
||||
CONFIG_GE1_RGMII_AN=y
|
||||
# CONFIG_GE1_RGMII_FORCE_1000 is not set
|
||||
# CONFIG_GE1_RGMII_NONE is not set
|
||||
# CONFIG_GE1_TRGMII_FORCE_2000 is not set
|
||||
# CONFIG_GE1_TRGMII_FORCE_2600 is not set
|
||||
CONFIG_GE2_INTERNAL_GPHY=y
|
||||
# CONFIG_GE2_MII_AN is not set
|
||||
# CONFIG_GE2_MII_FORCE_100 is not set
|
||||
# CONFIG_GE2_RGMII_AN is not set
|
||||
# CONFIG_GE2_RGMII_FORCE_1000 is not set
|
||||
# CONFIG_GE2_RVMII_FORCE_100 is not set
|
||||
CONFIG_GENERIC_ALLOCATOR=y
|
||||
CONFIG_GENERIC_BUG=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
|
||||
CONFIG_GENERIC_IDLE_POLL_SETUP=y
|
||||
CONFIG_GENERIC_IO=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
|
||||
CONFIG_GENERIC_MSI_IRQ=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_PHY=y
|
||||
CONFIG_GENERIC_PINCONF=y
|
||||
CONFIG_GENERIC_SCHED_CLOCK=y
|
||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GENERIC_STRNCPY_FROM_USER=y
|
||||
CONFIG_GENERIC_STRNLEN_USER=y
|
||||
CONFIG_GE_RGMII_INTERNAL_P0_AN=y
|
||||
CONFIG_GIGAPHY=y
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_DEVRES=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_HANDLE_DOMAIN_IRQ=y
|
||||
CONFIG_HARDIRQS_SW_RESEND=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT_MAP=y
|
||||
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
|
||||
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
|
||||
CONFIG_HAVE_ARCH_BITREVERSE=y
|
||||
CONFIG_HAVE_ARCH_JUMP_LABEL=y
|
||||
CONFIG_HAVE_ARCH_KGDB=y
|
||||
CONFIG_HAVE_ARCH_PFN_VALID=y
|
||||
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
|
||||
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
||||
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
|
||||
CONFIG_HAVE_BPF_JIT=y
|
||||
CONFIG_HAVE_CC_STACKPROTECTOR=y
|
||||
CONFIG_HAVE_CLK=y
|
||||
CONFIG_HAVE_CLK_PREPARE=y
|
||||
CONFIG_HAVE_CONTEXT_TRACKING=y
|
||||
CONFIG_HAVE_C_RECORDMCOUNT=y
|
||||
CONFIG_HAVE_DEBUG_KMEMLEAK=y
|
||||
CONFIG_HAVE_DMA_API_DEBUG=y
|
||||
CONFIG_HAVE_DMA_ATTRS=y
|
||||
CONFIG_HAVE_DMA_CONTIGUOUS=y
|
||||
CONFIG_HAVE_DYNAMIC_FTRACE=y
|
||||
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
|
||||
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
|
||||
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
|
||||
CONFIG_HAVE_FUNCTION_TRACER=y
|
||||
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
|
||||
CONFIG_HAVE_IDE=y
|
||||
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
|
||||
CONFIG_HAVE_KERNEL_GZIP=y
|
||||
CONFIG_HAVE_KERNEL_LZ4=y
|
||||
CONFIG_HAVE_KERNEL_LZMA=y
|
||||
CONFIG_HAVE_KERNEL_LZO=y
|
||||
CONFIG_HAVE_KERNEL_XZ=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_HSU_DMA_PCI is not set
|
||||
CONFIG_HWMON=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
# CONFIG_HW_SFQ is not set
|
||||
CONFIG_HZ_FIXED=0
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_MT65XX=y
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_IOMMU_HELPER=y
|
||||
# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
|
||||
CONFIG_IOMMU_SUPPORT=y
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_DOMAIN_HIERARCHY=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_KALLSYMS=y
|
||||
CONFIG_LAN_WAN_SUPPORT=y
|
||||
# CONFIG_LEDS_REGULATOR is not set
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_LOCKUP_DETECTOR=y
|
||||
CONFIG_LOCK_SPIN_ON_OWNER=y
|
||||
# CONFIG_LZ4_COMPRESS is not set
|
||||
# CONFIG_LZ4_DECOMPRESS is not set
|
||||
CONFIG_LZO_COMPRESS=y
|
||||
CONFIG_LZO_DECOMPRESS=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_MAC_TO_GIGAPHY_MODE_ADDR=0x1F
|
||||
CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2=0
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_MDIO_BITBANG=y
|
||||
CONFIG_MDIO_BOARDINFO=y
|
||||
CONFIG_MDIO_GPIO=y
|
||||
CONFIG_MEDIATEK_WATCHDOG=y
|
||||
# CONFIG_MFD_MAX77843 is not set
|
||||
# CONFIG_MFD_MT6323 is not set
|
||||
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_M25P80=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_MTK_INFRACFG=y
|
||||
CONFIG_MTK_PMIC_WRAP=y
|
||||
CONFIG_MTK_SCPSYS=y
|
||||
# CONFIG_MTK_SMB_HOOK is not set
|
||||
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_FLOW_LIMIT=y
|
||||
CONFIG_NLS=y
|
||||
CONFIG_NO_BOOTMEM=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_NO_HZ_COMMON=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_NR_CPUS=4
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_ADDRESS=y
|
||||
CONFIG_OF_ADDRESS_PCI=y
|
||||
CONFIG_OF_EARLY_FLATTREE=y
|
||||
CONFIG_OF_FLATTREE=y
|
||||
CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_OF_MTD=y
|
||||
CONFIG_OF_NET=y
|
||||
CONFIG_OF_PCI=y
|
||||
CONFIG_OF_PCI_IRQ=y
|
||||
CONFIG_OF_RESERVED_MEM=y
|
||||
CONFIG_OLD_SIGACTION=y
|
||||
CONFIG_OLD_SIGSUSPEND3=y
|
||||
CONFIG_PAGEFLAGS_EXTENDED=y
|
||||
CONFIG_PAGE_OFFSET=0xC0000000
|
||||
CONFIG_PCI=y
|
||||
# CONFIG_PCIE_IPROC is not set
|
||||
# CONFIG_PCI_DOMAINS_GENERIC is not set
|
||||
CONFIG_PCI_MSI=y
|
||||
CONFIG_PDMA_NEW=y
|
||||
CONFIG_PERF_USE_VMALLOC=y
|
||||
CONFIG_PGTABLE_LEVELS=2
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PINCTRL=y
|
||||
# CONFIG_PINCTRL_AMD is not set
|
||||
# CONFIG_PINCTRL_MT6397 is not set
|
||||
CONFIG_PINCTRL_MT7623=y
|
||||
CONFIG_PINCTRL_MT8127=y
|
||||
# CONFIG_PINCTRL_MT8135 is not set
|
||||
CONFIG_PINCTRL_MTK_COMMON=y
|
||||
CONFIG_PM=y
|
||||
CONFIG_PM_CLK=y
|
||||
# CONFIG_PM_DEBUG is not set
|
||||
CONFIG_PM_SLEEP=y
|
||||
CONFIG_PM_SLEEP_SMP=y
|
||||
CONFIG_POWER_RESET=y
|
||||
# CONFIG_POWER_RESET_BRCMSTB is not set
|
||||
# CONFIG_POWER_RESET_GPIO is not set
|
||||
# CONFIG_POWER_RESET_GPIO_RESTART is not set
|
||||
# CONFIG_POWER_RESET_LTC2952 is not set
|
||||
# CONFIG_POWER_RESET_SYSCON is not set
|
||||
# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set
|
||||
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_RAETH=y
|
||||
CONFIG_RAETH_CHECKSUM_OFFLOAD=y
|
||||
# CONFIG_RAETH_DVT is not set
|
||||
CONFIG_RAETH_GMAC2=y
|
||||
# CONFIG_RAETH_HW_LRO is not set
|
||||
# CONFIG_RAETH_HW_VLAN_TX is not set
|
||||
# CONFIG_RAETH_LRO is not set
|
||||
# CONFIG_RAETH_NAPI is not set
|
||||
CONFIG_RAETH_QDMA=y
|
||||
CONFIG_RAETH_QDMATX_QDMARX=y
|
||||
CONFIG_RAETH_SCATTER_GATHER_RX_DMA=y
|
||||
# CONFIG_RAETH_SKB_RECYCLE_2K is not set
|
||||
# CONFIG_RAETH_SPECIAL_TAG is not set
|
||||
# CONFIG_RAETH_TSO is not set
|
||||
CONFIG_RA_NAT_NONE=y
|
||||
# CONFIG_RA_NETWORK_TASKLET_BH is not set
|
||||
CONFIG_RA_NETWORK_WORKQUEUE_BH=y
|
||||
# CONFIG_RCU_BOOST is not set
|
||||
CONFIG_RCU_CPU_STALL_TIMEOUT=21
|
||||
# CONFIG_RCU_EXPEDITE_BOOT is not set
|
||||
CONFIG_RCU_STALL_COMMON=y
|
||||
CONFIG_RD_GZIP=y
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_REGMAP_MMIO=y
|
||||
CONFIG_REGULATOR=y
|
||||
# CONFIG_REGULATOR_DEBUG is not set
|
||||
# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
CONFIG_RFS_ACCEL=y
|
||||
CONFIG_RPS=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
# CONFIG_RTC_DRV_ABX80X is not set
|
||||
# CONFIG_RTC_DRV_CMOS is not set
|
||||
CONFIG_RT_3052_ESW=y
|
||||
CONFIG_RWSEM_SPIN_ON_OWNER=y
|
||||
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
|
||||
CONFIG_SCHED_HRTICK=y
|
||||
# CONFIG_SCSI_DMA is not set
|
||||
# CONFIG_SERIAL_8250_DMA is not set
|
||||
CONFIG_SERIAL_8250_MT6577=y
|
||||
CONFIG_SERIAL_8250_NR_UARTS=4
|
||||
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
|
||||
# CONFIG_SLAB is not set
|
||||
CONFIG_SLUB=y
|
||||
CONFIG_SLUB_CPU_PARTIAL=y
|
||||
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_STOP_MACHINE=y
|
||||
# CONFIG_STRIP_ASM_SYMS is not set
|
||||
CONFIG_SUSPEND=y
|
||||
CONFIG_SUSPEND_FREEZER=y
|
||||
CONFIG_SWCONFIG=y
|
||||
CONFIG_SWIOTLB=y
|
||||
CONFIG_SWP_EMULATE=y
|
||||
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
|
||||
CONFIG_THERMAL=y
|
||||
# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
|
||||
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
|
||||
# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
|
||||
# CONFIG_THERMAL_EMULATION is not set
|
||||
# CONFIG_THERMAL_GOV_FAIR_SHARE is not set
|
||||
CONFIG_THERMAL_GOV_STEP_WISE=y
|
||||
# CONFIG_THERMAL_GOV_USER_SPACE is not set
|
||||
CONFIG_THERMAL_HWMON=y
|
||||
CONFIG_THERMAL_OF=y
|
||||
# CONFIG_THUMB2_KERNEL is not set
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TIMER_STATS=y
|
||||
CONFIG_UEVENT_HELPER_PATH=""
|
||||
CONFIG_UID16=y
|
||||
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_MT65XX_USB3_PHY=y
|
||||
CONFIG_USB_PHY=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
# CONFIG_USB_UHCI_HCD is not set
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_XHCI_MTK=y
|
||||
CONFIG_USB_XHCI_PCI=y
|
||||
CONFIG_USB_XHCI_PLATFORM=y
|
||||
CONFIG_USE_OF=y
|
||||
# CONFIG_VDSO is not set
|
||||
CONFIG_VECTORS_BASE=0xffff0000
|
||||
CONFIG_VFP=y
|
||||
CONFIG_VFPv3=y
|
||||
CONFIG_VM_EVENT_COUNTERS=y
|
||||
CONFIG_WAN_AT_P0=y
|
||||
# CONFIG_WAN_AT_P4 is not set
|
||||
CONFIG_WATCHDOG_CORE=y
|
||||
# CONFIG_XEN is not set
|
||||
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_INFLATE=y
|
||||
CONFIG_ZONE_DMA_FLAG=0
|
28
target/linux/mediatek/image/Makefile
Normal file
28
target/linux/mediatek/image/Makefile
Normal file
@ -0,0 +1,28 @@
|
||||
# Copyright (c) 2014 The Linux Foundation. All rights reserved.
|
||||
#
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/image.mk
|
||||
|
||||
define Image/BuilduImage
|
||||
cat $(LINUX_DIR)/arch/arm/boot/dts/mt7623-evb.dtb >> $(KDIR)/zImage$(1)
|
||||
$(STAGING_DIR_HOST)/bin/lzma e $(KDIR)/zImage$(1) $(KDIR)/zImage$(1).lzma
|
||||
mkimage -A arm -O linux -T kernel -C lzma -a 0x80008000 -e 0x80008000 -n 'MIPS OpenWrt Linux-$(LINUX_VERSION)' -d $(KDIR)/zImage$(1).lzma $(KDIR)/uImage$(1)
|
||||
$(CP) $(KDIR)/uImage$(1) $(BIN_DIR)/$(IMG_PREFIX)-uImage$(1)
|
||||
endef
|
||||
|
||||
define Image/BuildKernel
|
||||
$(call Image/BuilduImage)
|
||||
ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),)
|
||||
$(call Image/BuilduImage,-initramfs)
|
||||
endif
|
||||
endef
|
||||
|
||||
define Image/Build/squashfs
|
||||
$(call prepare_generic_squashfs,$(KDIR)/root.squashfs)
|
||||
endef
|
||||
|
||||
define Image/Build
|
||||
$(call Image/Build/$(1),$(1))
|
||||
endef
|
||||
|
||||
$(eval $(call BuildImage))
|
@ -0,0 +1,100 @@
|
||||
From a38e86708141d75c643ffd58865c50a925134e4f Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Thu, 23 Apr 2015 10:35:38 +0200
|
||||
Subject: [PATCH 01/76] clk: make strings in parent name arrays const
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The clk functions and structs declare the parent_name arrays as
|
||||
'const char **parent_names' which means the parent name strings
|
||||
are const, but the array itself is not. Use
|
||||
'const char * const * parent_names' instead which also makes
|
||||
the array const. This allows us to put the parent_name arrays into
|
||||
the __initconst section.
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
|
||||
Tested-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
|
||||
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
|
||||
---
|
||||
drivers/clk/clk-composite.c | 2 +-
|
||||
drivers/clk/clk-mux.c | 4 ++--
|
||||
include/linux/clk-provider.h | 8 ++++----
|
||||
3 files changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
|
||||
index 956b7e5..077f4c7 100644
|
||||
--- a/drivers/clk/clk-composite.c
|
||||
+++ b/drivers/clk/clk-composite.c
|
||||
@@ -188,7 +188,7 @@ static void clk_composite_disable(struct clk_hw *hw)
|
||||
}
|
||||
|
||||
struct clk *clk_register_composite(struct device *dev, const char *name,
|
||||
- const char **parent_names, int num_parents,
|
||||
+ const char * const *parent_names, int num_parents,
|
||||
struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
|
||||
struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
|
||||
struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
|
||||
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
|
||||
index 69a094c..1fa2a8d 100644
|
||||
--- a/drivers/clk/clk-mux.c
|
||||
+++ b/drivers/clk/clk-mux.c
|
||||
@@ -114,7 +114,7 @@ const struct clk_ops clk_mux_ro_ops = {
|
||||
EXPORT_SYMBOL_GPL(clk_mux_ro_ops);
|
||||
|
||||
struct clk *clk_register_mux_table(struct device *dev, const char *name,
|
||||
- const char **parent_names, u8 num_parents, unsigned long flags,
|
||||
+ const char * const *parent_names, u8 num_parents, unsigned long flags,
|
||||
void __iomem *reg, u8 shift, u32 mask,
|
||||
u8 clk_mux_flags, u32 *table, spinlock_t *lock)
|
||||
{
|
||||
@@ -166,7 +166,7 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
|
||||
EXPORT_SYMBOL_GPL(clk_register_mux_table);
|
||||
|
||||
struct clk *clk_register_mux(struct device *dev, const char *name,
|
||||
- const char **parent_names, u8 num_parents, unsigned long flags,
|
||||
+ const char * const *parent_names, u8 num_parents, unsigned long flags,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
u8 clk_mux_flags, spinlock_t *lock)
|
||||
{
|
||||
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
|
||||
index df69531..ec609e5 100644
|
||||
--- a/include/linux/clk-provider.h
|
||||
+++ b/include/linux/clk-provider.h
|
||||
@@ -209,7 +209,7 @@ struct clk_ops {
|
||||
struct clk_init_data {
|
||||
const char *name;
|
||||
const struct clk_ops *ops;
|
||||
- const char **parent_names;
|
||||
+ const char * const *parent_names;
|
||||
u8 num_parents;
|
||||
unsigned long flags;
|
||||
};
|
||||
@@ -426,12 +426,12 @@ extern const struct clk_ops clk_mux_ops;
|
||||
extern const struct clk_ops clk_mux_ro_ops;
|
||||
|
||||
struct clk *clk_register_mux(struct device *dev, const char *name,
|
||||
- const char **parent_names, u8 num_parents, unsigned long flags,
|
||||
+ const char * const *parent_names, u8 num_parents, unsigned long flags,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
u8 clk_mux_flags, spinlock_t *lock);
|
||||
|
||||
struct clk *clk_register_mux_table(struct device *dev, const char *name,
|
||||
- const char **parent_names, u8 num_parents, unsigned long flags,
|
||||
+ const char * const *parent_names, u8 num_parents, unsigned long flags,
|
||||
void __iomem *reg, u8 shift, u32 mask,
|
||||
u8 clk_mux_flags, u32 *table, spinlock_t *lock);
|
||||
|
||||
@@ -518,7 +518,7 @@ struct clk_composite {
|
||||
};
|
||||
|
||||
struct clk *clk_register_composite(struct device *dev, const char *name,
|
||||
- const char **parent_names, int num_parents,
|
||||
+ const char * const *parent_names, int num_parents,
|
||||
struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
|
||||
struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
|
||||
struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,977 @@
|
||||
From f851b4ea6cae9fd5875036b6d3968375882ce56b Mon Sep 17 00:00:00 2001
|
||||
From: James Liao <jamesjj.liao@mediatek.com>
|
||||
Date: Thu, 23 Apr 2015 10:35:39 +0200
|
||||
Subject: [PATCH 02/76] clk: mediatek: Add initial common clock support for
|
||||
Mediatek SoCs.
|
||||
|
||||
This patch adds common clock support for Mediatek SoCs, including plls,
|
||||
muxes and clock gates.
|
||||
|
||||
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
|
||||
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
---
|
||||
drivers/clk/Makefile | 1 +
|
||||
drivers/clk/mediatek/Makefile | 1 +
|
||||
drivers/clk/mediatek/clk-gate.c | 137 ++++++++++++++++
|
||||
drivers/clk/mediatek/clk-gate.h | 49 ++++++
|
||||
drivers/clk/mediatek/clk-mtk.c | 220 ++++++++++++++++++++++++++
|
||||
drivers/clk/mediatek/clk-mtk.h | 159 +++++++++++++++++++
|
||||
drivers/clk/mediatek/clk-pll.c | 332 +++++++++++++++++++++++++++++++++++++++
|
||||
7 files changed, 899 insertions(+)
|
||||
create mode 100644 drivers/clk/mediatek/Makefile
|
||||
create mode 100644 drivers/clk/mediatek/clk-gate.c
|
||||
create mode 100644 drivers/clk/mediatek/clk-gate.h
|
||||
create mode 100644 drivers/clk/mediatek/clk-mtk.c
|
||||
create mode 100644 drivers/clk/mediatek/clk-mtk.h
|
||||
create mode 100644 drivers/clk/mediatek/clk-pll.c
|
||||
|
||||
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
|
||||
index 3d00c25..d965b3f 100644
|
||||
--- a/drivers/clk/Makefile
|
||||
+++ b/drivers/clk/Makefile
|
||||
@@ -51,6 +51,7 @@ obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/
|
||||
obj-$(CONFIG_ARCH_HIP04) += hisilicon/
|
||||
obj-$(CONFIG_ARCH_HIX5HD2) += hisilicon/
|
||||
obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/
|
||||
+obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
|
||||
ifeq ($(CONFIG_COMMON_CLK), y)
|
||||
obj-$(CONFIG_ARCH_MMP) += mmp/
|
||||
endif
|
||||
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
|
||||
new file mode 100644
|
||||
index 0000000..c384e97
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/mediatek/Makefile
|
||||
@@ -0,0 +1 @@
|
||||
+obj-y += clk-mtk.o clk-pll.o clk-gate.o
|
||||
diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
|
||||
new file mode 100644
|
||||
index 0000000..9d77ee3
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/mediatek/clk-gate.c
|
||||
@@ -0,0 +1,137 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2014 MediaTek Inc.
|
||||
+ * Author: James Liao <jamesjj.liao@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_address.h>
|
||||
+
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/clkdev.h>
|
||||
+
|
||||
+#include "clk-mtk.h"
|
||||
+#include "clk-gate.h"
|
||||
+
|
||||
+static int mtk_cg_bit_is_cleared(struct clk_hw *hw)
|
||||
+{
|
||||
+ struct mtk_clk_gate *cg = to_clk_gate(hw);
|
||||
+ u32 val;
|
||||
+
|
||||
+ regmap_read(cg->regmap, cg->sta_ofs, &val);
|
||||
+
|
||||
+ val &= BIT(cg->bit);
|
||||
+
|
||||
+ return val == 0;
|
||||
+}
|
||||
+
|
||||
+static int mtk_cg_bit_is_set(struct clk_hw *hw)
|
||||
+{
|
||||
+ struct mtk_clk_gate *cg = to_clk_gate(hw);
|
||||
+ u32 val;
|
||||
+
|
||||
+ regmap_read(cg->regmap, cg->sta_ofs, &val);
|
||||
+
|
||||
+ val &= BIT(cg->bit);
|
||||
+
|
||||
+ return val != 0;
|
||||
+}
|
||||
+
|
||||
+static void mtk_cg_set_bit(struct clk_hw *hw)
|
||||
+{
|
||||
+ struct mtk_clk_gate *cg = to_clk_gate(hw);
|
||||
+
|
||||
+ regmap_write(cg->regmap, cg->set_ofs, BIT(cg->bit));
|
||||
+}
|
||||
+
|
||||
+static void mtk_cg_clr_bit(struct clk_hw *hw)
|
||||
+{
|
||||
+ struct mtk_clk_gate *cg = to_clk_gate(hw);
|
||||
+
|
||||
+ regmap_write(cg->regmap, cg->clr_ofs, BIT(cg->bit));
|
||||
+}
|
||||
+
|
||||
+static int mtk_cg_enable(struct clk_hw *hw)
|
||||
+{
|
||||
+ mtk_cg_clr_bit(hw);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mtk_cg_disable(struct clk_hw *hw)
|
||||
+{
|
||||
+ mtk_cg_set_bit(hw);
|
||||
+}
|
||||
+
|
||||
+static int mtk_cg_enable_inv(struct clk_hw *hw)
|
||||
+{
|
||||
+ mtk_cg_set_bit(hw);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mtk_cg_disable_inv(struct clk_hw *hw)
|
||||
+{
|
||||
+ mtk_cg_clr_bit(hw);
|
||||
+}
|
||||
+
|
||||
+const struct clk_ops mtk_clk_gate_ops_setclr = {
|
||||
+ .is_enabled = mtk_cg_bit_is_cleared,
|
||||
+ .enable = mtk_cg_enable,
|
||||
+ .disable = mtk_cg_disable,
|
||||
+};
|
||||
+
|
||||
+const struct clk_ops mtk_clk_gate_ops_setclr_inv = {
|
||||
+ .is_enabled = mtk_cg_bit_is_set,
|
||||
+ .enable = mtk_cg_enable_inv,
|
||||
+ .disable = mtk_cg_disable_inv,
|
||||
+};
|
||||
+
|
||||
+struct clk *mtk_clk_register_gate(
|
||||
+ const char *name,
|
||||
+ const char *parent_name,
|
||||
+ struct regmap *regmap,
|
||||
+ int set_ofs,
|
||||
+ int clr_ofs,
|
||||
+ int sta_ofs,
|
||||
+ u8 bit,
|
||||
+ const struct clk_ops *ops)
|
||||
+{
|
||||
+ struct mtk_clk_gate *cg;
|
||||
+ struct clk *clk;
|
||||
+ struct clk_init_data init;
|
||||
+
|
||||
+ cg = kzalloc(sizeof(*cg), GFP_KERNEL);
|
||||
+ if (!cg)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ init.name = name;
|
||||
+ init.flags = CLK_SET_RATE_PARENT;
|
||||
+ init.parent_names = parent_name ? &parent_name : NULL;
|
||||
+ init.num_parents = parent_name ? 1 : 0;
|
||||
+ init.ops = ops;
|
||||
+
|
||||
+ cg->regmap = regmap;
|
||||
+ cg->set_ofs = set_ofs;
|
||||
+ cg->clr_ofs = clr_ofs;
|
||||
+ cg->sta_ofs = sta_ofs;
|
||||
+ cg->bit = bit;
|
||||
+
|
||||
+ cg->hw.init = &init;
|
||||
+
|
||||
+ clk = clk_register(NULL, &cg->hw);
|
||||
+ if (IS_ERR(clk))
|
||||
+ kfree(cg);
|
||||
+
|
||||
+ return clk;
|
||||
+}
|
||||
diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h
|
||||
new file mode 100644
|
||||
index 0000000..6b6780b
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/mediatek/clk-gate.h
|
||||
@@ -0,0 +1,49 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2014 MediaTek Inc.
|
||||
+ * Author: James Liao <jamesjj.liao@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __DRV_CLK_GATE_H
|
||||
+#define __DRV_CLK_GATE_H
|
||||
+
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/clk-provider.h>
|
||||
+
|
||||
+struct mtk_clk_gate {
|
||||
+ struct clk_hw hw;
|
||||
+ struct regmap *regmap;
|
||||
+ int set_ofs;
|
||||
+ int clr_ofs;
|
||||
+ int sta_ofs;
|
||||
+ u8 bit;
|
||||
+};
|
||||
+
|
||||
+static inline struct mtk_clk_gate *to_clk_gate(struct clk_hw *hw)
|
||||
+{
|
||||
+ return container_of(hw, struct mtk_clk_gate, hw);
|
||||
+}
|
||||
+
|
||||
+extern const struct clk_ops mtk_clk_gate_ops_setclr;
|
||||
+extern const struct clk_ops mtk_clk_gate_ops_setclr_inv;
|
||||
+
|
||||
+struct clk *mtk_clk_register_gate(
|
||||
+ const char *name,
|
||||
+ const char *parent_name,
|
||||
+ struct regmap *regmap,
|
||||
+ int set_ofs,
|
||||
+ int clr_ofs,
|
||||
+ int sta_ofs,
|
||||
+ u8 bit,
|
||||
+ const struct clk_ops *ops);
|
||||
+
|
||||
+#endif /* __DRV_CLK_GATE_H */
|
||||
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
|
||||
new file mode 100644
|
||||
index 0000000..18444ae
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/mediatek/clk-mtk.c
|
||||
@@ -0,0 +1,220 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2014 MediaTek Inc.
|
||||
+ * Author: James Liao <jamesjj.liao@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/clkdev.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+
|
||||
+#include "clk-mtk.h"
|
||||
+#include "clk-gate.h"
|
||||
+
|
||||
+struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
|
||||
+{
|
||||
+ int i;
|
||||
+ struct clk_onecell_data *clk_data;
|
||||
+
|
||||
+ clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
|
||||
+ if (!clk_data)
|
||||
+ return NULL;
|
||||
+
|
||||
+ clk_data->clks = kcalloc(clk_num, sizeof(*clk_data->clks), GFP_KERNEL);
|
||||
+ if (!clk_data->clks)
|
||||
+ goto err_out;
|
||||
+
|
||||
+ clk_data->clk_num = clk_num;
|
||||
+
|
||||
+ for (i = 0; i < clk_num; i++)
|
||||
+ clk_data->clks[i] = ERR_PTR(-ENOENT);
|
||||
+
|
||||
+ return clk_data;
|
||||
+err_out:
|
||||
+ kfree(clk_data);
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
|
||||
+ struct clk_onecell_data *clk_data)
|
||||
+{
|
||||
+ int i;
|
||||
+ struct clk *clk;
|
||||
+
|
||||
+ for (i = 0; i < num; i++) {
|
||||
+ const struct mtk_fixed_factor *ff = &clks[i];
|
||||
+
|
||||
+ clk = clk_register_fixed_factor(NULL, ff->name, ff->parent_name,
|
||||
+ CLK_SET_RATE_PARENT, ff->mult, ff->div);
|
||||
+
|
||||
+ if (IS_ERR(clk)) {
|
||||
+ pr_err("Failed to register clk %s: %ld\n",
|
||||
+ ff->name, PTR_ERR(clk));
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (clk_data)
|
||||
+ clk_data->clks[ff->id] = clk;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks,
|
||||
+ int num, struct clk_onecell_data *clk_data)
|
||||
+{
|
||||
+ int i;
|
||||
+ struct clk *clk;
|
||||
+ struct regmap *regmap;
|
||||
+
|
||||
+ if (!clk_data)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ 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_gate *gate = &clks[i];
|
||||
+
|
||||
+ clk = mtk_clk_register_gate(gate->name, gate->parent_name,
|
||||
+ regmap,
|
||||
+ gate->regs->set_ofs,
|
||||
+ gate->regs->clr_ofs,
|
||||
+ gate->regs->sta_ofs,
|
||||
+ gate->shift, gate->ops);
|
||||
+
|
||||
+ if (IS_ERR(clk)) {
|
||||
+ pr_err("Failed to register clk %s: %ld\n",
|
||||
+ gate->name, PTR_ERR(clk));
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ clk_data->clks[gate->id] = clk;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
|
||||
+ void __iomem *base, spinlock_t *lock)
|
||||
+{
|
||||
+ struct clk *clk;
|
||||
+ struct clk_mux *mux = NULL;
|
||||
+ struct clk_gate *gate = NULL;
|
||||
+ struct clk_divider *div = NULL;
|
||||
+ struct clk_hw *mux_hw = NULL, *gate_hw = NULL, *div_hw = NULL;
|
||||
+ const struct clk_ops *mux_ops = NULL, *gate_ops = NULL, *div_ops = NULL;
|
||||
+ const char * const *parent_names;
|
||||
+ const char *parent;
|
||||
+ int num_parents;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (mc->mux_shift >= 0) {
|
||||
+ mux = kzalloc(sizeof(*mux), GFP_KERNEL);
|
||||
+ if (!mux)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ mux->reg = base + mc->mux_reg;
|
||||
+ mux->mask = BIT(mc->mux_width) - 1;
|
||||
+ mux->shift = mc->mux_shift;
|
||||
+ mux->lock = lock;
|
||||
+
|
||||
+ mux_hw = &mux->hw;
|
||||
+ mux_ops = &clk_mux_ops;
|
||||
+
|
||||
+ parent_names = mc->parent_names;
|
||||
+ num_parents = mc->num_parents;
|
||||
+ } else {
|
||||
+ parent = mc->parent;
|
||||
+ parent_names = &parent;
|
||||
+ num_parents = 1;
|
||||
+ }
|
||||
+
|
||||
+ if (mc->gate_shift >= 0) {
|
||||
+ gate = kzalloc(sizeof(*gate), GFP_KERNEL);
|
||||
+ if (!gate) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_out;
|
||||
+ }
|
||||
+
|
||||
+ gate->reg = base + mc->gate_reg;
|
||||
+ gate->bit_idx = mc->gate_shift;
|
||||
+ gate->flags = CLK_GATE_SET_TO_DISABLE;
|
||||
+ gate->lock = lock;
|
||||
+
|
||||
+ gate_hw = &gate->hw;
|
||||
+ gate_ops = &clk_gate_ops;
|
||||
+ }
|
||||
+
|
||||
+ if (mc->divider_shift >= 0) {
|
||||
+ div = kzalloc(sizeof(*div), GFP_KERNEL);
|
||||
+ if (!div) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_out;
|
||||
+ }
|
||||
+
|
||||
+ div->reg = base + mc->divider_reg;
|
||||
+ div->shift = mc->divider_shift;
|
||||
+ div->width = mc->divider_width;
|
||||
+ div->lock = lock;
|
||||
+
|
||||
+ div_hw = &div->hw;
|
||||
+ div_ops = &clk_divider_ops;
|
||||
+ }
|
||||
+
|
||||
+ clk = clk_register_composite(NULL, mc->name, parent_names, num_parents,
|
||||
+ mux_hw, mux_ops,
|
||||
+ div_hw, div_ops,
|
||||
+ gate_hw, gate_ops,
|
||||
+ mc->flags);
|
||||
+
|
||||
+ if (IS_ERR(clk)) {
|
||||
+ kfree(gate);
|
||||
+ kfree(mux);
|
||||
+ }
|
||||
+
|
||||
+ return clk;
|
||||
+err_out:
|
||||
+ kfree(mux);
|
||||
+
|
||||
+ return ERR_PTR(ret);
|
||||
+}
|
||||
+
|
||||
+void mtk_clk_register_composites(const struct mtk_composite *mcs,
|
||||
+ int num, void __iomem *base, spinlock_t *lock,
|
||||
+ struct clk_onecell_data *clk_data)
|
||||
+{
|
||||
+ struct clk *clk;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < num; i++) {
|
||||
+ const struct mtk_composite *mc = &mcs[i];
|
||||
+
|
||||
+ clk = mtk_clk_register_composite(mc, base, lock);
|
||||
+
|
||||
+ if (IS_ERR(clk)) {
|
||||
+ pr_err("Failed to register clk %s: %ld\n",
|
||||
+ mc->name, PTR_ERR(clk));
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (clk_data)
|
||||
+ clk_data->clks[mc->id] = clk;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
|
||||
new file mode 100644
|
||||
index 0000000..694fc39
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/mediatek/clk-mtk.h
|
||||
@@ -0,0 +1,159 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2014 MediaTek Inc.
|
||||
+ * Author: James Liao <jamesjj.liao@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __DRV_CLK_MTK_H
|
||||
+#define __DRV_CLK_MTK_H
|
||||
+
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/bitops.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/clk-provider.h>
|
||||
+
|
||||
+#define MAX_MUX_GATE_BIT 31
|
||||
+#define INVALID_MUX_GATE_BIT (MAX_MUX_GATE_BIT + 1)
|
||||
+
|
||||
+#define MHZ (1000 * 1000)
|
||||
+
|
||||
+struct mtk_fixed_factor {
|
||||
+ int id;
|
||||
+ const char *name;
|
||||
+ const char *parent_name;
|
||||
+ int mult;
|
||||
+ int div;
|
||||
+};
|
||||
+
|
||||
+#define FACTOR(_id, _name, _parent, _mult, _div) { \
|
||||
+ .id = _id, \
|
||||
+ .name = _name, \
|
||||
+ .parent_name = _parent, \
|
||||
+ .mult = _mult, \
|
||||
+ .div = _div, \
|
||||
+ }
|
||||
+
|
||||
+extern void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
|
||||
+ int num, struct clk_onecell_data *clk_data);
|
||||
+
|
||||
+struct mtk_composite {
|
||||
+ int id;
|
||||
+ const char *name;
|
||||
+ const char * const * parent_names;
|
||||
+ const char *parent;
|
||||
+ unsigned flags;
|
||||
+
|
||||
+ uint32_t mux_reg;
|
||||
+ uint32_t divider_reg;
|
||||
+ uint32_t gate_reg;
|
||||
+
|
||||
+ signed char mux_shift;
|
||||
+ signed char mux_width;
|
||||
+ signed char gate_shift;
|
||||
+
|
||||
+ signed char divider_shift;
|
||||
+ signed char divider_width;
|
||||
+
|
||||
+ signed char num_parents;
|
||||
+};
|
||||
+
|
||||
+#define MUX_GATE(_id, _name, _parents, _reg, _shift, _width, _gate) { \
|
||||
+ .id = _id, \
|
||||
+ .name = _name, \
|
||||
+ .mux_reg = _reg, \
|
||||
+ .mux_shift = _shift, \
|
||||
+ .mux_width = _width, \
|
||||
+ .gate_reg = _reg, \
|
||||
+ .gate_shift = _gate, \
|
||||
+ .divider_shift = -1, \
|
||||
+ .parent_names = _parents, \
|
||||
+ .num_parents = ARRAY_SIZE(_parents), \
|
||||
+ .flags = CLK_SET_RATE_PARENT, \
|
||||
+ }
|
||||
+
|
||||
+#define MUX(_id, _name, _parents, _reg, _shift, _width) { \
|
||||
+ .id = _id, \
|
||||
+ .name = _name, \
|
||||
+ .mux_reg = _reg, \
|
||||
+ .mux_shift = _shift, \
|
||||
+ .mux_width = _width, \
|
||||
+ .gate_shift = -1, \
|
||||
+ .divider_shift = -1, \
|
||||
+ .parent_names = _parents, \
|
||||
+ .num_parents = ARRAY_SIZE(_parents), \
|
||||
+ .flags = CLK_SET_RATE_PARENT, \
|
||||
+ }
|
||||
+
|
||||
+#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, _div_width, _div_shift) { \
|
||||
+ .id = _id, \
|
||||
+ .parent = _parent, \
|
||||
+ .name = _name, \
|
||||
+ .divider_reg = _div_reg, \
|
||||
+ .divider_shift = _div_shift, \
|
||||
+ .divider_width = _div_width, \
|
||||
+ .gate_reg = _gate_reg, \
|
||||
+ .gate_shift = _gate_shift, \
|
||||
+ .mux_shift = -1, \
|
||||
+ .flags = 0, \
|
||||
+ }
|
||||
+
|
||||
+struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
|
||||
+ void __iomem *base, spinlock_t *lock);
|
||||
+
|
||||
+void mtk_clk_register_composites(const struct mtk_composite *mcs,
|
||||
+ int num, void __iomem *base, spinlock_t *lock,
|
||||
+ struct clk_onecell_data *clk_data);
|
||||
+
|
||||
+struct mtk_gate_regs {
|
||||
+ u32 sta_ofs;
|
||||
+ u32 clr_ofs;
|
||||
+ u32 set_ofs;
|
||||
+};
|
||||
+
|
||||
+struct mtk_gate {
|
||||
+ int id;
|
||||
+ const char *name;
|
||||
+ const char *parent_name;
|
||||
+ const struct mtk_gate_regs *regs;
|
||||
+ int shift;
|
||||
+ const struct clk_ops *ops;
|
||||
+};
|
||||
+
|
||||
+int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks,
|
||||
+ int num, struct clk_onecell_data *clk_data);
|
||||
+
|
||||
+struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num);
|
||||
+
|
||||
+#define HAVE_RST_BAR BIT(0)
|
||||
+
|
||||
+struct mtk_pll_data {
|
||||
+ int id;
|
||||
+ const char *name;
|
||||
+ uint32_t reg;
|
||||
+ uint32_t pwr_reg;
|
||||
+ uint32_t en_mask;
|
||||
+ uint32_t pd_reg;
|
||||
+ uint32_t tuner_reg;
|
||||
+ int pd_shift;
|
||||
+ unsigned int flags;
|
||||
+ const struct clk_ops *ops;
|
||||
+ u32 rst_bar_mask;
|
||||
+ unsigned long fmax;
|
||||
+ int pcwbits;
|
||||
+ uint32_t pcw_reg;
|
||||
+ int pcw_shift;
|
||||
+};
|
||||
+
|
||||
+void __init mtk_clk_register_plls(struct device_node *node,
|
||||
+ const struct mtk_pll_data *plls, int num_plls,
|
||||
+ struct clk_onecell_data *clk_data);
|
||||
+
|
||||
+#endif /* __DRV_CLK_MTK_H */
|
||||
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
|
||||
new file mode 100644
|
||||
index 0000000..66154ca
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/mediatek/clk-pll.c
|
||||
@@ -0,0 +1,332 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2014 MediaTek Inc.
|
||||
+ * Author: James Liao <jamesjj.liao@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/clkdev.h>
|
||||
+#include <linux/delay.h>
|
||||
+
|
||||
+#include "clk-mtk.h"
|
||||
+
|
||||
+#define REG_CON0 0
|
||||
+#define REG_CON1 4
|
||||
+
|
||||
+#define CON0_BASE_EN BIT(0)
|
||||
+#define CON0_PWR_ON BIT(0)
|
||||
+#define CON0_ISO_EN BIT(1)
|
||||
+#define CON0_PCW_CHG BIT(31)
|
||||
+
|
||||
+#define AUDPLL_TUNER_EN BIT(31)
|
||||
+
|
||||
+#define POSTDIV_MASK 0x7
|
||||
+#define INTEGER_BITS 7
|
||||
+
|
||||
+/*
|
||||
+ * MediaTek PLLs are configured through their pcw value. The pcw value describes
|
||||
+ * a divider in the PLL feedback loop which consists of 7 bits for the integer
|
||||
+ * part and the remaining bits (if present) for the fractional part. Also they
|
||||
+ * have a 3 bit power-of-two post divider.
|
||||
+ */
|
||||
+
|
||||
+struct mtk_clk_pll {
|
||||
+ struct clk_hw hw;
|
||||
+ void __iomem *base_addr;
|
||||
+ void __iomem *pd_addr;
|
||||
+ void __iomem *pwr_addr;
|
||||
+ void __iomem *tuner_addr;
|
||||
+ void __iomem *pcw_addr;
|
||||
+ const struct mtk_pll_data *data;
|
||||
+};
|
||||
+
|
||||
+static inline struct mtk_clk_pll *to_mtk_clk_pll(struct clk_hw *hw)
|
||||
+{
|
||||
+ return container_of(hw, struct mtk_clk_pll, hw);
|
||||
+}
|
||||
+
|
||||
+static int mtk_pll_is_prepared(struct clk_hw *hw)
|
||||
+{
|
||||
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
|
||||
+
|
||||
+ return (readl(pll->base_addr + REG_CON0) & CON0_BASE_EN) != 0;
|
||||
+}
|
||||
+
|
||||
+static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin,
|
||||
+ u32 pcw, int postdiv)
|
||||
+{
|
||||
+ int pcwbits = pll->data->pcwbits;
|
||||
+ int pcwfbits;
|
||||
+ u64 vco;
|
||||
+ u8 c = 0;
|
||||
+
|
||||
+ /* The fractional part of the PLL divider. */
|
||||
+ pcwfbits = pcwbits > INTEGER_BITS ? pcwbits - INTEGER_BITS : 0;
|
||||
+
|
||||
+ vco = (u64)fin * pcw;
|
||||
+
|
||||
+ if (pcwfbits && (vco & GENMASK(pcwfbits - 1, 0)))
|
||||
+ c = 1;
|
||||
+
|
||||
+ vco >>= pcwfbits;
|
||||
+
|
||||
+ if (c)
|
||||
+ vco++;
|
||||
+
|
||||
+ return ((unsigned long)vco + postdiv - 1) / postdiv;
|
||||
+}
|
||||
+
|
||||
+static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
|
||||
+ int postdiv)
|
||||
+{
|
||||
+ u32 con1, pd, val;
|
||||
+ int pll_en;
|
||||
+
|
||||
+ /* set postdiv */
|
||||
+ pd = readl(pll->pd_addr);
|
||||
+ pd &= ~(POSTDIV_MASK << pll->data->pd_shift);
|
||||
+ pd |= (ffs(postdiv) - 1) << pll->data->pd_shift;
|
||||
+ writel(pd, pll->pd_addr);
|
||||
+
|
||||
+ pll_en = readl(pll->base_addr + REG_CON0) & CON0_BASE_EN;
|
||||
+
|
||||
+ /* set pcw */
|
||||
+ val = readl(pll->pcw_addr);
|
||||
+
|
||||
+ val &= ~GENMASK(pll->data->pcw_shift + pll->data->pcwbits - 1,
|
||||
+ pll->data->pcw_shift);
|
||||
+ val |= pcw << pll->data->pcw_shift;
|
||||
+ writel(val, pll->pcw_addr);
|
||||
+
|
||||
+ con1 = readl(pll->base_addr + REG_CON1);
|
||||
+
|
||||
+ if (pll_en)
|
||||
+ con1 |= CON0_PCW_CHG;
|
||||
+
|
||||
+ writel(con1, pll->base_addr + REG_CON1);
|
||||
+ if (pll->tuner_addr)
|
||||
+ writel(con1 + 1, pll->tuner_addr);
|
||||
+
|
||||
+ if (pll_en)
|
||||
+ udelay(20);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * mtk_pll_calc_values - calculate good values for a given input frequency.
|
||||
+ * @pll: The pll
|
||||
+ * @pcw: The pcw value (output)
|
||||
+ * @postdiv: The post divider (output)
|
||||
+ * @freq: The desired target frequency
|
||||
+ * @fin: The input frequency
|
||||
+ *
|
||||
+ */
|
||||
+static void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv,
|
||||
+ u32 freq, u32 fin)
|
||||
+{
|
||||
+ unsigned long fmin = 1000 * MHZ;
|
||||
+ u64 _pcw;
|
||||
+ u32 val;
|
||||
+
|
||||
+ if (freq > pll->data->fmax)
|
||||
+ freq = pll->data->fmax;
|
||||
+
|
||||
+ for (val = 0; val < 4; val++) {
|
||||
+ *postdiv = 1 << val;
|
||||
+ if (freq * *postdiv >= fmin)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* _pcw = freq * postdiv / fin * 2^pcwfbits */
|
||||
+ _pcw = ((u64)freq << val) << (pll->data->pcwbits - INTEGER_BITS);
|
||||
+ do_div(_pcw, fin);
|
||||
+
|
||||
+ *pcw = (u32)_pcw;
|
||||
+}
|
||||
+
|
||||
+static int mtk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
|
||||
+ u32 pcw = 0;
|
||||
+ u32 postdiv;
|
||||
+
|
||||
+ mtk_pll_calc_values(pll, &pcw, &postdiv, rate, parent_rate);
|
||||
+ mtk_pll_set_rate_regs(pll, pcw, postdiv);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static unsigned long mtk_pll_recalc_rate(struct clk_hw *hw,
|
||||
+ unsigned long parent_rate)
|
||||
+{
|
||||
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
|
||||
+ u32 postdiv;
|
||||
+ u32 pcw;
|
||||
+
|
||||
+ postdiv = (readl(pll->pd_addr) >> pll->data->pd_shift) & POSTDIV_MASK;
|
||||
+ postdiv = 1 << postdiv;
|
||||
+
|
||||
+ pcw = readl(pll->pcw_addr) >> pll->data->pcw_shift;
|
||||
+ pcw &= GENMASK(pll->data->pcwbits - 1, 0);
|
||||
+
|
||||
+ return __mtk_pll_recalc_rate(pll, parent_rate, pcw, postdiv);
|
||||
+}
|
||||
+
|
||||
+static long mtk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
+ unsigned long *prate)
|
||||
+{
|
||||
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
|
||||
+ u32 pcw = 0;
|
||||
+ int postdiv;
|
||||
+
|
||||
+ mtk_pll_calc_values(pll, &pcw, &postdiv, rate, *prate);
|
||||
+
|
||||
+ return __mtk_pll_recalc_rate(pll, *prate, pcw, postdiv);
|
||||
+}
|
||||
+
|
||||
+static int mtk_pll_prepare(struct clk_hw *hw)
|
||||
+{
|
||||
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
|
||||
+ u32 r;
|
||||
+
|
||||
+ r = readl(pll->pwr_addr) | CON0_PWR_ON;
|
||||
+ writel(r, pll->pwr_addr);
|
||||
+ udelay(1);
|
||||
+
|
||||
+ r = readl(pll->pwr_addr) & ~CON0_ISO_EN;
|
||||
+ writel(r, pll->pwr_addr);
|
||||
+ udelay(1);
|
||||
+
|
||||
+ r = readl(pll->base_addr + REG_CON0);
|
||||
+ r |= pll->data->en_mask;
|
||||
+ writel(r, pll->base_addr + REG_CON0);
|
||||
+
|
||||
+ if (pll->tuner_addr) {
|
||||
+ r = readl(pll->tuner_addr) | AUDPLL_TUNER_EN;
|
||||
+ writel(r, pll->tuner_addr);
|
||||
+ }
|
||||
+
|
||||
+ udelay(20);
|
||||
+
|
||||
+ if (pll->data->flags & HAVE_RST_BAR) {
|
||||
+ r = readl(pll->base_addr + REG_CON0);
|
||||
+ r |= pll->data->rst_bar_mask;
|
||||
+ writel(r, pll->base_addr + REG_CON0);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mtk_pll_unprepare(struct clk_hw *hw)
|
||||
+{
|
||||
+ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
|
||||
+ u32 r;
|
||||
+
|
||||
+ if (pll->data->flags & HAVE_RST_BAR) {
|
||||
+ r = readl(pll->base_addr + REG_CON0);
|
||||
+ r &= ~pll->data->rst_bar_mask;
|
||||
+ writel(r, pll->base_addr + REG_CON0);
|
||||
+ }
|
||||
+
|
||||
+ if (pll->tuner_addr) {
|
||||
+ r = readl(pll->tuner_addr) & ~AUDPLL_TUNER_EN;
|
||||
+ writel(r, pll->tuner_addr);
|
||||
+ }
|
||||
+
|
||||
+ r = readl(pll->base_addr + REG_CON0);
|
||||
+ r &= ~CON0_BASE_EN;
|
||||
+ writel(r, pll->base_addr + REG_CON0);
|
||||
+
|
||||
+ r = readl(pll->pwr_addr) | CON0_ISO_EN;
|
||||
+ writel(r, pll->pwr_addr);
|
||||
+
|
||||
+ r = readl(pll->pwr_addr) & ~CON0_PWR_ON;
|
||||
+ writel(r, pll->pwr_addr);
|
||||
+}
|
||||
+
|
||||
+static const struct clk_ops mtk_pll_ops = {
|
||||
+ .is_prepared = mtk_pll_is_prepared,
|
||||
+ .prepare = mtk_pll_prepare,
|
||||
+ .unprepare = mtk_pll_unprepare,
|
||||
+ .recalc_rate = mtk_pll_recalc_rate,
|
||||
+ .round_rate = mtk_pll_round_rate,
|
||||
+ .set_rate = mtk_pll_set_rate,
|
||||
+};
|
||||
+
|
||||
+static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data,
|
||||
+ void __iomem *base)
|
||||
+{
|
||||
+ struct mtk_clk_pll *pll;
|
||||
+ struct clk_init_data init;
|
||||
+ struct clk *clk;
|
||||
+ const char *parent_name = "clk26m";
|
||||
+
|
||||
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
|
||||
+ if (!pll)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ pll->base_addr = base + data->reg;
|
||||
+ pll->pwr_addr = base + data->pwr_reg;
|
||||
+ pll->pd_addr = base + data->pd_reg;
|
||||
+ pll->pcw_addr = base + data->pcw_reg;
|
||||
+ if (data->tuner_reg)
|
||||
+ pll->tuner_addr = base + data->tuner_reg;
|
||||
+ pll->hw.init = &init;
|
||||
+ pll->data = data;
|
||||
+
|
||||
+ init.name = data->name;
|
||||
+ init.ops = &mtk_pll_ops;
|
||||
+ init.parent_names = &parent_name;
|
||||
+ init.num_parents = 1;
|
||||
+
|
||||
+ clk = clk_register(NULL, &pll->hw);
|
||||
+
|
||||
+ if (IS_ERR(clk))
|
||||
+ kfree(pll);
|
||||
+
|
||||
+ return clk;
|
||||
+}
|
||||
+
|
||||
+void __init mtk_clk_register_plls(struct device_node *node,
|
||||
+ const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
|
||||
+{
|
||||
+ void __iomem *base;
|
||||
+ int r, i;
|
||||
+ struct clk *clk;
|
||||
+
|
||||
+ base = of_iomap(node, 0);
|
||||
+ if (!base) {
|
||||
+ pr_err("%s(): ioremap failed\n", __func__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < num_plls; i++) {
|
||||
+ const struct mtk_pll_data *pll = &plls[i];
|
||||
+
|
||||
+ clk = mtk_clk_register_pll(pll, base);
|
||||
+
|
||||
+ if (IS_ERR(clk)) {
|
||||
+ pr_err("Failed to register clk %s: %ld\n",
|
||||
+ pll->name, PTR_ERR(clk));
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ clk_data->clks[pll->id] = clk;
|
||||
+ }
|
||||
+
|
||||
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
+ if (r)
|
||||
+ pr_err("%s(): could not register clock provider: %d\n",
|
||||
+ __func__, r);
|
||||
+}
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,155 @@
|
||||
From c91e8490e45c68ea517f70f24568034b7735e8b9 Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Thu, 23 Apr 2015 10:35:40 +0200
|
||||
Subject: [PATCH 03/76] clk: mediatek: Add reset controller support
|
||||
|
||||
The pericfg and infracfg units also provide reset lines to several
|
||||
other SoC internal units. This adds a function which can be called
|
||||
from the pericfg and infracfg initialization functions which will
|
||||
register the reset controller using reset_controller_register. The
|
||||
reset controller will provide support for resetting the units
|
||||
connected to the pericfg and infracfg controller. The units resetted
|
||||
by this controller can use the standard reset device tree binding
|
||||
to gain access to the reset lines.
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
|
||||
---
|
||||
drivers/clk/mediatek/Makefile | 1 +
|
||||
drivers/clk/mediatek/clk-mtk.h | 10 +++++
|
||||
drivers/clk/mediatek/reset.c | 97 ++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 108 insertions(+)
|
||||
create mode 100644 drivers/clk/mediatek/reset.c
|
||||
|
||||
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
|
||||
index c384e97..0b6f1c3 100644
|
||||
--- a/drivers/clk/mediatek/Makefile
|
||||
+++ b/drivers/clk/mediatek/Makefile
|
||||
@@ -1 +1,2 @@
|
||||
obj-y += clk-mtk.o clk-pll.o clk-gate.o
|
||||
+obj-$(CONFIG_RESET_CONTROLLER) += reset.o
|
||||
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
|
||||
index 694fc39..61035b9 100644
|
||||
--- a/drivers/clk/mediatek/clk-mtk.h
|
||||
+++ b/drivers/clk/mediatek/clk-mtk.h
|
||||
@@ -156,4 +156,14 @@ void __init mtk_clk_register_plls(struct device_node *node,
|
||||
const struct mtk_pll_data *plls, int num_plls,
|
||||
struct clk_onecell_data *clk_data);
|
||||
|
||||
+#ifdef CONFIG_RESET_CONTROLLER
|
||||
+void mtk_register_reset_controller(struct device_node *np,
|
||||
+ unsigned int num_regs, int regofs);
|
||||
+#else
|
||||
+static inline void mtk_register_reset_controller(struct device_node *np,
|
||||
+ unsigned int num_regs, int regofs)
|
||||
+{
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
#endif /* __DRV_CLK_MTK_H */
|
||||
diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c
|
||||
new file mode 100644
|
||||
index 0000000..9e9fe4b
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/mediatek/reset.c
|
||||
@@ -0,0 +1,97 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2014 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.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/reset-controller.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#include "clk-mtk.h"
|
||||
+
|
||||
+struct mtk_reset {
|
||||
+ struct regmap *regmap;
|
||||
+ int regofs;
|
||||
+ struct reset_controller_dev rcdev;
|
||||
+};
|
||||
+
|
||||
+static int mtk_reset_assert(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id)
|
||||
+{
|
||||
+ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
|
||||
+
|
||||
+ return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
|
||||
+ BIT(id % 32), ~0);
|
||||
+}
|
||||
+
|
||||
+static int mtk_reset_deassert(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id)
|
||||
+{
|
||||
+ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
|
||||
+
|
||||
+ return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
|
||||
+ BIT(id % 32), 0);
|
||||
+}
|
||||
+
|
||||
+static int mtk_reset(struct reset_controller_dev *rcdev,
|
||||
+ unsigned long id)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = mtk_reset_assert(rcdev, id);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ return mtk_reset_deassert(rcdev, id);
|
||||
+}
|
||||
+
|
||||
+static struct reset_control_ops mtk_reset_ops = {
|
||||
+ .assert = mtk_reset_assert,
|
||||
+ .deassert = mtk_reset_deassert,
|
||||
+ .reset = mtk_reset,
|
||||
+};
|
||||
+
|
||||
+void mtk_register_reset_controller(struct device_node *np,
|
||||
+ unsigned int num_regs, int regofs)
|
||||
+{
|
||||
+ struct mtk_reset *data;
|
||||
+ int ret;
|
||||
+ struct regmap *regmap;
|
||||
+
|
||||
+ regmap = syscon_node_to_regmap(np);
|
||||
+ if (IS_ERR(regmap)) {
|
||||
+ pr_err("Cannot find regmap for %s: %ld\n", np->full_name,
|
||||
+ PTR_ERR(regmap));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
+ if (!data)
|
||||
+ return;
|
||||
+
|
||||
+ data->regmap = regmap;
|
||||
+ data->regofs = regofs;
|
||||
+ data->rcdev.owner = THIS_MODULE;
|
||||
+ data->rcdev.nr_resets = num_regs * 32;
|
||||
+ data->rcdev.ops = &mtk_reset_ops;
|
||||
+ data->rcdev.of_node = np;
|
||||
+
|
||||
+ ret = reset_controller_register(&data->rcdev);
|
||||
+ if (ret) {
|
||||
+ pr_err("could not register reset controller: %d\n", ret);
|
||||
+ kfree(data);
|
||||
+ return;
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,952 @@
|
||||
From 242572135fdb513cba0506415c7e26a0909eb4b5 Mon Sep 17 00:00:00 2001
|
||||
From: James Liao <jamesjj.liao@mediatek.com>
|
||||
Date: Thu, 23 Apr 2015 10:35:41 +0200
|
||||
Subject: [PATCH 04/76] clk: mediatek: Add basic clocks for Mediatek MT8135.
|
||||
|
||||
This patch adds basic clocks for MT8135, including TOPCKGEN, PLLs,
|
||||
INFRA and PERI clocks.
|
||||
|
||||
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
|
||||
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
---
|
||||
drivers/clk/mediatek/Makefile | 1 +
|
||||
drivers/clk/mediatek/clk-mt8135.c | 644 ++++++++++++++++++++
|
||||
include/dt-bindings/clock/mt8135-clk.h | 194 ++++++
|
||||
.../dt-bindings/reset-controller/mt8135-resets.h | 64 ++
|
||||
4 files changed, 903 insertions(+)
|
||||
create mode 100644 drivers/clk/mediatek/clk-mt8135.c
|
||||
create mode 100644 include/dt-bindings/clock/mt8135-clk.h
|
||||
create mode 100644 include/dt-bindings/reset-controller/mt8135-resets.h
|
||||
|
||||
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
|
||||
index 0b6f1c3..12ce576 100644
|
||||
--- a/drivers/clk/mediatek/Makefile
|
||||
+++ b/drivers/clk/mediatek/Makefile
|
||||
@@ -1,2 +1,3 @@
|
||||
obj-y += clk-mtk.o clk-pll.o clk-gate.o
|
||||
obj-$(CONFIG_RESET_CONTROLLER) += reset.o
|
||||
+obj-y += clk-mt8135.o
|
||||
diff --git a/drivers/clk/mediatek/clk-mt8135.c b/drivers/clk/mediatek/clk-mt8135.c
|
||||
new file mode 100644
|
||||
index 0000000..a63435b
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/mediatek/clk-mt8135.c
|
||||
@@ -0,0 +1,644 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2014 MediaTek Inc.
|
||||
+ * Author: James Liao <jamesjj.liao@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <dt-bindings/clock/mt8135-clk.h>
|
||||
+
|
||||
+#include "clk-mtk.h"
|
||||
+#include "clk-gate.h"
|
||||
+
|
||||
+static DEFINE_SPINLOCK(mt8135_clk_lock);
|
||||
+
|
||||
+static const struct mtk_fixed_factor root_clk_alias[] __initconst = {
|
||||
+ FACTOR(CLK_TOP_DSI0_LNTC_DSICLK, "dsi0_lntc_dsiclk", "clk_null", 1, 1),
|
||||
+ FACTOR(CLK_TOP_HDMITX_CLKDIG_CTS, "hdmitx_clkdig_cts", "clk_null", 1, 1),
|
||||
+ FACTOR(CLK_TOP_CLKPH_MCK, "clkph_mck", "clk_null", 1, 1),
|
||||
+ FACTOR(CLK_TOP_CPUM_TCK_IN, "cpum_tck_in", "clk_null", 1, 1),
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_fixed_factor top_divs[] __initconst = {
|
||||
+ FACTOR(CLK_TOP_MAINPLL_806M, "mainpll_806m", "mainpll", 1, 2),
|
||||
+ FACTOR(CLK_TOP_MAINPLL_537P3M, "mainpll_537p3m", "mainpll", 1, 3),
|
||||
+ FACTOR(CLK_TOP_MAINPLL_322P4M, "mainpll_322p4m", "mainpll", 1, 5),
|
||||
+ FACTOR(CLK_TOP_MAINPLL_230P3M, "mainpll_230p3m", "mainpll", 1, 7),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_624M, "univpll_624m", "univpll", 1, 2),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_416M, "univpll_416m", "univpll", 1, 3),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_249P6M, "univpll_249p6m", "univpll", 1, 5),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_178P3M, "univpll_178p3m", "univpll", 1, 7),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_48M, "univpll_48m", "univpll", 1, 26),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
|
||||
+ FACTOR(CLK_TOP_MMPLL_D3, "mmpll_d3", "mmpll", 1, 3),
|
||||
+ FACTOR(CLK_TOP_MMPLL_D5, "mmpll_d5", "mmpll", 1, 5),
|
||||
+ FACTOR(CLK_TOP_MMPLL_D7, "mmpll_d7", "mmpll", 1, 7),
|
||||
+ FACTOR(CLK_TOP_MMPLL_D4, "mmpll_d4", "mmpll_d2", 1, 2),
|
||||
+ FACTOR(CLK_TOP_MMPLL_D6, "mmpll_d6", "mmpll_d3", 1, 2),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll_806m", 1, 1),
|
||||
+ FACTOR(CLK_TOP_SYSPLL_D4, "syspll_d4", "mainpll_806m", 1, 2),
|
||||
+ FACTOR(CLK_TOP_SYSPLL_D6, "syspll_d6", "mainpll_806m", 1, 3),
|
||||
+ FACTOR(CLK_TOP_SYSPLL_D8, "syspll_d8", "mainpll_806m", 1, 4),
|
||||
+ FACTOR(CLK_TOP_SYSPLL_D10, "syspll_d10", "mainpll_806m", 1, 5),
|
||||
+ FACTOR(CLK_TOP_SYSPLL_D12, "syspll_d12", "mainpll_806m", 1, 6),
|
||||
+ FACTOR(CLK_TOP_SYSPLL_D16, "syspll_d16", "mainpll_806m", 1, 8),
|
||||
+ FACTOR(CLK_TOP_SYSPLL_D24, "syspll_d24", "mainpll_806m", 1, 12),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll_537p3m", 1, 1),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_SYSPLL_D2P5, "syspll_d2p5", "mainpll_322p4m", 2, 1),
|
||||
+ FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll_322p4m", 1, 1),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_SYSPLL_D3P5, "syspll_d3p5", "mainpll_230p3m", 2, 1),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_624m", 1, 2),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_624m", 1, 4),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL1_D6, "univpll1_d6", "univpll_624m", 1, 6),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_624m", 1, 8),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL1_D10, "univpll1_d10", "univpll_624m", 1, 10),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_416m", 1, 2),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_416m", 1, 4),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL2_D6, "univpll2_d6", "univpll_416m", 1, 6),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_416m", 1, 8),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll_416m", 1, 1),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll_249p6m", 1, 1),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll_178p3m", 1, 1),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_D10, "univpll_d10", "univpll_249p6m", 1, 2),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll_48m", 1, 1),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_APLL, "apll_ck", "audpll", 1, 1),
|
||||
+ FACTOR(CLK_TOP_APLL_D4, "apll_d4", "audpll", 1, 4),
|
||||
+ FACTOR(CLK_TOP_APLL_D8, "apll_d8", "audpll", 1, 8),
|
||||
+ FACTOR(CLK_TOP_APLL_D16, "apll_d16", "audpll", 1, 16),
|
||||
+ FACTOR(CLK_TOP_APLL_D24, "apll_d24", "audpll", 1, 24),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2),
|
||||
+ FACTOR(CLK_TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4),
|
||||
+ FACTOR(CLK_TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_LVDSTX_CLKDIG_CT, "lvdstx_clkdig_cts", "lvdspll", 1, 1),
|
||||
+ FACTOR(CLK_TOP_VPLL_DPIX, "vpll_dpix_ck", "lvdspll", 1, 1),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_TVHDMI_H, "tvhdmi_h_ck", "tvdpll", 1, 1),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_HDMITX_CLKDIG_D2, "hdmitx_clkdig_d2", "hdmitx_clkdig_cts", 1, 2),
|
||||
+ FACTOR(CLK_TOP_HDMITX_CLKDIG_D3, "hdmitx_clkdig_d3", "hdmitx_clkdig_cts", 1, 3),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_TVHDMI_D2, "tvhdmi_d2", "tvhdmi_h_ck", 1, 2),
|
||||
+ FACTOR(CLK_TOP_TVHDMI_D4, "tvhdmi_d4", "tvhdmi_h_ck", 1, 4),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_MEMPLL_MCK_D4, "mempll_mck_d4", "clkph_mck", 1, 4),
|
||||
+};
|
||||
+
|
||||
+static const char * const axi_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll_d3",
|
||||
+ "syspll_d4",
|
||||
+ "syspll_d6",
|
||||
+ "univpll_d5",
|
||||
+ "univpll2_d2",
|
||||
+ "syspll_d3p5"
|
||||
+};
|
||||
+
|
||||
+static const char * const smi_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "clkph_mck",
|
||||
+ "syspll_d2p5",
|
||||
+ "syspll_d3",
|
||||
+ "syspll_d8",
|
||||
+ "univpll_d5",
|
||||
+ "univpll1_d2",
|
||||
+ "univpll1_d6",
|
||||
+ "mmpll_d3",
|
||||
+ "mmpll_d4",
|
||||
+ "mmpll_d5",
|
||||
+ "mmpll_d6",
|
||||
+ "mmpll_d7",
|
||||
+ "vdecpll",
|
||||
+ "lvdspll"
|
||||
+};
|
||||
+
|
||||
+static const char * const mfg_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "univpll1_d4",
|
||||
+ "syspll_d2",
|
||||
+ "syspll_d2p5",
|
||||
+ "syspll_d3",
|
||||
+ "univpll_d5",
|
||||
+ "univpll1_d2",
|
||||
+ "mmpll_d2",
|
||||
+ "mmpll_d3",
|
||||
+ "mmpll_d4",
|
||||
+ "mmpll_d5",
|
||||
+ "mmpll_d6",
|
||||
+ "mmpll_d7"
|
||||
+};
|
||||
+
|
||||
+static const char * const irda_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "univpll2_d8",
|
||||
+ "univpll1_d6"
|
||||
+};
|
||||
+
|
||||
+static const char * const cam_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll_d3",
|
||||
+ "syspll_d3p5",
|
||||
+ "syspll_d4",
|
||||
+ "univpll_d5",
|
||||
+ "univpll2_d2",
|
||||
+ "univpll_d7",
|
||||
+ "univpll1_d4"
|
||||
+};
|
||||
+
|
||||
+static const char * const aud_intbus_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll_d6",
|
||||
+ "univpll_d10"
|
||||
+};
|
||||
+
|
||||
+static const char * const jpg_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll_d5",
|
||||
+ "syspll_d4",
|
||||
+ "syspll_d3",
|
||||
+ "univpll_d7",
|
||||
+ "univpll2_d2",
|
||||
+ "univpll_d5"
|
||||
+};
|
||||
+
|
||||
+static const char * const disp_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll_d3p5",
|
||||
+ "syspll_d3",
|
||||
+ "univpll2_d2",
|
||||
+ "univpll_d5",
|
||||
+ "univpll1_d2",
|
||||
+ "lvdspll",
|
||||
+ "vdecpll"
|
||||
+};
|
||||
+
|
||||
+static const char * const msdc30_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll_d6",
|
||||
+ "syspll_d5",
|
||||
+ "univpll1_d4",
|
||||
+ "univpll2_d4",
|
||||
+ "msdcpll"
|
||||
+};
|
||||
+
|
||||
+static const char * const usb20_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "univpll2_d6",
|
||||
+ "univpll1_d10"
|
||||
+};
|
||||
+
|
||||
+static const char * const venc_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll_d3",
|
||||
+ "syspll_d8",
|
||||
+ "univpll_d5",
|
||||
+ "univpll1_d6",
|
||||
+ "mmpll_d4",
|
||||
+ "mmpll_d5",
|
||||
+ "mmpll_d6"
|
||||
+};
|
||||
+
|
||||
+static const char * const spi_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll_d6",
|
||||
+ "syspll_d8",
|
||||
+ "syspll_d10",
|
||||
+ "univpll1_d6",
|
||||
+ "univpll1_d8"
|
||||
+};
|
||||
+
|
||||
+static const char * const uart_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "univpll2_d8"
|
||||
+};
|
||||
+
|
||||
+static const char * const mem_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "clkph_mck"
|
||||
+};
|
||||
+
|
||||
+static const char * const camtg_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "univpll_d26",
|
||||
+ "univpll1_d6",
|
||||
+ "syspll_d16",
|
||||
+ "syspll_d8"
|
||||
+};
|
||||
+
|
||||
+static const char * const audio_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll_d24"
|
||||
+};
|
||||
+
|
||||
+static const char * const fix_parents[] __initconst = {
|
||||
+ "rtc32k",
|
||||
+ "clk26m",
|
||||
+ "univpll_d5",
|
||||
+ "univpll_d7",
|
||||
+ "univpll1_d2",
|
||||
+ "univpll1_d4",
|
||||
+ "univpll1_d6",
|
||||
+ "univpll1_d8"
|
||||
+};
|
||||
+
|
||||
+static const char * const vdec_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "vdecpll",
|
||||
+ "clkph_mck",
|
||||
+ "syspll_d2p5",
|
||||
+ "syspll_d3",
|
||||
+ "syspll_d3p5",
|
||||
+ "syspll_d4",
|
||||
+ "syspll_d5",
|
||||
+ "syspll_d6",
|
||||
+ "syspll_d8",
|
||||
+ "univpll1_d2",
|
||||
+ "univpll2_d2",
|
||||
+ "univpll_d7",
|
||||
+ "univpll_d10",
|
||||
+ "univpll2_d4",
|
||||
+ "lvdspll"
|
||||
+};
|
||||
+
|
||||
+static const char * const ddrphycfg_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "axi_sel",
|
||||
+ "syspll_d12"
|
||||
+};
|
||||
+
|
||||
+static const char * const dpilvds_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "lvdspll",
|
||||
+ "lvdspll_d2",
|
||||
+ "lvdspll_d4",
|
||||
+ "lvdspll_d8"
|
||||
+};
|
||||
+
|
||||
+static const char * const pmicspi_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "univpll2_d6",
|
||||
+ "syspll_d8",
|
||||
+ "syspll_d10",
|
||||
+ "univpll1_d10",
|
||||
+ "mempll_mck_d4",
|
||||
+ "univpll_d26",
|
||||
+ "syspll_d24"
|
||||
+};
|
||||
+
|
||||
+static const char * const smi_mfg_as_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "smi_sel",
|
||||
+ "mfg_sel",
|
||||
+ "mem_sel"
|
||||
+};
|
||||
+
|
||||
+static const char * const gcpu_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll_d4",
|
||||
+ "univpll_d7",
|
||||
+ "syspll_d5",
|
||||
+ "syspll_d6"
|
||||
+};
|
||||
+
|
||||
+static const char * const dpi1_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "tvhdmi_h_ck",
|
||||
+ "tvhdmi_d2",
|
||||
+ "tvhdmi_d4"
|
||||
+};
|
||||
+
|
||||
+static const char * const cci_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "mainpll_537p3m",
|
||||
+ "univpll_d3",
|
||||
+ "syspll_d2p5",
|
||||
+ "syspll_d3",
|
||||
+ "syspll_d5"
|
||||
+};
|
||||
+
|
||||
+static const char * const apll_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "apll_ck",
|
||||
+ "apll_d4",
|
||||
+ "apll_d8",
|
||||
+ "apll_d16",
|
||||
+ "apll_d24"
|
||||
+};
|
||||
+
|
||||
+static const char * const hdmipll_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "hdmitx_clkdig_cts",
|
||||
+ "hdmitx_clkdig_d2",
|
||||
+ "hdmitx_clkdig_d3"
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_composite top_muxes[] __initconst = {
|
||||
+ /* CLK_CFG_0 */
|
||||
+ MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
|
||||
+ 0x0140, 0, 3, INVALID_MUX_GATE_BIT),
|
||||
+ MUX_GATE(CLK_TOP_SMI_SEL, "smi_sel", smi_parents, 0x0140, 8, 4, 15),
|
||||
+ MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0140, 16, 4, 23),
|
||||
+ MUX_GATE(CLK_TOP_IRDA_SEL, "irda_sel", irda_parents, 0x0140, 24, 2, 31),
|
||||
+ /* CLK_CFG_1 */
|
||||
+ MUX_GATE(CLK_TOP_CAM_SEL, "cam_sel", cam_parents, 0x0144, 0, 3, 7),
|
||||
+ MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents,
|
||||
+ 0x0144, 8, 2, 15),
|
||||
+ MUX_GATE(CLK_TOP_JPG_SEL, "jpg_sel", jpg_parents, 0x0144, 16, 3, 23),
|
||||
+ MUX_GATE(CLK_TOP_DISP_SEL, "disp_sel", disp_parents, 0x0144, 24, 3, 31),
|
||||
+ /* CLK_CFG_2 */
|
||||
+ MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_parents, 0x0148, 0, 3, 7),
|
||||
+ MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_parents, 0x0148, 8, 3, 15),
|
||||
+ MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_parents, 0x0148, 16, 3, 23),
|
||||
+ MUX_GATE(CLK_TOP_MSDC30_4_SEL, "msdc30_4_sel", msdc30_parents, 0x0148, 24, 3, 31),
|
||||
+ /* CLK_CFG_3 */
|
||||
+ MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x014c, 0, 2, 7),
|
||||
+ /* CLK_CFG_4 */
|
||||
+ MUX_GATE(CLK_TOP_VENC_SEL, "venc_sel", venc_parents, 0x0150, 8, 3, 15),
|
||||
+ MUX_GATE(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x0150, 16, 3, 23),
|
||||
+ MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x0150, 24, 2, 31),
|
||||
+ /* CLK_CFG_6 */
|
||||
+ MUX_GATE(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x0158, 0, 2, 7),
|
||||
+ MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x0158, 8, 3, 15),
|
||||
+ MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", audio_parents, 0x0158, 24, 2, 31),
|
||||
+ /* CLK_CFG_7 */
|
||||
+ MUX_GATE(CLK_TOP_FIX_SEL, "fix_sel", fix_parents, 0x015c, 0, 3, 7),
|
||||
+ MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x015c, 8, 4, 15),
|
||||
+ MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents,
|
||||
+ 0x015c, 16, 2, 23),
|
||||
+ MUX_GATE(CLK_TOP_DPILVDS_SEL, "dpilvds_sel", dpilvds_parents, 0x015c, 24, 3, 31),
|
||||
+ /* CLK_CFG_8 */
|
||||
+ MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x0164, 0, 3, 7),
|
||||
+ MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_parents, 0x0164, 8, 3, 15),
|
||||
+ MUX_GATE(CLK_TOP_SMI_MFG_AS_SEL, "smi_mfg_as_sel", smi_mfg_as_parents,
|
||||
+ 0x0164, 16, 2, 23),
|
||||
+ MUX_GATE(CLK_TOP_GCPU_SEL, "gcpu_sel", gcpu_parents, 0x0164, 24, 3, 31),
|
||||
+ /* CLK_CFG_9 */
|
||||
+ MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0168, 0, 2, 7),
|
||||
+ MUX_GATE(CLK_TOP_CCI_SEL, "cci_sel", cci_parents, 0x0168, 8, 3, 15),
|
||||
+ MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", apll_parents, 0x0168, 16, 3, 23),
|
||||
+ MUX_GATE(CLK_TOP_HDMIPLL_SEL, "hdmipll_sel", hdmipll_parents, 0x0168, 24, 2, 31),
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_gate_regs infra_cg_regs = {
|
||||
+ .set_ofs = 0x0040,
|
||||
+ .clr_ofs = 0x0044,
|
||||
+ .sta_ofs = 0x0048,
|
||||
+};
|
||||
+
|
||||
+#define GATE_ICG(_id, _name, _parent, _shift) { \
|
||||
+ .id = _id, \
|
||||
+ .name = _name, \
|
||||
+ .parent_name = _parent, \
|
||||
+ .regs = &infra_cg_regs, \
|
||||
+ .shift = _shift, \
|
||||
+ .ops = &mtk_clk_gate_ops_setclr, \
|
||||
+ }
|
||||
+
|
||||
+static const struct mtk_gate infra_clks[] __initconst = {
|
||||
+ GATE_ICG(CLK_INFRA_PMIC_WRAP, "pmic_wrap_ck", "axi_sel", 23),
|
||||
+ GATE_ICG(CLK_INFRA_PMICSPI, "pmicspi_ck", "pmicspi_sel", 22),
|
||||
+ GATE_ICG(CLK_INFRA_CCIF1_AP_CTRL, "ccif1_ap_ctrl", "axi_sel", 21),
|
||||
+ GATE_ICG(CLK_INFRA_CCIF0_AP_CTRL, "ccif0_ap_ctrl", "axi_sel", 20),
|
||||
+ GATE_ICG(CLK_INFRA_KP, "kp_ck", "axi_sel", 16),
|
||||
+ GATE_ICG(CLK_INFRA_CPUM, "cpum_ck", "cpum_tck_in", 15),
|
||||
+ GATE_ICG(CLK_INFRA_M4U, "m4u_ck", "mem_sel", 8),
|
||||
+ GATE_ICG(CLK_INFRA_MFGAXI, "mfgaxi_ck", "axi_sel", 7),
|
||||
+ GATE_ICG(CLK_INFRA_DEVAPC, "devapc_ck", "axi_sel", 6),
|
||||
+ GATE_ICG(CLK_INFRA_AUDIO, "audio_ck", "aud_intbus_sel", 5),
|
||||
+ GATE_ICG(CLK_INFRA_MFG_BUS, "mfg_bus_ck", "axi_sel", 2),
|
||||
+ GATE_ICG(CLK_INFRA_SMI, "smi_ck", "smi_sel", 1),
|
||||
+ GATE_ICG(CLK_INFRA_DBGCLK, "dbgclk_ck", "axi_sel", 0),
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_gate_regs peri0_cg_regs = {
|
||||
+ .set_ofs = 0x0008,
|
||||
+ .clr_ofs = 0x0010,
|
||||
+ .sta_ofs = 0x0018,
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_gate_regs peri1_cg_regs = {
|
||||
+ .set_ofs = 0x000c,
|
||||
+ .clr_ofs = 0x0014,
|
||||
+ .sta_ofs = 0x001c,
|
||||
+};
|
||||
+
|
||||
+#define GATE_PERI0(_id, _name, _parent, _shift) { \
|
||||
+ .id = _id, \
|
||||
+ .name = _name, \
|
||||
+ .parent_name = _parent, \
|
||||
+ .regs = &peri0_cg_regs, \
|
||||
+ .shift = _shift, \
|
||||
+ .ops = &mtk_clk_gate_ops_setclr, \
|
||||
+ }
|
||||
+
|
||||
+#define GATE_PERI1(_id, _name, _parent, _shift) { \
|
||||
+ .id = _id, \
|
||||
+ .name = _name, \
|
||||
+ .parent_name = _parent, \
|
||||
+ .regs = &peri1_cg_regs, \
|
||||
+ .shift = _shift, \
|
||||
+ .ops = &mtk_clk_gate_ops_setclr, \
|
||||
+ }
|
||||
+
|
||||
+static const struct mtk_gate peri_gates[] __initconst = {
|
||||
+ /* PERI0 */
|
||||
+ GATE_PERI0(CLK_PERI_I2C5, "i2c5_ck", "axi_sel", 31),
|
||||
+ GATE_PERI0(CLK_PERI_I2C4, "i2c4_ck", "axi_sel", 30),
|
||||
+ GATE_PERI0(CLK_PERI_I2C3, "i2c3_ck", "axi_sel", 29),
|
||||
+ GATE_PERI0(CLK_PERI_I2C2, "i2c2_ck", "axi_sel", 28),
|
||||
+ GATE_PERI0(CLK_PERI_I2C1, "i2c1_ck", "axi_sel", 27),
|
||||
+ GATE_PERI0(CLK_PERI_I2C0, "i2c0_ck", "axi_sel", 26),
|
||||
+ GATE_PERI0(CLK_PERI_UART3, "uart3_ck", "axi_sel", 25),
|
||||
+ GATE_PERI0(CLK_PERI_UART2, "uart2_ck", "axi_sel", 24),
|
||||
+ GATE_PERI0(CLK_PERI_UART1, "uart1_ck", "axi_sel", 23),
|
||||
+ GATE_PERI0(CLK_PERI_UART0, "uart0_ck", "axi_sel", 22),
|
||||
+ GATE_PERI0(CLK_PERI_IRDA, "irda_ck", "irda_sel", 21),
|
||||
+ GATE_PERI0(CLK_PERI_NLI, "nli_ck", "axi_sel", 20),
|
||||
+ GATE_PERI0(CLK_PERI_MD_HIF, "md_hif_ck", "axi_sel", 19),
|
||||
+ GATE_PERI0(CLK_PERI_AP_HIF, "ap_hif_ck", "axi_sel", 18),
|
||||
+ GATE_PERI0(CLK_PERI_MSDC30_3, "msdc30_3_ck", "msdc30_4_sel", 17),
|
||||
+ GATE_PERI0(CLK_PERI_MSDC30_2, "msdc30_2_ck", "msdc30_3_sel", 16),
|
||||
+ GATE_PERI0(CLK_PERI_MSDC30_1, "msdc30_1_ck", "msdc30_2_sel", 15),
|
||||
+ GATE_PERI0(CLK_PERI_MSDC20_2, "msdc20_2_ck", "msdc30_1_sel", 14),
|
||||
+ GATE_PERI0(CLK_PERI_MSDC20_1, "msdc20_1_ck", "msdc30_0_sel", 13),
|
||||
+ GATE_PERI0(CLK_PERI_AP_DMA, "ap_dma_ck", "axi_sel", 12),
|
||||
+ GATE_PERI0(CLK_PERI_USB1, "usb1_ck", "usb20_sel", 11),
|
||||
+ GATE_PERI0(CLK_PERI_USB0, "usb0_ck", "usb20_sel", 10),
|
||||
+ GATE_PERI0(CLK_PERI_PWM, "pwm_ck", "axi_sel", 9),
|
||||
+ GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axi_sel", 8),
|
||||
+ GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axi_sel", 7),
|
||||
+ GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axi_sel", 6),
|
||||
+ GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axi_sel", 5),
|
||||
+ GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axi_sel", 4),
|
||||
+ GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axi_sel", 3),
|
||||
+ GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axi_sel", 2),
|
||||
+ GATE_PERI0(CLK_PERI_THERM, "therm_ck", "axi_sel", 1),
|
||||
+ GATE_PERI0(CLK_PERI_NFI, "nfi_ck", "axi_sel", 0),
|
||||
+ /* PERI1 */
|
||||
+ GATE_PERI1(CLK_PERI_USBSLV, "usbslv_ck", "axi_sel", 8),
|
||||
+ GATE_PERI1(CLK_PERI_USB1_MCU, "usb1_mcu_ck", "axi_sel", 7),
|
||||
+ GATE_PERI1(CLK_PERI_USB0_MCU, "usb0_mcu_ck", "axi_sel", 6),
|
||||
+ GATE_PERI1(CLK_PERI_GCPU, "gcpu_ck", "gcpu_sel", 5),
|
||||
+ GATE_PERI1(CLK_PERI_FHCTL, "fhctl_ck", "clk26m", 4),
|
||||
+ GATE_PERI1(CLK_PERI_SPI1, "spi1_ck", "spi_sel", 3),
|
||||
+ GATE_PERI1(CLK_PERI_AUXADC, "auxadc_ck", "clk26m", 2),
|
||||
+ GATE_PERI1(CLK_PERI_PERI_PWRAP, "peri_pwrap_ck", "axi_sel", 1),
|
||||
+ GATE_PERI1(CLK_PERI_I2C6, "i2c6_ck", "axi_sel", 0),
|
||||
+};
|
||||
+
|
||||
+static const char * const uart_ck_sel_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "uart_sel",
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_composite peri_clks[] __initconst = {
|
||||
+ MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents, 0x40c, 0, 1),
|
||||
+ MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents, 0x40c, 1, 1),
|
||||
+ MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents, 0x40c, 2, 1),
|
||||
+ MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1),
|
||||
+};
|
||||
+
|
||||
+static void __init mtk_topckgen_init(struct device_node *node)
|
||||
+{
|
||||
+ struct clk_onecell_data *clk_data;
|
||||
+ void __iomem *base;
|
||||
+ int r;
|
||||
+
|
||||
+ base = of_iomap(node, 0);
|
||||
+ if (!base) {
|
||||
+ pr_err("%s(): ioremap failed\n", __func__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
|
||||
+
|
||||
+ mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data);
|
||||
+ mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
|
||||
+ mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
|
||||
+ &mt8135_clk_lock, clk_data);
|
||||
+
|
||||
+ clk_prepare_enable(clk_data->clks[CLK_TOP_CCI_SEL]);
|
||||
+
|
||||
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
+ if (r)
|
||||
+ pr_err("%s(): could not register clock provider: %d\n",
|
||||
+ __func__, r);
|
||||
+}
|
||||
+CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8135-topckgen", mtk_topckgen_init);
|
||||
+
|
||||
+static void __init mtk_infrasys_init(struct device_node *node)
|
||||
+{
|
||||
+ struct clk_onecell_data *clk_data;
|
||||
+ int r;
|
||||
+
|
||||
+ clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
|
||||
+
|
||||
+ mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
|
||||
+ clk_data);
|
||||
+
|
||||
+ clk_prepare_enable(clk_data->clks[CLK_INFRA_M4U]);
|
||||
+
|
||||
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
+ if (r)
|
||||
+ pr_err("%s(): could not register clock provider: %d\n",
|
||||
+ __func__, r);
|
||||
+
|
||||
+ mtk_register_reset_controller(node, 2, 0x30);
|
||||
+}
|
||||
+CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt8135-infracfg", mtk_infrasys_init);
|
||||
+
|
||||
+static void __init mtk_pericfg_init(struct device_node *node)
|
||||
+{
|
||||
+ struct clk_onecell_data *clk_data;
|
||||
+ int r;
|
||||
+ void __iomem *base;
|
||||
+
|
||||
+ base = of_iomap(node, 0);
|
||||
+ if (!base) {
|
||||
+ pr_err("%s(): ioremap failed\n", __func__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
|
||||
+
|
||||
+ mtk_clk_register_gates(node, peri_gates, ARRAY_SIZE(peri_gates),
|
||||
+ clk_data);
|
||||
+ mtk_clk_register_composites(peri_clks, ARRAY_SIZE(peri_clks), base,
|
||||
+ &mt8135_clk_lock, clk_data);
|
||||
+
|
||||
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
+ if (r)
|
||||
+ pr_err("%s(): could not register clock provider: %d\n",
|
||||
+ __func__, r);
|
||||
+
|
||||
+ mtk_register_reset_controller(node, 2, 0);
|
||||
+}
|
||||
+CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8135-pericfg", mtk_pericfg_init);
|
||||
+
|
||||
+#define MT8135_PLL_FMAX (2000 * MHZ)
|
||||
+#define CON0_MT8135_RST_BAR BIT(27)
|
||||
+
|
||||
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \
|
||||
+ .id = _id, \
|
||||
+ .name = _name, \
|
||||
+ .reg = _reg, \
|
||||
+ .pwr_reg = _pwr_reg, \
|
||||
+ .en_mask = _en_mask, \
|
||||
+ .flags = _flags, \
|
||||
+ .rst_bar_mask = CON0_MT8135_RST_BAR, \
|
||||
+ .fmax = MT8135_PLL_FMAX, \
|
||||
+ .pcwbits = _pcwbits, \
|
||||
+ .pd_reg = _pd_reg, \
|
||||
+ .pd_shift = _pd_shift, \
|
||||
+ .tuner_reg = _tuner_reg, \
|
||||
+ .pcw_reg = _pcw_reg, \
|
||||
+ .pcw_shift = _pcw_shift, \
|
||||
+ }
|
||||
+
|
||||
+static const struct mtk_pll_data plls[] = {
|
||||
+ PLL(CLK_APMIXED_ARMPLL1, "armpll1", 0x200, 0x218, 0x80000001, 0, 21, 0x204, 24, 0x0, 0x204, 0),
|
||||
+ PLL(CLK_APMIXED_ARMPLL2, "armpll2", 0x2cc, 0x2e4, 0x80000001, 0, 21, 0x2d0, 24, 0x0, 0x2d0, 0),
|
||||
+ PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x21c, 0x234, 0xf0000001, HAVE_RST_BAR, 21, 0x21c, 6, 0x0, 0x220, 0),
|
||||
+ PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x238, 0x250, 0xf3000001, HAVE_RST_BAR, 7, 0x238, 6, 0x0, 0x238, 9),
|
||||
+ PLL(CLK_APMIXED_MMPLL, "mmpll", 0x254, 0x26c, 0xf0000001, HAVE_RST_BAR, 21, 0x254, 6, 0x0, 0x258, 0),
|
||||
+ PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x278, 0x290, 0x80000001, 0, 21, 0x278, 6, 0x0, 0x27c, 0),
|
||||
+ PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x294, 0x2ac, 0x80000001, 0, 31, 0x294, 6, 0x0, 0x298, 0),
|
||||
+ PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x2b0, 0x2c8, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x2b4, 0),
|
||||
+ PLL(CLK_APMIXED_AUDPLL, "audpll", 0x2e8, 0x300, 0x80000001, 0, 31, 0x2e8, 6, 0x2f8, 0x2ec, 0),
|
||||
+ PLL(CLK_APMIXED_VDECPLL, "vdecpll", 0x304, 0x31c, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x308, 0),
|
||||
+};
|
||||
+
|
||||
+static void __init mtk_apmixedsys_init(struct device_node *node)
|
||||
+{
|
||||
+ struct clk_onecell_data *clk_data;
|
||||
+
|
||||
+ clk_data = mtk_alloc_clk_data(ARRAY_SIZE(plls));
|
||||
+ if (!clk_data)
|
||||
+ return;
|
||||
+
|
||||
+ mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
|
||||
+}
|
||||
+CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8135-apmixedsys",
|
||||
+ mtk_apmixedsys_init);
|
||||
diff --git a/include/dt-bindings/clock/mt8135-clk.h b/include/dt-bindings/clock/mt8135-clk.h
|
||||
new file mode 100644
|
||||
index 0000000..6dac6c0
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/clock/mt8135-clk.h
|
||||
@@ -0,0 +1,194 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2014 MediaTek Inc.
|
||||
+ * Author: James Liao <jamesjj.liao@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _DT_BINDINGS_CLK_MT8135_H
|
||||
+#define _DT_BINDINGS_CLK_MT8135_H
|
||||
+
|
||||
+/* TOPCKGEN */
|
||||
+
|
||||
+#define CLK_TOP_DSI0_LNTC_DSICLK 1
|
||||
+#define CLK_TOP_HDMITX_CLKDIG_CTS 2
|
||||
+#define CLK_TOP_CLKPH_MCK 3
|
||||
+#define CLK_TOP_CPUM_TCK_IN 4
|
||||
+#define CLK_TOP_MAINPLL_806M 5
|
||||
+#define CLK_TOP_MAINPLL_537P3M 6
|
||||
+#define CLK_TOP_MAINPLL_322P4M 7
|
||||
+#define CLK_TOP_MAINPLL_230P3M 8
|
||||
+#define CLK_TOP_UNIVPLL_624M 9
|
||||
+#define CLK_TOP_UNIVPLL_416M 10
|
||||
+#define CLK_TOP_UNIVPLL_249P6M 11
|
||||
+#define CLK_TOP_UNIVPLL_178P3M 12
|
||||
+#define CLK_TOP_UNIVPLL_48M 13
|
||||
+#define CLK_TOP_MMPLL_D2 14
|
||||
+#define CLK_TOP_MMPLL_D3 15
|
||||
+#define CLK_TOP_MMPLL_D5 16
|
||||
+#define CLK_TOP_MMPLL_D7 17
|
||||
+#define CLK_TOP_MMPLL_D4 18
|
||||
+#define CLK_TOP_MMPLL_D6 19
|
||||
+#define CLK_TOP_SYSPLL_D2 20
|
||||
+#define CLK_TOP_SYSPLL_D4 21
|
||||
+#define CLK_TOP_SYSPLL_D6 22
|
||||
+#define CLK_TOP_SYSPLL_D8 23
|
||||
+#define CLK_TOP_SYSPLL_D10 24
|
||||
+#define CLK_TOP_SYSPLL_D12 25
|
||||
+#define CLK_TOP_SYSPLL_D16 26
|
||||
+#define CLK_TOP_SYSPLL_D24 27
|
||||
+#define CLK_TOP_SYSPLL_D3 28
|
||||
+#define CLK_TOP_SYSPLL_D2P5 29
|
||||
+#define CLK_TOP_SYSPLL_D5 30
|
||||
+#define CLK_TOP_SYSPLL_D3P5 31
|
||||
+#define CLK_TOP_UNIVPLL1_D2 32
|
||||
+#define CLK_TOP_UNIVPLL1_D4 33
|
||||
+#define CLK_TOP_UNIVPLL1_D6 34
|
||||
+#define CLK_TOP_UNIVPLL1_D8 35
|
||||
+#define CLK_TOP_UNIVPLL1_D10 36
|
||||
+#define CLK_TOP_UNIVPLL2_D2 37
|
||||
+#define CLK_TOP_UNIVPLL2_D4 38
|
||||
+#define CLK_TOP_UNIVPLL2_D6 39
|
||||
+#define CLK_TOP_UNIVPLL2_D8 40
|
||||
+#define CLK_TOP_UNIVPLL_D3 41
|
||||
+#define CLK_TOP_UNIVPLL_D5 42
|
||||
+#define CLK_TOP_UNIVPLL_D7 43
|
||||
+#define CLK_TOP_UNIVPLL_D10 44
|
||||
+#define CLK_TOP_UNIVPLL_D26 45
|
||||
+#define CLK_TOP_APLL 46
|
||||
+#define CLK_TOP_APLL_D4 47
|
||||
+#define CLK_TOP_APLL_D8 48
|
||||
+#define CLK_TOP_APLL_D16 49
|
||||
+#define CLK_TOP_APLL_D24 50
|
||||
+#define CLK_TOP_LVDSPLL_D2 51
|
||||
+#define CLK_TOP_LVDSPLL_D4 52
|
||||
+#define CLK_TOP_LVDSPLL_D8 53
|
||||
+#define CLK_TOP_LVDSTX_CLKDIG_CT 54
|
||||
+#define CLK_TOP_VPLL_DPIX 55
|
||||
+#define CLK_TOP_TVHDMI_H 56
|
||||
+#define CLK_TOP_HDMITX_CLKDIG_D2 57
|
||||
+#define CLK_TOP_HDMITX_CLKDIG_D3 58
|
||||
+#define CLK_TOP_TVHDMI_D2 59
|
||||
+#define CLK_TOP_TVHDMI_D4 60
|
||||
+#define CLK_TOP_MEMPLL_MCK_D4 61
|
||||
+#define CLK_TOP_AXI_SEL 62
|
||||
+#define CLK_TOP_SMI_SEL 63
|
||||
+#define CLK_TOP_MFG_SEL 64
|
||||
+#define CLK_TOP_IRDA_SEL 65
|
||||
+#define CLK_TOP_CAM_SEL 66
|
||||
+#define CLK_TOP_AUD_INTBUS_SEL 67
|
||||
+#define CLK_TOP_JPG_SEL 68
|
||||
+#define CLK_TOP_DISP_SEL 69
|
||||
+#define CLK_TOP_MSDC30_1_SEL 70
|
||||
+#define CLK_TOP_MSDC30_2_SEL 71
|
||||
+#define CLK_TOP_MSDC30_3_SEL 72
|
||||
+#define CLK_TOP_MSDC30_4_SEL 73
|
||||
+#define CLK_TOP_USB20_SEL 74
|
||||
+#define CLK_TOP_VENC_SEL 75
|
||||
+#define CLK_TOP_SPI_SEL 76
|
||||
+#define CLK_TOP_UART_SEL 77
|
||||
+#define CLK_TOP_MEM_SEL 78
|
||||
+#define CLK_TOP_CAMTG_SEL 79
|
||||
+#define CLK_TOP_AUDIO_SEL 80
|
||||
+#define CLK_TOP_FIX_SEL 81
|
||||
+#define CLK_TOP_VDEC_SEL 82
|
||||
+#define CLK_TOP_DDRPHYCFG_SEL 83
|
||||
+#define CLK_TOP_DPILVDS_SEL 84
|
||||
+#define CLK_TOP_PMICSPI_SEL 85
|
||||
+#define CLK_TOP_MSDC30_0_SEL 86
|
||||
+#define CLK_TOP_SMI_MFG_AS_SEL 87
|
||||
+#define CLK_TOP_GCPU_SEL 88
|
||||
+#define CLK_TOP_DPI1_SEL 89
|
||||
+#define CLK_TOP_CCI_SEL 90
|
||||
+#define CLK_TOP_APLL_SEL 91
|
||||
+#define CLK_TOP_HDMIPLL_SEL 92
|
||||
+#define CLK_TOP_NR_CLK 93
|
||||
+
|
||||
+/* APMIXED_SYS */
|
||||
+
|
||||
+#define CLK_APMIXED_ARMPLL1 1
|
||||
+#define CLK_APMIXED_ARMPLL2 2
|
||||
+#define CLK_APMIXED_MAINPLL 3
|
||||
+#define CLK_APMIXED_UNIVPLL 4
|
||||
+#define CLK_APMIXED_MMPLL 5
|
||||
+#define CLK_APMIXED_MSDCPLL 6
|
||||
+#define CLK_APMIXED_TVDPLL 7
|
||||
+#define CLK_APMIXED_LVDSPLL 8
|
||||
+#define CLK_APMIXED_AUDPLL 9
|
||||
+#define CLK_APMIXED_VDECPLL 10
|
||||
+#define CLK_APMIXED_NR_CLK 11
|
||||
+
|
||||
+/* INFRA_SYS */
|
||||
+
|
||||
+#define CLK_INFRA_PMIC_WRAP 1
|
||||
+#define CLK_INFRA_PMICSPI 2
|
||||
+#define CLK_INFRA_CCIF1_AP_CTRL 3
|
||||
+#define CLK_INFRA_CCIF0_AP_CTRL 4
|
||||
+#define CLK_INFRA_KP 5
|
||||
+#define CLK_INFRA_CPUM 6
|
||||
+#define CLK_INFRA_M4U 7
|
||||
+#define CLK_INFRA_MFGAXI 8
|
||||
+#define CLK_INFRA_DEVAPC 9
|
||||
+#define CLK_INFRA_AUDIO 10
|
||||
+#define CLK_INFRA_MFG_BUS 11
|
||||
+#define CLK_INFRA_SMI 12
|
||||
+#define CLK_INFRA_DBGCLK 13
|
||||
+#define CLK_INFRA_NR_CLK 14
|
||||
+
|
||||
+/* PERI_SYS */
|
||||
+
|
||||
+#define CLK_PERI_I2C5 1
|
||||
+#define CLK_PERI_I2C4 2
|
||||
+#define CLK_PERI_I2C3 3
|
||||
+#define CLK_PERI_I2C2 4
|
||||
+#define CLK_PERI_I2C1 5
|
||||
+#define CLK_PERI_I2C0 6
|
||||
+#define CLK_PERI_UART3 7
|
||||
+#define CLK_PERI_UART2 8
|
||||
+#define CLK_PERI_UART1 9
|
||||
+#define CLK_PERI_UART0 10
|
||||
+#define CLK_PERI_IRDA 11
|
||||
+#define CLK_PERI_NLI 12
|
||||
+#define CLK_PERI_MD_HIF 13
|
||||
+#define CLK_PERI_AP_HIF 14
|
||||
+#define CLK_PERI_MSDC30_3 15
|
||||
+#define CLK_PERI_MSDC30_2 16
|
||||
+#define CLK_PERI_MSDC30_1 17
|
||||
+#define CLK_PERI_MSDC20_2 18
|
||||
+#define CLK_PERI_MSDC20_1 19
|
||||
+#define CLK_PERI_AP_DMA 20
|
||||
+#define CLK_PERI_USB1 21
|
||||
+#define CLK_PERI_USB0 22
|
||||
+#define CLK_PERI_PWM 23
|
||||
+#define CLK_PERI_PWM7 24
|
||||
+#define CLK_PERI_PWM6 25
|
||||
+#define CLK_PERI_PWM5 26
|
||||
+#define CLK_PERI_PWM4 27
|
||||
+#define CLK_PERI_PWM3 28
|
||||
+#define CLK_PERI_PWM2 29
|
||||
+#define CLK_PERI_PWM1 30
|
||||
+#define CLK_PERI_THERM 31
|
||||
+#define CLK_PERI_NFI 32
|
||||
+#define CLK_PERI_USBSLV 33
|
||||
+#define CLK_PERI_USB1_MCU 34
|
||||
+#define CLK_PERI_USB0_MCU 35
|
||||
+#define CLK_PERI_GCPU 36
|
||||
+#define CLK_PERI_FHCTL 37
|
||||
+#define CLK_PERI_SPI1 38
|
||||
+#define CLK_PERI_AUXADC 39
|
||||
+#define CLK_PERI_PERI_PWRAP 40
|
||||
+#define CLK_PERI_I2C6 41
|
||||
+#define CLK_PERI_UART0_SEL 42
|
||||
+#define CLK_PERI_UART1_SEL 43
|
||||
+#define CLK_PERI_UART2_SEL 44
|
||||
+#define CLK_PERI_UART3_SEL 45
|
||||
+#define CLK_PERI_NR_CLK 46
|
||||
+
|
||||
+#endif /* _DT_BINDINGS_CLK_MT8135_H */
|
||||
diff --git a/include/dt-bindings/reset-controller/mt8135-resets.h b/include/dt-bindings/reset-controller/mt8135-resets.h
|
||||
new file mode 100644
|
||||
index 0000000..1fb6295
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/reset-controller/mt8135-resets.h
|
||||
@@ -0,0 +1,64 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2014 MediaTek Inc.
|
||||
+ * Author: Flora Fu, MediaTek
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT8135
|
||||
+#define _DT_BINDINGS_RESET_CONTROLLER_MT8135
|
||||
+
|
||||
+/* INFRACFG resets */
|
||||
+#define MT8135_INFRA_EMI_REG_RST 0
|
||||
+#define MT8135_INFRA_DRAMC0_A0_RST 1
|
||||
+#define MT8135_INFRA_CCIF0_RST 2
|
||||
+#define MT8135_INFRA_APCIRQ_EINT_RST 3
|
||||
+#define MT8135_INFRA_APXGPT_RST 4
|
||||
+#define MT8135_INFRA_SCPSYS_RST 5
|
||||
+#define MT8135_INFRA_CCIF1_RST 6
|
||||
+#define MT8135_INFRA_PMIC_WRAP_RST 7
|
||||
+#define MT8135_INFRA_KP_RST 8
|
||||
+#define MT8135_INFRA_EMI_RST 32
|
||||
+#define MT8135_INFRA_DRAMC0_RST 34
|
||||
+#define MT8135_INFRA_SMI_RST 35
|
||||
+#define MT8135_INFRA_M4U_RST 36
|
||||
+
|
||||
+/* PERICFG resets */
|
||||
+#define MT8135_PERI_UART0_SW_RST 0
|
||||
+#define MT8135_PERI_UART1_SW_RST 1
|
||||
+#define MT8135_PERI_UART2_SW_RST 2
|
||||
+#define MT8135_PERI_UART3_SW_RST 3
|
||||
+#define MT8135_PERI_IRDA_SW_RST 4
|
||||
+#define MT8135_PERI_PTP_SW_RST 5
|
||||
+#define MT8135_PERI_AP_HIF_SW_RST 6
|
||||
+#define MT8135_PERI_GPCU_SW_RST 7
|
||||
+#define MT8135_PERI_MD_HIF_SW_RST 8
|
||||
+#define MT8135_PERI_NLI_SW_RST 9
|
||||
+#define MT8135_PERI_AUXADC_SW_RST 10
|
||||
+#define MT8135_PERI_DMA_SW_RST 11
|
||||
+#define MT8135_PERI_NFI_SW_RST 14
|
||||
+#define MT8135_PERI_PWM_SW_RST 15
|
||||
+#define MT8135_PERI_THERM_SW_RST 16
|
||||
+#define MT8135_PERI_MSDC0_SW_RST 17
|
||||
+#define MT8135_PERI_MSDC1_SW_RST 18
|
||||
+#define MT8135_PERI_MSDC2_SW_RST 19
|
||||
+#define MT8135_PERI_MSDC3_SW_RST 20
|
||||
+#define MT8135_PERI_I2C0_SW_RST 22
|
||||
+#define MT8135_PERI_I2C1_SW_RST 23
|
||||
+#define MT8135_PERI_I2C2_SW_RST 24
|
||||
+#define MT8135_PERI_I2C3_SW_RST 25
|
||||
+#define MT8135_PERI_I2C4_SW_RST 26
|
||||
+#define MT8135_PERI_I2C5_SW_RST 27
|
||||
+#define MT8135_PERI_I2C6_SW_RST 28
|
||||
+#define MT8135_PERI_USB_SW_RST 29
|
||||
+#define MT8135_PERI_SPI1_SW_RST 33
|
||||
+#define MT8135_PERI_PWRAP_BRIDGE_SW_RST 34
|
||||
+
|
||||
+#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8135 */
|
||||
--
|
||||
1.7.10.4
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,179 @@
|
||||
From d6d7a7dc1b7db2e3d496bf67b30abc894edbc4bd Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Tue, 9 Jun 2015 10:46:59 +0200
|
||||
Subject: [PATCH 06/76] soc: mediatek: Add infracfg misc driver support
|
||||
|
||||
This adds support for some miscellaneous bits of the infracfg controller.
|
||||
The mtk_infracfg_set/clear_bus_protection functions are necessary for
|
||||
the scpsys power domain driver to handle the bus protection bits which
|
||||
are contained in the infacfg register space.
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
---
|
||||
drivers/soc/mediatek/Kconfig | 9 ++++
|
||||
drivers/soc/mediatek/Makefile | 1 +
|
||||
drivers/soc/mediatek/mtk-infracfg.c | 91 +++++++++++++++++++++++++++++++++
|
||||
include/linux/soc/mediatek/infracfg.h | 26 ++++++++++
|
||||
4 files changed, 127 insertions(+)
|
||||
create mode 100644 drivers/soc/mediatek/mtk-infracfg.c
|
||||
create mode 100644 include/linux/soc/mediatek/infracfg.h
|
||||
|
||||
diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
|
||||
index 3c18503..09da41e 100644
|
||||
--- a/drivers/soc/mediatek/Kconfig
|
||||
+++ b/drivers/soc/mediatek/Kconfig
|
||||
@@ -1,6 +1,15 @@
|
||||
#
|
||||
# MediaTek SoC drivers
|
||||
#
|
||||
+config MTK_INFRACFG
|
||||
+ bool "MediaTek INFRACFG Support"
|
||||
+ depends on ARCH_MEDIATEK
|
||||
+ select REGMAP
|
||||
+ help
|
||||
+ Say yes here to add support for the MediaTek INFRACFG controller. The
|
||||
+ INFRACFG controller contains various infrastructure registers not
|
||||
+ directly associated to any device.
|
||||
+
|
||||
config MTK_PMIC_WRAP
|
||||
tristate "MediaTek PMIC Wrapper Support"
|
||||
depends on ARCH_MEDIATEK
|
||||
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
|
||||
index ecaf4de..3fa940f 100644
|
||||
--- a/drivers/soc/mediatek/Makefile
|
||||
+++ b/drivers/soc/mediatek/Makefile
|
||||
@@ -1 +1,2 @@
|
||||
+obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
|
||||
obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
|
||||
diff --git a/drivers/soc/mediatek/mtk-infracfg.c b/drivers/soc/mediatek/mtk-infracfg.c
|
||||
new file mode 100644
|
||||
index 0000000..ca786e0
|
||||
--- /dev/null
|
||||
+++ b/drivers/soc/mediatek/mtk-infracfg.c
|
||||
@@ -0,0 +1,91 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/export.h>
|
||||
+#include <linux/jiffies.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/soc/mediatek/infracfg.h>
|
||||
+#include <asm/processor.h>
|
||||
+
|
||||
+#define INFRA_TOPAXI_PROTECTEN 0x0220
|
||||
+#define INFRA_TOPAXI_PROTECTSTA1 0x0228
|
||||
+
|
||||
+/**
|
||||
+ * mtk_infracfg_set_bus_protection - enable bus protection
|
||||
+ * @regmap: The infracfg regmap
|
||||
+ * @mask: The mask containing the protection bits to be enabled.
|
||||
+ *
|
||||
+ * This function enables the bus protection bits for disabled power
|
||||
+ * domains so that the system does not hanf when some unit accesses the
|
||||
+ * bus while in power down.
|
||||
+ */
|
||||
+int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask)
|
||||
+{
|
||||
+ unsigned long expired;
|
||||
+ u32 val;
|
||||
+ int ret;
|
||||
+
|
||||
+ regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, mask);
|
||||
+
|
||||
+ expired = jiffies + HZ;
|
||||
+
|
||||
+ while (1) {
|
||||
+ ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if ((val & mask) == mask)
|
||||
+ break;
|
||||
+
|
||||
+ cpu_relax();
|
||||
+ if (time_after(jiffies, expired))
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * mtk_infracfg_clear_bus_protection - disable bus protection
|
||||
+ * @regmap: The infracfg regmap
|
||||
+ * @mask: The mask containing the protection bits to be disabled.
|
||||
+ *
|
||||
+ * This function disables the bus protection bits previously enabled with
|
||||
+ * mtk_infracfg_set_bus_protection.
|
||||
+ */
|
||||
+int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask)
|
||||
+{
|
||||
+ unsigned long expired;
|
||||
+ int ret;
|
||||
+
|
||||
+ regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0);
|
||||
+
|
||||
+ expired = jiffies + HZ;
|
||||
+
|
||||
+ while (1) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (!(val & mask))
|
||||
+ break;
|
||||
+
|
||||
+ cpu_relax();
|
||||
+ if (time_after(jiffies, expired))
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h
|
||||
new file mode 100644
|
||||
index 0000000..a5714e9
|
||||
--- /dev/null
|
||||
+++ b/include/linux/soc/mediatek/infracfg.h
|
||||
@@ -0,0 +1,26 @@
|
||||
+#ifndef __SOC_MEDIATEK_INFRACFG_H
|
||||
+#define __SOC_MEDIATEK_INFRACFG_H
|
||||
+
|
||||
+#define MT8173_TOP_AXI_PROT_EN_MCI_M2 BIT(0)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_MM_M0 BIT(1)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_MM_M1 BIT(2)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_MMAPB_S BIT(6)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_L2C_M2 BIT(9)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_L2SS_SMI BIT(11)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_L2SS_ADD BIT(12)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_CCI_M2 BIT(13)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_MFG_S BIT(14)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_PERI_M0 BIT(15)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_PERI_M1 BIT(16)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_DEBUGSYS BIT(17)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_CQ_DMA BIT(18)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_GCPU BIT(19)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_IOMMU BIT(20)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_MFG_M0 BIT(21)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_MFG_M1 BIT(22)
|
||||
+#define MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT BIT(23)
|
||||
+
|
||||
+int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask);
|
||||
+int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask);
|
||||
+
|
||||
+#endif /* __SOC_MEDIATEK_INFRACFG_H */
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,57 @@
|
||||
From 06a1fd8a198771abc7c5badcf43a49a715ba4c76 Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Tue, 9 Jun 2015 10:47:00 +0200
|
||||
Subject: [PATCH 07/76] dt-bindings: soc: Add documentation for the MediaTek
|
||||
SCPSYS unit
|
||||
|
||||
This adds documentation for the MediaTek SCPSYS unit found in MT8173 SoCs.
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
---
|
||||
.../devicetree/bindings/soc/mediatek/scpsys.txt | 34 ++++++++++++++++++++
|
||||
1 file changed, 34 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
|
||||
new file mode 100644
|
||||
index 0000000..87f2091
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
|
||||
@@ -0,0 +1,34 @@
|
||||
+MediaTek SCPSYS
|
||||
+===============
|
||||
+
|
||||
+The System Control Processor System (SCPSYS) has several power management
|
||||
+related tasks in the system. The tasks include thermal measurement, dynamic
|
||||
+voltage frequency scaling (DVFS), interrupt filter and lowlevel sleep control.
|
||||
+The System Power Manager (SPM) inside the SCPSYS is for the MTCMOS power
|
||||
+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.
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible: Must be "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
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+ scpsys: scpsys@10006000 {
|
||||
+ #power-domain-cells = <1>;
|
||||
+ compatible = "mediatek,mt8173-scpsys";
|
||||
+ reg = <0 0x10006000 0 0x1000>;
|
||||
+ infracfg = <&infracfg>;
|
||||
+ };
|
||||
+
|
||||
+Example consumer:
|
||||
+
|
||||
+ afe: mt8173-afe-pcm@11220000 {
|
||||
+ compatible = "mediatek,mt8173-afe-pcm";
|
||||
+ power-domains = <&scpsys MT8173_POWER_DOMAIN_AUDIO>;
|
||||
+ };
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,573 @@
|
||||
From 04e2e2a895a95dc9e75403c2e8ea190dce9dc387 Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Tue, 9 Jun 2015 10:47:01 +0200
|
||||
Subject: [PATCH 08/76] soc: Mediatek: Add SCPSYS power domain driver
|
||||
|
||||
This adds a power domain driver for the Mediatek SCPSYS unit.
|
||||
|
||||
The System Control Processor System (SCPSYS) has several power
|
||||
management related tasks in the system. The tasks include thermal
|
||||
measurement, dynamic voltage frequency scaling (DVFS), interrupt
|
||||
filter and lowlevel sleep control. The System Power Manager (SPM)
|
||||
inside the SCPSYS is for the MTCMOS power domain control.
|
||||
|
||||
For now this driver only adds power domain support, the more
|
||||
advanced features are not yet supported. The driver implements
|
||||
the generic PM domain device tree bindings, the first user will
|
||||
most likely be the Mediatek AFE audio driver.
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
---
|
||||
drivers/soc/mediatek/Kconfig | 9 +
|
||||
drivers/soc/mediatek/Makefile | 1 +
|
||||
drivers/soc/mediatek/mtk-scpsys.c | 490 ++++++++++++++++++++++++++++++
|
||||
include/dt-bindings/power/mt8173-power.h | 15 +
|
||||
4 files changed, 515 insertions(+)
|
||||
create mode 100644 drivers/soc/mediatek/mtk-scpsys.c
|
||||
create mode 100644 include/dt-bindings/power/mt8173-power.h
|
||||
|
||||
diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
|
||||
index 09da41e..2dc5d90 100644
|
||||
--- a/drivers/soc/mediatek/Kconfig
|
||||
+++ b/drivers/soc/mediatek/Kconfig
|
||||
@@ -19,3 +19,12 @@ config MTK_PMIC_WRAP
|
||||
Say yes here to add support for MediaTek PMIC Wrapper found
|
||||
on different MediaTek SoCs. The PMIC wrapper is a proprietary
|
||||
hardware to connect the PMIC.
|
||||
+
|
||||
+config MTK_SCPSYS
|
||||
+ bool "MediaTek SCPSYS Support"
|
||||
+ depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
+ select REGMAP
|
||||
+ select MTK_INFRACFG
|
||||
+ help
|
||||
+ Say yes here to add support for the MediaTek SCPSYS power domain
|
||||
+ driver.
|
||||
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
|
||||
index 3fa940f..12998b0 100644
|
||||
--- a/drivers/soc/mediatek/Makefile
|
||||
+++ b/drivers/soc/mediatek/Makefile
|
||||
@@ -1,2 +1,3 @@
|
||||
obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
|
||||
obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
|
||||
+obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
|
||||
diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
|
||||
new file mode 100644
|
||||
index 0000000..b9eed37
|
||||
--- /dev/null
|
||||
+++ b/drivers/soc/mediatek/mtk-scpsys.c
|
||||
@@ -0,0 +1,490 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pm_domain.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/soc/mediatek/infracfg.h>
|
||||
+#include <dt-bindings/power/mt8173-power.h>
|
||||
+
|
||||
+#define SPM_VDE_PWR_CON 0x0210
|
||||
+#define SPM_MFG_PWR_CON 0x0214
|
||||
+#define SPM_VEN_PWR_CON 0x0230
|
||||
+#define SPM_ISP_PWR_CON 0x0238
|
||||
+#define SPM_DIS_PWR_CON 0x023c
|
||||
+#define SPM_VEN2_PWR_CON 0x0298
|
||||
+#define SPM_AUDIO_PWR_CON 0x029c
|
||||
+#define SPM_MFG_2D_PWR_CON 0x02c0
|
||||
+#define SPM_MFG_ASYNC_PWR_CON 0x02c4
|
||||
+#define SPM_USB_PWR_CON 0x02cc
|
||||
+#define SPM_PWR_STATUS 0x060c
|
||||
+#define SPM_PWR_STATUS_2ND 0x0610
|
||||
+
|
||||
+#define PWR_RST_B_BIT BIT(0)
|
||||
+#define PWR_ISO_BIT BIT(1)
|
||||
+#define PWR_ON_BIT BIT(2)
|
||||
+#define PWR_ON_2ND_BIT BIT(3)
|
||||
+#define PWR_CLK_DIS_BIT BIT(4)
|
||||
+
|
||||
+#define PWR_STATUS_DISP BIT(3)
|
||||
+#define PWR_STATUS_MFG BIT(4)
|
||||
+#define PWR_STATUS_ISP BIT(5)
|
||||
+#define PWR_STATUS_VDEC BIT(7)
|
||||
+#define PWR_STATUS_VENC_LT BIT(20)
|
||||
+#define PWR_STATUS_VENC BIT(21)
|
||||
+#define PWR_STATUS_MFG_2D BIT(22)
|
||||
+#define PWR_STATUS_MFG_ASYNC BIT(23)
|
||||
+#define PWR_STATUS_AUDIO BIT(24)
|
||||
+#define PWR_STATUS_USB BIT(25)
|
||||
+
|
||||
+enum clk_id {
|
||||
+ MT8173_CLK_NONE,
|
||||
+ MT8173_CLK_MM,
|
||||
+ MT8173_CLK_MFG,
|
||||
+ MT8173_CLK_MAX = MT8173_CLK_MFG,
|
||||
+};
|
||||
+
|
||||
+struct scp_domain_data {
|
||||
+ const char *name;
|
||||
+ u32 sta_mask;
|
||||
+ int ctl_offs;
|
||||
+ u32 sram_pdn_bits;
|
||||
+ u32 sram_pdn_ack_bits;
|
||||
+ u32 bus_prot_mask;
|
||||
+ enum clk_id clk_id;
|
||||
+};
|
||||
+
|
||||
+static const struct scp_domain_data scp_domain_data[] __initconst = {
|
||||
+ [MT8173_POWER_DOMAIN_VDEC] = {
|
||||
+ .name = "vdec",
|
||||
+ .sta_mask = PWR_STATUS_VDEC,
|
||||
+ .ctl_offs = SPM_VDE_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
+ .clk_id = MT8173_CLK_MM,
|
||||
+ },
|
||||
+ [MT8173_POWER_DOMAIN_VENC] = {
|
||||
+ .name = "venc",
|
||||
+ .sta_mask = PWR_STATUS_VENC,
|
||||
+ .ctl_offs = SPM_VEN_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
+ .clk_id = MT8173_CLK_MM,
|
||||
+ },
|
||||
+ [MT8173_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_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,
|
||||
+ },
|
||||
+ [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
|
||||
+ .name = "mfg_async",
|
||||
+ .sta_mask = PWR_STATUS_MFG_ASYNC,
|
||||
+ .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = 0,
|
||||
+ .clk_id = MT8173_CLK_MFG,
|
||||
+ },
|
||||
+ [MT8173_POWER_DOMAIN_MFG_2D] = {
|
||||
+ .name = "mfg_2d",
|
||||
+ .sta_mask = PWR_STATUS_MFG_2D,
|
||||
+ .ctl_offs = SPM_MFG_2D_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(13, 12),
|
||||
+ .clk_id = MT8173_CLK_NONE,
|
||||
+ },
|
||||
+ [MT8173_POWER_DOMAIN_MFG] = {
|
||||
+ .name = "mfg",
|
||||
+ .sta_mask = PWR_STATUS_MFG,
|
||||
+ .ctl_offs = SPM_MFG_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(13, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(21, 16),
|
||||
+ .clk_id = MT8173_CLK_NONE,
|
||||
+ .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
|
||||
+ MT8173_TOP_AXI_PROT_EN_MFG_M0 |
|
||||
+ MT8173_TOP_AXI_PROT_EN_MFG_M1 |
|
||||
+ MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+#define NUM_DOMAINS ARRAY_SIZE(scp_domain_data)
|
||||
+
|
||||
+struct scp;
|
||||
+
|
||||
+struct scp_domain {
|
||||
+ struct generic_pm_domain genpd;
|
||||
+ struct scp *scp;
|
||||
+ struct clk *clk;
|
||||
+ u32 sta_mask;
|
||||
+ void __iomem *ctl_addr;
|
||||
+ u32 sram_pdn_bits;
|
||||
+ u32 sram_pdn_ack_bits;
|
||||
+ u32 bus_prot_mask;
|
||||
+};
|
||||
+
|
||||
+struct scp {
|
||||
+ struct scp_domain domains[NUM_DOMAINS];
|
||||
+ struct genpd_onecell_data pd_data;
|
||||
+ struct device *dev;
|
||||
+ void __iomem *base;
|
||||
+ struct regmap *infracfg;
|
||||
+ struct clk *clk[MT8173_CLK_MAX];
|
||||
+};
|
||||
+
|
||||
+static int scpsys_domain_is_on(struct scp_domain *scpd)
|
||||
+{
|
||||
+ struct scp *scp = scpd->scp;
|
||||
+
|
||||
+ u32 status = readl(scp->base + SPM_PWR_STATUS) & scpd->sta_mask;
|
||||
+ u32 status2 = readl(scp->base + SPM_PWR_STATUS_2ND) & scpd->sta_mask;
|
||||
+
|
||||
+ /*
|
||||
+ * A domain is on when both status bits are set. If only one is set
|
||||
+ * return an error. This happens while powering up a domain
|
||||
+ */
|
||||
+
|
||||
+ if (status && status2)
|
||||
+ return true;
|
||||
+ if (!status && !status2)
|
||||
+ return false;
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int scpsys_power_on(struct generic_pm_domain *genpd)
|
||||
+{
|
||||
+ struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
|
||||
+ struct scp *scp = scpd->scp;
|
||||
+ unsigned long timeout;
|
||||
+ bool expired;
|
||||
+ void __iomem *ctl_addr = scpd->ctl_addr;
|
||||
+ u32 sram_pdn_ack = scpd->sram_pdn_ack_bits;
|
||||
+ u32 val;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (scpd->clk) {
|
||||
+ ret = clk_prepare_enable(scpd->clk);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ val = readl(ctl_addr);
|
||||
+ val |= PWR_ON_BIT;
|
||||
+ writel(val, ctl_addr);
|
||||
+ val |= PWR_ON_2ND_BIT;
|
||||
+ writel(val, ctl_addr);
|
||||
+
|
||||
+ /* wait until PWR_ACK = 1 */
|
||||
+ timeout = jiffies + HZ;
|
||||
+ expired = false;
|
||||
+ while (1) {
|
||||
+ ret = scpsys_domain_is_on(scpd);
|
||||
+ if (ret > 0)
|
||||
+ break;
|
||||
+
|
||||
+ if (expired) {
|
||||
+ ret = -ETIMEDOUT;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ cpu_relax();
|
||||
+
|
||||
+ if (time_after(jiffies, timeout))
|
||||
+ expired = true;
|
||||
+ }
|
||||
+
|
||||
+ val &= ~PWR_CLK_DIS_BIT;
|
||||
+ writel(val, ctl_addr);
|
||||
+
|
||||
+ val &= ~PWR_ISO_BIT;
|
||||
+ writel(val, ctl_addr);
|
||||
+
|
||||
+ val |= PWR_RST_B_BIT;
|
||||
+ writel(val, ctl_addr);
|
||||
+
|
||||
+ val &= ~scpd->sram_pdn_bits;
|
||||
+ writel(val, ctl_addr);
|
||||
+
|
||||
+ /* wait until SRAM_PDN_ACK all 0 */
|
||||
+ timeout = jiffies + HZ;
|
||||
+ expired = false;
|
||||
+ while (sram_pdn_ack && (readl(ctl_addr) & sram_pdn_ack)) {
|
||||
+
|
||||
+ if (expired) {
|
||||
+ ret = -ETIMEDOUT;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ cpu_relax();
|
||||
+
|
||||
+ if (time_after(jiffies, timeout))
|
||||
+ expired = true;
|
||||
+ }
|
||||
+
|
||||
+ if (scpd->bus_prot_mask) {
|
||||
+ ret = mtk_infracfg_clear_bus_protection(scp->infracfg,
|
||||
+ scpd->bus_prot_mask);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+out:
|
||||
+ dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int scpsys_power_off(struct generic_pm_domain *genpd)
|
||||
+{
|
||||
+ struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
|
||||
+ struct scp *scp = scpd->scp;
|
||||
+ unsigned long timeout;
|
||||
+ bool expired;
|
||||
+ void __iomem *ctl_addr = scpd->ctl_addr;
|
||||
+ u32 pdn_ack = scpd->sram_pdn_ack_bits;
|
||||
+ u32 val;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (scpd->bus_prot_mask) {
|
||||
+ ret = mtk_infracfg_set_bus_protection(scp->infracfg,
|
||||
+ scpd->bus_prot_mask);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ val = readl(ctl_addr);
|
||||
+ val |= scpd->sram_pdn_bits;
|
||||
+ writel(val, ctl_addr);
|
||||
+
|
||||
+ /* wait until SRAM_PDN_ACK all 1 */
|
||||
+ timeout = jiffies + HZ;
|
||||
+ expired = false;
|
||||
+ while (pdn_ack && (readl(ctl_addr) & pdn_ack) != pdn_ack) {
|
||||
+ if (expired) {
|
||||
+ ret = -ETIMEDOUT;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ cpu_relax();
|
||||
+
|
||||
+ if (time_after(jiffies, timeout))
|
||||
+ expired = true;
|
||||
+ }
|
||||
+
|
||||
+ val |= PWR_ISO_BIT;
|
||||
+ writel(val, ctl_addr);
|
||||
+
|
||||
+ val &= ~PWR_RST_B_BIT;
|
||||
+ writel(val, ctl_addr);
|
||||
+
|
||||
+ val |= PWR_CLK_DIS_BIT;
|
||||
+ writel(val, ctl_addr);
|
||||
+
|
||||
+ val &= ~PWR_ON_BIT;
|
||||
+ writel(val, ctl_addr);
|
||||
+
|
||||
+ val &= ~PWR_ON_2ND_BIT;
|
||||
+ writel(val, ctl_addr);
|
||||
+
|
||||
+ /* wait until PWR_ACK = 0 */
|
||||
+ timeout = jiffies + HZ;
|
||||
+ expired = false;
|
||||
+ while (1) {
|
||||
+ ret = scpsys_domain_is_on(scpd);
|
||||
+ if (ret == 0)
|
||||
+ break;
|
||||
+
|
||||
+ if (expired) {
|
||||
+ ret = -ETIMEDOUT;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ cpu_relax();
|
||||
+
|
||||
+ if (time_after(jiffies, timeout))
|
||||
+ expired = true;
|
||||
+ }
|
||||
+
|
||||
+ if (scpd->clk)
|
||||
+ clk_disable_unprepare(scpd->clk);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+out:
|
||||
+ dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int __init scpsys_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct genpd_onecell_data *pd_data;
|
||||
+ struct resource *res;
|
||||
+ int i, ret;
|
||||
+ struct scp *scp;
|
||||
+
|
||||
+ scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
|
||||
+ if (!scp)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ scp->dev = &pdev->dev;
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ scp->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (IS_ERR(scp->base))
|
||||
+ return PTR_ERR(scp->base);
|
||||
+
|
||||
+ pd_data = &scp->pd_data;
|
||||
+
|
||||
+ pd_data->domains = devm_kzalloc(&pdev->dev,
|
||||
+ sizeof(*pd_data->domains) * NUM_DOMAINS, GFP_KERNEL);
|
||||
+ if (!pd_data->domains)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ scp->clk[MT8173_CLK_MM] = devm_clk_get(&pdev->dev, "mm");
|
||||
+ if (IS_ERR(scp->clk[MT8173_CLK_MM])) {
|
||||
+ dev_err(&pdev->dev, "Failed to get mm clk: %ld\n",
|
||||
+ PTR_ERR(scp->clk[MT8173_CLK_MM]));
|
||||
+ return PTR_ERR(scp->clk[MT8173_CLK_MM]);
|
||||
+ }
|
||||
+
|
||||
+ scp->clk[MT8173_CLK_MFG] = devm_clk_get(&pdev->dev, "mfg");
|
||||
+ if (IS_ERR(scp->clk[MT8173_CLK_MFG])) {
|
||||
+ dev_err(&pdev->dev, "Failed to get mfg clk: %ld\n",
|
||||
+ PTR_ERR(scp->clk[MT8173_CLK_MFG]));
|
||||
+ return PTR_ERR(scp->clk[MT8173_CLK_MFG]);
|
||||
+ }
|
||||
+
|
||||
+ 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);
|
||||
+ }
|
||||
+
|
||||
+ pd_data->num_domains = NUM_DOMAINS;
|
||||
+
|
||||
+ for (i = 0; i < NUM_DOMAINS; 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];
|
||||
+
|
||||
+ pd_data->domains[i] = genpd;
|
||||
+ scpd->scp = scp;
|
||||
+
|
||||
+ scpd->sta_mask = data->sta_mask;
|
||||
+ scpd->ctl_addr = scp->base + data->ctl_offs;
|
||||
+ scpd->sram_pdn_bits = data->sram_pdn_bits;
|
||||
+ scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits;
|
||||
+ scpd->bus_prot_mask = data->bus_prot_mask;
|
||||
+ if (data->clk_id != MT8173_CLK_NONE)
|
||||
+ scpd->clk = scp->clk[data->clk_id];
|
||||
+
|
||||
+ genpd->name = data->name;
|
||||
+ genpd->power_off = scpsys_power_off;
|
||||
+ genpd->power_on = scpsys_power_on;
|
||||
+
|
||||
+ /*
|
||||
+ * Initially turn on all domains to make the domains usable
|
||||
+ * with !CONFIG_PM and to get the hardware in sync with the
|
||||
+ * software. The unused domains will be switched off during
|
||||
+ * late_init time.
|
||||
+ */
|
||||
+ genpd->power_on(genpd);
|
||||
+
|
||||
+ pm_genpd_init(genpd, NULL, false);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * We are not allowed to fail here since there is no way to unregister
|
||||
+ * a power domain. Once registered above we have to keep the domains
|
||||
+ * valid.
|
||||
+ */
|
||||
+
|
||||
+ ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
|
||||
+ pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
|
||||
+ if (ret && IS_ENABLED(CONFIG_PM))
|
||||
+ dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
|
||||
+
|
||||
+ ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D],
|
||||
+ pd_data->domains[MT8173_POWER_DOMAIN_MFG]);
|
||||
+ if (ret && IS_ENABLED(CONFIG_PM))
|
||||
+ dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
|
||||
+
|
||||
+ ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
|
||||
+ if (ret)
|
||||
+ dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id of_scpsys_match_tbl[] = {
|
||||
+ {
|
||||
+ .compatible = "mediatek,mt8173-scpsys",
|
||||
+ }, {
|
||||
+ /* sentinel */
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static struct platform_driver scpsys_drv = {
|
||||
+ .driver = {
|
||||
+ .name = "mtk-scpsys",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = of_match_ptr(of_scpsys_match_tbl),
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+module_platform_driver_probe(scpsys_drv, scpsys_probe);
|
||||
diff --git a/include/dt-bindings/power/mt8173-power.h b/include/dt-bindings/power/mt8173-power.h
|
||||
new file mode 100644
|
||||
index 0000000..b34cee9
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/power/mt8173-power.h
|
||||
@@ -0,0 +1,15 @@
|
||||
+#ifndef _DT_BINDINGS_POWER_MT8183_POWER_H
|
||||
+#define _DT_BINDINGS_POWER_MT8183_POWER_H
|
||||
+
|
||||
+#define MT8173_POWER_DOMAIN_VDEC 0
|
||||
+#define MT8173_POWER_DOMAIN_VENC 1
|
||||
+#define MT8173_POWER_DOMAIN_ISP 2
|
||||
+#define MT8173_POWER_DOMAIN_MM 3
|
||||
+#define MT8173_POWER_DOMAIN_VENC_LT 4
|
||||
+#define MT8173_POWER_DOMAIN_AUDIO 5
|
||||
+#define MT8173_POWER_DOMAIN_USB 6
|
||||
+#define MT8173_POWER_DOMAIN_MFG_ASYNC 7
|
||||
+#define MT8173_POWER_DOMAIN_MFG_2D 8
|
||||
+#define MT8173_POWER_DOMAIN_MFG 9
|
||||
+
|
||||
+#endif /* _DT_BINDINGS_POWER_MT8183_POWER_H */
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,154 @@
|
||||
From 87043a64dd5185dc076b3c3ab2e421b3a8c47798 Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Thu, 23 Apr 2015 10:35:43 +0200
|
||||
Subject: [PATCH 09/76] dt-bindings: ARM: Mediatek: Document devicetree
|
||||
bindings for clock/reset controllers
|
||||
|
||||
This adds the binding documentation for the apmixedsys, perisys and
|
||||
infracfg controllers found on Mediatek SoCs.
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
---
|
||||
.../bindings/arm/mediatek/mediatek,apmixedsys.txt | 23 +++++++++++++++
|
||||
.../bindings/arm/mediatek/mediatek,infracfg.txt | 30 ++++++++++++++++++++
|
||||
.../bindings/arm/mediatek/mediatek,pericfg.txt | 30 ++++++++++++++++++++
|
||||
.../bindings/arm/mediatek/mediatek,topckgen.txt | 23 +++++++++++++++
|
||||
4 files changed, 106 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
|
||||
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
|
||||
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
|
||||
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
|
||||
new file mode 100644
|
||||
index 0000000..5af6d73
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
|
||||
@@ -0,0 +1,23 @@
|
||||
+Mediatek apmixedsys controller
|
||||
+==============================
|
||||
+
|
||||
+The Mediatek apmixedsys controller provides the PLLs to the system.
|
||||
+
|
||||
+Required Properties:
|
||||
+
|
||||
+- compatible: Should be:
|
||||
+ - "mediatek,mt8135-apmixedsys"
|
||||
+ - "mediatek,mt8173-apmixedsys"
|
||||
+- #clock-cells: Must be 1
|
||||
+
|
||||
+The apmixedsys controller uses the common clk binding from
|
||||
+Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+apmixedsys: apmixedsys@10209000 {
|
||||
+ compatible = "mediatek,mt8173-apmixedsys";
|
||||
+ reg = <0 0x10209000 0 0x1000>;
|
||||
+ #clock-cells = <1>;
|
||||
+};
|
||||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
|
||||
new file mode 100644
|
||||
index 0000000..684da473
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
|
||||
@@ -0,0 +1,30 @@
|
||||
+Mediatek infracfg controller
|
||||
+============================
|
||||
+
|
||||
+The Mediatek infracfg controller provides various clocks and reset
|
||||
+outputs to the system.
|
||||
+
|
||||
+Required Properties:
|
||||
+
|
||||
+- compatible: Should be:
|
||||
+ - "mediatek,mt8135-infracfg", "syscon"
|
||||
+ - "mediatek,mt8173-infracfg", "syscon"
|
||||
+- #clock-cells: Must be 1
|
||||
+- #reset-cells: Must be 1
|
||||
+
|
||||
+The infracfg controller uses the common clk binding from
|
||||
+Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
|
||||
+Also it uses the common reset controller binding from
|
||||
+Documentation/devicetree/bindings/reset/reset.txt.
|
||||
+The available reset outputs are defined in
|
||||
+dt-bindings/reset-controller/mt*-resets.h
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+infracfg: infracfg@10001000 {
|
||||
+ compatible = "mediatek,mt8173-infracfg", "syscon";
|
||||
+ reg = <0 0x10001000 0 0x1000>;
|
||||
+ #clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
+};
|
||||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
|
||||
new file mode 100644
|
||||
index 0000000..fdb45c6
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
|
||||
@@ -0,0 +1,30 @@
|
||||
+Mediatek pericfg controller
|
||||
+===========================
|
||||
+
|
||||
+The Mediatek pericfg controller provides various clocks and reset
|
||||
+outputs to the system.
|
||||
+
|
||||
+Required Properties:
|
||||
+
|
||||
+- compatible: Should be:
|
||||
+ - "mediatek,mt8135-pericfg", "syscon"
|
||||
+ - "mediatek,mt8173-pericfg", "syscon"
|
||||
+- #clock-cells: Must be 1
|
||||
+- #reset-cells: Must be 1
|
||||
+
|
||||
+The pericfg controller uses the common clk binding from
|
||||
+Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
|
||||
+Also it uses the common reset controller binding from
|
||||
+Documentation/devicetree/bindings/reset/reset.txt.
|
||||
+The available reset outputs are defined in
|
||||
+dt-bindings/reset-controller/mt*-resets.h
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+pericfg: pericfg@10003000 {
|
||||
+ compatible = "mediatek,mt8173-pericfg", "syscon";
|
||||
+ reg = <0 0x10003000 0 0x1000>;
|
||||
+ #clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
+};
|
||||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
|
||||
new file mode 100644
|
||||
index 0000000..a425248
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
|
||||
@@ -0,0 +1,23 @@
|
||||
+Mediatek topckgen controller
|
||||
+============================
|
||||
+
|
||||
+The Mediatek topckgen controller provides various clocks to the system.
|
||||
+
|
||||
+Required Properties:
|
||||
+
|
||||
+- compatible: Should be:
|
||||
+ - "mediatek,mt8135-topckgen"
|
||||
+ - "mediatek,mt8173-topckgen"
|
||||
+- #clock-cells: Must be 1
|
||||
+
|
||||
+The topckgen controller uses the common clk binding from
|
||||
+Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+topckgen: topckgen@10000000 {
|
||||
+ compatible = "mediatek,mt8173-topckgen";
|
||||
+ reg = <0 0x10000000 0 0x1000>;
|
||||
+ #clock-cells = <1>;
|
||||
+};
|
||||
--
|
||||
1.7.10.4
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,27 @@
|
||||
From a2214b951a1102ad2a2a72b6ae6e71c148f8249f Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Wed, 13 May 2015 10:52:30 +0200
|
||||
Subject: [PATCH 11/76] thermal: trivial: fix typo in comment
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Acked-by: Eduardo Valentin <edubezval@gmail.com>
|
||||
---
|
||||
drivers/thermal/thermal_core.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
|
||||
index 62cc82a..244784f 100644
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -402,7 +402,7 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
|
||||
}
|
||||
|
||||
/**
|
||||
- * thermal_zone_get_temp() - returns its the temperature of thermal zone
|
||||
+ * thermal_zone_get_temp() - returns the temperature of a thermal zone
|
||||
* @tz: a valid pointer to a struct thermal_zone_device
|
||||
* @temp: a valid pointer to where to store the resulting temperature.
|
||||
*
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,34 @@
|
||||
From 41adcc8cf217dfb4b70c2da061e70034b3c9add0 Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Wed, 13 May 2015 10:52:31 +0200
|
||||
Subject: [PATCH 12/76] thermal: remove useless call to
|
||||
thermal_zone_device_set_polling
|
||||
|
||||
When the thermal zone has no get_temp callback then thermal_zone_device_register()
|
||||
calls thermal_zone_device_set_polling() with a polling delay of 0. This
|
||||
only cancels the poll_queue. Since the poll_queue hasn't been scheduled this
|
||||
is a no-op. Remove it.
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Acked-by: Eduardo Valentin <edubezval@gmail.com>
|
||||
---
|
||||
drivers/thermal/thermal_core.c | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
|
||||
index 244784f..1b68d20 100644
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -1571,9 +1571,6 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
|
||||
|
||||
INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
|
||||
|
||||
- if (!tz->ops->get_temp)
|
||||
- thermal_zone_device_set_polling(tz, 0);
|
||||
-
|
||||
thermal_zone_device_update(tz);
|
||||
|
||||
return tz;
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,106 @@
|
||||
From bddcae2b66a23bfb6d381d089b0b862235480a9b Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Wed, 13 May 2015 10:52:32 +0200
|
||||
Subject: [PATCH 13/76] thermal: Use IS_ENABLED instead of #ifdef
|
||||
|
||||
Use IS_ENABLED(CONFIG_THERMAL_EMULATION) to make the code more readable
|
||||
and to get rid of the addtional #ifdef around the variable definitions
|
||||
in thermal_zone_get_temp().
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
---
|
||||
drivers/thermal/thermal_core.c | 45 +++++++++++++++++-----------------------
|
||||
1 file changed, 19 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
|
||||
index 1b68d20..3e0fe55 100644
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -414,11 +414,9 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
|
||||
int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
-#ifdef CONFIG_THERMAL_EMULATION
|
||||
int count;
|
||||
int crit_temp = INT_MAX;
|
||||
enum thermal_trip_type type;
|
||||
-#endif
|
||||
|
||||
if (!tz || IS_ERR(tz) || !tz->ops->get_temp)
|
||||
goto exit;
|
||||
@@ -426,25 +424,21 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
|
||||
mutex_lock(&tz->lock);
|
||||
|
||||
ret = tz->ops->get_temp(tz, temp);
|
||||
-#ifdef CONFIG_THERMAL_EMULATION
|
||||
- if (!tz->emul_temperature)
|
||||
- goto skip_emul;
|
||||
-
|
||||
- for (count = 0; count < tz->trips; count++) {
|
||||
- ret = tz->ops->get_trip_type(tz, count, &type);
|
||||
- if (!ret && type == THERMAL_TRIP_CRITICAL) {
|
||||
- ret = tz->ops->get_trip_temp(tz, count, &crit_temp);
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
|
||||
- if (ret)
|
||||
- goto skip_emul;
|
||||
+ if (IS_ENABLED(CONFIG_THERMAL_EMULATION) && tz->emul_temperature) {
|
||||
+ for (count = 0; count < tz->trips; count++) {
|
||||
+ ret = tz->ops->get_trip_type(tz, count, &type);
|
||||
+ if (!ret && type == THERMAL_TRIP_CRITICAL) {
|
||||
+ ret = tz->ops->get_trip_temp(tz, count,
|
||||
+ &crit_temp);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- if (*temp < crit_temp)
|
||||
- *temp = tz->emul_temperature;
|
||||
-skip_emul:
|
||||
-#endif
|
||||
+ if (!ret && *temp < crit_temp)
|
||||
+ *temp = tz->emul_temperature;
|
||||
+ }
|
||||
+
|
||||
mutex_unlock(&tz->lock);
|
||||
exit:
|
||||
return ret;
|
||||
@@ -780,7 +774,6 @@ policy_show(struct device *dev, struct device_attribute *devattr, char *buf)
|
||||
return sprintf(buf, "%s\n", tz->governor->name);
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_THERMAL_EMULATION
|
||||
static ssize_t
|
||||
emul_temp_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
@@ -806,7 +799,6 @@ emul_temp_store(struct device *dev, struct device_attribute *attr,
|
||||
return ret ? ret : count;
|
||||
}
|
||||
static DEVICE_ATTR(emul_temp, S_IWUSR, NULL, emul_temp_store);
|
||||
-#endif/*CONFIG_THERMAL_EMULATION*/
|
||||
|
||||
static DEVICE_ATTR(type, 0444, type_show, NULL);
|
||||
static DEVICE_ATTR(temp, 0444, temp_show, NULL);
|
||||
@@ -1536,11 +1528,12 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
|
||||
goto unregister;
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_THERMAL_EMULATION
|
||||
- result = device_create_file(&tz->device, &dev_attr_emul_temp);
|
||||
- if (result)
|
||||
- goto unregister;
|
||||
-#endif
|
||||
+ if (IS_ENABLED(CONFIG_THERMAL_EMULATION)) {
|
||||
+ result = device_create_file(&tz->device, &dev_attr_emul_temp);
|
||||
+ if (result)
|
||||
+ goto unregister;
|
||||
+ }
|
||||
+
|
||||
/* Create policy attribute */
|
||||
result = device_create_file(&tz->device, &dev_attr_policy);
|
||||
if (result)
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,34 @@
|
||||
From 18f50eae474edc716b01959fad6898c8553b131c Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Wed, 13 May 2015 10:52:33 +0200
|
||||
Subject: [PATCH 14/76] thermal: Add comment explaining test for critical
|
||||
temperature
|
||||
|
||||
The code testing if a temperature should be emulated or not is
|
||||
not obvious. Add a comment explaining why this test is done.
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
|
||||
---
|
||||
drivers/thermal/thermal_core.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
|
||||
index 3e0fe55..e204deb 100644
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -435,6 +435,11 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
|
||||
}
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Only allow emulating a temperature when the real temperature
|
||||
+ * is below the critical temperature so that the emulation code
|
||||
+ * cannot hide critical conditions.
|
||||
+ */
|
||||
if (!ret && *temp < crit_temp)
|
||||
*temp = tz->emul_temperature;
|
||||
}
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,53 @@
|
||||
From 0b729a98127ef045096edf20dfe5c4eadac21d44 Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Wed, 13 May 2015 10:52:34 +0200
|
||||
Subject: [PATCH 15/76] thermal: inline only once used function
|
||||
|
||||
Inline update_temperature into its only caller to make the code
|
||||
more readable.
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
|
||||
---
|
||||
drivers/thermal/thermal_core.c | 17 +++++------------
|
||||
1 file changed, 5 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
|
||||
index e204deb..19da022 100644
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -450,9 +450,12 @@ exit:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
|
||||
|
||||
-static void update_temperature(struct thermal_zone_device *tz)
|
||||
+void thermal_zone_device_update(struct thermal_zone_device *tz)
|
||||
{
|
||||
- int temp, ret;
|
||||
+ int temp, ret, count;
|
||||
+
|
||||
+ if (!tz->ops->get_temp)
|
||||
+ return;
|
||||
|
||||
ret = thermal_zone_get_temp(tz, &temp);
|
||||
if (ret) {
|
||||
@@ -471,16 +474,6 @@ static void update_temperature(struct thermal_zone_device *tz)
|
||||
trace_thermal_temperature(tz);
|
||||
dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
|
||||
tz->last_temperature, tz->temperature);
|
||||
-}
|
||||
-
|
||||
-void thermal_zone_device_update(struct thermal_zone_device *tz)
|
||||
-{
|
||||
- int count;
|
||||
-
|
||||
- if (!tz->ops->get_temp)
|
||||
- return;
|
||||
-
|
||||
- update_temperature(tz);
|
||||
|
||||
for (count = 0; count < tz->trips; count++)
|
||||
handle_thermal_trip(tz, count);
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,123 @@
|
||||
From 5da86f6a2b4c2c318e153649dc8fd34fe73f8292 Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Wed, 13 May 2015 10:52:35 +0200
|
||||
Subject: [PATCH 16/76] thermal: streamline get_trend callbacks
|
||||
|
||||
The .get_trend callback in struct thermal_zone_device_ops has the prototype:
|
||||
|
||||
int (*get_trend) (struct thermal_zone_device *, int,
|
||||
enum thermal_trend *);
|
||||
|
||||
whereas the .get_trend callback in struct thermal_zone_of_device_ops has:
|
||||
|
||||
int (*get_trend)(void *, long *);
|
||||
|
||||
Streamline both prototypes and add the trip argument to the OF callback
|
||||
aswell and use enum thermal_trend * instead of an integer pointer.
|
||||
|
||||
While the OF prototype may be the better one, this should be decided at
|
||||
framework level and not on OF level.
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
---
|
||||
drivers/thermal/of-thermal.c | 11 +--------
|
||||
drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 25 +++++++-------------
|
||||
include/linux/thermal.h | 2 +-
|
||||
3 files changed, 10 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
|
||||
index 03839df..c84404d 100644
|
||||
--- a/drivers/thermal/of-thermal.c
|
||||
+++ b/drivers/thermal/of-thermal.c
|
||||
@@ -187,24 +187,15 @@ static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip,
|
||||
enum thermal_trend *trend)
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
- long dev_trend;
|
||||
int r;
|
||||
|
||||
if (!data->ops->get_trend)
|
||||
return -EINVAL;
|
||||
|
||||
- r = data->ops->get_trend(data->sensor_data, &dev_trend);
|
||||
+ r = data->ops->get_trend(data->sensor_data, trip, trend);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
- /* TODO: These intervals might have some thresholds, but in core code */
|
||||
- if (dev_trend > 0)
|
||||
- *trend = THERMAL_TREND_RAISING;
|
||||
- else if (dev_trend < 0)
|
||||
- *trend = THERMAL_TREND_DROPPING;
|
||||
- else
|
||||
- *trend = THERMAL_TREND_STABLE;
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
|
||||
index d3a42bf..ade78eb 100644
|
||||
--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
|
||||
+++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
|
||||
@@ -238,7 +238,7 @@ static int ti_thermal_get_trip_temp(struct thermal_zone_device *thermal,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int __ti_thermal_get_trend(void *p, long *trend)
|
||||
+static int __ti_thermal_get_trend(void *p, int trip, enum thermal_trend *trend)
|
||||
{
|
||||
struct ti_thermal_data *data = p;
|
||||
struct ti_bandgap *bgp;
|
||||
@@ -251,22 +251,6 @@ static int __ti_thermal_get_trend(void *p, long *trend)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- *trend = tr;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-/* Get the temperature trend callback functions for thermal zone */
|
||||
-static int ti_thermal_get_trend(struct thermal_zone_device *thermal,
|
||||
- int trip, enum thermal_trend *trend)
|
||||
-{
|
||||
- int ret;
|
||||
- long tr;
|
||||
-
|
||||
- ret = __ti_thermal_get_trend(thermal->devdata, &tr);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
if (tr > 0)
|
||||
*trend = THERMAL_TREND_RAISING;
|
||||
else if (tr < 0)
|
||||
@@ -277,6 +261,13 @@ static int ti_thermal_get_trend(struct thermal_zone_device *thermal,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* Get the temperature trend callback functions for thermal zone */
|
||||
+static int ti_thermal_get_trend(struct thermal_zone_device *thermal,
|
||||
+ int trip, enum thermal_trend *trend)
|
||||
+{
|
||||
+ return __ti_thermal_get_trend(thermal->devdata, trip, trend);
|
||||
+}
|
||||
+
|
||||
/* Get critical temperature callback functions for thermal zone */
|
||||
static int ti_thermal_get_crit_temp(struct thermal_zone_device *thermal,
|
||||
int *temp)
|
||||
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
|
||||
index e9f2863..5c6a589 100644
|
||||
--- a/include/linux/thermal.h
|
||||
+++ b/include/linux/thermal.h
|
||||
@@ -269,7 +269,7 @@ struct thermal_genl_event {
|
||||
*/
|
||||
struct thermal_zone_of_device_ops {
|
||||
int (*get_temp)(void *, int *);
|
||||
- int (*get_trend)(void *, long *);
|
||||
+ int (*get_trend)(void *, int, enum thermal_trend *);
|
||||
int (*set_emul_temp)(void *, int);
|
||||
};
|
||||
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,90 @@
|
||||
From 5b622cb2d6ff44b1fb0750beee61f93f2c00548a Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Wed, 13 May 2015 10:52:36 +0200
|
||||
Subject: [PATCH 17/76] thermal: Allow sensor ops to fail with -ENOSYS
|
||||
|
||||
The thermal core uses the existence of the .get_temp, .get_trend and
|
||||
.set_emul_temp to detect whether this operation exists and should be
|
||||
used or whether it should be emulated in software. This makes problems
|
||||
for of-thermal which has to modify the struct thermal_zone_device_ops
|
||||
during runtime whenever a sensor is registered or unregistered.
|
||||
|
||||
Let the core test for -ENOSYS from these callbacks and treat it like
|
||||
if the callbacks were not present.
|
||||
|
||||
This allows of-thermal to always set the sensor related callbacks and
|
||||
to make struct thermal_zone_device_ops const again.
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
---
|
||||
drivers/thermal/thermal_core.c | 24 +++++++++++++++++-------
|
||||
1 file changed, 17 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
|
||||
index 19da022..3d8f9f9 100644
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -413,13 +413,16 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
|
||||
*/
|
||||
int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
|
||||
{
|
||||
- int ret = -EINVAL;
|
||||
+ int ret;
|
||||
int count;
|
||||
int crit_temp = INT_MAX;
|
||||
enum thermal_trip_type type;
|
||||
|
||||
- if (!tz || IS_ERR(tz) || !tz->ops->get_temp)
|
||||
- goto exit;
|
||||
+ if (!tz || IS_ERR(tz))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (!tz->ops->get_temp)
|
||||
+ return -ENOSYS;
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
|
||||
@@ -445,7 +448,7 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
|
||||
}
|
||||
|
||||
mutex_unlock(&tz->lock);
|
||||
-exit:
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
|
||||
@@ -454,10 +457,11 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
|
||||
{
|
||||
int temp, ret, count;
|
||||
|
||||
- if (!tz->ops->get_temp)
|
||||
+ ret = thermal_zone_get_temp(tz, &temp);
|
||||
+
|
||||
+ if (ret == -ENOSYS)
|
||||
return;
|
||||
|
||||
- ret = thermal_zone_get_temp(tz, &temp);
|
||||
if (ret) {
|
||||
if (ret != -EAGAIN)
|
||||
dev_warn(&tz->device,
|
||||
@@ -783,10 +787,16 @@ emul_temp_store(struct device *dev, struct device_attribute *attr,
|
||||
if (kstrtoul(buf, 10, &temperature))
|
||||
return -EINVAL;
|
||||
|
||||
- if (!tz->ops->set_emul_temp) {
|
||||
+ if (tz->ops->set_emul_temp)
|
||||
+ ret = tz->ops->set_emul_temp(tz, temperature);
|
||||
+ else
|
||||
+ ret = -ENOSYS;
|
||||
+
|
||||
+ if (ret == -ENOSYS) {
|
||||
mutex_lock(&tz->lock);
|
||||
tz->emul_temperature = temperature;
|
||||
mutex_unlock(&tz->lock);
|
||||
+ ret = 0;
|
||||
} else {
|
||||
ret = tz->ops->set_emul_temp(tz, temperature);
|
||||
}
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,129 @@
|
||||
From 8c9c4ed500e92c10dc4965dcd00692b3102a328a Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Wed, 13 May 2015 10:52:37 +0200
|
||||
Subject: [PATCH 18/76] thermal: of: always set sensor related callbacks
|
||||
|
||||
Now that the thermal core treats -ENOSYS like the callbacks were
|
||||
not present at all we no longer have to overwrite the ops during
|
||||
runtime but instead can always set them and return -ENOSYS if no
|
||||
sensor is registered.
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
---
|
||||
drivers/thermal/of-thermal.c | 33 +++++++++++++--------------------
|
||||
1 file changed, 13 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
|
||||
index c84404d..b9c35bd 100644
|
||||
--- a/drivers/thermal/of-thermal.c
|
||||
+++ b/drivers/thermal/of-thermal.c
|
||||
@@ -91,7 +91,7 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz,
|
||||
{
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
- if (!data->ops->get_temp)
|
||||
+ if (!data->ops)
|
||||
return -EINVAL;
|
||||
|
||||
return data->ops->get_temp(data->sensor_data, temp);
|
||||
@@ -178,7 +178,7 @@ static int of_thermal_set_emul_temp(struct thermal_zone_device *tz,
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
|
||||
if (!data->ops || !data->ops->set_emul_temp)
|
||||
- return -EINVAL;
|
||||
+ return -ENOSYS;
|
||||
|
||||
return data->ops->set_emul_temp(data->sensor_data, temp);
|
||||
}
|
||||
@@ -189,8 +189,8 @@ static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip,
|
||||
struct __thermal_zone *data = tz->devdata;
|
||||
int r;
|
||||
|
||||
- if (!data->ops->get_trend)
|
||||
- return -EINVAL;
|
||||
+ if (!data->ops || !data->ops->get_trend)
|
||||
+ return -ENOSYS;
|
||||
|
||||
r = data->ops->get_trend(data->sensor_data, trip, trend);
|
||||
if (r)
|
||||
@@ -366,6 +366,10 @@ static int of_thermal_get_crit_temp(struct thermal_zone_device *tz,
|
||||
}
|
||||
|
||||
static struct thermal_zone_device_ops of_thermal_ops = {
|
||||
+ .get_temp = of_thermal_get_temp,
|
||||
+ .get_trend = of_thermal_get_trend,
|
||||
+ .set_emul_temp = of_thermal_set_emul_temp,
|
||||
+
|
||||
.get_mode = of_thermal_get_mode,
|
||||
.set_mode = of_thermal_set_mode,
|
||||
|
||||
@@ -399,13 +403,13 @@ thermal_zone_of_add_sensor(struct device_node *zone,
|
||||
if (!ops)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
+ if (!ops->get_temp)
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+
|
||||
mutex_lock(&tzd->lock);
|
||||
tz->ops = ops;
|
||||
tz->sensor_data = data;
|
||||
|
||||
- tzd->ops->get_temp = of_thermal_get_temp;
|
||||
- tzd->ops->get_trend = of_thermal_get_trend;
|
||||
- tzd->ops->set_emul_temp = of_thermal_set_emul_temp;
|
||||
mutex_unlock(&tzd->lock);
|
||||
|
||||
return tzd;
|
||||
@@ -535,9 +539,6 @@ void thermal_zone_of_sensor_unregister(struct device *dev,
|
||||
return;
|
||||
|
||||
mutex_lock(&tzd->lock);
|
||||
- tzd->ops->get_temp = NULL;
|
||||
- tzd->ops->get_trend = NULL;
|
||||
- tzd->ops->set_emul_temp = NULL;
|
||||
|
||||
tz->ops = NULL;
|
||||
tz->sensor_data = NULL;
|
||||
@@ -845,7 +846,6 @@ int __init of_parse_thermal_zones(void)
|
||||
{
|
||||
struct device_node *np, *child;
|
||||
struct __thermal_zone *tz;
|
||||
- struct thermal_zone_device_ops *ops;
|
||||
|
||||
np = of_find_node_by_name(NULL, "thermal-zones");
|
||||
if (!np) {
|
||||
@@ -869,29 +869,22 @@ int __init of_parse_thermal_zones(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
- ops = kmemdup(&of_thermal_ops, sizeof(*ops), GFP_KERNEL);
|
||||
- if (!ops)
|
||||
- goto exit_free;
|
||||
-
|
||||
tzp = kzalloc(sizeof(*tzp), GFP_KERNEL);
|
||||
- if (!tzp) {
|
||||
- kfree(ops);
|
||||
+ if (!tzp)
|
||||
goto exit_free;
|
||||
- }
|
||||
|
||||
/* No hwmon because there might be hwmon drivers registering */
|
||||
tzp->no_hwmon = true;
|
||||
|
||||
zone = thermal_zone_device_register(child->name, tz->ntrips,
|
||||
0, tz,
|
||||
- ops, tzp,
|
||||
+ &of_thermal_ops, tzp,
|
||||
tz->passive_delay,
|
||||
tz->polling_delay);
|
||||
if (IS_ERR(zone)) {
|
||||
pr_err("Failed to build %s zone %ld\n", child->name,
|
||||
PTR_ERR(zone));
|
||||
kfree(tzp);
|
||||
- kfree(ops);
|
||||
of_thermal_free_zone(tz);
|
||||
/* attempting to build remaining zones still */
|
||||
}
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,327 @@
|
||||
From 7cbee588bc6eee59c025f89cf9324943fda98934 Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Wed, 13 May 2015 10:52:38 +0200
|
||||
Subject: [PATCH 19/76] thermal: Make struct thermal_zone_device_ops const
|
||||
|
||||
Now that the of thermal support no longer changes the
|
||||
thermal_zone_device_ops it can be const again.
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
---
|
||||
Documentation/thermal/sysfs-api.txt | 2 +-
|
||||
drivers/acpi/thermal.c | 2 +-
|
||||
drivers/platform/x86/acerhdf.c | 2 +-
|
||||
drivers/platform/x86/intel_mid_thermal.c | 2 +-
|
||||
drivers/power/power_supply_core.c | 2 +-
|
||||
drivers/thermal/armada_thermal.c | 2 +-
|
||||
drivers/thermal/db8500_thermal.c | 2 +-
|
||||
drivers/thermal/dove_thermal.c | 2 +-
|
||||
drivers/thermal/imx_thermal.c | 2 +-
|
||||
drivers/thermal/int340x_thermal/int3400_thermal.c | 2 +-
|
||||
drivers/thermal/int340x_thermal/int340x_thermal_zone.c | 2 +-
|
||||
drivers/thermal/intel_soc_dts_thermal.c | 2 +-
|
||||
drivers/thermal/kirkwood_thermal.c | 2 +-
|
||||
drivers/thermal/of-thermal.c | 2 +-
|
||||
drivers/thermal/rcar_thermal.c | 2 +-
|
||||
drivers/thermal/spear_thermal.c | 2 +-
|
||||
drivers/thermal/st/st_thermal.c | 2 +-
|
||||
drivers/thermal/thermal_core.c | 2 +-
|
||||
drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 2 +-
|
||||
drivers/thermal/x86_pkg_temp_thermal.c | 2 +-
|
||||
include/linux/thermal.h | 6 +++---
|
||||
21 files changed, 23 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
|
||||
index 87519cb..bb346a2 100644
|
||||
--- a/Documentation/thermal/sysfs-api.txt
|
||||
+++ b/Documentation/thermal/sysfs-api.txt
|
||||
@@ -33,7 +33,7 @@ temperature) and throttle appropriate devices.
|
||||
1.1 thermal zone device interface
|
||||
1.1.1 struct thermal_zone_device *thermal_zone_device_register(char *type,
|
||||
int trips, int mask, void *devdata,
|
||||
- struct thermal_zone_device_ops *ops,
|
||||
+ const struct thermal_zone_device_ops *ops,
|
||||
const struct thermal_zone_params *tzp,
|
||||
int passive_delay, int polling_delay))
|
||||
|
||||
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
|
||||
index 68bff60..6b11462 100644
|
||||
--- a/drivers/acpi/thermal.c
|
||||
+++ b/drivers/acpi/thermal.c
|
||||
@@ -869,7 +869,7 @@ acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal,
|
||||
return acpi_thermal_cooling_device_cb(thermal, cdev, false);
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops acpi_thermal_zone_ops = {
|
||||
+static const struct thermal_zone_device_ops acpi_thermal_zone_ops = {
|
||||
.bind = acpi_thermal_bind_cooling_device,
|
||||
.unbind = acpi_thermal_unbind_cooling_device,
|
||||
.get_temp = thermal_get_temp,
|
||||
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
|
||||
index f2ce63c..bae9ca0 100644
|
||||
--- a/drivers/platform/x86/acerhdf.c
|
||||
+++ b/drivers/platform/x86/acerhdf.c
|
||||
@@ -482,7 +482,7 @@ static int acerhdf_get_crit_temp(struct thermal_zone_device *thermal,
|
||||
}
|
||||
|
||||
/* bind callback functions to thermalzone */
|
||||
-static struct thermal_zone_device_ops acerhdf_dev_ops = {
|
||||
+static const struct thermal_zone_device_ops acerhdf_dev_ops = {
|
||||
.bind = acerhdf_bind,
|
||||
.unbind = acerhdf_unbind,
|
||||
.get_temp = acerhdf_get_ec_temp,
|
||||
diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c
|
||||
index 0944e83..069d36b 100644
|
||||
--- a/drivers/platform/x86/intel_mid_thermal.c
|
||||
+++ b/drivers/platform/x86/intel_mid_thermal.c
|
||||
@@ -460,7 +460,7 @@ static int read_curr_temp(struct thermal_zone_device *tzd, unsigned long *temp)
|
||||
}
|
||||
|
||||
/* Can't be const */
|
||||
-static struct thermal_zone_device_ops tzd_ops = {
|
||||
+static const struct thermal_zone_device_ops tzd_ops = {
|
||||
.get_temp = read_curr_temp,
|
||||
};
|
||||
|
||||
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
|
||||
index 87e2fd1..878cb4e 100644
|
||||
--- a/drivers/power/power_supply_core.c
|
||||
+++ b/drivers/power/power_supply_core.c
|
||||
@@ -509,7 +509,7 @@ static int power_supply_read_temp(struct thermal_zone_device *tzd,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops psy_tzd_ops = {
|
||||
+static const struct thermal_zone_device_ops psy_tzd_ops = {
|
||||
.get_temp = power_supply_read_temp,
|
||||
};
|
||||
|
||||
diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
|
||||
index 26b8d32..3f59c8b 100644
|
||||
--- a/drivers/thermal/armada_thermal.c
|
||||
+++ b/drivers/thermal/armada_thermal.c
|
||||
@@ -183,7 +183,7 @@ static int armada_get_temp(struct thermal_zone_device *thermal,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops ops = {
|
||||
+static const struct thermal_zone_device_ops ops = {
|
||||
.get_temp = armada_get_temp,
|
||||
};
|
||||
|
||||
diff --git a/drivers/thermal/db8500_thermal.c b/drivers/thermal/db8500_thermal.c
|
||||
index b3eca71..38d6aab9 100644
|
||||
--- a/drivers/thermal/db8500_thermal.c
|
||||
+++ b/drivers/thermal/db8500_thermal.c
|
||||
@@ -210,7 +210,7 @@ static int db8500_sys_get_crit_temp(struct thermal_zone_device *thermal,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops thdev_ops = {
|
||||
+static const struct thermal_zone_device_ops thdev_ops = {
|
||||
.bind = db8500_cdev_bind,
|
||||
.unbind = db8500_cdev_unbind,
|
||||
.get_temp = db8500_sys_get_temp,
|
||||
diff --git a/drivers/thermal/dove_thermal.c b/drivers/thermal/dove_thermal.c
|
||||
index a0bc9de..e8fd627 100644
|
||||
--- a/drivers/thermal/dove_thermal.c
|
||||
+++ b/drivers/thermal/dove_thermal.c
|
||||
@@ -118,7 +118,7 @@ static int dove_get_temp(struct thermal_zone_device *thermal,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops ops = {
|
||||
+static const struct thermal_zone_device_ops ops = {
|
||||
.get_temp = dove_get_temp,
|
||||
};
|
||||
|
||||
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
|
||||
index f1424f0..8a3cfed 100644
|
||||
--- a/drivers/thermal/imx_thermal.c
|
||||
+++ b/drivers/thermal/imx_thermal.c
|
||||
@@ -332,7 +332,7 @@ static int imx_unbind(struct thermal_zone_device *tz,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops imx_tz_ops = {
|
||||
+static const struct thermal_zone_device_ops imx_tz_ops = {
|
||||
.bind = imx_bind,
|
||||
.unbind = imx_unbind,
|
||||
.get_temp = imx_get_temp,
|
||||
diff --git a/drivers/thermal/int340x_thermal/int3400_thermal.c b/drivers/thermal/int340x_thermal/int3400_thermal.c
|
||||
index 031018e..96bdf8a 100644
|
||||
--- a/drivers/thermal/int340x_thermal/int3400_thermal.c
|
||||
+++ b/drivers/thermal/int340x_thermal/int3400_thermal.c
|
||||
@@ -231,7 +231,7 @@ static int int3400_thermal_set_mode(struct thermal_zone_device *thermal,
|
||||
return result;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops int3400_thermal_ops = {
|
||||
+static const struct thermal_zone_device_ops int3400_thermal_ops = {
|
||||
.get_temp = int3400_thermal_get_temp,
|
||||
};
|
||||
|
||||
diff --git a/drivers/thermal/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/int340x_thermal/int340x_thermal_zone.c
|
||||
index b9b2666..bd9f9e8 100644
|
||||
--- a/drivers/thermal/int340x_thermal/int340x_thermal_zone.c
|
||||
+++ b/drivers/thermal/int340x_thermal/int340x_thermal_zone.c
|
||||
@@ -154,7 +154,7 @@ static int int340x_thermal_get_trip_hyst(struct thermal_zone_device *zone,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops int340x_thermal_zone_ops = {
|
||||
+static const struct thermal_zone_device_ops int340x_thermal_zone_ops = {
|
||||
.get_temp = int340x_thermal_get_zone_temp,
|
||||
.get_trip_temp = int340x_thermal_get_trip_temp,
|
||||
.get_trip_type = int340x_thermal_get_trip_type,
|
||||
diff --git a/drivers/thermal/intel_soc_dts_thermal.c b/drivers/thermal/intel_soc_dts_thermal.c
|
||||
index fd550b9..625ba6f 100644
|
||||
--- a/drivers/thermal/intel_soc_dts_thermal.c
|
||||
+++ b/drivers/thermal/intel_soc_dts_thermal.c
|
||||
@@ -270,7 +270,7 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops tzone_ops = {
|
||||
+static const struct thermal_zone_device_ops tzone_ops = {
|
||||
.get_temp = sys_get_curr_temp,
|
||||
.get_trip_temp = sys_get_trip_temp,
|
||||
.get_trip_type = sys_get_trip_type,
|
||||
diff --git a/drivers/thermal/kirkwood_thermal.c b/drivers/thermal/kirkwood_thermal.c
|
||||
index 11041fe..abba3e2 100644
|
||||
--- a/drivers/thermal/kirkwood_thermal.c
|
||||
+++ b/drivers/thermal/kirkwood_thermal.c
|
||||
@@ -60,7 +60,7 @@ static int kirkwood_get_temp(struct thermal_zone_device *thermal,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops ops = {
|
||||
+static const struct thermal_zone_device_ops ops = {
|
||||
.get_temp = kirkwood_get_temp,
|
||||
};
|
||||
|
||||
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
|
||||
index b9c35bd..bd3185e 100644
|
||||
--- a/drivers/thermal/of-thermal.c
|
||||
+++ b/drivers/thermal/of-thermal.c
|
||||
@@ -365,7 +365,7 @@ static int of_thermal_get_crit_temp(struct thermal_zone_device *tz,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops of_thermal_ops = {
|
||||
+static const struct thermal_zone_device_ops of_thermal_ops = {
|
||||
.get_temp = of_thermal_get_temp,
|
||||
.get_trend = of_thermal_get_trend,
|
||||
.set_emul_temp = of_thermal_set_emul_temp,
|
||||
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
|
||||
index 5d4ae7d..320ceac 100644
|
||||
--- a/drivers/thermal/rcar_thermal.c
|
||||
+++ b/drivers/thermal/rcar_thermal.c
|
||||
@@ -270,7 +270,7 @@ static int rcar_thermal_notify(struct thermal_zone_device *zone,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops rcar_thermal_zone_ops = {
|
||||
+static const struct thermal_zone_device_ops rcar_thermal_zone_ops = {
|
||||
.get_temp = rcar_thermal_get_temp,
|
||||
.get_trip_type = rcar_thermal_get_trip_type,
|
||||
.get_trip_temp = rcar_thermal_get_trip_temp,
|
||||
diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c
|
||||
index 534dd91..ec07743 100644
|
||||
--- a/drivers/thermal/spear_thermal.c
|
||||
+++ b/drivers/thermal/spear_thermal.c
|
||||
@@ -50,7 +50,7 @@ static inline int thermal_get_temp(struct thermal_zone_device *thermal,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops ops = {
|
||||
+static const struct thermal_zone_device_ops ops = {
|
||||
.get_temp = thermal_get_temp,
|
||||
};
|
||||
|
||||
diff --git a/drivers/thermal/st/st_thermal.c b/drivers/thermal/st/st_thermal.c
|
||||
index 44cbba9..0cb5c19 100644
|
||||
--- a/drivers/thermal/st/st_thermal.c
|
||||
+++ b/drivers/thermal/st/st_thermal.c
|
||||
@@ -175,7 +175,7 @@ static int st_thermal_get_trip_temp(struct thermal_zone_device *th,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops st_tz_ops = {
|
||||
+static const struct thermal_zone_device_ops st_tz_ops = {
|
||||
.get_temp = st_thermal_get_temp,
|
||||
.get_trip_type = st_thermal_get_trip_type,
|
||||
.get_trip_temp = st_thermal_get_trip_temp,
|
||||
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
|
||||
index 3d8f9f9..6bbf61f 100644
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -1451,7 +1451,7 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
|
||||
*/
|
||||
struct thermal_zone_device *thermal_zone_device_register(const char *type,
|
||||
int trips, int mask, void *devdata,
|
||||
- struct thermal_zone_device_ops *ops,
|
||||
+ const struct thermal_zone_device_ops *ops,
|
||||
const struct thermal_zone_params *tzp,
|
||||
int passive_delay, int polling_delay)
|
||||
{
|
||||
diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
|
||||
index ade78eb..e9c82fc 100644
|
||||
--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
|
||||
+++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c
|
||||
@@ -281,7 +281,7 @@ static const struct thermal_zone_of_device_ops ti_of_thermal_ops = {
|
||||
.get_trend = __ti_thermal_get_trend,
|
||||
};
|
||||
|
||||
-static struct thermal_zone_device_ops ti_thermal_ops = {
|
||||
+static const struct thermal_zone_device_ops ti_thermal_ops = {
|
||||
.get_temp = ti_thermal_get_temp,
|
||||
.get_trend = ti_thermal_get_trend,
|
||||
.bind = ti_thermal_bind,
|
||||
diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c
|
||||
index 054c6d45..bb2b975 100644
|
||||
--- a/drivers/thermal/x86_pkg_temp_thermal.c
|
||||
+++ b/drivers/thermal/x86_pkg_temp_thermal.c
|
||||
@@ -274,7 +274,7 @@ static int sys_get_trip_type(struct thermal_zone_device *thermal,
|
||||
}
|
||||
|
||||
/* Thermal zone callback registry */
|
||||
-static struct thermal_zone_device_ops tzone_ops = {
|
||||
+static const struct thermal_zone_device_ops tzone_ops = {
|
||||
.get_temp = sys_get_curr_temp,
|
||||
.get_trip_temp = sys_get_trip_temp,
|
||||
.get_trip_type = sys_get_trip_type,
|
||||
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
|
||||
index 5c6a589..07bd5e8 100644
|
||||
--- a/include/linux/thermal.h
|
||||
+++ b/include/linux/thermal.h
|
||||
@@ -181,7 +181,7 @@ struct thermal_zone_device {
|
||||
int emul_temperature;
|
||||
int passive;
|
||||
unsigned int forced_passive;
|
||||
- struct thermal_zone_device_ops *ops;
|
||||
+ const struct thermal_zone_device_ops *ops;
|
||||
const struct thermal_zone_params *tzp;
|
||||
struct thermal_governor *governor;
|
||||
struct list_head thermal_instances;
|
||||
@@ -313,7 +313,7 @@ void thermal_zone_of_sensor_unregister(struct device *dev,
|
||||
|
||||
#if IS_ENABLED(CONFIG_THERMAL)
|
||||
struct thermal_zone_device *thermal_zone_device_register(const char *, int, int,
|
||||
- void *, struct thermal_zone_device_ops *,
|
||||
+ void *, const struct thermal_zone_device_ops *,
|
||||
const struct thermal_zone_params *, int, int);
|
||||
void thermal_zone_device_unregister(struct thermal_zone_device *);
|
||||
|
||||
@@ -341,7 +341,7 @@ void thermal_notify_framework(struct thermal_zone_device *, int);
|
||||
#else
|
||||
static inline struct thermal_zone_device *thermal_zone_device_register(
|
||||
const char *type, int trips, int mask, void *devdata,
|
||||
- struct thermal_zone_device_ops *ops,
|
||||
+ const struct thermal_zone_device_ops *ops,
|
||||
const struct thermal_zone_params *tzp,
|
||||
int passive_delay, int polling_delay)
|
||||
{ return ERR_PTR(-ENODEV); }
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,124 @@
|
||||
From 346632bc00fe71c269709702fecb474bb22e933e Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Wed, 13 May 2015 10:52:39 +0200
|
||||
Subject: [PATCH 20/76] thermal: thermal: Add support for hardware-tracked
|
||||
trip points
|
||||
|
||||
This adds support for hardware-tracked trip points to the device tree
|
||||
thermal sensor framework.
|
||||
|
||||
The framework supports an arbitrary number of trip points. Whenever
|
||||
the current temperature is updated, the trip points immediately
|
||||
below and above the current temperature are found. A .set_trips
|
||||
callback is then called with the temperatures. If there is no trip
|
||||
point above or below the current temperature, the passed trip
|
||||
temperature will be -INT_MAX or INT_MAX respectively. In this callback,
|
||||
the driver should program the hardware such that it is notified
|
||||
when either of these trip points are triggered. When a trip point
|
||||
is triggered, the driver should call `thermal_zone_device_update'
|
||||
for the respective thermal zone. This will cause the trip points
|
||||
to be updated again.
|
||||
|
||||
If .set_trips is not implemented, the framework behaves as before.
|
||||
|
||||
This patch is based on an earlier version from Mikko Perttunen
|
||||
<mikko.perttunen@kapsi.fi>
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
---
|
||||
drivers/thermal/thermal_core.c | 43 ++++++++++++++++++++++++++++++++++++++++
|
||||
include/linux/thermal.h | 3 +++
|
||||
2 files changed, 46 insertions(+)
|
||||
|
||||
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
|
||||
index 6bbf61f..3ae1795 100644
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -453,6 +453,45 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
|
||||
|
||||
+static void thermal_zone_set_trips(struct thermal_zone_device *tz)
|
||||
+{
|
||||
+ int low = -INT_MAX;
|
||||
+ int high = INT_MAX;
|
||||
+ int trip_temp, hysteresis;
|
||||
+ int temp = tz->temperature;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!tz->ops->set_trips)
|
||||
+ return;
|
||||
+
|
||||
+ /* No need to change trip points */
|
||||
+ if (temp > tz->prev_low_trip && temp < tz->prev_high_trip)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < tz->trips; i++) {
|
||||
+ int trip_low;
|
||||
+
|
||||
+ tz->ops->get_trip_temp(tz, i, &trip_temp);
|
||||
+ tz->ops->get_trip_hyst(tz, i, &hysteresis);
|
||||
+
|
||||
+ trip_low = trip_temp - hysteresis;
|
||||
+
|
||||
+ if (trip_low < temp && trip_low > low)
|
||||
+ low = trip_low;
|
||||
+
|
||||
+ if (trip_temp > temp && trip_temp < high)
|
||||
+ high = trip_temp;
|
||||
+ }
|
||||
+
|
||||
+ tz->prev_low_trip = low;
|
||||
+ tz->prev_high_trip = high;
|
||||
+
|
||||
+ dev_dbg(&tz->device, "new temperature boundaries: %d < x < %d\n",
|
||||
+ low, high);
|
||||
+
|
||||
+ tz->ops->set_trips(tz, low, high);
|
||||
+}
|
||||
+
|
||||
void thermal_zone_device_update(struct thermal_zone_device *tz)
|
||||
{
|
||||
int temp, ret, count;
|
||||
@@ -479,6 +518,8 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
|
||||
dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
|
||||
tz->last_temperature, tz->temperature);
|
||||
|
||||
+ thermal_zone_set_trips(tz);
|
||||
+
|
||||
for (count = 0; count < tz->trips; count++)
|
||||
handle_thermal_trip(tz, count);
|
||||
}
|
||||
@@ -1494,6 +1535,8 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
|
||||
tz->trips = trips;
|
||||
tz->passive_delay = passive_delay;
|
||||
tz->polling_delay = polling_delay;
|
||||
+ tz->prev_low_trip = INT_MAX;
|
||||
+ tz->prev_high_trip = -INT_MAX;
|
||||
|
||||
dev_set_name(&tz->device, "thermal_zone%d", tz->id);
|
||||
result = device_register(&tz->device);
|
||||
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
|
||||
index 07bd5e8..aef6e13 100644
|
||||
--- a/include/linux/thermal.h
|
||||
+++ b/include/linux/thermal.h
|
||||
@@ -87,6 +87,7 @@ struct thermal_zone_device_ops {
|
||||
int (*unbind) (struct thermal_zone_device *,
|
||||
struct thermal_cooling_device *);
|
||||
int (*get_temp) (struct thermal_zone_device *, int *);
|
||||
+ int (*set_trips) (struct thermal_zone_device *, int, int);
|
||||
int (*get_mode) (struct thermal_zone_device *,
|
||||
enum thermal_device_mode *);
|
||||
int (*set_mode) (struct thermal_zone_device *,
|
||||
@@ -180,6 +181,8 @@ struct thermal_zone_device {
|
||||
int last_temperature;
|
||||
int emul_temperature;
|
||||
int passive;
|
||||
+ int prev_low_trip;
|
||||
+ int prev_high_trip;
|
||||
unsigned int forced_passive;
|
||||
const struct thermal_zone_device_ops *ops;
|
||||
const struct thermal_zone_params *tzp;
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,65 @@
|
||||
From 525f68bb9d9f6334dbcd2b5ec99f9d797ff53618 Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Wed, 13 May 2015 10:52:40 +0200
|
||||
Subject: [PATCH 21/76] thermal: of: implement .set_trips for device tree
|
||||
thermal zones
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
---
|
||||
drivers/thermal/of-thermal.c | 12 ++++++++++++
|
||||
include/linux/thermal.h | 3 +++
|
||||
2 files changed, 15 insertions(+)
|
||||
|
||||
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
|
||||
index bd3185e..f8dd847 100644
|
||||
--- a/drivers/thermal/of-thermal.c
|
||||
+++ b/drivers/thermal/of-thermal.c
|
||||
@@ -97,6 +97,17 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz,
|
||||
return data->ops->get_temp(data->sensor_data, temp);
|
||||
}
|
||||
|
||||
+static int of_thermal_set_trips(struct thermal_zone_device *tz,
|
||||
+ int low, int high)
|
||||
+{
|
||||
+ struct __thermal_zone *data = tz->devdata;
|
||||
+
|
||||
+ if (!data->ops || !data->ops->set_trips)
|
||||
+ return -ENOSYS;
|
||||
+
|
||||
+ return data->ops->set_trips(data->sensor_data, low, high);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* of_thermal_get_ntrips - function to export number of available trip
|
||||
* points.
|
||||
@@ -367,6 +378,7 @@ static int of_thermal_get_crit_temp(struct thermal_zone_device *tz,
|
||||
|
||||
static const struct thermal_zone_device_ops of_thermal_ops = {
|
||||
.get_temp = of_thermal_get_temp,
|
||||
+ .set_trips = of_thermal_set_trips,
|
||||
.get_trend = of_thermal_get_trend,
|
||||
.set_emul_temp = of_thermal_set_emul_temp,
|
||||
|
||||
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
|
||||
index aef6e13..b751f6b 100644
|
||||
--- a/include/linux/thermal.h
|
||||
+++ b/include/linux/thermal.h
|
||||
@@ -267,12 +267,15 @@ struct thermal_genl_event {
|
||||
*
|
||||
* Optional:
|
||||
* @get_trend: a pointer to a function that reads the sensor temperature trend.
|
||||
+ * @set_trips: a pointer to a function that sets a temperature window which shall
|
||||
+ * trigger an interrupt when it is left.
|
||||
* @set_emul_temp: a pointer to a function that sets sensor emulated
|
||||
* temperature.
|
||||
*/
|
||||
struct thermal_zone_of_device_ops {
|
||||
int (*get_temp)(void *, int *);
|
||||
int (*get_trend)(void *, int, enum thermal_trend *);
|
||||
+ int (*set_trips)(void *, int, int);
|
||||
int (*set_emul_temp)(void *, int);
|
||||
};
|
||||
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,57 @@
|
||||
From 9b799b8a4ecbf560f8fb996e8e5147a8f7b9a1b3 Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Wed, 13 May 2015 10:52:41 +0200
|
||||
Subject: [PATCH 22/76] dt-bindings: thermal: Add binding document for
|
||||
Mediatek thermal controller
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
---
|
||||
.../bindings/thermal/mediatek-thermal.txt | 36 ++++++++++++++++++++
|
||||
1 file changed, 36 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
|
||||
new file mode 100644
|
||||
index 0000000..adf5d2c
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
|
||||
@@ -0,0 +1,36 @@
|
||||
+* Mediatek Thermal
|
||||
+
|
||||
+This describes the device tree binding for the Mediatek thermal controller
|
||||
+which measures the on-SoC temperatures. This device does not have its own ADC,
|
||||
+instead it directly controls the AUXADC via AHB bus accesses. For this reason
|
||||
+this device needs phandles to the AUXADC.
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible: "mediatek,mt8173-thermal"
|
||||
+- reg: Address range of the thermal controller
|
||||
+- interrupts: IRQ for the thermal controller
|
||||
+- clocks, clock-names: Clocks needed for the thermal controller. required
|
||||
+ clocks are:
|
||||
+ "therm": Main clock needed for register access
|
||||
+ "auxadc": The AUXADC clock
|
||||
+- resets, reset-names: Reference to the reset controller controlling the thermal
|
||||
+ controller. Required reset-names:
|
||||
+ "therm": The main reset line
|
||||
+- auxadc: A phandle to the AUXADC which the thermal controller uses
|
||||
+- apmixedsys: A phandle to the APMIXEDSYS controller.
|
||||
+- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+ thermal: thermal@1100b000 {
|
||||
+ #thermal-sensor-cells = <1>;
|
||||
+ compatible = "mediatek,mt8173-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 MT8173_PERI_THERM_SW_RST>;
|
||||
+ reset-names = "therm";
|
||||
+ auxadc = <&auxadc>;
|
||||
+ apmixedsys = <&apmixedsys>;
|
||||
+ };
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,785 @@
|
||||
From 014330a304100782a26bc7df02778c8c386b2857 Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Wed, 13 May 2015 10:52:42 +0200
|
||||
Subject: [PATCH 23/76] thermal: Add Mediatek thermal controller support
|
||||
|
||||
This adds support for the Mediatek thermal controller found on MT8173
|
||||
and likely other SoCs.
|
||||
The controller is a bit special. It does not have its own ADC, instead
|
||||
it controls the on-SoC AUXADC via AHB bus accesses. For this reason
|
||||
we need the physical address of the AUXADC. Also it controls a mux
|
||||
using AHB bus accesses, so we need the APMIXEDSYS physical address aswell.
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
---
|
||||
drivers/thermal/Kconfig | 8 +
|
||||
drivers/thermal/Makefile | 1 +
|
||||
drivers/thermal/mtk_thermal.c | 728 +++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 737 insertions(+)
|
||||
create mode 100644 drivers/thermal/mtk_thermal.c
|
||||
|
||||
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
|
||||
index af40db0..3aa5500 100644
|
||||
--- a/drivers/thermal/Kconfig
|
||||
+++ b/drivers/thermal/Kconfig
|
||||
@@ -285,6 +285,14 @@ config ACPI_THERMAL_REL
|
||||
tristate
|
||||
depends on ACPI
|
||||
|
||||
+config MTK_THERMAL
|
||||
+ tristate "Temperature sensor driver for mediatek SoCs"
|
||||
+ depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
+ default y
|
||||
+ help
|
||||
+ Enable this option if you want to have support for thermal management
|
||||
+ controller present in Mediatek SoCs
|
||||
+
|
||||
menu "Texas Instruments thermal drivers"
|
||||
source "drivers/thermal/ti-soc-thermal/Kconfig"
|
||||
endmenu
|
||||
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
|
||||
index fa0dc48..51cfab7 100644
|
||||
--- a/drivers/thermal/Makefile
|
||||
+++ b/drivers/thermal/Makefile
|
||||
@@ -39,3 +39,4 @@ obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/
|
||||
obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/
|
||||
obj-$(CONFIG_ST_THERMAL) += st/
|
||||
obj-$(CONFIG_TEGRA_SOCTHERM) += tegra_soctherm.o
|
||||
+obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o
|
||||
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
|
||||
new file mode 100644
|
||||
index 0000000..27aab12
|
||||
--- /dev/null
|
||||
+++ b/drivers/thermal/mtk_thermal.c
|
||||
@@ -0,0 +1,728 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2014 MediaTek Inc.
|
||||
+ * Author: Hanyi.Wu <hanyi.wu@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/dmi.h>
|
||||
+#include <linux/thermal.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/time.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/reset.h>
|
||||
+
|
||||
+/* AUXADC Registers */
|
||||
+#define AUXADC_CON0_V 0x000
|
||||
+#define AUXADC_CON1_V 0x004
|
||||
+#define AUXADC_CON1_SET_V 0x008
|
||||
+#define AUXADC_CON1_CLR_V 0x00c
|
||||
+#define AUXADC_CON2_V 0x010
|
||||
+#define AUXADC_DATA(channel) (0x14 + (channel) * 4)
|
||||
+#define AUXADC_MISC_V 0x094
|
||||
+
|
||||
+#define AUXADC_CON1_CHANNEL(x) (1 << (x))
|
||||
+
|
||||
+/* Thermal Controller Registers */
|
||||
+#define TEMPMONCTL0 0x000
|
||||
+#define TEMPMONCTL1 0x004
|
||||
+#define TEMPMONCTL2 0x008
|
||||
+#define TEMPMONINT 0x00c
|
||||
+#define TEMPMONINTSTS 0x010
|
||||
+#define TEMPMONIDET0 0x014
|
||||
+#define TEMPMONIDET1 0x018
|
||||
+#define TEMPMONIDET2 0x01c
|
||||
+#define TEMPH2NTHRE 0x024
|
||||
+#define TEMPHTHRE 0x028
|
||||
+#define TEMPCTHRE 0x02c
|
||||
+#define TEMPOFFSETH 0x030
|
||||
+#define TEMPOFFSETL 0x034
|
||||
+#define TEMPMSRCTL0 0x038
|
||||
+#define TEMPMSRCTL1 0x03c
|
||||
+#define TEMPAHBPOLL 0x040
|
||||
+#define TEMPAHBTO 0x044
|
||||
+#define TEMPADCPNP0 0x048
|
||||
+#define TEMPADCPNP1 0x04c
|
||||
+#define TEMPADCPNP2 0x050
|
||||
+#define TEMPADCPNP3 0x0b4
|
||||
+
|
||||
+#define TEMPADCMUX 0x054
|
||||
+#define TEMPADCEXT 0x058
|
||||
+#define TEMPADCEXT1 0x05c
|
||||
+#define TEMPADCEN 0x060
|
||||
+#define TEMPPNPMUXADDR 0x064
|
||||
+#define TEMPADCMUXADDR 0x068
|
||||
+#define TEMPADCEXTADDR 0x06c
|
||||
+#define TEMPADCEXT1ADDR 0x070
|
||||
+#define TEMPADCENADDR 0x074
|
||||
+#define TEMPADCVALIDADDR 0x078
|
||||
+#define TEMPADCVOLTADDR 0x07c
|
||||
+#define TEMPRDCTRL 0x080
|
||||
+#define TEMPADCVALIDMASK 0x084
|
||||
+#define TEMPADCVOLTAGESHIFT 0x088
|
||||
+#define TEMPADCWRITECTRL 0x08c
|
||||
+#define TEMPMSR0 0x090
|
||||
+#define TEMPMSR1 0x094
|
||||
+#define TEMPMSR2 0x098
|
||||
+#define TEMPMSR3 0x0B8
|
||||
+
|
||||
+#define TEMPIMMD0 0x0a0
|
||||
+#define TEMPIMMD1 0x0a4
|
||||
+#define TEMPIMMD2 0x0a8
|
||||
+
|
||||
+#define TEMPPROTCTL 0x0c0
|
||||
+#define TEMPPROTTA 0x0c4
|
||||
+#define TEMPPROTTB 0x0c8
|
||||
+#define TEMPPROTTC 0x0cc
|
||||
+
|
||||
+#define TEMPSPARE0 0x0f0
|
||||
+#define TEMPSPARE1 0x0f4
|
||||
+#define TEMPSPARE2 0x0f8
|
||||
+#define TEMPSPARE3 0x0fc
|
||||
+
|
||||
+#define PTPCORESEL 0x400
|
||||
+#define THERMINTST 0x404
|
||||
+#define PTPODINTST 0x408
|
||||
+#define THSTAGE0ST 0x40c
|
||||
+#define THSTAGE1ST 0x410
|
||||
+#define THSTAGE2ST 0x414
|
||||
+#define THAHBST0 0x418
|
||||
+#define THAHBST1 0x41c /* Only for DE debug */
|
||||
+#define PTPSPARE0 0x420
|
||||
+#define PTPSPARE1 0x424
|
||||
+#define PTPSPARE2 0x428
|
||||
+#define PTPSPARE3 0x42c
|
||||
+#define THSLPEVEB 0x430
|
||||
+
|
||||
+#define TEMPMONINT_COLD(sp) ((1 << 0) << ((sp) * 5))
|
||||
+#define TEMPMONINT_HOT(sp) ((1 << 1) << ((sp) * 5))
|
||||
+#define TEMPMONINT_LOW_OFS(sp) ((1 << 2) << ((sp) * 5))
|
||||
+#define TEMPMONINT_HIGH_OFS(sp) ((1 << 3) << ((sp) * 5))
|
||||
+#define TEMPMONINT_HOT_TO_NORM(sp) ((1 << 4) << ((sp) * 5))
|
||||
+#define TEMPMONINT_TIMEOUT (1 << 15)
|
||||
+#define TEMPMONINT_IMMEDIATE_SENSE(sp) (1 << (16 + (sp)))
|
||||
+#define TEMPMONINT_FILTER_SENSE(sp) (1 << (19 + (sp)))
|
||||
+
|
||||
+#define TEMPADCWRITECTRL_ADC_PNP_WRITE (1 << 0)
|
||||
+#define TEMPADCWRITECTRL_ADC_MUX_WRITE (1 << 1)
|
||||
+#define TEMPADCWRITECTRL_ADC_EXTRA_WRITE (1 << 2)
|
||||
+#define TEMPADCWRITECTRL_ADC_EXTRA1_WRITE (1 << 3)
|
||||
+
|
||||
+#define TEMPADCVALIDMASK_VALID_HIGH (1 << 5)
|
||||
+#define TEMPADCVALIDMASK_VALID_POS(bit) (bit)
|
||||
+
|
||||
+#define TEMPPROTCTL_AVERAGE (0 << 16)
|
||||
+#define TEMPPROTCTL_MAXIMUM (1 << 16)
|
||||
+#define TEMPPROTCTL_SELECTED (2 << 16)
|
||||
+
|
||||
+#define MT8173_THERMAL_ZONE_CA57 0
|
||||
+#define MT8173_THERMAL_ZONE_CA53 1
|
||||
+#define MT8173_THERMAL_ZONE_GPU 2
|
||||
+#define MT8173_THERMAL_ZONE_CORE 3
|
||||
+
|
||||
+#define MT8173_TS1 0
|
||||
+#define MT8173_TS2 1
|
||||
+#define MT8173_TS3 2
|
||||
+#define MT8173_TS4 3
|
||||
+#define MT8173_TSABB 4
|
||||
+
|
||||
+/* AUXADC channel 11 is used for the temperature sensors */
|
||||
+#define MT8173_TEMP_AUXADC_CHANNEL 11
|
||||
+
|
||||
+/* The total number of temperature sensors in the MT8173 */
|
||||
+#define MT8173_NUM_SENSORS 5
|
||||
+
|
||||
+/* The number of banks in the MT8173 */
|
||||
+#define MT8173_NUM_BANKS 4
|
||||
+
|
||||
+/* The number of sensing points per bank */
|
||||
+#define MT8173_NUM_SENSING_POINTS 4
|
||||
+
|
||||
+#define THERMAL_NAME "mtk-thermal"
|
||||
+
|
||||
+struct mtk_thermal;
|
||||
+
|
||||
+struct mtk_thermal_bank {
|
||||
+ struct mtk_thermal *mt;
|
||||
+ struct thermal_zone_device *tz;
|
||||
+ int id;
|
||||
+};
|
||||
+
|
||||
+struct mtk_thermal {
|
||||
+ struct device *dev;
|
||||
+ void __iomem *thermal_base;
|
||||
+ void __iomem *auxadc_base;
|
||||
+
|
||||
+ u64 auxadc_phys_base;
|
||||
+ u64 apmixed_phys_base;
|
||||
+ struct reset_control *reset;
|
||||
+ struct clk *clk_peri_therm;
|
||||
+ struct clk *clk_auxadc;
|
||||
+
|
||||
+ struct mtk_thermal_bank banks[MT8173_NUM_BANKS];
|
||||
+
|
||||
+ struct mutex lock;
|
||||
+
|
||||
+ /* Calibration values */
|
||||
+ s32 adc_ge;
|
||||
+ s32 adc_oe;
|
||||
+ s32 degc_cali;
|
||||
+ s32 o_slope;
|
||||
+ s32 vts;
|
||||
+};
|
||||
+
|
||||
+struct mtk_thermal_bank_cfg {
|
||||
+ unsigned int enable_mask;
|
||||
+ unsigned int sensors[4];
|
||||
+};
|
||||
+
|
||||
+static int sensor_mux_values[MT8173_NUM_SENSORS] = { 0, 1, 2, 3, 16 };
|
||||
+
|
||||
+/*
|
||||
+ * The MT8173 thermal controller has four banks. Each bank can read up to
|
||||
+ * four temperature sensors simultaneously. The MT8173 has a total of 5
|
||||
+ * temperature sensors. We use each bank to measure a certain area of the
|
||||
+ * SoC. Since TS2 is located centrally in the SoC it is influenced by multiple
|
||||
+ * areas, hence is used in different banks.
|
||||
+ */
|
||||
+static struct mtk_thermal_bank_cfg bank_data[] = {
|
||||
+ {
|
||||
+ .enable_mask = 3,
|
||||
+ .sensors = { MT8173_TS2, MT8173_TS3 },
|
||||
+ }, {
|
||||
+ .enable_mask = 3,
|
||||
+ .sensors = { MT8173_TS2, MT8173_TS4 },
|
||||
+ }, {
|
||||
+ .enable_mask = 7,
|
||||
+ .sensors = { MT8173_TS1, MT8173_TS2, MT8173_TSABB },
|
||||
+ }, {
|
||||
+ .enable_mask = 1,
|
||||
+ .sensors = { MT8173_TS2 },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int tempmsr_ofs[MT8173_NUM_SENSING_POINTS] = {
|
||||
+ TEMPMSR0, TEMPMSR1, TEMPMSR2, TEMPMSR3
|
||||
+};
|
||||
+
|
||||
+static int tempadcpnp_ofs[MT8173_NUM_SENSING_POINTS] = {
|
||||
+ TEMPADCPNP0, TEMPADCPNP1, TEMPADCPNP2, TEMPADCPNP3
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * raw_to_mcelsius - convert a raw ADC value to mcelsius
|
||||
+ * @mt: The thermal controller
|
||||
+ * @raw: raw ADC value
|
||||
+ *
|
||||
+ * This converts the raw ADC value to mcelsius using the SoC specific
|
||||
+ * calibration constants
|
||||
+ */
|
||||
+static int raw_to_mcelsius(struct mtk_thermal *mt, u32 raw)
|
||||
+{
|
||||
+ s32 format_1, format_2, format_3, format_4;
|
||||
+ s32 xtoomt;
|
||||
+ s32 gain;
|
||||
+
|
||||
+ raw &= 0xfff;
|
||||
+
|
||||
+ gain = (10000 + mt->adc_ge);
|
||||
+
|
||||
+ xtoomt = ((((mt->vts + 3350 - mt->adc_oe) * 10000) / 4096) * 10000) /
|
||||
+ gain;
|
||||
+
|
||||
+ format_1 = ((mt->degc_cali * 10) >> 1);
|
||||
+ format_2 = (raw - mt->adc_oe);
|
||||
+ format_3 = (((((format_2) * 10000) >> 12) * 10000) / gain) - xtoomt;
|
||||
+ format_3 = format_3 * 15 / 18;
|
||||
+ format_4 = ((format_3 * 100) / (165 + mt->o_slope));
|
||||
+ format_4 = format_4 - (format_4 << 1);
|
||||
+
|
||||
+ return (format_1 + format_4) * 100;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * mcelsius_to_raw - convert mcelsius to raw ADC value
|
||||
+ * @mt: The thermal controller
|
||||
+ * @temp: The temperature in mcelsius
|
||||
+ *
|
||||
+ * This converts a temperature in mcelsius to a raw ADC value, needed to
|
||||
+ * calculate the trigger values for interrupt generation.
|
||||
+ */
|
||||
+static u32 mcelsius_to_raw(struct mtk_thermal *mt, int temp)
|
||||
+{
|
||||
+ s32 format_1, format_2, format_3, format_4;
|
||||
+ s32 xtoomt;
|
||||
+ s32 gain;
|
||||
+
|
||||
+ gain = (10000 + mt->adc_ge);
|
||||
+
|
||||
+ xtoomt = ((((mt->vts + 3350 - mt->adc_oe) * 10000) / 4096) * 10000) /
|
||||
+ gain;
|
||||
+
|
||||
+ format_1 = temp - (mt->degc_cali * 1000 / 2);
|
||||
+ format_2 = format_1 * (165 + mt->o_slope) * 18 / 15;
|
||||
+ format_2 = format_2 - 2 * format_2;
|
||||
+ format_3 = format_2 / 1000 + xtoomt * 10;
|
||||
+ format_4 = (format_3 * 4096 / 10000 * gain) / 100000 + mt->adc_oe;
|
||||
+
|
||||
+ return format_4;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * mtk_thermal_get_bank - get bank
|
||||
+ * @bank: The bank
|
||||
+ *
|
||||
+ * The bank registers are banked, we have to select a bank in the
|
||||
+ * PTPCORESEL register to access it.
|
||||
+ */
|
||||
+static void mtk_thermal_get_bank(struct mtk_thermal_bank *bank)
|
||||
+{
|
||||
+ struct mtk_thermal *mt = bank->mt;
|
||||
+ u32 val;
|
||||
+
|
||||
+ mutex_lock(&mt->lock);
|
||||
+
|
||||
+ val = readl(mt->thermal_base + PTPCORESEL);
|
||||
+ val &= ~0xf;
|
||||
+ val |= bank->id;
|
||||
+ writel(val, mt->thermal_base + PTPCORESEL);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * mtk_thermal_put_bank - release bank
|
||||
+ * @bank: The bank
|
||||
+ *
|
||||
+ * release a bank previously taken with mtk_thermal_get_bank,
|
||||
+ */
|
||||
+static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank)
|
||||
+{
|
||||
+ struct mtk_thermal *mt = bank->mt;
|
||||
+
|
||||
+ mutex_unlock(&mt->lock);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * mtk_thermal_bank_temperature - get the temperature of a bank
|
||||
+ * @bank: The bank
|
||||
+ *
|
||||
+ * The temperature of a bank is considered the maximum temperature of
|
||||
+ * the sensors associated to the bank.
|
||||
+ */
|
||||
+static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank)
|
||||
+{
|
||||
+ struct mtk_thermal *mt = bank->mt;
|
||||
+ int temp, i, max;
|
||||
+ u32 raw;
|
||||
+
|
||||
+ temp = max = -INT_MAX;
|
||||
+
|
||||
+ for (i = 0; i < 4; i++) {
|
||||
+ int sensno;
|
||||
+
|
||||
+ if (!(bank_data[bank->id].enable_mask & (1 << i)))
|
||||
+ continue;
|
||||
+
|
||||
+ raw = readl(mt->thermal_base + tempmsr_ofs[i]);
|
||||
+
|
||||
+ sensno = bank_data[bank->id].sensors[i];
|
||||
+ temp = raw_to_mcelsius(mt, raw);
|
||||
+
|
||||
+ if (temp > max)
|
||||
+ max = temp;
|
||||
+ }
|
||||
+
|
||||
+ return max;
|
||||
+}
|
||||
+
|
||||
+static void mtk_thermal_irq_bank(struct mtk_thermal_bank *bank)
|
||||
+{
|
||||
+ struct mtk_thermal *mt = bank->mt;
|
||||
+ int sp;
|
||||
+ u32 irqstat;
|
||||
+ bool update = false;
|
||||
+
|
||||
+ mtk_thermal_get_bank(bank);
|
||||
+
|
||||
+ irqstat = readl(mt->thermal_base + TEMPMONINTSTS);
|
||||
+
|
||||
+ mtk_thermal_put_bank(bank);
|
||||
+
|
||||
+ for (sp = 0; sp < 3; sp++) {
|
||||
+ if (irqstat & TEMPMONINT_LOW_OFS(sp)) {
|
||||
+ update = true;
|
||||
+ dev_vdbg(mt->dev, "bank %d sensor %d low offset interrupt\n",
|
||||
+ bank->id, sp);
|
||||
+ }
|
||||
+
|
||||
+ if (irqstat & TEMPMONINT_HIGH_OFS(sp)) {
|
||||
+ update = true;
|
||||
+ dev_vdbg(mt->dev, "bank %d sensor %d high offset interrupt\n",
|
||||
+ bank->id, sp);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (update)
|
||||
+ thermal_zone_device_update(bank->tz);
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t mtk_thermal_irq(int irq, void *dev_id)
|
||||
+{
|
||||
+ struct mtk_thermal *mt = dev_id;
|
||||
+ u32 irqstat = 0;
|
||||
+ int i;
|
||||
+
|
||||
+ irqstat = readl(mt->thermal_base + THERMINTST);
|
||||
+
|
||||
+ dev_vdbg(mt->dev, "thermal_interrupt_handler : THERMINTST = 0x%x\n",
|
||||
+ irqstat);
|
||||
+
|
||||
+ for (i = 0; i < MT8173_NUM_BANKS; i++) {
|
||||
+ if (!(irqstat & (1 << i)))
|
||||
+ mtk_thermal_irq_bank(&mt->banks[i]);
|
||||
+ }
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static int mtk_read_temp(void *data, int *temp)
|
||||
+{
|
||||
+ struct mtk_thermal_bank *bank = data;
|
||||
+
|
||||
+ mtk_thermal_get_bank(bank);
|
||||
+
|
||||
+ *temp = mtk_thermal_bank_temperature(bank);
|
||||
+
|
||||
+ mtk_thermal_put_bank(bank);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mtk_set_trips(void *data, int low, int high)
|
||||
+{
|
||||
+ struct mtk_thermal_bank *bank = data;
|
||||
+ struct mtk_thermal *mt = bank->mt;
|
||||
+ int i;
|
||||
+ u32 val, enable_mask;
|
||||
+ u32 raw_low, raw_high;
|
||||
+
|
||||
+ raw_low = mcelsius_to_raw(mt, low);
|
||||
+ raw_high = mcelsius_to_raw(mt, high);
|
||||
+
|
||||
+ mtk_thermal_get_bank(bank);
|
||||
+
|
||||
+ writel(0x0, mt->thermal_base + TEMPMONINT);
|
||||
+
|
||||
+ writel(TEMPPROTCTL_SELECTED, mt->thermal_base + TEMPPROTCTL);
|
||||
+
|
||||
+ writel(raw_low, mt->thermal_base + TEMPOFFSETL);
|
||||
+ writel(raw_high, mt->thermal_base + TEMPOFFSETH);
|
||||
+
|
||||
+ enable_mask = readl(mt->thermal_base + TEMPMONCTL0);
|
||||
+
|
||||
+ val = 0;
|
||||
+ for (i = 0; i < MT8173_NUM_SENSING_POINTS; i++)
|
||||
+ if (enable_mask & (1 << i))
|
||||
+ val |= TEMPMONINT_LOW_OFS(i) | TEMPMONINT_HIGH_OFS(i);
|
||||
+
|
||||
+ writel(val, mt->thermal_base + TEMPMONINT);
|
||||
+
|
||||
+ mtk_thermal_put_bank(bank);
|
||||
+
|
||||
+ dev_dbg(mt->dev, "new boundaries: %d (0x%04x) < x < %d (0x%04x)\n",
|
||||
+ low, mcelsius_to_raw(mt, low),
|
||||
+ high, mcelsius_to_raw(mt, high));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct thermal_zone_of_device_ops mtk_thermal_ops = {
|
||||
+ .get_temp = mtk_read_temp,
|
||||
+ .set_trips = mtk_set_trips,
|
||||
+};
|
||||
+
|
||||
+static void mtk_thermal_init_bank(struct mtk_thermal_bank *bank)
|
||||
+{
|
||||
+ struct mtk_thermal *mt = bank->mt;
|
||||
+ struct mtk_thermal_bank_cfg *cfg = &bank_data[bank->id];
|
||||
+ int i;
|
||||
+
|
||||
+ mtk_thermal_get_bank(bank);
|
||||
+
|
||||
+ /* bus clock 66M counting unit is 12 * 15.15ns * 256 = 46.540us */
|
||||
+ writel(0x0000000c, mt->thermal_base + TEMPMONCTL1);
|
||||
+
|
||||
+ /*
|
||||
+ * filt interval is 1 * 46.540us = 46.54us,
|
||||
+ * sen interval is 429 * 46.540us = 19.96ms
|
||||
+ */
|
||||
+ writel(0x000101ad, mt->thermal_base + TEMPMONCTL2);
|
||||
+
|
||||
+ /* poll is set to 10u */
|
||||
+ writel(0x00000300, mt->thermal_base + TEMPAHBPOLL);
|
||||
+
|
||||
+ /* temperature sampling control, 1 sample */
|
||||
+ writel(0x00000000, mt->thermal_base + TEMPMSRCTL0);
|
||||
+
|
||||
+ /* exceed this polling time, IRQ would be inserted */
|
||||
+ writel(0xffffffff, mt->thermal_base + TEMPAHBTO);
|
||||
+
|
||||
+ /* number of interrupts per event, 1 is enough */
|
||||
+ writel(0x0, mt->thermal_base + TEMPMONIDET0);
|
||||
+ writel(0x0, mt->thermal_base + TEMPMONIDET1);
|
||||
+
|
||||
+ /*
|
||||
+ * The MT8173 thermal controller does not have its own ADC. Instead it
|
||||
+ * uses AHB bus accesses to control the AUXADC. To do this the thermal
|
||||
+ * controller has to be programmed with the physical addresses of the
|
||||
+ * AUXADC registers and with the various bit positions in the AUXADC.
|
||||
+ * Also the thermal controller controls a mux in the APMIXEDSYS register
|
||||
+ * space.
|
||||
+ */
|
||||
+
|
||||
+ /*
|
||||
+ * this value will be stored to TEMPPNPMUXADDR (TEMPSPARE0)
|
||||
+ * automatically by hw
|
||||
+ */
|
||||
+ writel(1 << MT8173_TEMP_AUXADC_CHANNEL, mt->thermal_base + TEMPADCMUX);
|
||||
+
|
||||
+ /* AHB address for auxadc mux selection */
|
||||
+ writel(mt->auxadc_phys_base + 0x00c,
|
||||
+ mt->thermal_base + TEMPADCMUXADDR);
|
||||
+
|
||||
+ /* AHB address for pnp sensor mux selection */
|
||||
+ writel(mt->apmixed_phys_base + 0x0604,
|
||||
+ mt->thermal_base + TEMPPNPMUXADDR);
|
||||
+
|
||||
+ /* AHB value for auxadc enable */
|
||||
+ writel(1 << MT8173_TEMP_AUXADC_CHANNEL, mt->thermal_base + TEMPADCEN);
|
||||
+
|
||||
+ /* AHB address for auxadc enable (channel 0 immediate mode selected) */
|
||||
+ writel(mt->auxadc_phys_base + AUXADC_CON1_SET_V,
|
||||
+ mt->thermal_base + TEMPADCENADDR);
|
||||
+
|
||||
+ /* AHB address for auxadc valid bit */
|
||||
+ writel(mt->auxadc_phys_base + AUXADC_DATA(MT8173_TEMP_AUXADC_CHANNEL),
|
||||
+ mt->thermal_base + TEMPADCVALIDADDR);
|
||||
+
|
||||
+ /* AHB address for auxadc voltage output */
|
||||
+ writel(mt->auxadc_phys_base + AUXADC_DATA(MT8173_TEMP_AUXADC_CHANNEL),
|
||||
+ mt->thermal_base + TEMPADCVOLTADDR);
|
||||
+
|
||||
+ /* read valid & voltage are at the same register */
|
||||
+ writel(0x0, mt->thermal_base + TEMPRDCTRL);
|
||||
+
|
||||
+ /* indicate where the valid bit is */
|
||||
+ writel(TEMPADCVALIDMASK_VALID_HIGH | TEMPADCVALIDMASK_VALID_POS(12),
|
||||
+ mt->thermal_base + TEMPADCVALIDMASK);
|
||||
+
|
||||
+ /* no shift */
|
||||
+ writel(0x0, mt->thermal_base + TEMPADCVOLTAGESHIFT);
|
||||
+
|
||||
+ /* enable auxadc mux write transaction */
|
||||
+ writel(TEMPADCWRITECTRL_ADC_MUX_WRITE,
|
||||
+ mt->thermal_base + TEMPADCWRITECTRL);
|
||||
+
|
||||
+ for (i = 0; i < MT8173_NUM_SENSING_POINTS; i++)
|
||||
+ writel(sensor_mux_values[cfg->sensors[i]],
|
||||
+ mt->thermal_base + tempadcpnp_ofs[i]);
|
||||
+
|
||||
+ writel(cfg->enable_mask, mt->thermal_base + TEMPMONCTL0);
|
||||
+
|
||||
+ writel(TEMPADCWRITECTRL_ADC_PNP_WRITE | TEMPADCWRITECTRL_ADC_MUX_WRITE,
|
||||
+ mt->thermal_base + TEMPADCWRITECTRL);
|
||||
+
|
||||
+ mtk_thermal_put_bank(bank);
|
||||
+}
|
||||
+
|
||||
+static u64 of_get_phys_base(struct device_node *np)
|
||||
+{
|
||||
+ u64 size64;
|
||||
+ const __be32 *regaddr_p;
|
||||
+
|
||||
+ regaddr_p = of_get_address(np, 0, &size64, NULL);
|
||||
+ if (!regaddr_p)
|
||||
+ return OF_BAD_ADDR;
|
||||
+
|
||||
+ return of_translate_address(np, regaddr_p);
|
||||
+}
|
||||
+
|
||||
+static int mtk_thermal_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ int ret, i;
|
||||
+ struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node;
|
||||
+ int irq;
|
||||
+ struct mtk_thermal *mt;
|
||||
+ struct resource *res;
|
||||
+
|
||||
+ mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL);
|
||||
+ if (!mt)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ mt->clk_peri_therm = devm_clk_get(&pdev->dev, "therm");
|
||||
+ if (IS_ERR(mt->clk_peri_therm))
|
||||
+ return PTR_ERR(mt->clk_peri_therm);
|
||||
+
|
||||
+ mt->clk_auxadc = devm_clk_get(&pdev->dev, "auxadc");
|
||||
+ if (IS_ERR(mt->clk_auxadc))
|
||||
+ return PTR_ERR(mt->clk_auxadc);
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ mt->thermal_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (IS_ERR(mt->thermal_base))
|
||||
+ return PTR_ERR(mt->thermal_base);
|
||||
+
|
||||
+ mt->reset = devm_reset_control_get(&pdev->dev, "therm");
|
||||
+ if (IS_ERR(mt->reset)) {
|
||||
+ ret = PTR_ERR(mt->reset);
|
||||
+ dev_err(&pdev->dev, "cannot get reset: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ mutex_init(&mt->lock);
|
||||
+
|
||||
+ mt->dev = &pdev->dev;
|
||||
+
|
||||
+ auxadc = of_parse_phandle(np, "auxadc", 0);
|
||||
+ if (!auxadc) {
|
||||
+ dev_err(&pdev->dev, "missing auxadc node\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ mt->auxadc_phys_base = of_get_phys_base(auxadc);
|
||||
+ if (mt->auxadc_phys_base == OF_BAD_ADDR) {
|
||||
+ dev_err(&pdev->dev, "Can't get auxadc phys address\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ apmixedsys = of_parse_phandle(np, "apmixedsys", 0);
|
||||
+ if (!apmixedsys) {
|
||||
+ dev_err(&pdev->dev, "missing apmixedsys node\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ mt->apmixed_phys_base = of_get_phys_base(apmixedsys);
|
||||
+ if (mt->apmixed_phys_base == OF_BAD_ADDR) {
|
||||
+ dev_err(&pdev->dev, "Can't get auxadc phys address\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ irq = platform_get_irq(pdev, 0);
|
||||
+ if (!irq) {
|
||||
+ dev_err(&pdev->dev, "Can't find irq\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, mtk_thermal_irq,
|
||||
+ IRQF_ONESHOT, THERMAL_NAME, mt);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "Can't request irq %d: %d\n", irq, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_prepare_enable(mt->clk_auxadc);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "Can't enable auxadc clk: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ reset_control_reset(mt->reset);
|
||||
+
|
||||
+ ret = clk_prepare_enable(mt->clk_peri_therm);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "Can't enable peri clk: %d\n", ret);
|
||||
+ goto err_enable_clk;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * These calibration values should finally be provided by the
|
||||
+ * firmware or fuses. For now use default values.
|
||||
+ */
|
||||
+ mt->adc_ge = ((512 - 512) * 10000) / 4096;
|
||||
+ mt->adc_oe = 512 - 512;
|
||||
+ mt->degc_cali = 40;
|
||||
+ mt->o_slope = 0;
|
||||
+ mt->vts = 260;
|
||||
+
|
||||
+ for (i = 0; i < MT8173_NUM_BANKS; i++) {
|
||||
+ struct mtk_thermal_bank *bank = &mt->banks[i];
|
||||
+
|
||||
+ bank->id = i;
|
||||
+ bank->mt = mt;
|
||||
+ mtk_thermal_init_bank(&mt->banks[i]);
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, mt);
|
||||
+
|
||||
+ /*
|
||||
+ * This is needed after initialising the banks because otherwise
|
||||
+ * the first temperature read contains bogus high temperatures which
|
||||
+ * immediately cause a system shutdown.
|
||||
+ */
|
||||
+ msleep(100);
|
||||
+
|
||||
+ for (i = 0; i < MT8173_NUM_BANKS; i++) {
|
||||
+ struct mtk_thermal_bank *bank = &mt->banks[i];
|
||||
+
|
||||
+ bank->tz = thermal_zone_of_sensor_register(&pdev->dev, i, bank,
|
||||
+ &mtk_thermal_ops);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_enable_clk:
|
||||
+ clk_disable_unprepare(mt->clk_peri_therm);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int mtk_thermal_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mtk_thermal *mt = platform_get_drvdata(pdev);
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < MT8173_NUM_BANKS; i++) {
|
||||
+ struct mtk_thermal_bank *bank = &mt->banks[i];
|
||||
+
|
||||
+ if (!IS_ERR(bank))
|
||||
+ thermal_zone_of_sensor_unregister(&pdev->dev, bank->tz);
|
||||
+ }
|
||||
+
|
||||
+ clk_disable_unprepare(mt->clk_peri_therm);
|
||||
+ clk_disable_unprepare(mt->clk_auxadc);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mtk_thermal_of_match[] = {
|
||||
+ {
|
||||
+ .compatible = "mediatek,mt8173-thermal",
|
||||
+ }, {
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct platform_driver mtk_thermal_driver = {
|
||||
+ .probe = mtk_thermal_probe,
|
||||
+ .remove = mtk_thermal_remove,
|
||||
+ .driver = {
|
||||
+ .name = THERMAL_NAME,
|
||||
+ .of_match_table = mtk_thermal_of_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(mtk_thermal_driver);
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,49 @@
|
||||
From 720e25e5c821336f7fa0c5fb564475c791c00340 Mon Sep 17 00:00:00 2001
|
||||
From: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Date: Wed, 13 May 2015 10:52:43 +0200
|
||||
Subject: [PATCH 24/76] ARM64: dts: mt8173: Add thermal/auxadc device nodes
|
||||
|
||||
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
---
|
||||
arch/arm64/boot/dts/mediatek/mt8173.dtsi | 18 ++++++++++++++++++
|
||||
1 file changed, 18 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
|
||||
index 924fdb6..50d424f 100644
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
|
||||
@@ -147,6 +147,11 @@
|
||||
(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||
};
|
||||
|
||||
+ auxadc: auxadc@11001000 {
|
||||
+ compatible = "mediatek,mt8173-auxadc";
|
||||
+ reg = <0 0x11001000 0 0x1000>;
|
||||
+ };
|
||||
+
|
||||
uart0: serial@11002000 {
|
||||
compatible = "mediatek,mt8173-uart",
|
||||
"mediatek,mt6577-uart";
|
||||
@@ -182,6 +187,19 @@
|
||||
clocks = <&uart_clk>;
|
||||
status = "disabled";
|
||||
};
|
||||
+
|
||||
+ thermal: thermal@1100b000 {
|
||||
+ #thermal-sensor-cells = <1>;
|
||||
+ compatible = "mediatek,mt8173-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 MT8173_PERI_THERM_SW_RST>;
|
||||
+ reset-names = "therm";
|
||||
+ auxadc = <&auxadc>;
|
||||
+ apmixedsys = <&apmixedsys>;
|
||||
+ };
|
||||
};
|
||||
|
||||
};
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,53 @@
|
||||
From a6de66d3cf5add25f2b8913332117f3334db506e Mon Sep 17 00:00:00 2001
|
||||
From: Leilk Liu <leilk.liu@mediatek.com>
|
||||
Date: Fri, 8 May 2015 16:55:41 +0800
|
||||
Subject: [PATCH 25/76] dt-bindings: ARM: Mediatek: Document devicetree
|
||||
bindings for spi bus
|
||||
|
||||
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
|
||||
---
|
||||
.../devicetree/bindings/spi/spi-mt65xx.txt | 32 ++++++++++++++++++++
|
||||
1 file changed, 32 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/spi/spi-mt65xx.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
|
||||
new file mode 100644
|
||||
index 0000000..04c28fd
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
|
||||
@@ -0,0 +1,32 @@
|
||||
+MTK SPI device
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible: should be one of the following.
|
||||
+ - mediatek,mt8173-spi: for mt8173 platforms
|
||||
+ - mediatek,mt8135-spi: for mt8135 platforms
|
||||
+ - mediatek,mt6589-spi: for mt6589 platforms
|
||||
+
|
||||
+- reg: Address and length of the register set for the device
|
||||
+
|
||||
+- interrupts: Should contain spi interrupt
|
||||
+
|
||||
+- clock-names: tuple listing input clock names.
|
||||
+ Required elements: "main"
|
||||
+
|
||||
+- clocks: phandles to input clocks.
|
||||
+
|
||||
+- pad-select: should specify spi pad used, only required for MT8173.
|
||||
+ This value should be 0~3.
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+- SoC Specific Portion:
|
||||
+spi: spi@1100a000 {
|
||||
+ compatible = "mediatek,mt8173-spi";
|
||||
+ reg = <0 0x1100a000 0 0x1000>;
|
||||
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ clocks = <&pericfg PERI_SPI0>;
|
||||
+ clock-names = "main";
|
||||
+ pad-select = <1>;
|
||||
+ status = "disabled";
|
||||
+};
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,679 @@
|
||||
From 047222cfefe97ef8706f03117bc8deada4cb4ddd Mon Sep 17 00:00:00 2001
|
||||
From: Leilk Liu <leilk.liu@mediatek.com>
|
||||
Date: Fri, 8 May 2015 16:55:42 +0800
|
||||
Subject: [PATCH 26/76] spi: mediatek: Add spi bus for Mediatek MT8173
|
||||
|
||||
This patch adds basic spi bus for MT8173.
|
||||
|
||||
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
|
||||
---
|
||||
drivers/spi/Kconfig | 10 +
|
||||
drivers/spi/Makefile | 1 +
|
||||
drivers/spi/spi-mt65xx.c | 622 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 633 insertions(+)
|
||||
create mode 100644 drivers/spi/spi-mt65xx.c
|
||||
|
||||
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
|
||||
index 72b0590..53dbea3 100644
|
||||
--- a/drivers/spi/Kconfig
|
||||
+++ b/drivers/spi/Kconfig
|
||||
@@ -325,6 +325,16 @@ config SPI_MESON_SPIFC
|
||||
This enables master mode support for the SPIFC (SPI flash
|
||||
controller) available in Amlogic Meson SoCs.
|
||||
|
||||
+config SPI_MT65XX
|
||||
+ tristate "MediaTek SPI controller"
|
||||
+ depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
+ select SPI_BITBANG
|
||||
+ help
|
||||
+ This selects the MediaTek(R) SPI bus driver.
|
||||
+ If you want to use MediaTek(R) SPI interface,
|
||||
+ say Y or M here.If you are not sure, say N.
|
||||
+ SPI drivers for Mediatek mt65XX series ARM SoCs.
|
||||
+
|
||||
config SPI_OC_TINY
|
||||
tristate "OpenCores tiny SPI"
|
||||
depends on GPIOLIB
|
||||
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
|
||||
index d8cbf65..ab332ef 100644
|
||||
--- a/drivers/spi/Makefile
|
||||
+++ b/drivers/spi/Makefile
|
||||
@@ -48,6 +48,7 @@ obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o
|
||||
obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o
|
||||
obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o
|
||||
obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o
|
||||
+obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o
|
||||
obj-$(CONFIG_SPI_MXS) += spi-mxs.o
|
||||
obj-$(CONFIG_SPI_NUC900) += spi-nuc900.o
|
||||
obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o
|
||||
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
|
||||
new file mode 100644
|
||||
index 0000000..92c119d
|
||||
--- /dev/null
|
||||
+++ b/drivers/spi/spi-mt65xx.c
|
||||
@@ -0,0 +1,622 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015 MediaTek Inc.
|
||||
+ * Author: Leilk Liu <leilk.liu@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/ioport.h>
|
||||
+#include <linux/errno.h>
|
||||
+#include <linux/spi/spi.h>
|
||||
+#include <linux/workqueue.h>
|
||||
+#include <linux/dma-mapping.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/irqreturn.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/sched.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/spi/spi_bitbang.h>
|
||||
+#include <linux/gpio.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_gpio.h>
|
||||
+
|
||||
+#define SPI_CFG0_REG 0x0000
|
||||
+#define SPI_CFG1_REG 0x0004
|
||||
+#define SPI_TX_SRC_REG 0x0008
|
||||
+#define SPI_RX_DST_REG 0x000c
|
||||
+#define SPI_CMD_REG 0x0018
|
||||
+#define SPI_STATUS0_REG 0x001c
|
||||
+#define SPI_PAD_SEL_REG 0x0024
|
||||
+
|
||||
+#define SPI_CFG0_SCK_HIGH_OFFSET 0
|
||||
+#define SPI_CFG0_SCK_LOW_OFFSET 8
|
||||
+#define SPI_CFG0_CS_HOLD_OFFSET 16
|
||||
+#define SPI_CFG0_CS_SETUP_OFFSET 24
|
||||
+
|
||||
+#define SPI_CFG0_SCK_HIGH_MASK 0xff
|
||||
+#define SPI_CFG0_SCK_LOW_MASK 0xff00
|
||||
+#define SPI_CFG0_CS_HOLD_MASK 0xff0000
|
||||
+#define SPI_CFG0_CS_SETUP_MASK 0xff000000
|
||||
+
|
||||
+#define SPI_CFG1_CS_IDLE_OFFSET 0
|
||||
+#define SPI_CFG1_PACKET_LOOP_OFFSET 8
|
||||
+#define SPI_CFG1_PACKET_LENGTH_OFFSET 16
|
||||
+#define SPI_CFG1_GET_TICK_DLY_OFFSET 30
|
||||
+
|
||||
+#define SPI_CFG1_CS_IDLE_MASK 0xff
|
||||
+#define SPI_CFG1_PACKET_LOOP_MASK 0xff00
|
||||
+#define SPI_CFG1_PACKET_LENGTH_MASK 0x3ff0000
|
||||
+#define SPI_CFG1_GET_TICK_DLY_MASK 0xc0000000
|
||||
+
|
||||
+#define SPI_CMD_ACT_OFFSET 0
|
||||
+#define SPI_CMD_RESUME_OFFSET 1
|
||||
+#define SPI_CMD_RST_OFFSET 2
|
||||
+#define SPI_CMD_PAUSE_EN_OFFSET 4
|
||||
+#define SPI_CMD_DEASSERT_OFFSET 5
|
||||
+#define SPI_CMD_CPHA_OFFSET 8
|
||||
+#define SPI_CMD_CPOL_OFFSET 9
|
||||
+#define SPI_CMD_RX_DMA_OFFSET 10
|
||||
+#define SPI_CMD_TX_DMA_OFFSET 11
|
||||
+#define SPI_CMD_TXMSBF_OFFSET 12
|
||||
+#define SPI_CMD_RXMSBF_OFFSET 13
|
||||
+#define SPI_CMD_RX_ENDIAN_OFFSET 14
|
||||
+#define SPI_CMD_TX_ENDIAN_OFFSET 15
|
||||
+#define SPI_CMD_FINISH_IE_OFFSET 16
|
||||
+#define SPI_CMD_PAUSE_IE_OFFSET 17
|
||||
+
|
||||
+#define SPI_CMD_RESUME_MASK 0x2
|
||||
+#define SPI_CMD_RST_MASK 0x4
|
||||
+#define SPI_CMD_PAUSE_EN_MASK 0x10
|
||||
+#define SPI_CMD_DEASSERT_MASK 0x20
|
||||
+#define SPI_CMD_CPHA_MASK 0x100
|
||||
+#define SPI_CMD_CPOL_MASK 0x200
|
||||
+#define SPI_CMD_RX_DMA_MASK 0x400
|
||||
+#define SPI_CMD_TX_DMA_MASK 0x800
|
||||
+#define SPI_CMD_TXMSBF_MASK 0x1000
|
||||
+#define SPI_CMD_RXMSBF_MASK 0x2000
|
||||
+#define SPI_CMD_RX_ENDIAN_MASK 0x4000
|
||||
+#define SPI_CMD_TX_ENDIAN_MASK 0x8000
|
||||
+#define SPI_CMD_FINISH_IE_MASK 0x10000
|
||||
+
|
||||
+#define COMPAT_MT6589 (0x1 << 0)
|
||||
+#define COMPAT_MT8173 (0x1 << 1)
|
||||
+
|
||||
+#define MT8173_MAX_PAD_SEL 3
|
||||
+
|
||||
+#define IDLE 0
|
||||
+#define INPROGRESS 1
|
||||
+#define PAUSED 2
|
||||
+
|
||||
+#define PACKET_SIZE 1024
|
||||
+
|
||||
+struct mtk_chip_config {
|
||||
+ u32 setuptime;
|
||||
+ u32 holdtime;
|
||||
+ u32 high_time;
|
||||
+ u32 low_time;
|
||||
+ u32 cs_idletime;
|
||||
+ u32 tx_mlsb;
|
||||
+ u32 rx_mlsb;
|
||||
+ u32 tx_endian;
|
||||
+ u32 rx_endian;
|
||||
+ u32 pause;
|
||||
+ u32 finish_intr;
|
||||
+ u32 deassert;
|
||||
+ u32 tckdly;
|
||||
+};
|
||||
+
|
||||
+struct mtk_spi_ddata {
|
||||
+ struct spi_bitbang bitbang;
|
||||
+ void __iomem *base;
|
||||
+ u32 irq;
|
||||
+ u32 state;
|
||||
+ u32 platform_compat;
|
||||
+ u32 pad_sel;
|
||||
+ struct clk *clk;
|
||||
+
|
||||
+ const u8 *tx_buf;
|
||||
+ u8 *rx_buf;
|
||||
+ u32 tx_len, rx_len;
|
||||
+ struct completion done;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * A piece of default chip info unless the platform
|
||||
+ * supplies it.
|
||||
+ */
|
||||
+static const struct mtk_chip_config mtk_default_chip_info = {
|
||||
+ .setuptime = 10,
|
||||
+ .holdtime = 12,
|
||||
+ .high_time = 6,
|
||||
+ .low_time = 6,
|
||||
+ .cs_idletime = 12,
|
||||
+ .rx_mlsb = 1,
|
||||
+ .tx_mlsb = 1,
|
||||
+ .tx_endian = 0,
|
||||
+ .rx_endian = 0,
|
||||
+ .pause = 0,
|
||||
+ .finish_intr = 1,
|
||||
+ .deassert = 0,
|
||||
+ .tckdly = 0,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id mtk_spi_of_match[] = {
|
||||
+ { .compatible = "mediatek,mt6589-spi", .data = (void *)COMPAT_MT6589},
|
||||
+ { .compatible = "mediatek,mt8173-spi", .data = (void *)COMPAT_MT8173},
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mtk_spi_of_match);
|
||||
+
|
||||
+static void mtk_spi_reset(struct mtk_spi_ddata *mdata)
|
||||
+{
|
||||
+ u32 reg_val;
|
||||
+
|
||||
+ /*set the software reset bit in SPI_CMD_REG.*/
|
||||
+ reg_val = readl(mdata->base + SPI_CMD_REG);
|
||||
+ reg_val &= ~SPI_CMD_RST_MASK;
|
||||
+ reg_val |= 1 << SPI_CMD_RST_OFFSET;
|
||||
+ writel(reg_val, mdata->base + SPI_CMD_REG);
|
||||
+ reg_val = readl(mdata->base + SPI_CMD_REG);
|
||||
+ reg_val &= ~SPI_CMD_RST_MASK;
|
||||
+ writel(reg_val, mdata->base + SPI_CMD_REG);
|
||||
+}
|
||||
+
|
||||
+static void mtk_set_pause_bit(struct mtk_spi_ddata *mdata)
|
||||
+{
|
||||
+ u32 reg_val;
|
||||
+
|
||||
+ reg_val = readl(mdata->base + SPI_CMD_REG);
|
||||
+ reg_val |= 1 << SPI_CMD_PAUSE_EN_OFFSET;
|
||||
+ reg_val |= 1 << SPI_CMD_PAUSE_IE_OFFSET;
|
||||
+ writel(reg_val, mdata->base + SPI_CMD_REG);
|
||||
+}
|
||||
+
|
||||
+static void mtk_clear_pause_bit(struct mtk_spi_ddata *mdata)
|
||||
+{
|
||||
+ u32 reg_val;
|
||||
+
|
||||
+ reg_val = readl(mdata->base + SPI_CMD_REG);
|
||||
+ reg_val &= ~SPI_CMD_PAUSE_EN_MASK;
|
||||
+ writel(reg_val, mdata->base + SPI_CMD_REG);
|
||||
+}
|
||||
+
|
||||
+static int mtk_spi_config(struct mtk_spi_ddata *mdata,
|
||||
+ struct mtk_chip_config *chip_config)
|
||||
+{
|
||||
+ u32 reg_val;
|
||||
+
|
||||
+ /* set the timing */
|
||||
+ reg_val = readl(mdata->base + SPI_CFG0_REG);
|
||||
+ reg_val &= ~(SPI_CFG0_SCK_HIGH_MASK | SPI_CFG0_SCK_LOW_MASK);
|
||||
+ reg_val &= ~(SPI_CFG0_CS_HOLD_MASK | SPI_CFG0_CS_SETUP_MASK);
|
||||
+ reg_val |= ((chip_config->high_time - 1) << SPI_CFG0_SCK_HIGH_OFFSET);
|
||||
+ reg_val |= ((chip_config->low_time - 1) << SPI_CFG0_SCK_LOW_OFFSET);
|
||||
+ reg_val |= ((chip_config->holdtime - 1) << SPI_CFG0_CS_HOLD_OFFSET);
|
||||
+ reg_val |= ((chip_config->setuptime - 1) << SPI_CFG0_CS_SETUP_OFFSET);
|
||||
+ writel(reg_val, mdata->base + SPI_CFG0_REG);
|
||||
+
|
||||
+ reg_val = readl(mdata->base + SPI_CFG1_REG);
|
||||
+ reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
|
||||
+ reg_val |= ((chip_config->cs_idletime - 1) << SPI_CFG1_CS_IDLE_OFFSET);
|
||||
+ reg_val &= ~SPI_CFG1_GET_TICK_DLY_MASK;
|
||||
+ reg_val |= ((chip_config->tckdly) << SPI_CFG1_GET_TICK_DLY_OFFSET);
|
||||
+ writel(reg_val, mdata->base + SPI_CFG1_REG);
|
||||
+
|
||||
+ /* set the mlsbx and mlsbtx */
|
||||
+ reg_val = readl(mdata->base + SPI_CMD_REG);
|
||||
+ reg_val &= ~(SPI_CMD_TX_ENDIAN_MASK | SPI_CMD_RX_ENDIAN_MASK);
|
||||
+ reg_val &= ~(SPI_CMD_TXMSBF_MASK | SPI_CMD_RXMSBF_MASK);
|
||||
+ reg_val |= (chip_config->tx_mlsb << SPI_CMD_TXMSBF_OFFSET);
|
||||
+ reg_val |= (chip_config->rx_mlsb << SPI_CMD_RXMSBF_OFFSET);
|
||||
+ reg_val |= (chip_config->tx_endian << SPI_CMD_TX_ENDIAN_OFFSET);
|
||||
+ reg_val |= (chip_config->rx_endian << SPI_CMD_RX_ENDIAN_OFFSET);
|
||||
+ writel(reg_val, mdata->base + SPI_CMD_REG);
|
||||
+
|
||||
+ /* set finish and pause interrupt always enable */
|
||||
+ reg_val = readl(mdata->base + SPI_CMD_REG);
|
||||
+ reg_val &= ~SPI_CMD_FINISH_IE_MASK;
|
||||
+ reg_val |= (chip_config->finish_intr << SPI_CMD_FINISH_IE_OFFSET);
|
||||
+ writel(reg_val, mdata->base + SPI_CMD_REG);
|
||||
+
|
||||
+ reg_val = readl(mdata->base + SPI_CMD_REG);
|
||||
+ reg_val |= 1 << SPI_CMD_TX_DMA_OFFSET;
|
||||
+ reg_val |= 1 << SPI_CMD_RX_DMA_OFFSET;
|
||||
+ writel(reg_val, mdata->base + SPI_CMD_REG);
|
||||
+
|
||||
+ /* set deassert mode */
|
||||
+ reg_val = readl(mdata->base + SPI_CMD_REG);
|
||||
+ reg_val &= ~SPI_CMD_DEASSERT_MASK;
|
||||
+ reg_val |= (chip_config->deassert << SPI_CMD_DEASSERT_OFFSET);
|
||||
+ writel(reg_val, mdata->base + SPI_CMD_REG);
|
||||
+
|
||||
+ /* pad select */
|
||||
+ if (mdata->platform_compat & COMPAT_MT8173)
|
||||
+ writel(mdata->pad_sel, mdata->base + SPI_PAD_SEL_REG);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mtk_spi_setup_transfer(struct spi_device *spi,
|
||||
+ struct spi_transfer *t)
|
||||
+{
|
||||
+ u32 reg_val;
|
||||
+ struct spi_master *master = spi->master;
|
||||
+ struct mtk_spi_ddata *mdata = spi_master_get_devdata(master);
|
||||
+ struct spi_message *m = master->cur_msg;
|
||||
+ struct mtk_chip_config *chip_config;
|
||||
+
|
||||
+ u8 cpha = spi->mode & SPI_CPHA ? 1 : 0;
|
||||
+ u8 cpol = spi->mode & SPI_CPOL ? 1 : 0;
|
||||
+
|
||||
+ reg_val = readl(mdata->base + SPI_CMD_REG);
|
||||
+ reg_val &= ~(SPI_CMD_CPHA_MASK | SPI_CMD_CPOL_MASK);
|
||||
+ reg_val |= (cpha << SPI_CMD_CPHA_OFFSET);
|
||||
+ reg_val |= (cpol << SPI_CMD_CPOL_OFFSET);
|
||||
+ writel(reg_val, mdata->base + SPI_CMD_REG);
|
||||
+
|
||||
+ if (t->cs_change) {
|
||||
+ if (!(list_is_last(&t->transfer_list, &m->transfers)))
|
||||
+ mdata->state = IDLE;
|
||||
+ } else {
|
||||
+ mdata->state = IDLE;
|
||||
+ mtk_spi_reset(mdata);
|
||||
+ }
|
||||
+
|
||||
+ chip_config = (struct mtk_chip_config *)spi->controller_data;
|
||||
+ if (!chip_config) {
|
||||
+ chip_config = (void *)&mtk_default_chip_info;
|
||||
+ spi->controller_data = chip_config;
|
||||
+ mdata->state = IDLE;
|
||||
+ }
|
||||
+
|
||||
+ mtk_spi_config(mdata, chip_config);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mtk_spi_chipselect(struct spi_device *spi, int is_on)
|
||||
+{
|
||||
+ struct mtk_spi_ddata *mdata = spi_master_get_devdata(spi->master);
|
||||
+
|
||||
+ switch (is_on) {
|
||||
+ case BITBANG_CS_ACTIVE:
|
||||
+ mtk_set_pause_bit(mdata);
|
||||
+ break;
|
||||
+ case BITBANG_CS_INACTIVE:
|
||||
+ mtk_clear_pause_bit(mdata);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void mtk_spi_start_transfer(struct mtk_spi_ddata *mdata)
|
||||
+{
|
||||
+ u32 reg_val;
|
||||
+
|
||||
+ reg_val = readl(mdata->base + SPI_CMD_REG);
|
||||
+ reg_val |= 1 << SPI_CMD_ACT_OFFSET;
|
||||
+ writel(reg_val, mdata->base + SPI_CMD_REG);
|
||||
+}
|
||||
+
|
||||
+static void mtk_spi_resume_transfer(struct mtk_spi_ddata *mdata)
|
||||
+{
|
||||
+ u32 reg_val;
|
||||
+
|
||||
+ reg_val = readl(mdata->base + SPI_CMD_REG);
|
||||
+ reg_val &= ~SPI_CMD_RESUME_MASK;
|
||||
+ reg_val |= 1 << SPI_CMD_RESUME_OFFSET;
|
||||
+ writel(reg_val, mdata->base + SPI_CMD_REG);
|
||||
+}
|
||||
+
|
||||
+static int mtk_spi_setup_packet(struct mtk_spi_ddata *mdata,
|
||||
+ struct spi_transfer *xfer)
|
||||
+{
|
||||
+ struct device *dev = &mdata->bitbang.master->dev;
|
||||
+ u32 packet_size, packet_loop, reg_val;
|
||||
+
|
||||
+ packet_size = min_t(unsigned, xfer->len, PACKET_SIZE);
|
||||
+
|
||||
+ /* mtk hw has the restriction that xfer len must be a multiple of 1024,
|
||||
+ * when it is greater than 1024bytes.
|
||||
+ */
|
||||
+ if (xfer->len % packet_size) {
|
||||
+ dev_err(dev, "ERROR!The lens must be a multiple of %d, your len %d\n",
|
||||
+ PACKET_SIZE, xfer->len);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ packet_loop = xfer->len / packet_size;
|
||||
+
|
||||
+ reg_val = readl(mdata->base + SPI_CFG1_REG);
|
||||
+ reg_val &= ~(SPI_CFG1_PACKET_LENGTH_MASK + SPI_CFG1_PACKET_LOOP_MASK);
|
||||
+ reg_val |= (packet_size - 1) << SPI_CFG1_PACKET_LENGTH_OFFSET;
|
||||
+ reg_val |= (packet_loop - 1) << SPI_CFG1_PACKET_LOOP_OFFSET;
|
||||
+ writel(reg_val, mdata->base + SPI_CFG1_REG);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mtk_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *xfer)
|
||||
+{
|
||||
+ struct spi_master *master = spi->master;
|
||||
+ struct mtk_spi_ddata *mdata = spi_master_get_devdata(master);
|
||||
+ struct device *dev = &mdata->bitbang.master->dev;
|
||||
+ int cmd, ret;
|
||||
+
|
||||
+ /* mtk spi hw tx/rx have 4bytes aligned restriction,
|
||||
+ * so kmalloc tx/rx buffer to workaround here.
|
||||
+ */
|
||||
+ mdata->tx_buf = NULL;
|
||||
+ mdata->rx_buf = NULL;
|
||||
+ if (xfer->tx_buf) {
|
||||
+ mdata->tx_buf = kmalloc(xfer->len, GFP_KERNEL);
|
||||
+ if (!mdata->tx_buf) {
|
||||
+ dev_err(dev, "malloc tx_buf failed.\n");
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+ memcpy((void *)mdata->tx_buf, xfer->tx_buf, xfer->len);
|
||||
+ }
|
||||
+ if (xfer->rx_buf) {
|
||||
+ mdata->rx_buf = kmalloc(xfer->len, GFP_KERNEL);
|
||||
+ if (!mdata->rx_buf) {
|
||||
+ dev_err(dev, "malloc rx_buf failed.\n");
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ reinit_completion(&mdata->done);
|
||||
+
|
||||
+ xfer->tx_dma = DMA_ERROR_CODE;
|
||||
+ xfer->rx_dma = DMA_ERROR_CODE;
|
||||
+ if (xfer->tx_buf) {
|
||||
+ xfer->tx_dma = dma_map_single(dev, (void *)mdata->tx_buf,
|
||||
+ xfer->len, DMA_TO_DEVICE);
|
||||
+ if (dma_mapping_error(dev, xfer->tx_dma)) {
|
||||
+ dev_err(dev, "dma mapping tx_buf error.\n");
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+ }
|
||||
+ if (xfer->rx_buf) {
|
||||
+ xfer->rx_dma = dma_map_single(dev, mdata->rx_buf,
|
||||
+ xfer->len, DMA_FROM_DEVICE);
|
||||
+ if (dma_mapping_error(dev, xfer->rx_dma)) {
|
||||
+ if (xfer->tx_buf)
|
||||
+ dma_unmap_single(dev, xfer->tx_dma,
|
||||
+ xfer->len, DMA_TO_DEVICE);
|
||||
+ dev_err(dev, "dma mapping rx_buf error.\n");
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = mtk_spi_setup_packet(mdata, xfer);
|
||||
+ if (ret != 0)
|
||||
+ goto err_free;
|
||||
+
|
||||
+ /* Here is mt8173 HW issue: RX must enable TX, then TX transfer
|
||||
+ * dummy data; TX don't need to enable RX. so enable TX dma for
|
||||
+ * RX to workaround.
|
||||
+ */
|
||||
+ cmd = readl(mdata->base + SPI_CMD_REG);
|
||||
+ if (xfer->tx_buf || (mdata->platform_compat & COMPAT_MT8173))
|
||||
+ cmd |= 1 << SPI_CMD_TX_DMA_OFFSET;
|
||||
+ if (xfer->rx_buf)
|
||||
+ cmd |= 1 << SPI_CMD_RX_DMA_OFFSET;
|
||||
+ writel(cmd, mdata->base + SPI_CMD_REG);
|
||||
+
|
||||
+ /* set up the DMA bus address */
|
||||
+ if (xfer->tx_dma != DMA_ERROR_CODE)
|
||||
+ writel(cpu_to_le32(xfer->tx_dma), mdata->base + SPI_TX_SRC_REG);
|
||||
+ if (xfer->rx_dma != DMA_ERROR_CODE)
|
||||
+ writel(cpu_to_le32(xfer->rx_dma), mdata->base + SPI_RX_DST_REG);
|
||||
+
|
||||
+ if (mdata->state == IDLE)
|
||||
+ mtk_spi_start_transfer(mdata);
|
||||
+ else if (mdata->state == PAUSED)
|
||||
+ mtk_spi_resume_transfer(mdata);
|
||||
+ else
|
||||
+ mdata->state = INPROGRESS;
|
||||
+
|
||||
+ wait_for_completion(&mdata->done);
|
||||
+
|
||||
+ if (xfer->tx_dma != DMA_ERROR_CODE) {
|
||||
+ dma_unmap_single(dev, xfer->tx_dma, xfer->len, DMA_TO_DEVICE);
|
||||
+ xfer->tx_dma = DMA_ERROR_CODE;
|
||||
+ }
|
||||
+ if (xfer->rx_dma != DMA_ERROR_CODE) {
|
||||
+ dma_unmap_single(dev, xfer->rx_dma, xfer->len, DMA_FROM_DEVICE);
|
||||
+ xfer->rx_dma = DMA_ERROR_CODE;
|
||||
+ }
|
||||
+
|
||||
+ /* spi disable dma */
|
||||
+ cmd = readl(mdata->base + SPI_CMD_REG);
|
||||
+ cmd &= ~SPI_CMD_TX_DMA_MASK;
|
||||
+ cmd &= ~SPI_CMD_RX_DMA_MASK;
|
||||
+ writel(cmd, mdata->base + SPI_CMD_REG);
|
||||
+
|
||||
+ if (xfer->rx_buf)
|
||||
+ memcpy(xfer->rx_buf, mdata->rx_buf, xfer->len);
|
||||
+
|
||||
+ ret = xfer->len;
|
||||
+
|
||||
+err_free:
|
||||
+ kfree(mdata->tx_buf);
|
||||
+ kfree(mdata->rx_buf);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
|
||||
+{
|
||||
+ struct mtk_spi_ddata *mdata = dev_id;
|
||||
+ u32 reg_val;
|
||||
+
|
||||
+ reg_val = readl(mdata->base + SPI_STATUS0_REG);
|
||||
+ if (reg_val & 0x2)
|
||||
+ mdata->state = PAUSED;
|
||||
+ else
|
||||
+ mdata->state = IDLE;
|
||||
+ complete(&mdata->done);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static unsigned long mtk_get_device_prop(struct platform_device *pdev)
|
||||
+{
|
||||
+ const struct of_device_id *match;
|
||||
+
|
||||
+ match = of_match_node(mtk_spi_of_match, pdev->dev.of_node);
|
||||
+ return (unsigned long)match->data;
|
||||
+}
|
||||
+
|
||||
+static int mtk_spi_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct spi_master *master;
|
||||
+ struct mtk_spi_ddata *mdata;
|
||||
+ struct resource *res;
|
||||
+ int ret;
|
||||
+
|
||||
+ master = spi_alloc_master(&pdev->dev, sizeof(struct mtk_spi_ddata));
|
||||
+ if (!master) {
|
||||
+ dev_err(&pdev->dev, "failed to alloc spi master\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, master);
|
||||
+
|
||||
+ master->dev.of_node = pdev->dev.of_node;
|
||||
+ master->bus_num = pdev->id;
|
||||
+ master->num_chipselect = 1;
|
||||
+ master->mode_bits = SPI_CPOL | SPI_CPHA;
|
||||
+
|
||||
+ mdata = spi_master_get_devdata(master);
|
||||
+
|
||||
+ mdata->bitbang.master = master;
|
||||
+ mdata->bitbang.chipselect = mtk_spi_chipselect;
|
||||
+ mdata->bitbang.setup_transfer = mtk_spi_setup_transfer;
|
||||
+ mdata->bitbang.txrx_bufs = mtk_spi_txrx_bufs;
|
||||
+ mdata->platform_compat = mtk_get_device_prop(pdev);
|
||||
+
|
||||
+ if (mdata->platform_compat & COMPAT_MT8173) {
|
||||
+ ret = of_property_read_u32(pdev->dev.of_node, "pad-select",
|
||||
+ &mdata->pad_sel);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "failed to read pad select: %d\n",
|
||||
+ ret);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ if (mdata->pad_sel > MT8173_MAX_PAD_SEL) {
|
||||
+ dev_err(&pdev->dev, "wrong pad-select: %u\n",
|
||||
+ mdata->pad_sel);
|
||||
+ goto err;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ init_completion(&mdata->done);
|
||||
+
|
||||
+ mdata->clk = devm_clk_get(&pdev->dev, "main");
|
||||
+ if (IS_ERR(mdata->clk)) {
|
||||
+ ret = PTR_ERR(mdata->clk);
|
||||
+ dev_err(&pdev->dev, "failed to get clock: %d\n", ret);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ if (!res) {
|
||||
+ ret = -ENODEV;
|
||||
+ dev_err(&pdev->dev, "failed to determine base address\n");
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ mdata->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (IS_ERR(mdata->base)) {
|
||||
+ ret = PTR_ERR(mdata->base);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ ret = platform_get_irq(pdev, 0);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&pdev->dev, "failed to get irq (%d)\n", ret);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ mdata->irq = ret;
|
||||
+
|
||||
+ if (!pdev->dev.dma_mask)
|
||||
+ pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||
+
|
||||
+ mdata->bitbang.master->dev.dma_mask = pdev->dev.dma_mask;
|
||||
+
|
||||
+ ret = clk_prepare_enable(mdata->clk);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&pdev->dev, "failed to enable clock (%d)\n", ret);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_request_irq(&pdev->dev, mdata->irq, mtk_spi_interrupt,
|
||||
+ IRQF_TRIGGER_NONE, dev_name(&pdev->dev), mdata);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "failed to register irq (%d)\n", ret);
|
||||
+ goto err_disable_clk;
|
||||
+ }
|
||||
+
|
||||
+ ret = spi_bitbang_start(&mdata->bitbang);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "spi_bitbang_start failed (%d)\n", ret);
|
||||
+err_disable_clk:
|
||||
+ clk_disable_unprepare(mdata->clk);
|
||||
+err:
|
||||
+ spi_master_put(master);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int mtk_spi_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct spi_master *master = platform_get_drvdata(pdev);
|
||||
+ struct mtk_spi_ddata *mdata = spi_master_get_devdata(master);
|
||||
+
|
||||
+ spi_bitbang_stop(&mdata->bitbang);
|
||||
+ mtk_spi_reset(mdata);
|
||||
+ clk_disable_unprepare(mdata->clk);
|
||||
+ spi_master_put(master);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+struct platform_driver mtk_spi_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "mtk-spi",
|
||||
+ .of_match_table = mtk_spi_of_match,
|
||||
+ },
|
||||
+ .probe = mtk_spi_probe,
|
||||
+ .remove = mtk_spi_remove,
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(mtk_spi_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("MTK SPI Controller driver");
|
||||
+MODULE_AUTHOR("Leilk Liu <leilk.liu@mediatek.com>");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
+MODULE_ALIAS("platform: mtk_spi");
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,47 @@
|
||||
From 908a87b47af8303c9aa8fb6aa183ca9f8b544d78 Mon Sep 17 00:00:00 2001
|
||||
From: YH Huang <yh.huang@mediatek.com>
|
||||
Date: Mon, 11 May 2015 17:26:21 +0800
|
||||
Subject: [PATCH 27/76] dt-bindings: pwm: add Mediatek display PWM bindings
|
||||
|
||||
Document the device-tree binding of Mediatek display PWM.
|
||||
|
||||
Signed-off-by: YH Huang <yh.huang@mediatek.com>
|
||||
---
|
||||
.../devicetree/bindings/pwm/pwm-disp-mediatek.txt | 25 ++++++++++++++++++++
|
||||
1 file changed, 25 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/pwm/pwm-disp-mediatek.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/pwm/pwm-disp-mediatek.txt b/Documentation/devicetree/bindings/pwm/pwm-disp-mediatek.txt
|
||||
new file mode 100644
|
||||
index 0000000..ef54e9d
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/pwm/pwm-disp-mediatek.txt
|
||||
@@ -0,0 +1,25 @@
|
||||
+Mediatek display PWM controller
|
||||
+
|
||||
+Required properties:
|
||||
+ - compatible: should be "mediatek,<name>-disp-pwm"
|
||||
+ - "mediatek,mt8173-disp-pwm": found on mt8173 SoC
|
||||
+ - "mediatek,mt6595-disp-pwm": found on mt6595 SoC
|
||||
+ - reg: physical base address and length of the controller's registers
|
||||
+ - #pwm-cells: must be 2. See pwm.txt in this directory
|
||||
+ for a description of the cell format
|
||||
+ - clocks: phandle and clock specifier of the PWM reference clock
|
||||
+ - clock-names: must contain the following
|
||||
+ - "main": clock used to generate PWM signals
|
||||
+ - "mm": sync signals from the modules of mmsys
|
||||
+
|
||||
+Example:
|
||||
+ pwm0: pwm@1401e000 {
|
||||
+ compatible = "mediatek,mt8173-disp-pwm",
|
||||
+ "mediatek,mt6595-disp-pwm";
|
||||
+ reg = <0 0x1401e000 0 0x1000>;
|
||||
+ #pwm-cells = <2>;
|
||||
+ clocks = <&mmsys MM_DISP_PWM026M>,
|
||||
+ <&mmsys MM_DISP_PWM0MM>;
|
||||
+ clock-names = "main",
|
||||
+ "mm";
|
||||
+ };
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,281 @@
|
||||
From 77e664940f6daa86965d16a2047188519341a31a Mon Sep 17 00:00:00 2001
|
||||
From: YH Huang <yh.huang@mediatek.com>
|
||||
Date: Mon, 11 May 2015 17:26:22 +0800
|
||||
Subject: [PATCH 28/76] pwm: add Mediatek display PWM driver support
|
||||
|
||||
Add display PWM driver support to modify backlight for MT8173/MT6595.
|
||||
|
||||
Signed-off-by: YH Huang <yh.huang@mediatek.com>
|
||||
---
|
||||
drivers/pwm/Kconfig | 9 ++
|
||||
drivers/pwm/Makefile | 1 +
|
||||
drivers/pwm/pwm-disp-mediatek.c | 225 +++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 235 insertions(+)
|
||||
create mode 100644 drivers/pwm/pwm-disp-mediatek.c
|
||||
|
||||
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
|
||||
index b1541f4..9edbb5a 100644
|
||||
--- a/drivers/pwm/Kconfig
|
||||
+++ b/drivers/pwm/Kconfig
|
||||
@@ -111,6 +111,15 @@ config PWM_CLPS711X
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called pwm-clps711x.
|
||||
|
||||
+config PWM_DISP_MEDIATEK
|
||||
+ tristate "MEDIATEK display PWM driver"
|
||||
+ depends on OF
|
||||
+ help
|
||||
+ Generic PWM framework driver for mediatek disp-pwm device.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the module
|
||||
+ will be called pwm-disp-mediatek.
|
||||
+
|
||||
config PWM_EP93XX
|
||||
tristate "Cirrus Logic EP93xx PWM support"
|
||||
depends on ARCH_EP93XX
|
||||
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
|
||||
index ec50eb5..c5ff72a 100644
|
||||
--- a/drivers/pwm/Makefile
|
||||
+++ b/drivers/pwm/Makefile
|
||||
@@ -8,6 +8,7 @@ obj-$(CONFIG_PWM_BCM_KONA) += pwm-bcm-kona.o
|
||||
obj-$(CONFIG_PWM_BCM2835) += pwm-bcm2835.o
|
||||
obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o
|
||||
obj-$(CONFIG_PWM_CLPS711X) += pwm-clps711x.o
|
||||
+obj-$(CONFIG_PWM_DISP_MEDIATEK) += pwm-disp-mediatek.o
|
||||
obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o
|
||||
obj-$(CONFIG_PWM_FSL_FTM) += pwm-fsl-ftm.o
|
||||
obj-$(CONFIG_PWM_IMG) += pwm-img.o
|
||||
diff --git a/drivers/pwm/pwm-disp-mediatek.c b/drivers/pwm/pwm-disp-mediatek.c
|
||||
new file mode 100644
|
||||
index 0000000..38293af
|
||||
--- /dev/null
|
||||
+++ b/drivers/pwm/pwm-disp-mediatek.c
|
||||
@@ -0,0 +1,225 @@
|
||||
+/*
|
||||
+ * Mediatek display pulse-width-modulation controller driver.
|
||||
+ * Copyright (c) 2015 MediaTek Inc.
|
||||
+ * Author: YH Huang <yh.huang@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/pwm.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#define DISP_PWM_EN_OFF (0x0)
|
||||
+#define PWM_ENABLE_SHIFT (0x0)
|
||||
+#define PWM_ENABLE_MASK (0x1 << PWM_ENABLE_SHIFT)
|
||||
+
|
||||
+#define DISP_PWM_COMMIT_OFF (0x08)
|
||||
+#define PWM_COMMIT_SHIFT (0x0)
|
||||
+#define PWM_COMMIT_MASK (0x1 << PWM_COMMIT_SHIFT)
|
||||
+
|
||||
+#define DISP_PWM_CON_0_OFF (0x10)
|
||||
+#define PWM_CLKDIV_SHIFT (0x10)
|
||||
+#define PWM_CLKDIV_MASK (0x3ff << PWM_CLKDIV_SHIFT)
|
||||
+#define PWM_CLKDIV_MAX (0x000003ff)
|
||||
+
|
||||
+#define DISP_PWM_CON_1_OFF (0x14)
|
||||
+#define PWM_PERIOD_SHIFT (0x0)
|
||||
+#define PWM_PERIOD_MASK (0xfff << PWM_PERIOD_SHIFT)
|
||||
+#define PWM_PERIOD_MAX (0x00000fff)
|
||||
+/* Shift log2(PWM_PERIOD_MAX + 1) as divisor */
|
||||
+#define PWM_PERIOD_BIT_SHIFT 12
|
||||
+
|
||||
+#define PWM_HIGH_WIDTH_SHIFT (0x10)
|
||||
+#define PWM_HIGH_WIDTH_MASK (0x1fff << PWM_HIGH_WIDTH_SHIFT)
|
||||
+
|
||||
+#define NUM_PWM 1
|
||||
+
|
||||
+struct mtk_disp_pwm_chip {
|
||||
+ struct pwm_chip chip;
|
||||
+ struct device *dev;
|
||||
+ struct clk *clk_main;
|
||||
+ struct clk *clk_mm;
|
||||
+ void __iomem *mmio_base;
|
||||
+};
|
||||
+
|
||||
+static void mtk_disp_pwm_setting(void __iomem *address, u32 value, u32 mask)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(address);
|
||||
+ val &= ~mask;
|
||||
+ val |= value;
|
||||
+ writel(val, address);
|
||||
+}
|
||||
+
|
||||
+static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
+ int duty_ns, int period_ns)
|
||||
+{
|
||||
+ struct mtk_disp_pwm_chip *mpc;
|
||||
+ u64 div, rate;
|
||||
+ u32 clk_div, period, high_width, rem;
|
||||
+
|
||||
+ /*
|
||||
+ * Find period, high_width and clk_div to suit duty_ns and period_ns.
|
||||
+ * Calculate proper div value to keep period value in the bound.
|
||||
+ *
|
||||
+ * period_ns = 10^9 * (clk_div + 1) * (period +1) / PWM_CLK_RATE
|
||||
+ * duty_ns = 10^9 * (clk_div + 1) * (high_width + 1) / PWM_CLK_RATE
|
||||
+ *
|
||||
+ * period = (PWM_CLK_RATE * period_ns) / (10^9 * (clk_div + 1)) - 1
|
||||
+ * high_width = (PWM_CLK_RATE * duty_ns) / (10^9 * (clk_div + 1)) - 1
|
||||
+ */
|
||||
+ mpc = container_of(chip, struct mtk_disp_pwm_chip, chip);
|
||||
+ rate = clk_get_rate(mpc->clk_main);
|
||||
+ clk_div = div_u64_rem(rate * period_ns, NSEC_PER_SEC, &rem) >>
|
||||
+ PWM_PERIOD_BIT_SHIFT;
|
||||
+ if (clk_div > PWM_CLKDIV_MAX)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ div = clk_div + 1;
|
||||
+ period = div64_u64(rate * period_ns, NSEC_PER_SEC * div);
|
||||
+ if (period > 0)
|
||||
+ period--;
|
||||
+ high_width = div64_u64(rate * duty_ns, NSEC_PER_SEC * div);
|
||||
+ if (high_width > 0)
|
||||
+ high_width--;
|
||||
+
|
||||
+ mtk_disp_pwm_setting(mpc->mmio_base + DISP_PWM_CON_0_OFF,
|
||||
+ clk_div << PWM_CLKDIV_SHIFT, PWM_CLKDIV_MASK);
|
||||
+ mtk_disp_pwm_setting(mpc->mmio_base + DISP_PWM_CON_1_OFF,
|
||||
+ (period << PWM_PERIOD_SHIFT) |
|
||||
+ (high_width << PWM_HIGH_WIDTH_SHIFT),
|
||||
+ PWM_PERIOD_MASK | PWM_HIGH_WIDTH_MASK);
|
||||
+
|
||||
+ mtk_disp_pwm_setting(mpc->mmio_base + DISP_PWM_COMMIT_OFF,
|
||||
+ 1 << PWM_COMMIT_SHIFT, PWM_COMMIT_MASK);
|
||||
+ mtk_disp_pwm_setting(mpc->mmio_base + DISP_PWM_COMMIT_OFF,
|
||||
+ 0 << PWM_COMMIT_SHIFT, PWM_COMMIT_MASK);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mtk_disp_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
+{
|
||||
+ struct mtk_disp_pwm_chip *mpc;
|
||||
+
|
||||
+ mpc = container_of(chip, struct mtk_disp_pwm_chip, chip);
|
||||
+ mtk_disp_pwm_setting(mpc->mmio_base + DISP_PWM_EN_OFF,
|
||||
+ 1 << PWM_ENABLE_SHIFT, PWM_ENABLE_MASK);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mtk_disp_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
+{
|
||||
+ struct mtk_disp_pwm_chip *mpc;
|
||||
+
|
||||
+ mpc = container_of(chip, struct mtk_disp_pwm_chip, chip);
|
||||
+ mtk_disp_pwm_setting(mpc->mmio_base + DISP_PWM_EN_OFF,
|
||||
+ 0 << PWM_ENABLE_SHIFT, PWM_ENABLE_MASK);
|
||||
+}
|
||||
+
|
||||
+static const struct pwm_ops mtk_disp_pwm_ops = {
|
||||
+ .config = mtk_disp_pwm_config,
|
||||
+ .enable = mtk_disp_pwm_enable,
|
||||
+ .disable = mtk_disp_pwm_disable,
|
||||
+ .owner = THIS_MODULE,
|
||||
+};
|
||||
+
|
||||
+static int mtk_disp_pwm_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mtk_disp_pwm_chip *pwm;
|
||||
+ struct resource *r;
|
||||
+ int ret;
|
||||
+
|
||||
+ pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
|
||||
+ if (!pwm)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ pwm->dev = &pdev->dev;
|
||||
+
|
||||
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ pwm->mmio_base = devm_ioremap_resource(&pdev->dev, r);
|
||||
+ if (IS_ERR(pwm->mmio_base))
|
||||
+ return PTR_ERR(pwm->mmio_base);
|
||||
+
|
||||
+ pwm->clk_main = devm_clk_get(&pdev->dev, "main");
|
||||
+ if (IS_ERR(pwm->clk_main))
|
||||
+ return PTR_ERR(pwm->clk_main);
|
||||
+ pwm->clk_mm = devm_clk_get(&pdev->dev, "mm");
|
||||
+ if (IS_ERR(pwm->clk_mm))
|
||||
+ return PTR_ERR(pwm->clk_mm);
|
||||
+
|
||||
+ ret = clk_prepare_enable(pwm->clk_main);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ ret = clk_prepare_enable(pwm->clk_mm);
|
||||
+ if (ret < 0) {
|
||||
+ clk_disable_unprepare(pwm->clk_main);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, pwm);
|
||||
+
|
||||
+ pwm->chip.dev = &pdev->dev;
|
||||
+ pwm->chip.ops = &mtk_disp_pwm_ops;
|
||||
+ pwm->chip.base = -1;
|
||||
+ pwm->chip.npwm = NUM_PWM;
|
||||
+
|
||||
+ ret = pwmchip_add(&pwm->chip);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mtk_disp_pwm_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mtk_disp_pwm_chip *pc = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ if (WARN_ON(!pc))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ clk_disable_unprepare(pc->clk_main);
|
||||
+ clk_disable_unprepare(pc->clk_mm);
|
||||
+
|
||||
+ return pwmchip_remove(&pc->chip);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mtk_disp_pwm_of_match[] = {
|
||||
+ { .compatible = "mediatek,mt6595-disp-pwm" },
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
+MODULE_DEVICE_TABLE(of, mtk_disp_pwm_of_match);
|
||||
+
|
||||
+static struct platform_driver mtk_disp_pwm_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "mediatek-disp-pwm",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = mtk_disp_pwm_of_match,
|
||||
+ },
|
||||
+ .probe = mtk_disp_pwm_probe,
|
||||
+ .remove = mtk_disp_pwm_remove,
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(mtk_disp_pwm_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("YH Huang <yh.huang@mediatek.com>");
|
||||
+MODULE_DESCRIPTION("MediaTek SoC display PWM driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,64 @@
|
||||
From d1447a6815913823ef5e75d70efc6f08f288ee40 Mon Sep 17 00:00:00 2001
|
||||
From: Xudong Chen <xudong.chen@mediatek.com>
|
||||
Date: Wed, 6 May 2015 16:37:05 +0800
|
||||
Subject: [PATCH 29/76] dt-bindings: Add I2C bindings for mt65xx/mt81xx.
|
||||
|
||||
Add devicetree bindings for Mediatek Soc I2C driver.
|
||||
|
||||
Signed-off-by: Xudong Chen <xudong.chen@mediatek.com>
|
||||
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
|
||||
---
|
||||
.../devicetree/bindings/i2c/i2c-mt6577.txt | 41 ++++++++++++++++++++
|
||||
1 file changed, 41 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/i2c/i2c-mt6577.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt6577.txt b/Documentation/devicetree/bindings/i2c/i2c-mt6577.txt
|
||||
new file mode 100644
|
||||
index 0000000..0ce6fa3
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/i2c/i2c-mt6577.txt
|
||||
@@ -0,0 +1,41 @@
|
||||
+* Mediatek's I2C controller
|
||||
+
|
||||
+The Mediatek's I2C controller is used to interface with I2C devices.
|
||||
+
|
||||
+Required properties:
|
||||
+ - compatible: value should be either of the following.
|
||||
+ (a) "mediatek,mt6577-i2c", for i2c compatible with mt6577 i2c.
|
||||
+ (b) "mediatek,mt6589-i2c", for i2c compatible with mt6589 i2c.
|
||||
+ (c) "mediatek,mt8127-i2c", for i2c compatible with mt8127 i2c.
|
||||
+ (d) "mediatek,mt8135-i2c", for i2c compatible with mt8135 i2c.
|
||||
+ (e) "mediatek,mt8173-i2c", for i2c compatible with mt8173 i2c.
|
||||
+ - reg: physical base address of the controller and dma base, length of memory
|
||||
+ mapped region.
|
||||
+ - interrupts: interrupt number to the cpu.
|
||||
+ - clock-div: the fixed value for frequency divider of clock source in i2c
|
||||
+ module. Each IC may be different.
|
||||
+ - clocks: clock name from clock manager
|
||||
+ - clock-names: Must include "main" and "dma", if enable have-pmic need include
|
||||
+ "pmic" extra.
|
||||
+
|
||||
+Optional properties:
|
||||
+ - clock-frequency: Frequency in Hz of the bus when transfer, the default value
|
||||
+ is 100000.
|
||||
+ - mediatek,have-pmic: platform can control i2c form special pmic side.
|
||||
+ Only mt6589 and mt8135 support this feature.
|
||||
+ - mediatek,use-push-pull: IO config use push-pull mode.
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+ i2c0: i2c@1100d000 {
|
||||
+ compatible = "mediatek,mt6577-i2c";
|
||||
+ reg = <0x1100d000 0x70>,
|
||||
+ <0x11000300 0x80>;
|
||||
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ clock-frequency = <400000>;
|
||||
+ mediatek,have-pmic;
|
||||
+ clock-div = <16>;
|
||||
+ clocks = <&i2c0_ck>, <&ap_dma_ck>;
|
||||
+ clock-names = "main", "dma";
|
||||
+ };
|
||||
+
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,760 @@
|
||||
From 2471bc43c6079ab956a04f29ffd1ab8371b7bd73 Mon Sep 17 00:00:00 2001
|
||||
From: Xudong Chen <xudong.chen@mediatek.com>
|
||||
Date: Wed, 6 May 2015 16:37:06 +0800
|
||||
Subject: [PATCH 30/76] I2C: mediatek: Add driver for MediaTek I2C controller
|
||||
|
||||
The mediatek SoCs have I2C controller that handle I2C transfer.
|
||||
This patch include common I2C bus driver.
|
||||
This driver is compatible with I2C controller on mt65xx/mt81xx.
|
||||
|
||||
Signed-off-by: Xudong Chen <xudong.chen@mediatek.com>
|
||||
Signed-off-by: Liguo Zhang <liguo.zhang@mediatek.com>
|
||||
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
|
||||
---
|
||||
drivers/i2c/busses/Kconfig | 9 +
|
||||
drivers/i2c/busses/Makefile | 1 +
|
||||
drivers/i2c/busses/i2c-mt65xx.c | 700 +++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 710 insertions(+)
|
||||
create mode 100644 drivers/i2c/busses/i2c-mt65xx.c
|
||||
|
||||
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
|
||||
index 2255af2..14c7266 100644
|
||||
--- a/drivers/i2c/busses/Kconfig
|
||||
+++ b/drivers/i2c/busses/Kconfig
|
||||
@@ -620,6 +620,15 @@ config I2C_MPC
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called i2c-mpc.
|
||||
|
||||
+config I2C_MT65XX
|
||||
+ tristate "MediaTek I2C adapter"
|
||||
+ depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
+ help
|
||||
+ This selects the MediaTek(R) Integrated Inter Circuit bus driver
|
||||
+ for MT65xx and MT81xx.
|
||||
+ If you want to use MediaTek(R) I2C interface, say Y or M here.
|
||||
+ If unsure, say N.
|
||||
+
|
||||
config I2C_MV64XXX
|
||||
tristate "Marvell mv64xxx I2C Controller"
|
||||
depends on MV64X60 || PLAT_ORION || ARCH_SUNXI
|
||||
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
|
||||
index cdf941d..abbf422 100644
|
||||
--- a/drivers/i2c/busses/Makefile
|
||||
+++ b/drivers/i2c/busses/Makefile
|
||||
@@ -60,6 +60,7 @@ obj-$(CONFIG_I2C_JZ4780) += i2c-jz4780.o
|
||||
obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o
|
||||
obj-$(CONFIG_I2C_MESON) += i2c-meson.o
|
||||
obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
|
||||
+obj-$(CONFIG_I2C_MT65XX) += i2c-mt65xx.o
|
||||
obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o
|
||||
obj-$(CONFIG_I2C_MXS) += i2c-mxs.o
|
||||
obj-$(CONFIG_I2C_NOMADIK) += i2c-nomadik.o
|
||||
diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
|
||||
new file mode 100644
|
||||
index 0000000..faecf7e
|
||||
--- /dev/null
|
||||
+++ b/drivers/i2c/busses/i2c-mt65xx.c
|
||||
@@ -0,0 +1,700 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2014 MediaTek Inc.
|
||||
+ * Author: Xudong.chen <xudong.chen@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/i2c.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/sched.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/errno.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/mm.h>
|
||||
+#include <linux/dma-mapping.h>
|
||||
+#include <linux/scatterlist.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/completion.h>
|
||||
+
|
||||
+#define I2C_HS_NACKERR (1 << 2)
|
||||
+#define I2C_ACKERR (1 << 1)
|
||||
+#define I2C_TRANSAC_COMP (1 << 0)
|
||||
+#define I2C_TRANSAC_START (1 << 0)
|
||||
+#define I2C_TIMING_STEP_DIV_MASK (0x3f << 0)
|
||||
+#define I2C_TIMING_SAMPLE_COUNT_MASK (0x7 << 0)
|
||||
+#define I2C_TIMING_SAMPLE_DIV_MASK (0x7 << 8)
|
||||
+#define I2C_TIMING_DATA_READ_MASK (0x7 << 12)
|
||||
+#define I2C_DCM_DISABLE 0x0000
|
||||
+#define I2C_IO_CONFIG_OPEN_DRAIN 0x0003
|
||||
+#define I2C_IO_CONFIG_PUSH_PULL 0x0000
|
||||
+#define I2C_SOFT_RST 0x0001
|
||||
+#define I2C_FIFO_ADDR_CLR 0x0001
|
||||
+#define I2C_DELAY_LEN 0x0002
|
||||
+#define I2C_ST_START_CON 0x8001
|
||||
+#define I2C_FS_START_CON 0x1800
|
||||
+#define I2C_TIME_CLR_VALUE 0x0000
|
||||
+#define I2C_TIME_DEFAULT_VALUE 0x0003
|
||||
+#define I2C_FS_TIME_INIT_VALUE 0x1303
|
||||
+#define I2C_WRRD_TRANAC_VALUE 0x0002
|
||||
+#define I2C_RD_TRANAC_VALUE 0x0001
|
||||
+
|
||||
+#define I2C_DMA_CON_TX 0x0000
|
||||
+#define I2C_DMA_CON_RX 0x0001
|
||||
+#define I2C_DMA_START_EN 0x0001
|
||||
+#define I2C_DMA_INT_FLAG_NONE 0x0000
|
||||
+#define I2C_DMA_CLR_FLAG 0x0000
|
||||
+
|
||||
+#define I2C_DEFAUT_SPEED 100000 /* hz */
|
||||
+#define MAX_FS_MODE_SPEED 400000
|
||||
+#define MAX_HS_MODE_SPEED 3400000
|
||||
+#define MAX_MSG_NUM_MT6577 1
|
||||
+#define MAX_DMA_TRANS_SIZE_MT6577 255
|
||||
+#define MAX_WRRD_TRANS_SIZE_MT6577 31
|
||||
+#define MAX_SAMPLE_CNT_DIV 8
|
||||
+#define MAX_STEP_CNT_DIV 64
|
||||
+#define MAX_HS_STEP_CNT_DIV 8
|
||||
+
|
||||
+#define I2C_CONTROL_RS (0x1 << 1)
|
||||
+#define I2C_CONTROL_DMA_EN (0x1 << 2)
|
||||
+#define I2C_CONTROL_CLK_EXT_EN (0x1 << 3)
|
||||
+#define I2C_CONTROL_DIR_CHANGE (0x1 << 4)
|
||||
+#define I2C_CONTROL_ACKERR_DET_EN (0x1 << 5)
|
||||
+#define I2C_CONTROL_TRANSFER_LEN_CHANGE (0x1 << 6)
|
||||
+#define I2C_CONTROL_WRAPPER (0x1 << 0)
|
||||
+
|
||||
+#define I2C_DRV_NAME "mt-i2c"
|
||||
+
|
||||
+enum DMA_REGS_OFFSET {
|
||||
+ OFFSET_INT_FLAG = 0x0,
|
||||
+ OFFSET_INT_EN = 0x04,
|
||||
+ OFFSET_EN = 0x08,
|
||||
+ OFFSET_CON = 0x18,
|
||||
+ OFFSET_TX_MEM_ADDR = 0x1c,
|
||||
+ OFFSET_RX_MEM_ADDR = 0x20,
|
||||
+ OFFSET_TX_LEN = 0x24,
|
||||
+ OFFSET_RX_LEN = 0x28,
|
||||
+};
|
||||
+
|
||||
+enum i2c_trans_st_rs {
|
||||
+ I2C_TRANS_STOP = 0,
|
||||
+ I2C_TRANS_REPEATED_START,
|
||||
+};
|
||||
+
|
||||
+enum mtk_trans_op {
|
||||
+ I2C_MASTER_WR = 1,
|
||||
+ I2C_MASTER_RD,
|
||||
+ I2C_MASTER_WRRD,
|
||||
+};
|
||||
+
|
||||
+enum I2C_REGS_OFFSET {
|
||||
+ OFFSET_DATA_PORT = 0x0,
|
||||
+ OFFSET_SLAVE_ADDR = 0x04,
|
||||
+ OFFSET_INTR_MASK = 0x08,
|
||||
+ OFFSET_INTR_STAT = 0x0c,
|
||||
+ OFFSET_CONTROL = 0x10,
|
||||
+ OFFSET_TRANSFER_LEN = 0x14,
|
||||
+ OFFSET_TRANSAC_LEN = 0x18,
|
||||
+ OFFSET_DELAY_LEN = 0x1c,
|
||||
+ OFFSET_TIMING = 0x20,
|
||||
+ OFFSET_START = 0x24,
|
||||
+ OFFSET_EXT_CONF = 0x28,
|
||||
+ OFFSET_FIFO_STAT = 0x30,
|
||||
+ OFFSET_FIFO_THRESH = 0x34,
|
||||
+ OFFSET_FIFO_ADDR_CLR = 0x38,
|
||||
+ OFFSET_IO_CONFIG = 0x40,
|
||||
+ OFFSET_RSV_DEBUG = 0x44,
|
||||
+ OFFSET_HS = 0x48,
|
||||
+ OFFSET_SOFTRESET = 0x50,
|
||||
+ OFFSET_DCM_EN = 0x54,
|
||||
+ OFFSET_PATH_DIR = 0x60,
|
||||
+ OFFSET_DEBUGSTAT = 0x64,
|
||||
+ OFFSET_DEBUGCTRL = 0x68,
|
||||
+ OFFSET_TRANSFER_LEN_AUX = 0x6c,
|
||||
+};
|
||||
+
|
||||
+struct mtk_i2c_data {
|
||||
+ unsigned int clk_frequency; /* bus speed in Hz */
|
||||
+ unsigned int flags;
|
||||
+ unsigned int clk_src_div;
|
||||
+};
|
||||
+
|
||||
+struct mtk_i2c_compatible {
|
||||
+ const struct i2c_adapter_quirks *quirks;
|
||||
+ unsigned char pmic_i2c;
|
||||
+ unsigned char dcm;
|
||||
+};
|
||||
+
|
||||
+struct mtk_i2c {
|
||||
+ struct i2c_adapter adap; /* i2c host adapter */
|
||||
+ struct device *dev;
|
||||
+ struct completion msg_complete;
|
||||
+
|
||||
+ /* set in i2c probe */
|
||||
+ void __iomem *base; /* i2c base addr */
|
||||
+ void __iomem *pdmabase; /* dma base address*/
|
||||
+ struct clk *clk_main; /* main clock for i2c bus */
|
||||
+ struct clk *clk_dma; /* DMA clock for i2c via DMA */
|
||||
+ struct clk *clk_pmic; /* PMIC clock for i2c from PMIC */
|
||||
+ bool have_pmic; /* can use i2c pins from PMIC */
|
||||
+ bool use_push_pull; /* IO config push-pull mode */
|
||||
+
|
||||
+ u16 irq_stat; /* interrupt status */
|
||||
+ unsigned int speed_hz; /* The speed in transfer */
|
||||
+ enum mtk_trans_op op;
|
||||
+ u16 timing_reg;
|
||||
+ u16 high_speed_reg;
|
||||
+ const struct mtk_i2c_compatible *dev_comp;
|
||||
+};
|
||||
+
|
||||
+static const struct i2c_adapter_quirks mt6577_i2c_quirks = {
|
||||
+ .flags = I2C_AQ_COMB_WRITE_THEN_READ,
|
||||
+ .max_num_msgs = MAX_MSG_NUM_MT6577,
|
||||
+ .max_write_len = MAX_DMA_TRANS_SIZE_MT6577,
|
||||
+ .max_read_len = MAX_DMA_TRANS_SIZE_MT6577,
|
||||
+ .max_comb_1st_msg_len = MAX_DMA_TRANS_SIZE_MT6577,
|
||||
+ .max_comb_2nd_msg_len = MAX_WRRD_TRANS_SIZE_MT6577,
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_i2c_compatible mt6577_compat = {
|
||||
+ .quirks = &mt6577_i2c_quirks,
|
||||
+ .pmic_i2c = 0,
|
||||
+ .dcm = 1,
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_i2c_compatible mt6589_compat = {
|
||||
+ .quirks = &mt6577_i2c_quirks,
|
||||
+ .pmic_i2c = 1,
|
||||
+ .dcm = 0,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id mtk_i2c_of_match[] = {
|
||||
+ { .compatible = "mediatek,mt6577-i2c", .data = (void *)&mt6577_compat },
|
||||
+ { .compatible = "mediatek,mt6589-i2c", .data = (void *)&mt6589_compat },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mtk_i2c_of_match);
|
||||
+
|
||||
+static inline void mtk_i2c_writew(u16 value, struct mtk_i2c *i2c, u8 offset)
|
||||
+{
|
||||
+ writew(value, i2c->base + offset);
|
||||
+}
|
||||
+
|
||||
+static inline u16 mtk_i2c_readw(struct mtk_i2c *i2c, u8 offset)
|
||||
+{
|
||||
+ return readw(i2c->base + offset);
|
||||
+}
|
||||
+
|
||||
+static inline void mtk_i2c_writel_dma(u32 value, struct mtk_i2c *i2c, u8 offset)
|
||||
+{
|
||||
+ writel(value, i2c->pdmabase + offset);
|
||||
+}
|
||||
+
|
||||
+static int mtk_i2c_clock_enable(struct mtk_i2c *i2c)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = clk_prepare_enable(i2c->clk_dma);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = clk_prepare_enable(i2c->clk_main);
|
||||
+ if (ret)
|
||||
+ goto err_main;
|
||||
+
|
||||
+ if (i2c->have_pmic) {
|
||||
+ ret = clk_prepare_enable(i2c->clk_pmic);
|
||||
+ if (ret)
|
||||
+ goto err_pmic;
|
||||
+ }
|
||||
+ return 0;
|
||||
+
|
||||
+err_pmic:
|
||||
+ clk_disable_unprepare(i2c->clk_main);
|
||||
+err_main:
|
||||
+ clk_disable_unprepare(i2c->clk_dma);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void mtk_i2c_clock_disable(struct mtk_i2c *i2c)
|
||||
+{
|
||||
+ if (i2c->have_pmic)
|
||||
+ clk_disable_unprepare(i2c->clk_pmic);
|
||||
+
|
||||
+ clk_disable_unprepare(i2c->clk_main);
|
||||
+ clk_disable_unprepare(i2c->clk_dma);
|
||||
+}
|
||||
+
|
||||
+static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
|
||||
+{
|
||||
+ u16 control_reg;
|
||||
+
|
||||
+ mtk_i2c_writew(I2C_SOFT_RST, i2c, OFFSET_SOFTRESET);
|
||||
+ /* Set ioconfig */
|
||||
+ if (i2c->use_push_pull)
|
||||
+ mtk_i2c_writew(I2C_IO_CONFIG_PUSH_PULL, i2c, OFFSET_IO_CONFIG);
|
||||
+ else
|
||||
+ mtk_i2c_writew(I2C_IO_CONFIG_OPEN_DRAIN, i2c, OFFSET_IO_CONFIG);
|
||||
+
|
||||
+ if (i2c->dev_comp->dcm)
|
||||
+ mtk_i2c_writew(I2C_DCM_DISABLE, i2c, OFFSET_DCM_EN);
|
||||
+
|
||||
+ mtk_i2c_writew(i2c->timing_reg, i2c, OFFSET_TIMING);
|
||||
+ mtk_i2c_writew(i2c->high_speed_reg, i2c, OFFSET_HS);
|
||||
+
|
||||
+ /* If use i2c pin from PMIC mt6397 side, need set PATH_DIR first */
|
||||
+ if (i2c->have_pmic)
|
||||
+ mtk_i2c_writew(I2C_CONTROL_WRAPPER, i2c, OFFSET_PATH_DIR);
|
||||
+
|
||||
+ control_reg = I2C_CONTROL_ACKERR_DET_EN |
|
||||
+ I2C_CONTROL_CLK_EXT_EN | I2C_CONTROL_DMA_EN;
|
||||
+ mtk_i2c_writew(control_reg, i2c, OFFSET_CONTROL);
|
||||
+ mtk_i2c_writew(I2C_DELAY_LEN, i2c, OFFSET_DELAY_LEN);
|
||||
+}
|
||||
+
|
||||
+/* calculate i2c port speed */
|
||||
+static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int clk_src_in_hz)
|
||||
+{
|
||||
+ unsigned int khz;
|
||||
+ unsigned int step_cnt;
|
||||
+ unsigned int sample_cnt;
|
||||
+ unsigned int sclk;
|
||||
+ unsigned int hclk;
|
||||
+ unsigned int max_step_cnt;
|
||||
+ unsigned int sample_div = MAX_SAMPLE_CNT_DIV;
|
||||
+ unsigned int step_div;
|
||||
+ unsigned int min_div;
|
||||
+ unsigned int best_mul;
|
||||
+ unsigned int cnt_mul;
|
||||
+
|
||||
+ if (i2c->speed_hz > MAX_HS_MODE_SPEED)
|
||||
+ return -EINVAL;
|
||||
+ else if (i2c->speed_hz > MAX_FS_MODE_SPEED)
|
||||
+ max_step_cnt = MAX_HS_STEP_CNT_DIV;
|
||||
+ else
|
||||
+ max_step_cnt = MAX_STEP_CNT_DIV;
|
||||
+
|
||||
+ step_div = max_step_cnt;
|
||||
+ /* Find the best combination */
|
||||
+ khz = i2c->speed_hz / 1000;
|
||||
+ hclk = clk_src_in_hz / 1000;
|
||||
+ min_div = ((hclk >> 1) + khz - 1) / khz;
|
||||
+ best_mul = MAX_SAMPLE_CNT_DIV * max_step_cnt;
|
||||
+
|
||||
+ for (sample_cnt = 1; sample_cnt <= MAX_SAMPLE_CNT_DIV; sample_cnt++) {
|
||||
+ step_cnt = (min_div + sample_cnt - 1) / sample_cnt;
|
||||
+ cnt_mul = step_cnt * sample_cnt;
|
||||
+ if (step_cnt > max_step_cnt)
|
||||
+ continue;
|
||||
+
|
||||
+ if (cnt_mul < best_mul) {
|
||||
+ best_mul = cnt_mul;
|
||||
+ sample_div = sample_cnt;
|
||||
+ step_div = step_cnt;
|
||||
+ if (best_mul == min_div)
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ sample_cnt = sample_div;
|
||||
+ step_cnt = step_div;
|
||||
+ sclk = hclk / (2 * sample_cnt * step_cnt);
|
||||
+ if (sclk > khz) {
|
||||
+ dev_dbg(i2c->dev, "%s mode: unsupported speed (%ldkhz)\n",
|
||||
+ (i2c->speed_hz > MAX_HS_MODE_SPEED) ? "HS" : "ST/FT",
|
||||
+ (long int)khz);
|
||||
+ return -ENOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ step_cnt--;
|
||||
+ sample_cnt--;
|
||||
+
|
||||
+ if (i2c->speed_hz > MAX_FS_MODE_SPEED) {
|
||||
+ /* Set the hign speed mode register */
|
||||
+ i2c->timing_reg = I2C_FS_TIME_INIT_VALUE;
|
||||
+ i2c->high_speed_reg = I2C_TIME_DEFAULT_VALUE |
|
||||
+ (sample_cnt & I2C_TIMING_SAMPLE_COUNT_MASK) << 12 |
|
||||
+ (step_cnt & I2C_TIMING_SAMPLE_COUNT_MASK) << 8;
|
||||
+ } else {
|
||||
+ i2c->timing_reg =
|
||||
+ (sample_cnt & I2C_TIMING_SAMPLE_COUNT_MASK) << 8 |
|
||||
+ (step_cnt & I2C_TIMING_STEP_DIV_MASK) << 0;
|
||||
+ /* Disable the high speed transaction */
|
||||
+ i2c->high_speed_reg = I2C_TIME_CLR_VALUE;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs)
|
||||
+{
|
||||
+ u16 addr_reg;
|
||||
+ u16 control_reg;
|
||||
+ dma_addr_t rpaddr = 0;
|
||||
+ dma_addr_t wpaddr = 0;
|
||||
+ int ret;
|
||||
+
|
||||
+ i2c->irq_stat = 0;
|
||||
+
|
||||
+ reinit_completion(&i2c->msg_complete);
|
||||
+
|
||||
+ control_reg = mtk_i2c_readw(i2c, OFFSET_CONTROL) &
|
||||
+ ~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS);
|
||||
+ if (i2c->speed_hz > 400000)
|
||||
+ control_reg |= I2C_CONTROL_RS;
|
||||
+ if (i2c->op == I2C_MASTER_WRRD)
|
||||
+ control_reg |= I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS;
|
||||
+ mtk_i2c_writew(control_reg, i2c, OFFSET_CONTROL);
|
||||
+
|
||||
+ /* set start condition */
|
||||
+ if (i2c->speed_hz <= 100000)
|
||||
+ mtk_i2c_writew(I2C_ST_START_CON, i2c, OFFSET_EXT_CONF);
|
||||
+ else
|
||||
+ mtk_i2c_writew(I2C_FS_START_CON, i2c, OFFSET_EXT_CONF);
|
||||
+
|
||||
+ addr_reg = msgs->addr << 1;
|
||||
+ if (i2c->op == I2C_MASTER_RD)
|
||||
+ addr_reg |= 0x1;
|
||||
+ mtk_i2c_writew(addr_reg, i2c, OFFSET_SLAVE_ADDR);
|
||||
+
|
||||
+ /* Clear interrupt status */
|
||||
+ mtk_i2c_writew(I2C_HS_NACKERR | I2C_ACKERR | I2C_TRANSAC_COMP,
|
||||
+ i2c, OFFSET_INTR_STAT);
|
||||
+ mtk_i2c_writew(I2C_FIFO_ADDR_CLR, i2c, OFFSET_FIFO_ADDR_CLR);
|
||||
+
|
||||
+ /* Enable interrupt */
|
||||
+ mtk_i2c_writew(I2C_HS_NACKERR | I2C_ACKERR | I2C_TRANSAC_COMP,
|
||||
+ i2c, OFFSET_INTR_MASK);
|
||||
+
|
||||
+ /* Set transfer and transaction len */
|
||||
+ if (i2c->op == I2C_MASTER_WRRD) {
|
||||
+ mtk_i2c_writew(msgs->len | ((msgs + 1)->len) << 8,
|
||||
+ i2c, OFFSET_TRANSFER_LEN);
|
||||
+ mtk_i2c_writew(I2C_WRRD_TRANAC_VALUE, i2c, OFFSET_TRANSAC_LEN);
|
||||
+ } else {
|
||||
+ mtk_i2c_writew(msgs->len, i2c, OFFSET_TRANSFER_LEN);
|
||||
+ mtk_i2c_writew(I2C_RD_TRANAC_VALUE, i2c, OFFSET_TRANSAC_LEN);
|
||||
+ }
|
||||
+
|
||||
+ /* Prepare buffer data to start transfer */
|
||||
+ if (i2c->op == I2C_MASTER_RD) {
|
||||
+ mtk_i2c_writel_dma(I2C_DMA_INT_FLAG_NONE, i2c, OFFSET_INT_FLAG);
|
||||
+ mtk_i2c_writel_dma(I2C_DMA_CON_RX, i2c, OFFSET_CON);
|
||||
+ rpaddr = dma_map_single(i2c->adap.dev.parent, msgs->buf,
|
||||
+ msgs->len, DMA_FROM_DEVICE);
|
||||
+ if (dma_mapping_error(i2c->adap.dev.parent, rpaddr))
|
||||
+ return -ENOMEM;
|
||||
+ mtk_i2c_writel_dma((u32)rpaddr, i2c, OFFSET_RX_MEM_ADDR);
|
||||
+ mtk_i2c_writel_dma(msgs->len, i2c, OFFSET_RX_LEN);
|
||||
+ } else if (i2c->op == I2C_MASTER_WR) {
|
||||
+ mtk_i2c_writel_dma(I2C_DMA_INT_FLAG_NONE, i2c, OFFSET_INT_FLAG);
|
||||
+ mtk_i2c_writel_dma(I2C_DMA_CON_TX, i2c, OFFSET_CON);
|
||||
+ wpaddr = dma_map_single(i2c->adap.dev.parent, msgs->buf,
|
||||
+ msgs->len, DMA_TO_DEVICE);
|
||||
+ if (dma_mapping_error(i2c->adap.dev.parent, wpaddr))
|
||||
+ return -ENOMEM;
|
||||
+ mtk_i2c_writel_dma((u32)wpaddr, i2c, OFFSET_TX_MEM_ADDR);
|
||||
+ mtk_i2c_writel_dma(msgs->len, i2c, OFFSET_TX_LEN);
|
||||
+ } else {
|
||||
+ mtk_i2c_writel_dma(I2C_DMA_CLR_FLAG, i2c, OFFSET_INT_FLAG);
|
||||
+ mtk_i2c_writel_dma(I2C_DMA_CLR_FLAG, i2c, OFFSET_CON);
|
||||
+ wpaddr = dma_map_single(i2c->adap.dev.parent, msgs->buf,
|
||||
+ msgs->len, DMA_TO_DEVICE);
|
||||
+ if (dma_mapping_error(i2c->adap.dev.parent, wpaddr))
|
||||
+ return -ENOMEM;
|
||||
+ rpaddr = dma_map_single(i2c->adap.dev.parent, (msgs + 1)->buf,
|
||||
+ (msgs + 1)->len,
|
||||
+ DMA_FROM_DEVICE);
|
||||
+ if (dma_mapping_error(i2c->adap.dev.parent, rpaddr)) {
|
||||
+ dma_unmap_single(i2c->adap.dev.parent, wpaddr,
|
||||
+ msgs->len, DMA_TO_DEVICE);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+ mtk_i2c_writel_dma((u32)wpaddr, i2c, OFFSET_TX_MEM_ADDR);
|
||||
+ mtk_i2c_writel_dma((u32)rpaddr, i2c, OFFSET_RX_MEM_ADDR);
|
||||
+ mtk_i2c_writel_dma(msgs->len, i2c, OFFSET_TX_LEN);
|
||||
+ mtk_i2c_writel_dma((msgs + 1)->len, i2c, OFFSET_RX_LEN);
|
||||
+ }
|
||||
+
|
||||
+ /* flush before sending start */
|
||||
+ mb();
|
||||
+ mtk_i2c_writel_dma(I2C_DMA_START_EN, i2c, OFFSET_EN);
|
||||
+ mtk_i2c_writew(I2C_TRANSAC_START, i2c, OFFSET_START);
|
||||
+
|
||||
+ ret = wait_for_completion_timeout(&i2c->msg_complete,
|
||||
+ i2c->adap.timeout);
|
||||
+
|
||||
+ /* Clear interrupt mask */
|
||||
+ mtk_i2c_writew(~(I2C_HS_NACKERR | I2C_ACKERR
|
||||
+ | I2C_TRANSAC_COMP), i2c, OFFSET_INTR_MASK);
|
||||
+
|
||||
+ if (i2c->op == I2C_MASTER_WR) {
|
||||
+ dma_unmap_single(i2c->adap.dev.parent, wpaddr,
|
||||
+ msgs->len, DMA_TO_DEVICE);
|
||||
+ } else if (i2c->op == I2C_MASTER_RD) {
|
||||
+ dma_unmap_single(i2c->adap.dev.parent, rpaddr,
|
||||
+ msgs->len, DMA_FROM_DEVICE);
|
||||
+ } else {
|
||||
+ dma_unmap_single(i2c->adap.dev.parent, wpaddr, msgs->len,
|
||||
+ DMA_TO_DEVICE);
|
||||
+ dma_unmap_single(i2c->adap.dev.parent, rpaddr, (msgs + 1)->len,
|
||||
+ DMA_FROM_DEVICE);
|
||||
+ }
|
||||
+
|
||||
+ if (ret == 0) {
|
||||
+ dev_dbg(i2c->dev, "addr: %x, transfer timeout\n", msgs->addr);
|
||||
+ mtk_i2c_init_hw(i2c);
|
||||
+ return -ETIMEDOUT;
|
||||
+ }
|
||||
+
|
||||
+ completion_done(&i2c->msg_complete);
|
||||
+
|
||||
+ if (i2c->irq_stat & (I2C_HS_NACKERR | I2C_ACKERR)) {
|
||||
+ dev_dbg(i2c->dev, "addr: %x, transfer ACK error\n", msgs->addr);
|
||||
+ mtk_i2c_init_hw(i2c);
|
||||
+ return -EREMOTEIO;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mtk_i2c_transfer(struct i2c_adapter *adap,
|
||||
+ struct i2c_msg msgs[], int num)
|
||||
+{
|
||||
+ int ret;
|
||||
+ int left_num = num;
|
||||
+ struct mtk_i2c *i2c = i2c_get_adapdata(adap);
|
||||
+
|
||||
+ ret = mtk_i2c_clock_enable(i2c);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (msgs->buf == NULL) {
|
||||
+ dev_dbg(i2c->dev, "data buffer is NULL.\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto err_exit;
|
||||
+ }
|
||||
+
|
||||
+ if (msgs->flags & I2C_M_RD)
|
||||
+ i2c->op = I2C_MASTER_RD;
|
||||
+ else
|
||||
+ i2c->op = I2C_MASTER_WR;
|
||||
+
|
||||
+ if (num > 1) {
|
||||
+ /* combined two messages into one transaction */
|
||||
+ i2c->op = I2C_MASTER_WRRD;
|
||||
+ left_num--;
|
||||
+ }
|
||||
+
|
||||
+ /* always use DMA mode. */
|
||||
+ ret = mtk_i2c_do_transfer(i2c, msgs);
|
||||
+ if (ret < 0)
|
||||
+ goto err_exit;
|
||||
+
|
||||
+ /* the return value is number of executed messages */
|
||||
+ ret = num;
|
||||
+
|
||||
+err_exit:
|
||||
+ mtk_i2c_clock_disable(i2c);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t mtk_i2c_irq(int irqno, void *dev_id)
|
||||
+{
|
||||
+ struct mtk_i2c *i2c = dev_id;
|
||||
+
|
||||
+ i2c->irq_stat = mtk_i2c_readw(i2c, OFFSET_INTR_STAT);
|
||||
+ mtk_i2c_writew(I2C_HS_NACKERR | I2C_ACKERR
|
||||
+ | I2C_TRANSAC_COMP, i2c, OFFSET_INTR_STAT);
|
||||
+
|
||||
+ complete(&i2c->msg_complete);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static u32 mtk_i2c_functionality(struct i2c_adapter *adap)
|
||||
+{
|
||||
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
|
||||
+}
|
||||
+
|
||||
+static const struct i2c_algorithm mtk_i2c_algorithm = {
|
||||
+ .master_xfer = mtk_i2c_transfer,
|
||||
+ .functionality = mtk_i2c_functionality,
|
||||
+};
|
||||
+
|
||||
+static int mtk_i2c_parse_dt(struct device_node *np, struct mtk_i2c *i2c,
|
||||
+ unsigned int *clk_src_div)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = of_property_read_u32(np, "clock-frequency", &i2c->speed_hz);
|
||||
+ if (ret < 0)
|
||||
+ i2c->speed_hz = I2C_DEFAUT_SPEED;
|
||||
+
|
||||
+ ret = of_property_read_u32(np, "clock-div", clk_src_div);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (*clk_src_div == 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ i2c->have_pmic = of_property_read_bool(np, "mediatek,have-pmic");
|
||||
+ i2c->use_push_pull =
|
||||
+ of_property_read_bool(np, "mediatek,use-push-pull");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mtk_i2c_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ const struct of_device_id *of_id;
|
||||
+ int ret = 0;
|
||||
+ struct mtk_i2c *i2c;
|
||||
+ struct clk *clk;
|
||||
+ unsigned int clk_src_in_hz;
|
||||
+ unsigned int clk_src_div;
|
||||
+ struct resource *res;
|
||||
+ int irq;
|
||||
+
|
||||
+ i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
|
||||
+ if (i2c == NULL)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ret = mtk_i2c_parse_dt(pdev->dev.of_node, i2c, &clk_src_div);
|
||||
+ if (ret)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ i2c->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (IS_ERR(i2c->base))
|
||||
+ return PTR_ERR(i2c->base);
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
+ i2c->pdmabase = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (IS_ERR(i2c->pdmabase))
|
||||
+ return PTR_ERR(i2c->pdmabase);
|
||||
+
|
||||
+ irq = platform_get_irq(pdev, 0);
|
||||
+ if (irq <= 0)
|
||||
+ return irq;
|
||||
+
|
||||
+ init_completion(&i2c->msg_complete);
|
||||
+
|
||||
+ of_id = of_match_node(mtk_i2c_of_match, pdev->dev.of_node);
|
||||
+ if (!of_id)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ i2c->dev_comp = of_id->data;
|
||||
+ i2c->adap.dev.of_node = pdev->dev.of_node;
|
||||
+ i2c->dev = &i2c->adap.dev;
|
||||
+ i2c->adap.dev.parent = &pdev->dev;
|
||||
+ i2c->adap.owner = THIS_MODULE;
|
||||
+ i2c->adap.algo = &mtk_i2c_algorithm;
|
||||
+ i2c->adap.quirks = i2c->dev_comp->quirks;
|
||||
+ i2c->adap.timeout = 2 * HZ;
|
||||
+ i2c->adap.retries = 1;
|
||||
+
|
||||
+ if (i2c->have_pmic && !i2c->dev_comp->pmic_i2c)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ i2c->clk_main = devm_clk_get(&pdev->dev, "main");
|
||||
+ if (IS_ERR(i2c->clk_main)) {
|
||||
+ dev_err(&pdev->dev, "cannot get main clock\n");
|
||||
+ return PTR_ERR(i2c->clk_main);
|
||||
+ }
|
||||
+
|
||||
+ i2c->clk_dma = devm_clk_get(&pdev->dev, "dma");
|
||||
+ if (IS_ERR(i2c->clk_dma)) {
|
||||
+ dev_err(&pdev->dev, "cannot get dma clock\n");
|
||||
+ return PTR_ERR(i2c->clk_dma);
|
||||
+ }
|
||||
+
|
||||
+ clk = i2c->clk_main;
|
||||
+ if (i2c->have_pmic) {
|
||||
+ i2c->clk_pmic = devm_clk_get(&pdev->dev, "pmic");
|
||||
+ if (IS_ERR(i2c->clk_pmic)) {
|
||||
+ dev_err(&pdev->dev, "cannot get pmic clock\n");
|
||||
+ return PTR_ERR(i2c->clk_pmic);
|
||||
+ }
|
||||
+ clk = i2c->clk_pmic;
|
||||
+ }
|
||||
+ clk_src_in_hz = clk_get_rate(clk) / clk_src_div;
|
||||
+
|
||||
+ dev_dbg(&pdev->dev, "clock source %p,clock src frequency %d\n",
|
||||
+ i2c->clk_main, clk_src_in_hz);
|
||||
+ strlcpy(i2c->adap.name, I2C_DRV_NAME, sizeof(i2c->adap.name));
|
||||
+
|
||||
+ ret = mtk_i2c_set_speed(i2c, clk_src_in_hz);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "Failed to set the speed.\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ret = mtk_i2c_clock_enable(i2c);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "clock enable failed!\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ mtk_i2c_init_hw(i2c);
|
||||
+ mtk_i2c_clock_disable(i2c);
|
||||
+
|
||||
+ ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq,
|
||||
+ IRQF_TRIGGER_NONE, I2C_DRV_NAME, i2c);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&pdev->dev,
|
||||
+ "Request I2C IRQ %d fail\n", irq);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ i2c_set_adapdata(&i2c->adap, i2c);
|
||||
+ ret = i2c_add_adapter(&i2c->adap);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "Failed to add i2c bus to i2c core\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, i2c);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mtk_i2c_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mtk_i2c *i2c = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ i2c_del_adapter(&i2c->adap);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver mtk_i2c_driver = {
|
||||
+ .probe = mtk_i2c_probe,
|
||||
+ .remove = mtk_i2c_remove,
|
||||
+ .driver = {
|
||||
+ .name = I2C_DRV_NAME,
|
||||
+ .of_match_table = of_match_ptr(mtk_i2c_of_match),
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(mtk_i2c_driver);
|
||||
+
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
+MODULE_DESCRIPTION("MediaTek I2C Bus Driver");
|
||||
+MODULE_AUTHOR("Xudong Chen <xudong.chen@mediatek.com>");
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,244 @@
|
||||
From 5f33206ebe4fb4a2cc8634f29c3e3c9bc01e3416 Mon Sep 17 00:00:00 2001
|
||||
From: Eddie Huang <eddie.huang@mediatek.com>
|
||||
Date: Wed, 6 May 2015 16:37:07 +0800
|
||||
Subject: [PATCH 31/76] I2C: mediatek: Add driver for MediaTek MT8173 I2C
|
||||
controller
|
||||
|
||||
Add mediatek MT8173 I2C controller driver. Compare to I2C controller
|
||||
of earlier mediatek SoC, MT8173 fix write-then-read limitation, and
|
||||
also increase message size to 64kb.
|
||||
|
||||
Signed-off-by: Xudong Chen <xudong.chen@mediatek.com>
|
||||
Signed-off-by: Liguo Zhang <liguo.zhang@mediatek.com>
|
||||
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
|
||||
---
|
||||
drivers/i2c/busses/i2c-mt65xx.c | 104 ++++++++++++++++++++++++++++-----------
|
||||
1 file changed, 76 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
|
||||
index faecf7e..c501421 100644
|
||||
--- a/drivers/i2c/busses/i2c-mt65xx.c
|
||||
+++ b/drivers/i2c/busses/i2c-mt65xx.c
|
||||
@@ -33,10 +33,13 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/completion.h>
|
||||
|
||||
+#define I2C_RS_TRANSFER (1 << 4)
|
||||
#define I2C_HS_NACKERR (1 << 2)
|
||||
#define I2C_ACKERR (1 << 1)
|
||||
#define I2C_TRANSAC_COMP (1 << 0)
|
||||
#define I2C_TRANSAC_START (1 << 0)
|
||||
+#define I2C_RS_MUL_CNFG (1 << 15)
|
||||
+#define I2C_RS_MUL_TRIG (1 << 14)
|
||||
#define I2C_TIMING_STEP_DIV_MASK (0x3f << 0)
|
||||
#define I2C_TIMING_SAMPLE_COUNT_MASK (0x7 << 0)
|
||||
#define I2C_TIMING_SAMPLE_DIV_MASK (0x7 << 8)
|
||||
@@ -67,6 +70,9 @@
|
||||
#define MAX_MSG_NUM_MT6577 1
|
||||
#define MAX_DMA_TRANS_SIZE_MT6577 255
|
||||
#define MAX_WRRD_TRANS_SIZE_MT6577 31
|
||||
+#define MAX_MSG_NUM_MT8173 65535
|
||||
+#define MAX_DMA_TRANS_SIZE_MT8173 65535
|
||||
+#define MAX_WRRD_TRANS_SIZE_MT8173 65535
|
||||
#define MAX_SAMPLE_CNT_DIV 8
|
||||
#define MAX_STEP_CNT_DIV 64
|
||||
#define MAX_HS_STEP_CNT_DIV 8
|
||||
@@ -139,6 +145,7 @@ struct mtk_i2c_compatible {
|
||||
const struct i2c_adapter_quirks *quirks;
|
||||
unsigned char pmic_i2c;
|
||||
unsigned char dcm;
|
||||
+ unsigned char auto_restart;
|
||||
};
|
||||
|
||||
struct mtk_i2c {
|
||||
@@ -172,21 +179,39 @@ static const struct i2c_adapter_quirks mt6577_i2c_quirks = {
|
||||
.max_comb_2nd_msg_len = MAX_WRRD_TRANS_SIZE_MT6577,
|
||||
};
|
||||
|
||||
+static const struct i2c_adapter_quirks mt8173_i2c_quirks = {
|
||||
+ .max_num_msgs = MAX_MSG_NUM_MT8173,
|
||||
+ .max_write_len = MAX_DMA_TRANS_SIZE_MT8173,
|
||||
+ .max_read_len = MAX_DMA_TRANS_SIZE_MT8173,
|
||||
+ .max_comb_1st_msg_len = MAX_DMA_TRANS_SIZE_MT8173,
|
||||
+ .max_comb_2nd_msg_len = MAX_WRRD_TRANS_SIZE_MT8173,
|
||||
+};
|
||||
+
|
||||
static const struct mtk_i2c_compatible mt6577_compat = {
|
||||
.quirks = &mt6577_i2c_quirks,
|
||||
.pmic_i2c = 0,
|
||||
.dcm = 1,
|
||||
+ .auto_restart = 0,
|
||||
};
|
||||
|
||||
static const struct mtk_i2c_compatible mt6589_compat = {
|
||||
.quirks = &mt6577_i2c_quirks,
|
||||
.pmic_i2c = 1,
|
||||
.dcm = 0,
|
||||
+ .auto_restart = 0,
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_i2c_compatible mt8173_compat = {
|
||||
+ .quirks = &mt8173_i2c_quirks,
|
||||
+ .pmic_i2c = 0,
|
||||
+ .dcm = 1,
|
||||
+ .auto_restart = 1,
|
||||
};
|
||||
|
||||
static const struct of_device_id mtk_i2c_of_match[] = {
|
||||
{ .compatible = "mediatek,mt6577-i2c", .data = (void *)&mt6577_compat },
|
||||
{ .compatible = "mediatek,mt6589-i2c", .data = (void *)&mt6589_compat },
|
||||
+ { .compatible = "mediatek,mt8173-i2c", .data = (void *)&mt8173_compat },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mtk_i2c_of_match);
|
||||
@@ -343,9 +368,11 @@ static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int clk_src_in_hz)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs)
|
||||
+static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
|
||||
+ int num, int left_num)
|
||||
{
|
||||
u16 addr_reg;
|
||||
+ u16 start_reg;
|
||||
u16 control_reg;
|
||||
dma_addr_t rpaddr = 0;
|
||||
dma_addr_t wpaddr = 0;
|
||||
@@ -361,6 +388,8 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs)
|
||||
control_reg |= I2C_CONTROL_RS;
|
||||
if (i2c->op == I2C_MASTER_WRRD)
|
||||
control_reg |= I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS;
|
||||
+ if (left_num >= 1)
|
||||
+ control_reg |= I2C_CONTROL_RS;
|
||||
mtk_i2c_writew(control_reg, i2c, OFFSET_CONTROL);
|
||||
|
||||
/* set start condition */
|
||||
@@ -375,13 +404,13 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs)
|
||||
mtk_i2c_writew(addr_reg, i2c, OFFSET_SLAVE_ADDR);
|
||||
|
||||
/* Clear interrupt status */
|
||||
- mtk_i2c_writew(I2C_HS_NACKERR | I2C_ACKERR | I2C_TRANSAC_COMP,
|
||||
- i2c, OFFSET_INTR_STAT);
|
||||
+ mtk_i2c_writew(I2C_RS_TRANSFER | I2C_HS_NACKERR | I2C_ACKERR
|
||||
+ | I2C_TRANSAC_COMP, i2c, OFFSET_INTR_STAT);
|
||||
mtk_i2c_writew(I2C_FIFO_ADDR_CLR, i2c, OFFSET_FIFO_ADDR_CLR);
|
||||
|
||||
/* Enable interrupt */
|
||||
- mtk_i2c_writew(I2C_HS_NACKERR | I2C_ACKERR | I2C_TRANSAC_COMP,
|
||||
- i2c, OFFSET_INTR_MASK);
|
||||
+ mtk_i2c_writew(I2C_RS_TRANSFER | I2C_HS_NACKERR | I2C_ACKERR
|
||||
+ | I2C_TRANSAC_COMP, i2c, OFFSET_INTR_MASK);
|
||||
|
||||
/* Set transfer and transaction len */
|
||||
if (i2c->op == I2C_MASTER_WRRD) {
|
||||
@@ -390,7 +419,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs)
|
||||
mtk_i2c_writew(I2C_WRRD_TRANAC_VALUE, i2c, OFFSET_TRANSAC_LEN);
|
||||
} else {
|
||||
mtk_i2c_writew(msgs->len, i2c, OFFSET_TRANSFER_LEN);
|
||||
- mtk_i2c_writew(I2C_RD_TRANAC_VALUE, i2c, OFFSET_TRANSAC_LEN);
|
||||
+ mtk_i2c_writew(num, i2c, OFFSET_TRANSAC_LEN);
|
||||
}
|
||||
|
||||
/* Prepare buffer data to start transfer */
|
||||
@@ -436,13 +465,23 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs)
|
||||
/* flush before sending start */
|
||||
mb();
|
||||
mtk_i2c_writel_dma(I2C_DMA_START_EN, i2c, OFFSET_EN);
|
||||
- mtk_i2c_writew(I2C_TRANSAC_START, i2c, OFFSET_START);
|
||||
+
|
||||
+ if (!i2c->dev_comp->auto_restart) {
|
||||
+ start_reg = I2C_TRANSAC_START;
|
||||
+ } else {
|
||||
+ if (left_num >= 1)
|
||||
+ start_reg = I2C_TRANSAC_START | I2C_RS_MUL_CNFG
|
||||
+ | I2C_RS_MUL_TRIG;
|
||||
+ else
|
||||
+ start_reg = I2C_TRANSAC_START | I2C_RS_MUL_TRIG;
|
||||
+ }
|
||||
+ mtk_i2c_writew(start_reg, i2c, OFFSET_START);
|
||||
|
||||
ret = wait_for_completion_timeout(&i2c->msg_complete,
|
||||
i2c->adap.timeout);
|
||||
|
||||
/* Clear interrupt mask */
|
||||
- mtk_i2c_writew(~(I2C_HS_NACKERR | I2C_ACKERR
|
||||
+ mtk_i2c_writew(~(I2C_RS_TRANSFER | I2C_HS_NACKERR | I2C_ACKERR
|
||||
| I2C_TRANSAC_COMP), i2c, OFFSET_INTR_MASK);
|
||||
|
||||
if (i2c->op == I2C_MASTER_WR) {
|
||||
@@ -472,6 +511,10 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs)
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
|
||||
+ if (i2c->irq_stat & I2C_RS_TRANSFER)
|
||||
+ dev_dbg(i2c->dev, "addr: %x, restart transfer interrupt.\n",
|
||||
+ msgs->addr);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -486,28 +529,33 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- if (msgs->buf == NULL) {
|
||||
- dev_dbg(i2c->dev, "data buffer is NULL.\n");
|
||||
- ret = -EINVAL;
|
||||
- goto err_exit;
|
||||
- }
|
||||
-
|
||||
- if (msgs->flags & I2C_M_RD)
|
||||
- i2c->op = I2C_MASTER_RD;
|
||||
- else
|
||||
- i2c->op = I2C_MASTER_WR;
|
||||
+ while (left_num--) {
|
||||
+ if (msgs->buf == NULL) {
|
||||
+ dev_dbg(i2c->dev, "data buffer is NULL.\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto err_exit;
|
||||
+ }
|
||||
|
||||
- if (num > 1) {
|
||||
- /* combined two messages into one transaction */
|
||||
- i2c->op = I2C_MASTER_WRRD;
|
||||
- left_num--;
|
||||
- }
|
||||
+ if (msgs->flags & I2C_M_RD)
|
||||
+ i2c->op = I2C_MASTER_RD;
|
||||
+ else
|
||||
+ i2c->op = I2C_MASTER_WR;
|
||||
+
|
||||
+ if (!i2c->dev_comp->auto_restart) {
|
||||
+ if (num > 1) {
|
||||
+ /* combined two messages into one transaction */
|
||||
+ i2c->op = I2C_MASTER_WRRD;
|
||||
+ left_num--;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- /* always use DMA mode. */
|
||||
- ret = mtk_i2c_do_transfer(i2c, msgs);
|
||||
- if (ret < 0)
|
||||
- goto err_exit;
|
||||
+ /* always use DMA mode. */
|
||||
+ ret = mtk_i2c_do_transfer(i2c, msgs, num, left_num);
|
||||
+ if (ret < 0)
|
||||
+ goto err_exit;
|
||||
|
||||
+ msgs++;
|
||||
+ }
|
||||
/* the return value is number of executed messages */
|
||||
ret = num;
|
||||
|
||||
@@ -521,7 +569,7 @@ static irqreturn_t mtk_i2c_irq(int irqno, void *dev_id)
|
||||
struct mtk_i2c *i2c = dev_id;
|
||||
|
||||
i2c->irq_stat = mtk_i2c_readw(i2c, OFFSET_INTR_STAT);
|
||||
- mtk_i2c_writew(I2C_HS_NACKERR | I2C_ACKERR
|
||||
+ mtk_i2c_writew(I2C_RS_TRANSFER | I2C_HS_NACKERR | I2C_ACKERR
|
||||
| I2C_TRANSAC_COMP, i2c, OFFSET_INTR_STAT);
|
||||
|
||||
complete(&i2c->msg_complete);
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,150 @@
|
||||
From d83532fe7eb9cc7b8cc39dd9f2bbd9873d4e390b Mon Sep 17 00:00:00 2001
|
||||
From: "pi-cheng.chen" <pi-cheng.chen@linaro.org>
|
||||
Date: Mon, 8 Jun 2015 20:29:20 +0800
|
||||
Subject: [PATCH 32/76] dt-bindings: mediatek: Add MT8173 cpufreq driver
|
||||
binding
|
||||
|
||||
This patch adds device tree binding document for MT8173 cpufreq driver.
|
||||
|
||||
Signed-off-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
|
||||
---
|
||||
.../devicetree/bindings/cpufreq/cpufreq-mt8173.txt | 127 ++++++++++++++++++++
|
||||
1 file changed, 127 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-mt8173.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mt8173.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-mt8173.txt
|
||||
new file mode 100644
|
||||
index 0000000..7708a65
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mt8173.txt
|
||||
@@ -0,0 +1,127 @@
|
||||
+
|
||||
+Mediatek MT8173 cpufreq driver
|
||||
+-------------------
|
||||
+
|
||||
+Mediatek MT8173 cpufreq driver for CPU frequency scaling.
|
||||
+
|
||||
+Required properties:
|
||||
+- clocks: A list of phandle + clock-specifier pairs for the clocks listed in clock names.
|
||||
+- clock-names: Should contain the following:
|
||||
+ "cpu" - The multiplexer for clock input of CPU cluster.
|
||||
+ "intermediate" - A parent of "cpu" clock which is used as "intermediate" clock
|
||||
+ source (usually MAINPLL) when the original CPU PLL is under
|
||||
+ transition and not stable yet.
|
||||
+- operating-points: Table of frequencies and voltage CPU could be transitioned into,
|
||||
+ Frequency should be in KHz units and voltage should be in microvolts.
|
||||
+- proc-supply: Regulator for Vproc of CPU cluster.
|
||||
+
|
||||
+Optional properties:
|
||||
+- sram-supply: Regulator for Vsram of CPU cluster. When present, the cpufreq driver
|
||||
+ needs to do "voltage trace" to step by step scale up/down Vproc and
|
||||
+ Vsram to fit SoC specific needs. When absent, the voltage scaling
|
||||
+ flow is handled by hardware, hence no software "voltage trace" is
|
||||
+ needed.
|
||||
+
|
||||
+Example:
|
||||
+--------
|
||||
+ cpu0: cpu@0 {
|
||||
+ device_type = "cpu";
|
||||
+ compatible = "arm,cortex-a53";
|
||||
+ reg = <0x000>;
|
||||
+ enable-method = "psci";
|
||||
+ cpu-idle-states = <&CPU_SLEEP_0>;
|
||||
+ clocks = <&infracfg CLK_INFRA_CA53SEL>,
|
||||
+ <&apmixedsys CLK_APMIXED_MAINPLL>;
|
||||
+ clock-names = "cpu", "intermediate";
|
||||
+ operating-points = <
|
||||
+ 507000 859000
|
||||
+ 702000 908000
|
||||
+ 1001000 983000
|
||||
+ 1105000 1009000
|
||||
+ 1183000 1028000
|
||||
+ 1404000 1083000
|
||||
+ 1508000 1109000
|
||||
+ 1573000 1125000
|
||||
+ >;
|
||||
+ };
|
||||
+
|
||||
+ cpu1: cpu@1 {
|
||||
+ device_type = "cpu";
|
||||
+ compatible = "arm,cortex-a53";
|
||||
+ reg = <0x001>;
|
||||
+ enable-method = "psci";
|
||||
+ cpu-idle-states = <&CPU_SLEEP_0>;
|
||||
+ clocks = <&infracfg CLK_INFRA_CA53SEL>,
|
||||
+ <&apmixedsys CLK_APMIXED_MAINPLL>;
|
||||
+ clock-names = "cpu", "intermediate";
|
||||
+ operating-points = <
|
||||
+ 507000 859000
|
||||
+ 702000 908000
|
||||
+ 1001000 983000
|
||||
+ 1105000 1009000
|
||||
+ 1183000 1028000
|
||||
+ 1404000 1083000
|
||||
+ 1508000 1109000
|
||||
+ 1573000 1125000
|
||||
+ >;
|
||||
+ };
|
||||
+
|
||||
+ cpu2: cpu@100 {
|
||||
+ device_type = "cpu";
|
||||
+ compatible = "arm,cortex-a57";
|
||||
+ reg = <0x100>;
|
||||
+ enable-method = "psci";
|
||||
+ cpu-idle-states = <&CPU_SLEEP_0>;
|
||||
+ clocks = <&infracfg CLK_INFRA_CA57SEL>,
|
||||
+ <&apmixedsys CLK_APMIXED_MAINPLL>;
|
||||
+ clock-names = "cpu", "intermediate";
|
||||
+ operating-points = <
|
||||
+ 507000 828000
|
||||
+ 702000 867000
|
||||
+ 1001000 927000
|
||||
+ 1209000 968000
|
||||
+ 1404000 1007000
|
||||
+ 1612000 1049000
|
||||
+ 1807000 1089000
|
||||
+ 1989000 1125000
|
||||
+ >;
|
||||
+ };
|
||||
+
|
||||
+ cpu3: cpu@101 {
|
||||
+ device_type = "cpu";
|
||||
+ compatible = "arm,cortex-a57";
|
||||
+ reg = <0x101>;
|
||||
+ enable-method = "psci";
|
||||
+ cpu-idle-states = <&CPU_SLEEP_0>;
|
||||
+ clocks = <&infracfg CLK_INFRA_CA57SEL>,
|
||||
+ <&apmixedsys CLK_APMIXED_MAINPLL>;
|
||||
+ clock-names = "cpu", "intermediate";
|
||||
+ operating-points = <
|
||||
+ 507000 828000
|
||||
+ 702000 867000
|
||||
+ 1001000 927000
|
||||
+ 1209000 968000
|
||||
+ 1404000 1007000
|
||||
+ 1612000 1049000
|
||||
+ 1807000 1089000
|
||||
+ 1989000 1125000
|
||||
+ >;
|
||||
+ };
|
||||
+
|
||||
+ &cpu0 {
|
||||
+ proc-supply = <&mt6397_vpca15_reg>;
|
||||
+ };
|
||||
+
|
||||
+ &cpu1 {
|
||||
+ proc-supply = <&mt6397_vpca15_reg>;
|
||||
+ };
|
||||
+
|
||||
+ &cpu2 {
|
||||
+ proc-supply = <&da9211_vcpu_reg>;
|
||||
+ sram-supply = <&mt6397_vsramca7_reg>;
|
||||
+ };
|
||||
+
|
||||
+ &cpu3 {
|
||||
+ proc-supply = <&da9211_vcpu_reg>;
|
||||
+ sram-supply = <&mt6397_vsramca7_reg>;
|
||||
+ };
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,604 @@
|
||||
From 2028cb37c941014f6a817d27a867ee1d37ccf2b6 Mon Sep 17 00:00:00 2001
|
||||
From: "pi-cheng.chen" <pi-cheng.chen@linaro.org>
|
||||
Date: Mon, 8 Jun 2015 20:29:21 +0800
|
||||
Subject: [PATCH 33/76] cpufreq: mediatek: Add MT8173 cpufreq driver
|
||||
|
||||
This patch implements MT8173 cpufreq driver.
|
||||
|
||||
Signed-off-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
|
||||
---
|
||||
drivers/cpufreq/Kconfig.arm | 7 +
|
||||
drivers/cpufreq/Makefile | 1 +
|
||||
drivers/cpufreq/mt8173-cpufreq.c | 550 ++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 558 insertions(+)
|
||||
create mode 100644 drivers/cpufreq/mt8173-cpufreq.c
|
||||
|
||||
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
|
||||
index 4f3dbc8..350752b 100644
|
||||
--- a/drivers/cpufreq/Kconfig.arm
|
||||
+++ b/drivers/cpufreq/Kconfig.arm
|
||||
@@ -141,6 +141,13 @@ config ARM_KIRKWOOD_CPUFREQ
|
||||
This adds the CPUFreq driver for Marvell Kirkwood
|
||||
SoCs.
|
||||
|
||||
+config ARM_MT8173_CPUFREQ
|
||||
+ bool "Mediatek MT8173 CPUFreq support"
|
||||
+ depends on ARCH_MEDIATEK && REGULATOR
|
||||
+ select PM_OPP
|
||||
+ help
|
||||
+ This adds the CPUFreq driver support for Mediatek MT8173 SoC.
|
||||
+
|
||||
config ARM_OMAP2PLUS_CPUFREQ
|
||||
bool "TI OMAP2+"
|
||||
depends on ARCH_OMAP2PLUS
|
||||
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
|
||||
index cdce92a..97f9a9b 100644
|
||||
--- a/drivers/cpufreq/Makefile
|
||||
+++ b/drivers/cpufreq/Makefile
|
||||
@@ -63,6 +63,7 @@ obj-$(CONFIG_ARM_HISI_ACPU_CPUFREQ) += hisi-acpu-cpufreq.o
|
||||
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_MT8173_CPUFREQ) += mt8173-cpufreq.o
|
||||
obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
|
||||
obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o
|
||||
obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o
|
||||
diff --git a/drivers/cpufreq/mt8173-cpufreq.c b/drivers/cpufreq/mt8173-cpufreq.c
|
||||
new file mode 100644
|
||||
index 0000000..d539e7b
|
||||
--- /dev/null
|
||||
+++ b/drivers/cpufreq/mt8173-cpufreq.c
|
||||
@@ -0,0 +1,550 @@
|
||||
+/*
|
||||
+ * 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/cpufreq.h>
|
||||
+#include <linux/cpumask.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/pm_opp.h>
|
||||
+#include <linux/regulator/consumer.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#define MIN_VOLT_SHIFT (100000)
|
||||
+#define MAX_VOLT_SHIFT (200000)
|
||||
+#define MAX_VOLT_LIMIT (1150000)
|
||||
+#define VOLT_TOL (10000)
|
||||
+
|
||||
+/*
|
||||
+ * The struct mtk_cpu_dvfs_info holds necessary information for doing CPU DVFS
|
||||
+ * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in
|
||||
+ * Mediatek SoCs has two voltage inputs, Vproc and Vsram. In some cases the two
|
||||
+ * voltage inputs need to be controlled under a hardware limitation:
|
||||
+ * 100mV < Vsram - Vproc < 200mV
|
||||
+ *
|
||||
+ * 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 list_head node;
|
||||
+ cpumask_var_t cpus;
|
||||
+ struct cpufreq_frequency_table *freq_table;
|
||||
+ struct device *cpu_dev;
|
||||
+ struct regulator *proc_reg;
|
||||
+ struct regulator *sram_reg;
|
||||
+ struct clk *cpu_clk;
|
||||
+ struct clk *inter_clk;
|
||||
+ int intermediate_voltage;
|
||||
+ bool need_voltage_trace;
|
||||
+};
|
||||
+
|
||||
+static LIST_HEAD(cpu_dvfs_info_list);
|
||||
+
|
||||
+static inline struct mtk_cpu_dvfs_info *to_mtk_cpu_dvfs_info(
|
||||
+ struct list_head *list)
|
||||
+{
|
||||
+ return list_entry(list, struct mtk_cpu_dvfs_info, node);
|
||||
+}
|
||||
+
|
||||
+static inline void mtk_cpu_dvfs_info_add(struct mtk_cpu_dvfs_info *info)
|
||||
+{
|
||||
+ list_add(&info->node, &cpu_dvfs_info_list);
|
||||
+}
|
||||
+
|
||||
+static struct mtk_cpu_dvfs_info *mtk_cpu_dvfs_info_get(int cpu)
|
||||
+{
|
||||
+ struct mtk_cpu_dvfs_info *info;
|
||||
+ struct list_head *list;
|
||||
+
|
||||
+ list_for_each(list, &cpu_dvfs_info_list) {
|
||||
+ info = to_mtk_cpu_dvfs_info(list);
|
||||
+
|
||||
+ if (cpumask_test_cpu(cpu, info->cpus))
|
||||
+ return info;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void mtk_cpu_dvfs_info_release(void)
|
||||
+{
|
||||
+ struct list_head *list, *tmp;
|
||||
+ struct mtk_cpu_dvfs_info *info;
|
||||
+
|
||||
+ list_for_each_safe(list, tmp, &cpu_dvfs_info_list) {
|
||||
+ info = to_mtk_cpu_dvfs_info(list);
|
||||
+
|
||||
+ dev_pm_opp_free_cpufreq_table(info->cpu_dev,
|
||||
+ &info->freq_table);
|
||||
+
|
||||
+ if (!IS_ERR(info->proc_reg))
|
||||
+ regulator_put(info->proc_reg);
|
||||
+ if (!IS_ERR(info->sram_reg))
|
||||
+ regulator_put(info->sram_reg);
|
||||
+ if (!IS_ERR(info->cpu_clk))
|
||||
+ clk_put(info->cpu_clk);
|
||||
+ if (!IS_ERR(info->inter_clk))
|
||||
+ clk_put(info->inter_clk);
|
||||
+
|
||||
+ of_free_opp_table(info->cpu_dev);
|
||||
+
|
||||
+ list_del(list);
|
||||
+ kfree(info);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
+
|
||||
+static int mtk_cpufreq_voltage_trace(struct mtk_cpu_dvfs_info *info,
|
||||
+ int new_vproc)
|
||||
+{
|
||||
+ struct regulator *proc_reg = info->proc_reg;
|
||||
+ struct regulator *sram_reg = info->sram_reg;
|
||||
+ int old_vproc, old_vsram, new_vsram, vsram, vproc, ret;
|
||||
+
|
||||
+ old_vproc = regulator_get_voltage(proc_reg);
|
||||
+ old_vsram = regulator_get_voltage(sram_reg);
|
||||
+ /* Vsram should not exceed the maximum allowed voltage of SoC. */
|
||||
+ new_vsram = min(new_vproc + MIN_VOLT_SHIFT, MAX_VOLT_LIMIT);
|
||||
+
|
||||
+ if (old_vproc < new_vproc) {
|
||||
+ /*
|
||||
+ * When scaling up voltages, Vsram and Vproc scale up step
|
||||
+ * by step. At each step, set Vsram to (Vproc + 200mV) first,
|
||||
+ * then set Vproc to (Vsram - 100mV).
|
||||
+ * Keep doing it until Vsram and Vproc hit target voltages.
|
||||
+ */
|
||||
+ do {
|
||||
+ old_vsram = regulator_get_voltage(sram_reg);
|
||||
+ old_vproc = regulator_get_voltage(proc_reg);
|
||||
+
|
||||
+ vsram = MIN(new_vsram, old_vproc + MAX_VOLT_SHIFT);
|
||||
+
|
||||
+ if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) {
|
||||
+ vsram = MAX_VOLT_LIMIT;
|
||||
+
|
||||
+ /*
|
||||
+ * If the target Vsram hits the maximum voltage,
|
||||
+ * try to set the exact voltage value first.
|
||||
+ */
|
||||
+ ret = regulator_set_voltage(sram_reg, vsram,
|
||||
+ vsram);
|
||||
+ if (ret)
|
||||
+ ret = regulator_set_voltage(sram_reg,
|
||||
+ vsram - VOLT_TOL,
|
||||
+ vsram);
|
||||
+
|
||||
+ vproc = new_vproc;
|
||||
+ } else {
|
||||
+ ret = regulator_set_voltage(sram_reg, vsram,
|
||||
+ vsram + VOLT_TOL);
|
||||
+
|
||||
+ vproc = vsram - MIN_VOLT_SHIFT;
|
||||
+ }
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regulator_set_voltage(proc_reg, vproc,
|
||||
+ vproc + VOLT_TOL);
|
||||
+ if (ret) {
|
||||
+ regulator_set_voltage(sram_reg, old_vsram,
|
||||
+ old_vsram);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ } while (vproc < new_vproc || vsram < new_vsram);
|
||||
+ } else if (old_vproc > new_vproc) {
|
||||
+ /*
|
||||
+ * When scaling down voltages, Vsram and Vproc scale down step
|
||||
+ * by step. At each step, set Vproc to (Vsram - 200mV) first,
|
||||
+ * then set Vproc to (Vproc + 100mV).
|
||||
+ * Keep doing it until Vsram and Vproc hit target voltages.
|
||||
+ */
|
||||
+ do {
|
||||
+ old_vproc = regulator_get_voltage(proc_reg);
|
||||
+ old_vsram = regulator_get_voltage(sram_reg);
|
||||
+
|
||||
+ vproc = MAX(new_vproc, old_vsram - MAX_VOLT_SHIFT);
|
||||
+ ret = regulator_set_voltage(proc_reg, vproc,
|
||||
+ vproc + VOLT_TOL);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (vproc == new_vproc)
|
||||
+ vsram = new_vsram;
|
||||
+ else
|
||||
+ vsram = MAX(new_vsram, vproc + MIN_VOLT_SHIFT);
|
||||
+
|
||||
+ if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) {
|
||||
+ vsram = MAX_VOLT_LIMIT;
|
||||
+
|
||||
+ /*
|
||||
+ * If the target Vsram hits the maximum voltage,
|
||||
+ * try to set the exact voltage value first.
|
||||
+ */
|
||||
+ ret = regulator_set_voltage(sram_reg, vsram,
|
||||
+ vsram);
|
||||
+ if (ret)
|
||||
+ ret = regulator_set_voltage(sram_reg,
|
||||
+ vsram - VOLT_TOL,
|
||||
+ vsram);
|
||||
+ } else {
|
||||
+ ret = regulator_set_voltage(sram_reg, vsram,
|
||||
+ vsram + VOLT_TOL);
|
||||
+ }
|
||||
+
|
||||
+ if (ret) {
|
||||
+ regulator_set_voltage(proc_reg, old_vproc,
|
||||
+ old_vproc);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ } while (vproc > new_vproc + VOLT_TOL ||
|
||||
+ vsram > new_vsram + VOLT_TOL);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc)
|
||||
+{
|
||||
+ if (info->need_voltage_trace)
|
||||
+ return mtk_cpufreq_voltage_trace(info, vproc);
|
||||
+ else
|
||||
+ 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 int mtk_cpufreq_init(struct cpufreq_policy *policy)
|
||||
+{
|
||||
+ struct mtk_cpu_dvfs_info *info;
|
||||
+ int ret;
|
||||
+
|
||||
+ info = mtk_cpu_dvfs_info_get(policy->cpu);
|
||||
+ if (!info) {
|
||||
+ pr_err("%s: mtk cpu dvfs info for cpu%d is not initialized\n",
|
||||
+ __func__, policy->cpu);
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ ret = cpufreq_table_validate_and_show(policy, info->freq_table);
|
||||
+ if (ret) {
|
||||
+ pr_err("%s: invalid frequency table: %d\n", __func__, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ cpumask_copy(policy->cpus, info->cpus);
|
||||
+ policy->driver_data = info;
|
||||
+ policy->clk = info->cpu_clk;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct cpufreq_driver mt8173_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,
|
||||
+ .name = "mtk-cpufreq",
|
||||
+ .attr = cpufreq_generic_attr,
|
||||
+};
|
||||
+
|
||||
+static int mtk_cpu_dvfs_info_init(int cpu)
|
||||
+{
|
||||
+ struct device *cpu_dev;
|
||||
+ struct regulator *proc_reg = ERR_PTR(-ENODEV);
|
||||
+ struct regulator *sram_reg = ERR_PTR(-ENODEV);
|
||||
+ struct clk *cpu_clk = ERR_PTR(-ENODEV);
|
||||
+ struct clk *inter_clk = ERR_PTR(-ENODEV);
|
||||
+ struct mtk_cpu_dvfs_info *info;
|
||||
+ struct cpufreq_frequency_table *freq_table;
|
||||
+ 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;
|
||||
+ }
|
||||
+
|
||||
+ ret = of_init_opp_table(cpu_dev);
|
||||
+ if (ret) {
|
||||
+ pr_warn("no OPP table for cpu%d\n", cpu);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ 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);
|
||||
+ goto out_free_opp_table;
|
||||
+ }
|
||||
+
|
||||
+ 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(cpu_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;
|
||||
+ }
|
||||
+
|
||||
+ /* Both presence and absence of sram regulator are valid cases. */
|
||||
+ sram_reg = regulator_get_exclusive(cpu_dev, "sram");
|
||||
+
|
||||
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||
+ if (!info) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto out_free_resources;
|
||||
+ }
|
||||
+
|
||||
+ ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
|
||||
+ if (ret) {
|
||||
+ pr_err("failed to init cpufreq table for cpu%d: %d\n",
|
||||
+ cpu, ret);
|
||||
+ goto out_free_mtk_cpu_dvfs_info;
|
||||
+ }
|
||||
+
|
||||
+ if (!alloc_cpumask_var(&info->cpus, GFP_KERNEL))
|
||||
+ goto out_free_cpufreq_table;
|
||||
+
|
||||
+ /* 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)) {
|
||||
+ pr_err("failed to get intermediate opp for cpu%d\n", cpu);
|
||||
+ ret = PTR_ERR(opp);
|
||||
+ goto out_free_cpumask;
|
||||
+ }
|
||||
+ info->intermediate_voltage = dev_pm_opp_get_voltage(opp);
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
+ /* CPUs in the same cluster share a clock and power domain. */
|
||||
+ cpumask_copy(info->cpus, &cpu_topology[cpu].core_sibling);
|
||||
+
|
||||
+ info->cpu_dev = cpu_dev;
|
||||
+ info->proc_reg = proc_reg;
|
||||
+ info->sram_reg = IS_ERR(sram_reg) ? NULL : sram_reg;
|
||||
+ info->cpu_clk = cpu_clk;
|
||||
+ info->inter_clk = inter_clk;
|
||||
+ info->freq_table = freq_table;
|
||||
+
|
||||
+ /*
|
||||
+ * If SRAM regulator is present, software "voltage trace" is needed
|
||||
+ * for this CPU power domain.
|
||||
+ */
|
||||
+ info->need_voltage_trace = !IS_ERR(sram_reg);
|
||||
+
|
||||
+ mtk_cpu_dvfs_info_add(info);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+out_free_cpumask:
|
||||
+ free_cpumask_var(info->cpus);
|
||||
+
|
||||
+out_free_cpufreq_table:
|
||||
+ dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
|
||||
+
|
||||
+out_free_mtk_cpu_dvfs_info:
|
||||
+ kfree(info);
|
||||
+
|
||||
+out_free_resources:
|
||||
+ if (!IS_ERR(proc_reg))
|
||||
+ regulator_put(proc_reg);
|
||||
+ if (!IS_ERR(sram_reg))
|
||||
+ regulator_put(sram_reg);
|
||||
+ if (!IS_ERR(cpu_clk))
|
||||
+ clk_put(cpu_clk);
|
||||
+ if (!IS_ERR(inter_clk))
|
||||
+ clk_put(inter_clk);
|
||||
+
|
||||
+out_free_opp_table:
|
||||
+ of_free_opp_table(cpu_dev);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int mt8173_cpufreq_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ int cpu, ret;
|
||||
+
|
||||
+ for_each_possible_cpu(cpu) {
|
||||
+ /*
|
||||
+ * If the struct mtk_cpu_dvfs_info for the cpu power domain
|
||||
+ * is already initialized, skip this CPU.
|
||||
+ */
|
||||
+ if (!mtk_cpu_dvfs_info_get(cpu)) {
|
||||
+ ret = mtk_cpu_dvfs_info_init(cpu);
|
||||
+ if (ret) {
|
||||
+ if (ret != -EPROBE_DEFER)
|
||||
+ pr_err("%s probe fail\n", __func__);
|
||||
+
|
||||
+ mtk_cpu_dvfs_info_release();
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = cpufreq_register_driver(&mt8173_cpufreq_driver);
|
||||
+ if (ret) {
|
||||
+ pr_err("failed to register mtk cpufreq driver\n");
|
||||
+ mtk_cpu_dvfs_info_release();
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver mt8173_cpufreq_platdrv = {
|
||||
+ .driver = {
|
||||
+ .name = "mt8173-cpufreq",
|
||||
+ },
|
||||
+ .probe = mt8173_cpufreq_probe,
|
||||
+};
|
||||
+module_platform_driver(mt8173_cpufreq_platdrv);
|
||||
+
|
||||
+static int mt8173_cpufreq_driver_init(void)
|
||||
+{
|
||||
+ struct platform_device *pdev;
|
||||
+
|
||||
+ if (!of_machine_is_compatible("mediatek,mt8173"))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ pdev = platform_device_register_simple("mt8173-cpufreq", -1, NULL, 0);
|
||||
+ if (IS_ERR(pdev)) {
|
||||
+ pr_err("failed to register mtk-cpufreq platform device\n");
|
||||
+ return PTR_ERR(pdev);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+module_init(mt8173_cpufreq_driver_init);
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,54 @@
|
||||
From fe43da8836dbf8e48377d208000877a17e465f3f Mon Sep 17 00:00:00 2001
|
||||
From: Chaotian Jing <chaotian.jing@mediatek.com>
|
||||
Date: Mon, 15 Jun 2015 19:20:47 +0800
|
||||
Subject: [PATCH 34/76] mmc: dt-bindings: add Mediatek MMC bindings
|
||||
|
||||
Document the device-tree binding of Mediatek MMC host
|
||||
|
||||
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
|
||||
---
|
||||
Documentation/devicetree/bindings/mmc/mtk-sd.txt | 32 ++++++++++++++++++++++
|
||||
1 file changed, 32 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/mmc/mtk-sd.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
|
||||
new file mode 100644
|
||||
index 0000000..a1adfa4
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
|
||||
@@ -0,0 +1,32 @@
|
||||
+* MTK MMC controller
|
||||
+
|
||||
+The MTK MSDC can act as a MMC controller
|
||||
+to support MMC, SD, and SDIO types of memory cards.
|
||||
+
|
||||
+This file documents differences between the core properties in mmc.txt
|
||||
+and the properties used by the msdc driver.
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible: Should be "mediatek,mt8173-mmc","mediatek,mt8135-mmc"
|
||||
+- interrupts: Should contain MSDC interrupt number
|
||||
+- clocks: MSDC source clock, HCLK
|
||||
+- clock-names: "source", "hclk"
|
||||
+- pinctrl-names: should be "default", "state_uhs"
|
||||
+- pinctrl-0: should contain default/high speed pin ctrl
|
||||
+- pinctrl-1: should contain uhs mode pin ctrl
|
||||
+- vmmc-supply: power to the Core
|
||||
+- vqmmc-supply: power to the IO
|
||||
+
|
||||
+Examples:
|
||||
+mmc0: mmc@11230000 {
|
||||
+ compatible = "mediatek,mt8173-mmc", "mediatek,mt8135-mmc";
|
||||
+ reg = <0 0x11230000 0 0x108>;
|
||||
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ vmmc-supply = <&mt6397_vemc_3v3_reg>;
|
||||
+ vqmmc-supply = <&mt6397_vio18_reg>;
|
||||
+ clocks = <&pericfg CLK_PERI_MSDC30_0>, <&topckgen CLK_TOP_MSDC50_0_H_SEL>;
|
||||
+ clock-names = "source", "hclk";
|
||||
+ pinctrl-names = "default", "state_uhs";
|
||||
+ pinctrl-0 = <&mmc0_pins_default>;
|
||||
+ pinctrl-1 = <&mmc0_pins_uhs>;
|
||||
+};
|
||||
--
|
||||
1.7.10.4
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,209 @@
|
||||
From 4ca0e8a959569852b520b607d39ce6ceeeb0f518 Mon Sep 17 00:00:00 2001
|
||||
From: Chaotian Jing <chaotian.jing@mediatek.com>
|
||||
Date: Mon, 15 Jun 2015 19:20:49 +0800
|
||||
Subject: [PATCH 36/76] mmc: mediatek: Add PM support for MMC driver
|
||||
|
||||
Add PM support for Mediatek MMC driver
|
||||
Save/restore registers when PM
|
||||
|
||||
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
|
||||
---
|
||||
drivers/mmc/host/mtk-sd.c | 89 +++++++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 86 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
|
||||
index 952be2e..7c20f28 100644
|
||||
--- a/drivers/mmc/host/mtk-sd.c
|
||||
+++ b/drivers/mmc/host/mtk-sd.c
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/platform_device.h>
|
||||
+#include <linux/pm.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
@@ -212,6 +214,7 @@
|
||||
#define MSDC_ASYNC_FLAG (0x1 << 1)
|
||||
#define MSDC_MMAP_FLAG (0x1 << 2)
|
||||
|
||||
+#define MTK_MMC_AUTOSUSPEND_DELAY 50
|
||||
#define CMD_TIMEOUT (HZ/10 * 5) /* 100ms x5 */
|
||||
#define DAT_TIMEOUT (HZ * 5) /* 1000ms x5 */
|
||||
|
||||
@@ -254,6 +257,15 @@ struct msdc_dma {
|
||||
dma_addr_t bd_addr; /* the physical address of bd array */
|
||||
};
|
||||
|
||||
+struct msdc_save_para {
|
||||
+ u32 msdc_cfg;
|
||||
+ u32 iocon;
|
||||
+ u32 sdc_cfg;
|
||||
+ u32 pad_tune;
|
||||
+ u32 patch_bit0;
|
||||
+ u32 patch_bit1;
|
||||
+};
|
||||
+
|
||||
struct msdc_host {
|
||||
struct device *dev;
|
||||
struct mmc_host *mmc; /* mmc structure */
|
||||
@@ -286,6 +298,7 @@ struct msdc_host {
|
||||
u32 sclk; /* SD/MS bus clock frequency */
|
||||
bool ddr;
|
||||
bool vqmmc_enabled;
|
||||
+ struct msdc_save_para save_para; /* used when gate HCLK */
|
||||
};
|
||||
|
||||
static void sdr_set_bits(void __iomem *reg, u32 bs)
|
||||
@@ -677,6 +690,9 @@ static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq)
|
||||
if (mrq->data)
|
||||
msdc_unprepare_data(host, mrq);
|
||||
mmc_request_done(host->mmc, mrq);
|
||||
+
|
||||
+ pm_runtime_mark_last_busy(host->dev);
|
||||
+ pm_runtime_put_autosuspend(host->dev);
|
||||
}
|
||||
|
||||
/* returns true if command is fully handled; returns false otherwise */
|
||||
@@ -831,6 +847,8 @@ static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
WARN_ON(host->mrq);
|
||||
host->mrq = mrq;
|
||||
|
||||
+ pm_runtime_get_sync(host->dev);
|
||||
+
|
||||
if (mrq->data)
|
||||
msdc_prepare_data(host, mrq);
|
||||
|
||||
@@ -1145,6 +1163,8 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
int ret;
|
||||
u32 ddr = 0;
|
||||
|
||||
+ pm_runtime_get_sync(host->dev);
|
||||
+
|
||||
if (ios->timing == MMC_TIMING_UHS_DDR50 ||
|
||||
ios->timing == MMC_TIMING_MMC_DDR52)
|
||||
ddr = 1;
|
||||
@@ -1159,7 +1179,7 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
ios->vdd);
|
||||
if (ret) {
|
||||
dev_err(host->dev, "Failed to set vmmc power!\n");
|
||||
- return;
|
||||
+ goto end;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1187,6 +1207,10 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
|
||||
if (host->mclk != ios->clock || host->ddr != ddr)
|
||||
msdc_set_mclk(host, ddr, ios->clock);
|
||||
+
|
||||
+end:
|
||||
+ pm_runtime_mark_last_busy(host->dev);
|
||||
+ pm_runtime_put_autosuspend(host->dev);
|
||||
}
|
||||
|
||||
static struct mmc_host_ops mt_msdc_ops = {
|
||||
@@ -1310,12 +1334,18 @@ static int msdc_drv_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto release;
|
||||
|
||||
+ pm_runtime_set_active(host->dev);
|
||||
+ pm_runtime_set_autosuspend_delay(host->dev, MTK_MMC_AUTOSUSPEND_DELAY);
|
||||
+ pm_runtime_use_autosuspend(host->dev);
|
||||
+ pm_runtime_enable(host->dev);
|
||||
ret = mmc_add_host(mmc);
|
||||
+
|
||||
if (ret)
|
||||
- goto release;
|
||||
+ goto end;
|
||||
|
||||
return 0;
|
||||
-
|
||||
+end:
|
||||
+ pm_runtime_disable(host->dev);
|
||||
release:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
msdc_deinit_hw(host);
|
||||
@@ -1343,11 +1373,15 @@ static int msdc_drv_remove(struct platform_device *pdev)
|
||||
mmc = platform_get_drvdata(pdev);
|
||||
host = mmc_priv(mmc);
|
||||
|
||||
+ pm_runtime_get_sync(host->dev);
|
||||
+
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
mmc_remove_host(host->mmc);
|
||||
msdc_deinit_hw(host);
|
||||
msdc_gate_clock(host);
|
||||
|
||||
+ pm_runtime_disable(host->dev);
|
||||
+ pm_runtime_put_noidle(host->dev);
|
||||
dma_free_coherent(&pdev->dev,
|
||||
sizeof(struct mt_gpdma_desc),
|
||||
host->dma.gpd, host->dma.gpd_addr);
|
||||
@@ -1359,6 +1393,54 @@ static int msdc_drv_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_PM
|
||||
+static void msdc_save_reg(struct msdc_host *host)
|
||||
+{
|
||||
+ host->save_para.msdc_cfg = readl(host->base + MSDC_CFG);
|
||||
+ host->save_para.iocon = readl(host->base + MSDC_IOCON);
|
||||
+ host->save_para.sdc_cfg = readl(host->base + SDC_CFG);
|
||||
+ host->save_para.pad_tune = readl(host->base + MSDC_PAD_TUNE);
|
||||
+ host->save_para.patch_bit0 = readl(host->base + MSDC_PATCH_BIT);
|
||||
+ host->save_para.patch_bit1 = readl(host->base + MSDC_PATCH_BIT1);
|
||||
+}
|
||||
+
|
||||
+static void msdc_restore_reg(struct msdc_host *host)
|
||||
+{
|
||||
+ writel(host->save_para.msdc_cfg, host->base + MSDC_CFG);
|
||||
+ writel(host->save_para.iocon, host->base + MSDC_IOCON);
|
||||
+ writel(host->save_para.sdc_cfg, host->base + SDC_CFG);
|
||||
+ writel(host->save_para.pad_tune, host->base + MSDC_PAD_TUNE);
|
||||
+ writel(host->save_para.patch_bit0, host->base + MSDC_PATCH_BIT);
|
||||
+ writel(host->save_para.patch_bit1, host->base + MSDC_PATCH_BIT1);
|
||||
+}
|
||||
+
|
||||
+static int msdc_runtime_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct mmc_host *mmc = dev_get_drvdata(dev);
|
||||
+ struct msdc_host *host = mmc_priv(mmc);
|
||||
+
|
||||
+ msdc_save_reg(host);
|
||||
+ msdc_gate_clock(host);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int msdc_runtime_resume(struct device *dev)
|
||||
+{
|
||||
+ struct mmc_host *mmc = dev_get_drvdata(dev);
|
||||
+ struct msdc_host *host = mmc_priv(mmc);
|
||||
+
|
||||
+ msdc_ungate_clock(host);
|
||||
+ msdc_restore_reg(host);
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+static const struct dev_pm_ops msdc_dev_pm_ops = {
|
||||
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
|
||||
+ pm_runtime_force_resume)
|
||||
+ SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume, NULL)
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id msdc_of_ids[] = {
|
||||
{ .compatible = "mediatek,mt8135-mmc", },
|
||||
{}
|
||||
@@ -1370,6 +1452,7 @@ static struct platform_driver mt_msdc_driver = {
|
||||
.driver = {
|
||||
.name = "mtk-msdc",
|
||||
.of_match_table = msdc_of_ids,
|
||||
+ .pm = &msdc_dev_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,28 @@
|
||||
From 0435517df474d830711b7e1dc56e2d47ae5083b5 Mon Sep 17 00:00:00 2001
|
||||
From: Eddie Huang <eddie.huang@mediatek.com>
|
||||
Date: Mon, 15 Jun 2015 19:20:52 +0800
|
||||
Subject: [PATCH 37/76] arm64: mediatek: Add Mediatek MMC support in defconfig
|
||||
|
||||
Add CONFIG_MMC_MTK=y in defconfig
|
||||
|
||||
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
|
||||
Signed-off-by: Eddie Huang <eddie.huang@mediatek.com>
|
||||
---
|
||||
arch/arm64/configs/defconfig | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
|
||||
index 2ed7449..e03288a 100644
|
||||
--- a/arch/arm64/configs/defconfig
|
||||
+++ b/arch/arm64/configs/defconfig
|
||||
@@ -138,6 +138,7 @@ CONFIG_MMC_ARMMMCI=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_SPI=y
|
||||
+CONFIG_MMC_MTK=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_EFI=y
|
||||
CONFIG_RTC_DRV_XGENE=y
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,29 @@
|
||||
From 3069c2bfe0da7c6c13a61b0e1d457fd0e021e27b Mon Sep 17 00:00:00 2001
|
||||
From: Yingjoe Chen <yingjoe.chen@mediatek.com>
|
||||
Date: Mon, 15 Jun 2015 19:20:53 +0800
|
||||
Subject: [PATCH 38/76] ARM: multi_v7_defconfig: Enable Mediatek MMC support
|
||||
multi-v7
|
||||
|
||||
Add CONFIG_MMC_MTK=y in defconfig
|
||||
|
||||
Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
|
||||
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
|
||||
---
|
||||
arch/arm/configs/multi_v7_defconfig | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
|
||||
index fbbb191..bfa09ab 100644
|
||||
--- a/arch/arm/configs/multi_v7_defconfig
|
||||
+++ b/arch/arm/configs/multi_v7_defconfig
|
||||
@@ -477,6 +477,7 @@ CONFIG_MMC_DW_EXYNOS=y
|
||||
CONFIG_MMC_DW_ROCKCHIP=y
|
||||
CONFIG_MMC_SH_MMCIF=y
|
||||
CONFIG_MMC_SUNXI=y
|
||||
+CONFIG_MMC_MTK=y
|
||||
CONFIG_NEW_LEDS=y
|
||||
CONFIG_LEDS_CLASS=y
|
||||
CONFIG_LEDS_GPIO=y
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,32 @@
|
||||
From 9d4cba66a74cbdf25f43a7a8cc360370214ba5fc Mon Sep 17 00:00:00 2001
|
||||
From: "Joe.C" <yingjoe.chen@mediatek.com>
|
||||
Date: Fri, 1 May 2015 15:43:24 +0800
|
||||
Subject: [PATCH 39/76] clocksource: mediatek: Don't run event_handler if it
|
||||
is NULL
|
||||
|
||||
Spurious timer interrupt is noticed in mtk timer and cause kernel
|
||||
crash. In mtk_timer_interrupt(), only run event_handler if it is
|
||||
not NULL.
|
||||
|
||||
Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
|
||||
---
|
||||
drivers/clocksource/mtk_timer.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c
|
||||
index 68ab423..85e0ab5 100644
|
||||
--- a/drivers/clocksource/mtk_timer.c
|
||||
+++ b/drivers/clocksource/mtk_timer.c
|
||||
@@ -143,7 +143,8 @@ static irqreturn_t mtk_timer_interrupt(int irq, void *dev_id)
|
||||
|
||||
/* Acknowledge timer0 irq */
|
||||
writel(GPT_IRQ_ACK(GPT_CLK_EVT), evt->gpt_base + GPT_IRQ_ACK_REG);
|
||||
- evt->dev.event_handler(&evt->dev);
|
||||
+ if (evt->dev.event_handler)
|
||||
+ evt->dev.event_handler(&evt->dev);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,51 @@
|
||||
From 3b3c2406dd9797bc806e0ce756142a33d209c4e8 Mon Sep 17 00:00:00 2001
|
||||
From: "Joe.C" <yingjoe.chen@mediatek.com>
|
||||
Date: Fri, 1 May 2015 15:43:25 +0800
|
||||
Subject: [PATCH 40/76] clocksource: mediatek: Use GPT as sched clock source
|
||||
|
||||
When cpu is in deep idle, arch timer will stop counting. Setup GPT as
|
||||
sched clock source so it can keep counting in idle.
|
||||
|
||||
Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
|
||||
---
|
||||
drivers/clocksource/mtk_timer.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c
|
||||
index 85e0ab5..9a90c7b 100644
|
||||
--- a/drivers/clocksource/mtk_timer.c
|
||||
+++ b/drivers/clocksource/mtk_timer.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
+#include <linux/sched_clock.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define GPT_IRQ_EN_REG 0x00
|
||||
@@ -59,6 +60,13 @@ struct mtk_clock_event_device {
|
||||
struct clock_event_device dev;
|
||||
};
|
||||
|
||||
+static void __iomem *gpt_base __read_mostly;
|
||||
+
|
||||
+static u64 notrace mtk_read_sched_clock(void)
|
||||
+{
|
||||
+ return readl_relaxed(gpt_base + TIMER_CNT_REG(GPT_CLK_SRC));
|
||||
+}
|
||||
+
|
||||
static inline struct mtk_clock_event_device *to_mtk_clk(
|
||||
struct clock_event_device *c)
|
||||
{
|
||||
@@ -239,6 +247,8 @@ static void __init mtk_timer_init(struct device_node *node)
|
||||
mtk_timer_setup(evt, GPT_CLK_SRC, TIMER_CTRL_OP_FREERUN);
|
||||
clocksource_mmio_init(evt->gpt_base + TIMER_CNT_REG(GPT_CLK_SRC),
|
||||
node->name, rate, 300, 32, clocksource_mmio_readl_up);
|
||||
+ gpt_base = evt->gpt_base;
|
||||
+ sched_clock_register(mtk_read_sched_clock, 32, rate);
|
||||
|
||||
/* Configure clock event */
|
||||
mtk_timer_setup(evt, GPT_CLK_EVT, TIMER_CTRL_OP_REPEAT);
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,63 @@
|
||||
From eec99287ace37015ed313b4fc27ba205a158b66c Mon Sep 17 00:00:00 2001
|
||||
From: Matthias Brugger <matthias.bgg@gmail.com>
|
||||
Date: Fri, 1 May 2015 15:43:26 +0800
|
||||
Subject: [PATCH 41/76] arm: mediatek: enable gpt6 on boot up to make arch
|
||||
timer working
|
||||
|
||||
We enable GTP6 which ungates the arch timer clock.
|
||||
In the future this should be done in the bootloader.
|
||||
|
||||
Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
|
||||
Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
|
||||
---
|
||||
arch/arm/mach-mediatek/mediatek.c | 29 +++++++++++++++++++++++++++++
|
||||
1 file changed, 29 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c
|
||||
index a954900..6b38d67 100644
|
||||
--- a/arch/arm/mach-mediatek/mediatek.c
|
||||
+++ b/arch/arm/mach-mediatek/mediatek.c
|
||||
@@ -16,6 +16,34 @@
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <asm/mach/arch.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/clk-provider.h>
|
||||
+#include <linux/clocksource.h>
|
||||
+
|
||||
+
|
||||
+#define GPT6_CON_MT65xx 0x10008060
|
||||
+#define GPT_ENABLE 0x31
|
||||
+
|
||||
+static void __init mediatek_timer_init(void)
|
||||
+{
|
||||
+ void __iomem *gpt_base = 0;
|
||||
+
|
||||
+ if (of_machine_is_compatible("mediatek,mt6589") ||
|
||||
+ of_machine_is_compatible("mediatek,mt8135") ||
|
||||
+ of_machine_is_compatible("mediatek,mt8127")) {
|
||||
+ /* turn on GPT6 which ungates arch timer clocks */
|
||||
+ gpt_base = ioremap(GPT6_CON_MT65xx, 0x04);
|
||||
+ }
|
||||
+
|
||||
+ /* enabel clock and set to free-run */
|
||||
+ if (gpt_base) {
|
||||
+ writel(GPT_ENABLE, gpt_base);
|
||||
+ iounmap(gpt_base);
|
||||
+ }
|
||||
+
|
||||
+ of_clk_init(NULL);
|
||||
+ clocksource_of_init();
|
||||
+};
|
||||
|
||||
static const char * const mediatek_board_dt_compat[] = {
|
||||
"mediatek,mt6589",
|
||||
@@ -27,4 +55,5 @@ static const char * const mediatek_board_dt_compat[] = {
|
||||
|
||||
DT_MACHINE_START(MEDIATEK_DT, "Mediatek Cortex-A7 (Device Tree)")
|
||||
.dt_compat = mediatek_board_dt_compat,
|
||||
+ .init_time = mediatek_timer_init,
|
||||
MACHINE_END
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,178 @@
|
||||
From daa2c1f9202f08628d4f91a1cf4dafb44c9bcafe Mon Sep 17 00:00:00 2001
|
||||
From: "Joe.C" <yingjoe.chen@mediatek.com>
|
||||
Date: Fri, 1 May 2015 15:43:28 +0800
|
||||
Subject: [PATCH 42/76] ARM: mediatek: add smp bringup code
|
||||
|
||||
Add support for booting secondary CPUs on mt6589, mt8127
|
||||
and mt8135.
|
||||
|
||||
Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
|
||||
---
|
||||
arch/arm/mach-mediatek/Makefile | 3 +
|
||||
arch/arm/mach-mediatek/platsmp.c | 145 ++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 148 insertions(+)
|
||||
create mode 100644 arch/arm/mach-mediatek/platsmp.c
|
||||
|
||||
diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
|
||||
index 43e619f..2116460 100644
|
||||
--- a/arch/arm/mach-mediatek/Makefile
|
||||
+++ b/arch/arm/mach-mediatek/Makefile
|
||||
@@ -1 +1,4 @@
|
||||
+ifeq ($(CONFIG_SMP),y)
|
||||
+obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
|
||||
+endif
|
||||
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
|
||||
diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c
|
||||
new file mode 100644
|
||||
index 0000000..e266b3d
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/mach-mediatek/platsmp.c
|
||||
@@ -0,0 +1,145 @@
|
||||
+/*
|
||||
+ * arch/arm/mach-mediatek/platsmp.c
|
||||
+ *
|
||||
+ * Copyright (c) 2014 Mediatek Inc.
|
||||
+ * Author: Shunli Wang <shunli.wang@mediatek.com>
|
||||
+ * Yingjoe Chen <yingjoe.chen@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ */
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/memblock.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/string.h>
|
||||
+#include <linux/threads.h>
|
||||
+
|
||||
+#define MTK_MAX_CPU 8
|
||||
+#define MTK_SMP_REG_SIZE 0x1000
|
||||
+
|
||||
+struct mtk_smp_boot_info {
|
||||
+ unsigned long smp_base;
|
||||
+ unsigned int jump_reg;
|
||||
+ unsigned int boot_reg;
|
||||
+ unsigned int core_keys[MTK_MAX_CPU - 1];
|
||||
+ unsigned int core_regs[MTK_MAX_CPU - 1];
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_smp_boot_info mtk_mt8135_tz_boot = {
|
||||
+ 0x80002000, 1020, 1012,
|
||||
+ { 0x534c4131, 0x4c415332, 0x41534c33 },
|
||||
+ { 1016, 1016, 1016},
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_smp_boot_info mtk_mt6589_boot = {
|
||||
+ 0x10002000, 0x34, 0x30,
|
||||
+ { 0x534c4131, 0x4c415332, 0x41534c33 },
|
||||
+ { 0x38, 0x3c, 0x40 },
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = {
|
||||
+ { .compatible = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot },
|
||||
+ { .compatible = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot },
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
|
||||
+ { .compatible = "mediatek,mt6589", .data = &mtk_mt6589_boot },
|
||||
+};
|
||||
+
|
||||
+static void __iomem *mtk_smp_base;
|
||||
+static const struct mtk_smp_boot_info *mtk_smp_info;
|
||||
+
|
||||
+static int mtk_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||
+{
|
||||
+ if (!mtk_smp_base)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (!mtk_smp_info->core_keys[cpu-1])
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ writel_relaxed(mtk_smp_info->core_keys[cpu-1],
|
||||
+ mtk_smp_base + mtk_smp_info->core_regs[cpu-1]);
|
||||
+
|
||||
+ arch_send_wakeup_ipi_mask(cpumask_of(cpu));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void __init __mtk_smp_prepare_cpus(unsigned int max_cpus, int trustzone)
|
||||
+{
|
||||
+ int i, num;
|
||||
+ const struct of_device_id *infos;
|
||||
+
|
||||
+ if (trustzone) {
|
||||
+ num = ARRAY_SIZE(mtk_tz_smp_boot_infos);
|
||||
+ infos = mtk_tz_smp_boot_infos;
|
||||
+ } else {
|
||||
+ num = ARRAY_SIZE(mtk_smp_boot_infos);
|
||||
+ infos = mtk_smp_boot_infos;
|
||||
+ }
|
||||
+
|
||||
+ /* Find smp boot info for this SoC */
|
||||
+ for (i = 0; i < num; i++) {
|
||||
+ if (of_machine_is_compatible(infos[i].compatible)) {
|
||||
+ mtk_smp_info = infos[i].data;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!mtk_smp_info) {
|
||||
+ pr_err("%s: Device is not supported\n", __func__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (trustzone) {
|
||||
+ if (memblock_reserve(mtk_smp_info->smp_base, MTK_SMP_REG_SIZE)) {
|
||||
+ pr_err("%s: Can't reserve smp memory\n", __func__);
|
||||
+ return;
|
||||
+ }
|
||||
+ mtk_smp_base = phys_to_virt(mtk_smp_info->smp_base);
|
||||
+ } else {
|
||||
+ mtk_smp_base = ioremap(mtk_smp_info->smp_base, MTK_SMP_REG_SIZE);
|
||||
+ if (!mtk_smp_base) {
|
||||
+ pr_err("%s: Can't remap %lx\n", __func__,
|
||||
+ mtk_smp_info->smp_base);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * write the address of slave startup address into the system-wide
|
||||
+ * jump register
|
||||
+ */
|
||||
+ writel_relaxed(virt_to_phys(secondary_startup),
|
||||
+ mtk_smp_base + mtk_smp_info->jump_reg);
|
||||
+}
|
||||
+
|
||||
+static void __init mtk_tz_smp_prepare_cpus(unsigned int max_cpus)
|
||||
+{
|
||||
+ __mtk_smp_prepare_cpus(max_cpus, 1);
|
||||
+}
|
||||
+
|
||||
+static void __init mtk_smp_prepare_cpus(unsigned int max_cpus)
|
||||
+{
|
||||
+ __mtk_smp_prepare_cpus(max_cpus, 0);
|
||||
+}
|
||||
+
|
||||
+static struct smp_operations mt81xx_tz_smp_ops __initdata = {
|
||||
+ .smp_prepare_cpus = mtk_tz_smp_prepare_cpus,
|
||||
+ .smp_boot_secondary = mtk_boot_secondary,
|
||||
+};
|
||||
+CPU_METHOD_OF_DECLARE(mt81xx_tz_smp, "mediatek,mt81xx-tz-smp", &mt81xx_tz_smp_ops);
|
||||
+
|
||||
+static struct smp_operations mt65xx_smp_ops __initdata = {
|
||||
+ .smp_prepare_cpus = mtk_smp_prepare_cpus,
|
||||
+ .smp_boot_secondary = mtk_boot_secondary,
|
||||
+};
|
||||
+CPU_METHOD_OF_DECLARE(mt65xx_smp, "mediatek,mt65xx-smp", &mt65xx_smp_ops);
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,53 @@
|
||||
From e75f8b666c976aff2aa30b967f74df021d800993 Mon Sep 17 00:00:00 2001
|
||||
From: "Joe.C" <yingjoe.chen@mediatek.com>
|
||||
Date: Fri, 1 May 2015 15:43:30 +0800
|
||||
Subject: [PATCH 43/76] ARM: dts: mt8127: enable basic SMP bringup for mt8127
|
||||
|
||||
Add arch timer node to enable arch-timer support. MT8127 firmware
|
||||
doesn't correctly setup arch-timer frequency and CNTVOFF, add
|
||||
properties to workaround this.
|
||||
|
||||
This also set cpu enable-method to enable SMP.
|
||||
|
||||
Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
|
||||
---
|
||||
arch/arm/boot/dts/mt8127.dtsi | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/mt8127.dtsi b/arch/arm/boot/dts/mt8127.dtsi
|
||||
index aaa7862..7c2090d 100644
|
||||
--- a/arch/arm/boot/dts/mt8127.dtsi
|
||||
+++ b/arch/arm/boot/dts/mt8127.dtsi
|
||||
@@ -23,6 +23,7 @@
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
+ enable-method = "mediatek,mt81xx-tz-smp";
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
@@ -72,6 +73,21 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ timer {
|
||||
+ compatible = "arm,armv7-timer";
|
||||
+ interrupt-parent = <&gic>;
|
||||
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
|
||||
+ IRQ_TYPE_LEVEL_LOW)>,
|
||||
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) |
|
||||
+ IRQ_TYPE_LEVEL_LOW)>,
|
||||
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
|
||||
+ IRQ_TYPE_LEVEL_LOW)>,
|
||||
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
|
||||
+ IRQ_TYPE_LEVEL_LOW)>;
|
||||
+ clock-frequency = <13000000>;
|
||||
+ arm,cpu-registers-not-fw-configured;
|
||||
+ };
|
||||
+
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,60 @@
|
||||
From 8d61eb953496aba51b94dac07c31c7e069c784bd Mon Sep 17 00:00:00 2001
|
||||
From: Chunfeng Yun <chunfeng.yun@mediatek.com>
|
||||
Date: Wed, 27 May 2015 19:47:58 +0800
|
||||
Subject: [PATCH 44/76] dt-bindings: Add usb3.0 phy binding for MT65xx SoCs
|
||||
|
||||
add a DT binding documentation of usb3.0 phy for MT65xx
|
||||
SoCs from Mediatek.
|
||||
|
||||
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
|
||||
---
|
||||
.../devicetree/bindings/usb/mt65xx-u3phy.txt | 37 ++++++++++++++++++++
|
||||
1 file changed, 37 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/usb/mt65xx-u3phy.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/usb/mt65xx-u3phy.txt b/Documentation/devicetree/bindings/usb/mt65xx-u3phy.txt
|
||||
new file mode 100644
|
||||
index 0000000..b0b91b0
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/usb/mt65xx-u3phy.txt
|
||||
@@ -0,0 +1,37 @@
|
||||
+MT65xx U3PHY
|
||||
+
|
||||
+The device node for Mediatek SOC usb3.0 phy
|
||||
+
|
||||
+Required properties:
|
||||
+ - compatible : Should be "mediatek,mt8173-u3phy"
|
||||
+ - reg : Offset and length of registers, the first is for mac domain,
|
||||
+ another for phy domain
|
||||
+ - power-domains: to enable usb's mtcmos
|
||||
+ - reg-vusb33-supply: regulator of usb avdd3.3v
|
||||
+ - clocks : must support all clocks that phy need
|
||||
+ - clock-names: should be "wakeup_deb_p0", "wakeup_deb_p1" for wakeup
|
||||
+ debounce control clocks, "sys_mac" for sys and mac clocks and
|
||||
+ "u3phya_ref" for u3phya reference clock.
|
||||
+
|
||||
+Optional properties:
|
||||
+ - disable-usb2-p1 : disable port1 of usb2.0 which has two ports.
|
||||
+ - reg-p1-vbus-supply : regulator of port1's vbus;
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+u3phy: usb-phy@11271000 {
|
||||
+ compatible = "mediatek,mt8173-u3phy";
|
||||
+ reg = <0 0x11271000 0 0x3000>,
|
||||
+ <0 0x11280000 0 0x20000>;
|
||||
+ power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>;
|
||||
+ reg-vusb33-supply = <&mt6397_usb_reg>;
|
||||
+ clocks = <&perisys PERI_USB0>,
|
||||
+ <&perisys PERI_USB1>,
|
||||
+ <&topckgen CLK_TOP_USB30_SEL>,
|
||||
+ <&apmixedsys CLK_APMIXED_REF2USB_TX>;
|
||||
+ clock-names = "wakeup_deb_p0",
|
||||
+ "wakeup_deb_p1",
|
||||
+ "sys_mac",
|
||||
+ "u3phya_ref";
|
||||
+ disable-usb2-p1;
|
||||
+};
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,43 @@
|
||||
From 8629bcb28208ef5b9f5eeb6d4b669651c9521b30 Mon Sep 17 00:00:00 2001
|
||||
From: Chunfeng Yun <chunfeng.yun@mediatek.com>
|
||||
Date: Wed, 27 May 2015 19:47:59 +0800
|
||||
Subject: [PATCH 45/76] dt-bindings: Add a binding for Mediatek xHCI host
|
||||
controller
|
||||
|
||||
add a DT binding documentation of xHCI host controller for
|
||||
the MT8173 SoC from Mediatek.
|
||||
|
||||
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
|
||||
---
|
||||
.../devicetree/bindings/usb/mt8173-xhci.txt | 19 +++++++++++++++++++
|
||||
1 file changed, 19 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/usb/mt8173-xhci.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/usb/mt8173-xhci.txt b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt
|
||||
new file mode 100644
|
||||
index 0000000..da28570
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt
|
||||
@@ -0,0 +1,19 @@
|
||||
+MT65XX xhci
|
||||
+
|
||||
+The device node for Mediatek SOC usb3.0 host controller
|
||||
+
|
||||
+Required properties:
|
||||
+ - compatible : supports "mediatek,mt8173-xhci", "generic-xhci"
|
||||
+ - reg : Offset and length of registers
|
||||
+ - interrupts : Interrupt; mode, number and trigger
|
||||
+ - usb-phy : the phy that xhci will bind
|
||||
+ - usb3-lpm-capable: suppots USB3 LPM
|
||||
+
|
||||
+Example:
|
||||
+usb: usb30@11270000 {
|
||||
+ compatible = "mediatek,mt8173-xhci", "generic-xhci";
|
||||
+ reg = <0 0x11270000 0 0x1000>;
|
||||
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ usb-phy = <&u3phy>;
|
||||
+ usb3-lpm-capable;
|
||||
+};
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,779 @@
|
||||
From cee7c5a343bdecf407c876289327c567bfd34fd4 Mon Sep 17 00:00:00 2001
|
||||
From: Chunfeng Yun <chunfeng.yun@mediatek.com>
|
||||
Date: Wed, 27 May 2015 19:48:01 +0800
|
||||
Subject: [PATCH 46/76] usb: phy: add usb3.0 phy driver for mt65xx SoCs
|
||||
|
||||
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
|
||||
---
|
||||
drivers/usb/phy/Kconfig | 10 +
|
||||
drivers/usb/phy/Makefile | 1 +
|
||||
drivers/usb/phy/phy-mt65xx-usb3.c | 724 +++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 735 insertions(+)
|
||||
create mode 100644 drivers/usb/phy/phy-mt65xx-usb3.c
|
||||
|
||||
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
|
||||
index 2175678..dfca566 100644
|
||||
--- a/drivers/usb/phy/Kconfig
|
||||
+++ b/drivers/usb/phy/Kconfig
|
||||
@@ -151,6 +151,16 @@ config USB_MSM_OTG
|
||||
This driver is not supported on boards like trout which
|
||||
has an external PHY.
|
||||
|
||||
+config USB_MT65XX_USB3_PHY
|
||||
+ tristate "Mediatek USB3.0 PHY controller Driver"
|
||||
+ depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
+ select USB_PHY
|
||||
+ help
|
||||
+ Say 'Y' here to add support for Mediatek USB3.0 PHY driver
|
||||
+ for mt65xx SoCs. it supports two usb2.0 ports and
|
||||
+ one usb3.0 port.
|
||||
+ To compile this driver as a module, choose M here
|
||||
+
|
||||
config USB_MV_OTG
|
||||
tristate "Marvell USB OTG support"
|
||||
depends on USB_EHCI_MV && USB_MV_UDC && PM
|
||||
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
|
||||
index 75f2bba..d6113a4 100644
|
||||
--- a/drivers/usb/phy/Makefile
|
||||
+++ b/drivers/usb/phy/Makefile
|
||||
@@ -20,6 +20,7 @@ obj-$(CONFIG_USB_EHCI_TEGRA) += phy-tegra-usb.o
|
||||
obj-$(CONFIG_USB_GPIO_VBUS) += phy-gpio-vbus-usb.o
|
||||
obj-$(CONFIG_USB_ISP1301) += phy-isp1301.o
|
||||
obj-$(CONFIG_USB_MSM_OTG) += phy-msm-usb.o
|
||||
+obj-$(CONFIG_USB_MT65XX_USB3_PHY) += phy-mt65xx-usb3.o
|
||||
obj-$(CONFIG_USB_MV_OTG) += phy-mv-usb.o
|
||||
obj-$(CONFIG_USB_MXS_PHY) += phy-mxs-usb.o
|
||||
obj-$(CONFIG_USB_RCAR_PHY) += phy-rcar-usb.o
|
||||
diff --git a/drivers/usb/phy/phy-mt65xx-usb3.c b/drivers/usb/phy/phy-mt65xx-usb3.c
|
||||
new file mode 100644
|
||||
index 0000000..ec5cf24
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/phy/phy-mt65xx-usb3.c
|
||||
@@ -0,0 +1,724 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015 MediaTek Inc.
|
||||
+ * Author: Chunfeng.Yun <chunfeng.yun@mediatek.com>
|
||||
+ *
|
||||
+ * This software is licensed under the terms of the GNU General Public
|
||||
+ * License version 2, as published by the Free Software Foundation, and
|
||||
+ * may be copied, distributed, and modified under those terms.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/resource.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/export.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/regulator/consumer.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/gpio.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/of_gpio.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/usb/otg.h>
|
||||
+#include <linux/usb/of.h>
|
||||
+#include <linux/usb/phy.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/iopoll.h>
|
||||
+
|
||||
+/*
|
||||
+ * relative to MAC base address
|
||||
+ */
|
||||
+#define SSUSB_USB3_MAC_CSR_BASE (0x1400)
|
||||
+#define SSUSB_USB3_SYS_CSR_BASE (0x1400)
|
||||
+#define SSUSB_USB2_CSR_BASE (0x2400)
|
||||
+
|
||||
+/*
|
||||
+ * for sifslv1 register
|
||||
+ * relative to USB3_SIF_BASE base address
|
||||
+ */
|
||||
+#define SSUSB_SIFSLV_IPPC_BASE (0x700)
|
||||
+
|
||||
+/*
|
||||
+ * for sifslv2 register
|
||||
+ * relative to USB3_SIF_BASE base address
|
||||
+ */
|
||||
+#define SSUSB_SIFSLV_U2PHY_COM_BASE (0x10800)
|
||||
+#define SSUSB_SIFSLV_U3PHYD_BASE (0x10900)
|
||||
+#define SSUSB_SIFSLV_U2FREQ_BASE (0x10f00)
|
||||
+#define SSUSB_USB30_PHYA_SIV_B_BASE (0x10b00)
|
||||
+#define SSUSB_SIFSLV_U3PHYA_DA_BASE (0x10c00)
|
||||
+#define SSUSB_SIFSLV_SPLLC (0x10000)
|
||||
+
|
||||
+/*port1 refs. +0x800(refer to port0)*/
|
||||
+#define U3P_PORT_OFFSET (0x800) /*based on port0 */
|
||||
+#define U3P_PHY_BASE(index) ((U3P_PORT_OFFSET) * (index))
|
||||
+
|
||||
+#define U3P_IP_PW_CTRL0 (SSUSB_SIFSLV_IPPC_BASE+0x0000)
|
||||
+#define CTRL0_IP_SW_RST (0x1<<0)
|
||||
+
|
||||
+#define U3P_IP_PW_CTRL1 (SSUSB_SIFSLV_IPPC_BASE+0x0004)
|
||||
+#define CTRL1_IP_HOST_PDN (0x1<<0)
|
||||
+
|
||||
+#define U3P_IP_PW_STS1 (SSUSB_SIFSLV_IPPC_BASE+0x0010)
|
||||
+#define STS1_U3_MAC_RST (0x1 << 16)
|
||||
+#define STS1_SYS125_RST (0x1 << 10)
|
||||
+#define STS1_REF_RST (0x1 << 8)
|
||||
+#define STS1_SYSPLL_STABLE (0x1 << 0)
|
||||
+
|
||||
+#define U3P_IP_PW_STS2 (SSUSB_SIFSLV_IPPC_BASE+0x0014)
|
||||
+#define STS2_U2_MAC_RST (0x1 << 0)
|
||||
+
|
||||
+#define U3P_IP_XHCI_CAP (SSUSB_SIFSLV_IPPC_BASE + 0x24)
|
||||
+#define CAP_U3_PORT_NUM(p) ((p) & 0xff)
|
||||
+#define CAP_U2_PORT_NUM(p) (((p) >> 8) & 0xff)
|
||||
+
|
||||
+#define U3P_U3_CTRL_0P (SSUSB_SIFSLV_IPPC_BASE+0x0030)
|
||||
+#define CTRL_U3_PORT_HOST_SEL (0x1<<2)
|
||||
+#define CTRL_U3_PORT_PDN (0x1<<1)
|
||||
+#define CTRL_U3_PORT_DIS (0x1<<0)
|
||||
+
|
||||
+#define U3P_U2_CTRL_0P (SSUSB_SIFSLV_IPPC_BASE+0x0050)
|
||||
+#define CTRL_U2_PORT_HOST_SEL (0x1<<2)
|
||||
+#define CTRL_U2_PORT_PDN (0x1<<1)
|
||||
+#define CTRL_U2_PORT_DIS (0x1<<0)
|
||||
+
|
||||
+#define U3P_U3_CTRL(p) (U3P_U3_CTRL_0P + ((p) * 0x08))
|
||||
+#define U3P_U2_CTRL(p) (U3P_U2_CTRL_0P + ((p) * 0x08))
|
||||
+
|
||||
+#define U3P_USBPHYACR5 (SSUSB_SIFSLV_U2PHY_COM_BASE+0x0014)
|
||||
+#define PA5_RG_U2_HSTX_SRCTRL (0x7<<12)
|
||||
+#define PA5_RG_U2_HSTX_SRCTRL_VAL(x) ((0x7 & (x)) << 12)
|
||||
+#define PA5_RG_U2_HS_100U_U3_EN (0x1<<11)
|
||||
+
|
||||
+#define U3P_USBPHYACR6 (SSUSB_SIFSLV_U2PHY_COM_BASE+0x0018)
|
||||
+#define PA6_RG_U2_ISO_EN (0x1<<31)
|
||||
+#define PA6_RG_U2_BC11_SW_EN (0x1<<23)
|
||||
+#define PA6_RG_U2_OTG_VBUSCMP_EN (0x1<<20)
|
||||
+
|
||||
+#define U3P_U2PHYACR4 (SSUSB_SIFSLV_U2PHY_COM_BASE+0x0020)
|
||||
+#define P2C_RG_USB20_GPIO_CTL (0x1<<9)
|
||||
+#define P2C_USB20_GPIO_MODE (0x1<<8)
|
||||
+#define P2C_U2_GPIO_CTR_MSK (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
|
||||
+
|
||||
+#define U3P_U2PHYDTM0 (SSUSB_SIFSLV_U2PHY_COM_BASE+0x0068)
|
||||
+#define P2C_FORCE_UART_EN (0x1<<26)
|
||||
+#define P2C_FORCE_DATAIN (0x1<<23)
|
||||
+#define P2C_FORCE_DM_PULLDOWN (0x1<<21)
|
||||
+#define P2C_FORCE_DP_PULLDOWN (0x1<<20)
|
||||
+#define P2C_FORCE_XCVRSEL (0x1<<19)
|
||||
+#define P2C_FORCE_SUSPENDM (0x1<<18)
|
||||
+#define P2C_FORCE_TERMSEL (0x1<<17)
|
||||
+#define P2C_RG_DATAIN (0xf<<10)
|
||||
+#define P2C_RG_DATAIN_VAL(x) ((0xf & (x)) << 10)
|
||||
+#define P2C_RG_DMPULLDOWN (0x1<<7)
|
||||
+#define P2C_RG_DPPULLDOWN (0x1<<6)
|
||||
+#define P2C_RG_XCVRSEL (0x3<<4)
|
||||
+#define P2C_RG_XCVRSEL_VAL(x) ((0x3 & (x)) << 4)
|
||||
+#define P2C_RG_SUSPENDM (0x1<<3)
|
||||
+#define P2C_RG_TERMSEL (0x1<<2)
|
||||
+#define P2C_DTM0_PART_MASK \
|
||||
+ (P2C_FORCE_DATAIN | P2C_FORCE_DM_PULLDOWN | \
|
||||
+ P2C_FORCE_DP_PULLDOWN | P2C_FORCE_XCVRSEL | \
|
||||
+ P2C_FORCE_TERMSEL | P2C_RG_DMPULLDOWN | \
|
||||
+ P2C_RG_TERMSEL)
|
||||
+
|
||||
+#define U3P_U2PHYDTM1 (SSUSB_SIFSLV_U2PHY_COM_BASE+0x006C)
|
||||
+#define P2C_RG_UART_EN (0x1<<16)
|
||||
+#define P2C_RG_VBUSVALID (0x1<<5)
|
||||
+#define P2C_RG_SESSEND (0x1<<4)
|
||||
+#define P2C_RG_AVALID (0x1<<2)
|
||||
+
|
||||
+#define U3P_U3_PHYA_REG0 (SSUSB_USB30_PHYA_SIV_B_BASE+0x0000)
|
||||
+#define P3A_RG_U3_VUSB10_ON (1<<5)
|
||||
+
|
||||
+#define U3P_U3_PHYA_REG6 (SSUSB_USB30_PHYA_SIV_B_BASE+0x0018)
|
||||
+#define P3A_RG_TX_EIDLE_CM (0xf<<28)
|
||||
+#define P3A_RG_TX_EIDLE_CM_VAL(x) ((0xf & (x)) << 28)
|
||||
+
|
||||
+#define U3P_U3_PHYA_REG9 (SSUSB_USB30_PHYA_SIV_B_BASE+0x0024)
|
||||
+#define P3A_RG_RX_DAC_MUX (0x1f<<1)
|
||||
+#define P3A_RG_RX_DAC_MUX_VAL(x) ((0x1f & (x)) << 1)
|
||||
+
|
||||
+#define U3P_U3PHYA_DA_REG0 (SSUSB_SIFSLV_U3PHYA_DA_BASE + 0x0)
|
||||
+#define P3A_RG_XTAL_EXT_EN_U3 (0x3<<10)
|
||||
+#define P3A_RG_XTAL_EXT_EN_U3_VAL(x) ((0x3 & (x)) << 10)
|
||||
+
|
||||
+#define U3P_PHYD_CDR1 (SSUSB_SIFSLV_U3PHYD_BASE+0x5c)
|
||||
+#define P3D_RG_CDR_BIR_LTD1 (0x1f<<24)
|
||||
+#define P3D_RG_CDR_BIR_LTD1_VAL(x) ((0x1f & (x)) << 24)
|
||||
+#define P3D_RG_CDR_BIR_LTD0 (0x1f<<8)
|
||||
+#define P3D_RG_CDR_BIR_LTD0_VAL(x) ((0x1f & (x)) << 8)
|
||||
+
|
||||
+#define U3P_XTALCTL3 (SSUSB_SIFSLV_SPLLC + 0x18)
|
||||
+#define XC3_RG_U3_XTAL_RX_PWD (0x1<<9)
|
||||
+#define XC3_RG_U3_FRC_XTAL_RX_PWD (0x1<<8)
|
||||
+
|
||||
+#define U3P_UX_EXIT_LFPS_PARAM (SSUSB_USB3_MAC_CSR_BASE+0x00A0)
|
||||
+#define RX_UX_EXIT_REF (0xff<<8)
|
||||
+#define RX_UX_EXIT_REF_VAL (0x3 << 8)
|
||||
+
|
||||
+#define U3P_REF_CLK_PARAM (SSUSB_USB3_MAC_CSR_BASE+0x00B0)
|
||||
+#define REF_CLK_1000NS (0xff << 0)
|
||||
+#define REF_CLK_VAL_DEF (0xa << 0)
|
||||
+
|
||||
+#define U3P_LINK_PM_TIMER (SSUSB_USB3_SYS_CSR_BASE+0x0208)
|
||||
+#define PM_LC_TIMEOUT (0xf<<0)
|
||||
+#define PM_LC_TIMEOUT_VAL (0x3 << 0)
|
||||
+
|
||||
+#define U3P_TIMING_PULSE_CTRL (SSUSB_USB3_SYS_CSR_BASE+0x02B4)
|
||||
+#define U3T_CNT_1US (0xff << 0)
|
||||
+#define U3T_CNT_1US_VAL (0x3f << 0) /* 62.5MHz: 63 */
|
||||
+
|
||||
+#define U3P_U2_TIMING_PARAM (SSUSB_USB2_CSR_BASE+0x0040)
|
||||
+#define U2T_VAL_1US (0xff<<0)
|
||||
+#define U2T_VAL_1US_VAL (0x3f << 0) /* 62.5MHz: 63 */
|
||||
+
|
||||
+
|
||||
+struct mt65xx_u3phy {
|
||||
+ struct usb_phy phy;
|
||||
+ struct device *dev;
|
||||
+ struct regulator *vusb33;
|
||||
+ struct regulator *p1_vbus;
|
||||
+ void __iomem *mac_base; /* only device-mac regs, exclude xhci's */
|
||||
+ void __iomem *sif_base; /* include sif & sif2 */
|
||||
+ struct clk *wk_deb_p0; /* port0's wakeup debounce clock */
|
||||
+ struct clk *wk_deb_p1;
|
||||
+ struct clk *sys_mac; /* sys and mac clock */
|
||||
+ struct clk *u3phya_ref; /* reference clock of usb3 anolog phy */
|
||||
+ bool enable_usb2_p1;
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static void u3p_writel(void __iomem *base, u32 offset, u32 data)
|
||||
+{
|
||||
+ writel(data, base + offset);
|
||||
+}
|
||||
+
|
||||
+static u32 u3p_readl(void __iomem *base, u32 offset)
|
||||
+{
|
||||
+ return readl(base + offset);
|
||||
+}
|
||||
+
|
||||
+static void u3p_setmsk(void __iomem *base, u32 offset, u32 msk)
|
||||
+{
|
||||
+ void __iomem *addr = base + offset;
|
||||
+
|
||||
+ writel((readl(addr) | msk), addr);
|
||||
+}
|
||||
+
|
||||
+static void u3p_clrmsk(void __iomem *base, u32 offset, u32 msk)
|
||||
+{
|
||||
+ void __iomem *addr = base + offset;
|
||||
+
|
||||
+ writel((readl(addr) & ~msk), addr);
|
||||
+}
|
||||
+
|
||||
+static void u3p_setval(void __iomem *base, u32 offset,
|
||||
+ u32 mask, u32 value)
|
||||
+{
|
||||
+ void __iomem *addr = base + offset;
|
||||
+ unsigned int new_value;
|
||||
+
|
||||
+ new_value = (readl(addr) & ~mask) | value;
|
||||
+ writel(new_value, addr);
|
||||
+}
|
||||
+
|
||||
+static void phy_index_power_on(struct mt65xx_u3phy *u3phy, int index)
|
||||
+{
|
||||
+ void __iomem *sif_base = u3phy->sif_base + U3P_PHY_BASE(index);
|
||||
+
|
||||
+ if (!index) {
|
||||
+ /* Set RG_SSUSB_VUSB10_ON as 1 after VUSB10 ready */
|
||||
+ u3p_setmsk(sif_base, U3P_U3_PHYA_REG0, P3A_RG_U3_VUSB10_ON);
|
||||
+ /* power domain iso disable */
|
||||
+ u3p_clrmsk(sif_base, U3P_USBPHYACR6, PA6_RG_U2_ISO_EN);
|
||||
+ }
|
||||
+
|
||||
+ /* switch to USB function. (system register, force ip into usb mode) */
|
||||
+ u3p_clrmsk(sif_base, U3P_U2PHYDTM0, P2C_FORCE_UART_EN);
|
||||
+ u3p_clrmsk(sif_base, U3P_U2PHYDTM1, P2C_RG_UART_EN);
|
||||
+ if (!index)
|
||||
+ u3p_clrmsk(sif_base, U3P_U2PHYACR4, P2C_U2_GPIO_CTR_MSK);
|
||||
+
|
||||
+ /* (force_suspendm=0) (let suspendm=1, enable usb 480MHz pll) */
|
||||
+ u3p_clrmsk(sif_base, U3P_U2PHYDTM0, P2C_FORCE_SUSPENDM);
|
||||
+ u3p_clrmsk(sif_base, U3P_U2PHYDTM0,
|
||||
+ P2C_RG_XCVRSEL | P2C_RG_DATAIN | P2C_DTM0_PART_MASK);
|
||||
+
|
||||
+ /* DP/DM BC1.1 path Disable */
|
||||
+ u3p_clrmsk(sif_base, U3P_USBPHYACR6, PA6_RG_U2_BC11_SW_EN);
|
||||
+ /* OTG Enable */
|
||||
+ u3p_setmsk(sif_base, U3P_USBPHYACR6, PA6_RG_U2_OTG_VBUSCMP_EN);
|
||||
+ u3p_setval(sif_base, U3P_U3PHYA_DA_REG0, P3A_RG_XTAL_EXT_EN_U3,
|
||||
+ P3A_RG_XTAL_EXT_EN_U3_VAL(2));
|
||||
+ u3p_setval(sif_base, U3P_U3_PHYA_REG9, P3A_RG_RX_DAC_MUX,
|
||||
+ P3A_RG_RX_DAC_MUX_VAL(4));
|
||||
+
|
||||
+ if (!index) {
|
||||
+ u3p_setmsk(sif_base, U3P_XTALCTL3, XC3_RG_U3_XTAL_RX_PWD);
|
||||
+ u3p_setmsk(sif_base, U3P_XTALCTL3, XC3_RG_U3_FRC_XTAL_RX_PWD);
|
||||
+ /* [mt8173]disable Change 100uA current from SSUSB */
|
||||
+ u3p_clrmsk(sif_base, U3P_USBPHYACR5, PA5_RG_U2_HS_100U_U3_EN);
|
||||
+ }
|
||||
+ u3p_setval(sif_base, U3P_U3_PHYA_REG6, P3A_RG_TX_EIDLE_CM,
|
||||
+ P3A_RG_TX_EIDLE_CM_VAL(0xe));
|
||||
+ u3p_setval(sif_base, U3P_PHYD_CDR1, P3D_RG_CDR_BIR_LTD0,
|
||||
+ P3D_RG_CDR_BIR_LTD0_VAL(0xc));
|
||||
+ u3p_setval(sif_base, U3P_PHYD_CDR1, P3D_RG_CDR_BIR_LTD1,
|
||||
+ P3D_RG_CDR_BIR_LTD1_VAL(0x3));
|
||||
+
|
||||
+ udelay(800);
|
||||
+ u3p_setmsk(sif_base, U3P_U2PHYDTM1, P2C_RG_VBUSVALID | P2C_RG_AVALID);
|
||||
+ u3p_clrmsk(sif_base, U3P_U2PHYDTM1, P2C_RG_SESSEND);
|
||||
+
|
||||
+ /* USB 2.0 slew rate calibration */
|
||||
+ u3p_setval(sif_base, U3P_USBPHYACR5, PA5_RG_U2_HSTX_SRCTRL,
|
||||
+ PA5_RG_U2_HSTX_SRCTRL_VAL(4));
|
||||
+
|
||||
+ dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void phy_index_power_off(struct mt65xx_u3phy *u3phy, int index)
|
||||
+{
|
||||
+ void __iomem *sif_base = u3phy->sif_base + U3P_PHY_BASE(index);
|
||||
+
|
||||
+ /* switch to USB function. (system register, force ip into usb mode) */
|
||||
+ u3p_clrmsk(sif_base, U3P_U2PHYDTM0, P2C_FORCE_UART_EN);
|
||||
+ u3p_clrmsk(sif_base, U3P_U2PHYDTM1, P2C_RG_UART_EN);
|
||||
+ if (!index)
|
||||
+ u3p_clrmsk(sif_base, U3P_U2PHYACR4, P2C_U2_GPIO_CTR_MSK);
|
||||
+
|
||||
+ u3p_setmsk(sif_base, U3P_U2PHYDTM0, P2C_FORCE_SUSPENDM);
|
||||
+ u3p_setval(sif_base, U3P_U2PHYDTM0,
|
||||
+ P2C_RG_XCVRSEL, P2C_RG_XCVRSEL_VAL(1));
|
||||
+ u3p_setval(sif_base, U3P_U2PHYDTM0,
|
||||
+ P2C_RG_DATAIN, P2C_RG_DATAIN_VAL(0));
|
||||
+ u3p_setmsk(sif_base, U3P_U2PHYDTM0, P2C_DTM0_PART_MASK);
|
||||
+ /* DP/DM BC1.1 path Disable */
|
||||
+ u3p_clrmsk(sif_base, U3P_USBPHYACR6, PA6_RG_U2_BC11_SW_EN);
|
||||
+ /* OTG Disable */
|
||||
+ u3p_clrmsk(sif_base, U3P_USBPHYACR6, PA6_RG_U2_OTG_VBUSCMP_EN);
|
||||
+ if (!index) {
|
||||
+ /* Change 100uA current switch to USB2.0 */
|
||||
+ u3p_clrmsk(sif_base, U3P_USBPHYACR5, PA5_RG_U2_HS_100U_U3_EN);
|
||||
+ }
|
||||
+ udelay(800);
|
||||
+
|
||||
+ /* let suspendm=0, set utmi into analog power down */
|
||||
+ u3p_clrmsk(sif_base, U3P_U2PHYDTM0, P2C_RG_SUSPENDM);
|
||||
+ udelay(1);
|
||||
+
|
||||
+ u3p_clrmsk(sif_base, U3P_U2PHYDTM1, P2C_RG_VBUSVALID | P2C_RG_AVALID);
|
||||
+ u3p_setmsk(sif_base, U3P_U2PHYDTM1, P2C_RG_SESSEND);
|
||||
+ if (!index) {
|
||||
+ /* Set RG_SSUSB_VUSB10_ON as 1 after VUSB10 ready */
|
||||
+ u3p_clrmsk(sif_base, U3P_U3_PHYA_REG0, P3A_RG_U3_VUSB10_ON);
|
||||
+ }
|
||||
+ dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int check_ip_clk_status(struct mt65xx_u3phy *u3phy)
|
||||
+{
|
||||
+ int ret;
|
||||
+ int u3_port_num;
|
||||
+ int u2_port_num;
|
||||
+ u32 xhci_cap;
|
||||
+ u32 val;
|
||||
+ void __iomem *sif_base = u3phy->sif_base;
|
||||
+
|
||||
+ xhci_cap = u3p_readl(sif_base, U3P_IP_XHCI_CAP);
|
||||
+ u3_port_num = CAP_U3_PORT_NUM(xhci_cap);
|
||||
+ u2_port_num = CAP_U2_PORT_NUM(xhci_cap);
|
||||
+
|
||||
+ ret = readl_poll_timeout(sif_base + U3P_IP_PW_STS1, val,
|
||||
+ (val & STS1_SYSPLL_STABLE), 100, 10000);
|
||||
+ if (ret) {
|
||||
+ dev_err(u3phy->dev, "sypll is not stable!!!\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = readl_poll_timeout(sif_base + U3P_IP_PW_STS1, val,
|
||||
+ (val & STS1_REF_RST), 100, 10000);
|
||||
+ if (ret) {
|
||||
+ dev_err(u3phy->dev, "ref_clk is still active!!!\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = readl_poll_timeout(sif_base + U3P_IP_PW_STS1, val,
|
||||
+ (val & STS1_SYS125_RST), 100, 10000);
|
||||
+ if (ret) {
|
||||
+ dev_err(u3phy->dev, "sys125_ck is still active!!!\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (u3_port_num) {
|
||||
+ ret = readl_poll_timeout(sif_base + U3P_IP_PW_STS1, val,
|
||||
+ (val & STS1_U3_MAC_RST), 100, 10000);
|
||||
+ if (ret) {
|
||||
+ dev_err(u3phy->dev, "mac3_mac_ck is still active!!!\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (u2_port_num) {
|
||||
+ ret = readl_poll_timeout(sif_base + U3P_IP_PW_STS2, val,
|
||||
+ (val & STS2_U2_MAC_RST), 100, 10000);
|
||||
+ if (ret) {
|
||||
+ dev_err(u3phy->dev, "mac2_sys_ck is still active!!!\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int u3phy_ports_enable(struct mt65xx_u3phy *u3phy)
|
||||
+{
|
||||
+ int i;
|
||||
+ u32 temp;
|
||||
+ int u3_port_num;
|
||||
+ int u2_port_num;
|
||||
+ void __iomem *sif_base = u3phy->sif_base;
|
||||
+
|
||||
+ temp = u3p_readl(sif_base, U3P_IP_XHCI_CAP);
|
||||
+ u3_port_num = CAP_U3_PORT_NUM(temp);
|
||||
+ u2_port_num = CAP_U2_PORT_NUM(temp);
|
||||
+ dev_dbg(u3phy->dev, "%s u2p:%d, u3p:%d\n",
|
||||
+ __func__, u2_port_num, u3_port_num);
|
||||
+
|
||||
+ /* power on host ip */
|
||||
+ u3p_clrmsk(sif_base, U3P_IP_PW_CTRL1, CTRL1_IP_HOST_PDN);
|
||||
+
|
||||
+ /* power on and enable all u3 ports */
|
||||
+ for (i = 0; i < u3_port_num; i++) {
|
||||
+ temp = u3p_readl(sif_base, U3P_U3_CTRL(i));
|
||||
+ temp &= ~(CTRL_U3_PORT_PDN | CTRL_U3_PORT_DIS);
|
||||
+ temp |= CTRL_U3_PORT_HOST_SEL;
|
||||
+ u3p_writel(sif_base, U3P_U3_CTRL(i), temp);
|
||||
+ }
|
||||
+
|
||||
+ /* power on and enable all u2 ports */
|
||||
+ for (i = 0; i < u2_port_num; i++) {
|
||||
+ temp = u3p_readl(sif_base, U3P_U2_CTRL(i));
|
||||
+ temp &= ~(CTRL_U2_PORT_PDN | CTRL_U2_PORT_DIS);
|
||||
+ temp |= CTRL_U2_PORT_HOST_SEL;
|
||||
+ u3p_writel(sif_base, U3P_U2_CTRL(i), temp);
|
||||
+ }
|
||||
+ return check_ip_clk_status(u3phy);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void u3phy_timing_init(struct mt65xx_u3phy *u3phy)
|
||||
+{
|
||||
+ void __iomem *mbase = u3phy->mac_base;
|
||||
+ int u3_port_num;
|
||||
+ u32 temp;
|
||||
+
|
||||
+ temp = u3p_readl(u3phy->sif_base, U3P_IP_XHCI_CAP);
|
||||
+ u3_port_num = CAP_U3_PORT_NUM(temp);
|
||||
+
|
||||
+ if (u3_port_num) {
|
||||
+ /* set MAC reference clock speed */
|
||||
+ u3p_setval(mbase, U3P_UX_EXIT_LFPS_PARAM,
|
||||
+ RX_UX_EXIT_REF, RX_UX_EXIT_REF_VAL);
|
||||
+ /* set REF_CLK */
|
||||
+ u3p_setval(mbase, U3P_REF_CLK_PARAM,
|
||||
+ REF_CLK_1000NS, REF_CLK_VAL_DEF);
|
||||
+ /* set SYS_CLK */
|
||||
+ u3p_setval(mbase, U3P_TIMING_PULSE_CTRL,
|
||||
+ U3T_CNT_1US, U3T_CNT_1US_VAL);
|
||||
+ /* set LINK_PM_TIMER=3 */
|
||||
+ u3p_setval(mbase, U3P_LINK_PM_TIMER,
|
||||
+ PM_LC_TIMEOUT, PM_LC_TIMEOUT_VAL);
|
||||
+ }
|
||||
+ u3p_setval(mbase, U3P_U2_TIMING_PARAM, U2T_VAL_1US, U2T_VAL_1US_VAL);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int u3phy_clks_enable(struct mt65xx_u3phy *u3phy)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = clk_prepare_enable(u3phy->sys_mac);
|
||||
+ if (ret) {
|
||||
+ dev_err(u3phy->dev, "failed to enable sys_mac\n");
|
||||
+ goto sys_mac_err;
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_prepare_enable(u3phy->u3phya_ref);
|
||||
+ if (ret) {
|
||||
+ dev_err(u3phy->dev, "failed to enable u3phya_ref\n");
|
||||
+ goto u3phya_ref_err;
|
||||
+ }
|
||||
+ ret = clk_prepare_enable(u3phy->wk_deb_p0);
|
||||
+ if (ret) {
|
||||
+ dev_err(u3phy->dev, "failed to enable wk_deb_p0\n");
|
||||
+ goto usb_p0_err;
|
||||
+ }
|
||||
+ if (u3phy->enable_usb2_p1) {
|
||||
+ ret = clk_prepare_enable(u3phy->wk_deb_p1);
|
||||
+ if (ret) {
|
||||
+ dev_err(u3phy->dev, "failed to enable wk_deb_p1\n");
|
||||
+ goto usb_p1_err;
|
||||
+ }
|
||||
+ }
|
||||
+ udelay(50);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+usb_p1_err:
|
||||
+ clk_disable_unprepare(u3phy->wk_deb_p0);
|
||||
+usb_p0_err:
|
||||
+ clk_disable_unprepare(u3phy->u3phya_ref);
|
||||
+u3phya_ref_err:
|
||||
+ clk_disable_unprepare(u3phy->sys_mac);
|
||||
+sys_mac_err:
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static void u3phy_clks_disable(struct mt65xx_u3phy *u3phy)
|
||||
+{
|
||||
+ if (u3phy->enable_usb2_p1)
|
||||
+ clk_disable_unprepare(u3phy->wk_deb_p1);
|
||||
+ clk_disable_unprepare(u3phy->wk_deb_p0);
|
||||
+ clk_disable_unprepare(u3phy->u3phya_ref);
|
||||
+ clk_disable_unprepare(u3phy->sys_mac);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int mt65xx_u3phy_init(struct usb_phy *phy)
|
||||
+{
|
||||
+ struct mt65xx_u3phy *u3phy;
|
||||
+ int ret;
|
||||
+
|
||||
+ u3phy = container_of(phy, struct mt65xx_u3phy, phy);
|
||||
+ dev_dbg(u3phy->dev, "%s+\n", __func__);
|
||||
+
|
||||
+ if (u3phy->enable_usb2_p1) {
|
||||
+ ret = regulator_enable(u3phy->p1_vbus);
|
||||
+ if (ret) {
|
||||
+ dev_err(u3phy->dev, "failed to enable p1-vbus\n");
|
||||
+ goto reg_p1_err;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = regulator_enable(u3phy->vusb33);
|
||||
+ if (ret) {
|
||||
+ dev_err(u3phy->dev, "failed to enable vusb33\n");
|
||||
+ goto reg_err;
|
||||
+ }
|
||||
+
|
||||
+ ret = pm_runtime_get_sync(u3phy->dev);
|
||||
+ if (ret < 0)
|
||||
+ goto pm_err;
|
||||
+
|
||||
+ ret = u3phy_clks_enable(u3phy);
|
||||
+ if (ret) {
|
||||
+ dev_err(u3phy->dev, "failed to enable clks\n");
|
||||
+ goto clks_err;
|
||||
+ }
|
||||
+
|
||||
+ /* reset whole ip */
|
||||
+ u3p_setmsk(u3phy->sif_base, U3P_IP_PW_CTRL0, CTRL0_IP_SW_RST);
|
||||
+ u3p_clrmsk(u3phy->sif_base, U3P_IP_PW_CTRL0, CTRL0_IP_SW_RST);
|
||||
+
|
||||
+ ret = u3phy_ports_enable(u3phy);
|
||||
+ if (ret) {
|
||||
+ dev_err(u3phy->dev, "failed to enable ports\n");
|
||||
+ goto port_err;
|
||||
+ }
|
||||
+ u3phy_timing_init(u3phy);
|
||||
+ phy_index_power_on(u3phy, 0);
|
||||
+ if (u3phy->enable_usb2_p1)
|
||||
+ phy_index_power_on(u3phy, 1);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+port_err:
|
||||
+ u3phy_clks_disable(u3phy);
|
||||
+clks_err:
|
||||
+ pm_runtime_put_sync(u3phy->dev);
|
||||
+pm_err:
|
||||
+ regulator_disable(u3phy->vusb33);
|
||||
+reg_err:
|
||||
+ if (u3phy->enable_usb2_p1)
|
||||
+ regulator_disable(u3phy->p1_vbus);
|
||||
+reg_p1_err:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void mt65xx_u3phy_shutdown(struct usb_phy *phy)
|
||||
+{
|
||||
+ struct mt65xx_u3phy *u3phy;
|
||||
+
|
||||
+ u3phy = container_of(phy, struct mt65xx_u3phy, phy);
|
||||
+ dev_dbg(u3phy->dev, "%s+\n", __func__);
|
||||
+
|
||||
+ phy_index_power_off(u3phy, 0);
|
||||
+ if (u3phy->enable_usb2_p1) {
|
||||
+ phy_index_power_off(u3phy, 1);
|
||||
+ regulator_disable(u3phy->p1_vbus);
|
||||
+ }
|
||||
+ u3phy_clks_disable(u3phy);
|
||||
+ pm_runtime_put_sync(u3phy->dev);
|
||||
+ regulator_disable(u3phy->vusb33);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int mt65xx_u3phy_suspend(struct usb_phy *x, int suspend)
|
||||
+{
|
||||
+ struct mt65xx_u3phy *u3phy = container_of(x, struct mt65xx_u3phy, phy);
|
||||
+
|
||||
+ if (suspend) {
|
||||
+ mt65xx_u3phy_shutdown(&u3phy->phy);
|
||||
+ return 0;
|
||||
+ } else {
|
||||
+ return mt65xx_u3phy_init(&u3phy->phy);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static const struct of_device_id mt65xx_u3phy_id_table[] = {
|
||||
+ { .compatible = "mediatek,mt8173-u3phy",},
|
||||
+ { },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mt65xx_u3phy_id_table);
|
||||
+
|
||||
+
|
||||
+static int mt65xx_u3phy_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct device_node *np = dev->of_node;
|
||||
+ struct resource *mac_res;
|
||||
+ struct resource *sif_res;
|
||||
+ struct mt65xx_u3phy *u3phy;
|
||||
+ int retval = -ENOMEM;
|
||||
+
|
||||
+ u3phy = devm_kzalloc(&pdev->dev, sizeof(*u3phy), GFP_KERNEL);
|
||||
+ if (!u3phy)
|
||||
+ goto err;
|
||||
+
|
||||
+ u3phy->dev = &pdev->dev;
|
||||
+
|
||||
+ mac_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ u3phy->mac_base = devm_ioremap_resource(dev, mac_res);
|
||||
+ if (IS_ERR(u3phy->mac_base)) {
|
||||
+ dev_err(dev, "failed to remap mac regs\n");
|
||||
+ retval = PTR_ERR(u3phy->mac_base);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
+ u3phy->sif_base = devm_ioremap_resource(dev, sif_res);
|
||||
+ if (IS_ERR(u3phy->sif_base)) {
|
||||
+ dev_err(dev, "failed to remap sif regs\n");
|
||||
+ retval = PTR_ERR(u3phy->sif_base);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ u3phy->enable_usb2_p1 = !of_property_read_bool(np, "disable-usb2-p1");
|
||||
+ dev_dbg(dev, "enable_usb2_p1 - %d\n", u3phy->enable_usb2_p1);
|
||||
+
|
||||
+ u3phy->sys_mac = devm_clk_get(u3phy->dev, "sys_mac");
|
||||
+ if (IS_ERR(u3phy->sys_mac)) {
|
||||
+ dev_err(dev, "error to get sys_mac\n");
|
||||
+ retval = PTR_ERR(u3phy->sys_mac);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ u3phy->u3phya_ref = devm_clk_get(u3phy->dev, "u3phya_ref");
|
||||
+ if (IS_ERR(u3phy->u3phya_ref)) {
|
||||
+ dev_err(dev, "error to get u3phya_ref\n");
|
||||
+ retval = PTR_ERR(u3phy->u3phya_ref);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ u3phy->wk_deb_p0 = devm_clk_get(u3phy->dev, "wakeup_deb_p0");
|
||||
+ if (IS_ERR(u3phy->wk_deb_p0)) {
|
||||
+ dev_err(dev, "error to get wakeup_deb_p0\n");
|
||||
+ retval = PTR_ERR(u3phy->wk_deb_p0);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ if (u3phy->enable_usb2_p1) {
|
||||
+ u3phy->wk_deb_p1 = devm_clk_get(u3phy->dev, "wakeup_deb_p1");
|
||||
+ if (IS_ERR(u3phy->wk_deb_p1)) {
|
||||
+ dev_err(dev, "error to get wakeup_deb_p1\n");
|
||||
+ retval = PTR_ERR(u3phy->wk_deb_p1);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ u3phy->p1_vbus = devm_regulator_get(u3phy->dev, "reg-p1-vbus");
|
||||
+ if (IS_ERR_OR_NULL(u3phy->p1_vbus)) {
|
||||
+ dev_err(dev, "fail to get p1-vbus\n");
|
||||
+ retval = PTR_ERR(u3phy->p1_vbus);
|
||||
+ goto err;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ u3phy->vusb33 = devm_regulator_get(u3phy->dev, "reg-vusb33");
|
||||
+ if (IS_ERR_OR_NULL(u3phy->vusb33)) {
|
||||
+ dev_err(dev, "fail to get vusb33\n");
|
||||
+ retval = PTR_ERR(u3phy->vusb33);
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ pm_runtime_enable(dev);
|
||||
+ u3phy->phy.dev = u3phy->dev;
|
||||
+ u3phy->phy.label = "mt65xx-usb3phy";
|
||||
+ u3phy->phy.type = USB_PHY_TYPE_USB3;
|
||||
+ u3phy->phy.init = mt65xx_u3phy_init;
|
||||
+ u3phy->phy.shutdown = mt65xx_u3phy_shutdown;
|
||||
+ u3phy->phy.set_suspend = mt65xx_u3phy_suspend;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, u3phy);
|
||||
+ retval = usb_add_phy_dev(&u3phy->phy);
|
||||
+ if (retval) {
|
||||
+ dev_err(dev, "failed to add phy\n");
|
||||
+ goto add_phy_err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+add_phy_err:
|
||||
+ pm_runtime_disable(dev);
|
||||
+err:
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static int mt65xx_u3phy_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mt65xx_u3phy *u3phy = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ mt65xx_u3phy_shutdown(&u3phy->phy);
|
||||
+ pm_runtime_disable(&pdev->dev);
|
||||
+ usb_remove_phy(&u3phy->phy);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver mt65xx_u3phy_driver = {
|
||||
+ .probe = mt65xx_u3phy_probe,
|
||||
+ .remove = mt65xx_u3phy_remove,
|
||||
+ .driver = {
|
||||
+ .name = "mt65xx-u3phy",
|
||||
+ .of_match_table = mt65xx_u3phy_id_table,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(mt65xx_u3phy_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Mt65xx USB PHY driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,832 @@
|
||||
From e604b6c864f2e3b6fe0706c4bef886533d92f67a Mon Sep 17 00:00:00 2001
|
||||
From: Chunfeng Yun <chunfeng.yun@mediatek.com>
|
||||
Date: Wed, 27 May 2015 19:48:02 +0800
|
||||
Subject: [PATCH 47/76] xhci: mediatek: support MTK xHCI host controller
|
||||
|
||||
MTK xhci host controller defines some extra SW scheduling
|
||||
parameters for HW to minimize the scheduling effort for
|
||||
synchronous and interrupt endpoints. The parameters are
|
||||
put into reseved DWs of slot context and endpoint context.
|
||||
|
||||
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
|
||||
---
|
||||
drivers/usb/host/Kconfig | 9 +
|
||||
drivers/usb/host/Makefile | 3 +
|
||||
drivers/usb/host/xhci-mtk.c | 470 ++++++++++++++++++++++++++++++++++++++++++
|
||||
drivers/usb/host/xhci-mtk.h | 119 +++++++++++
|
||||
drivers/usb/host/xhci-plat.c | 22 +-
|
||||
drivers/usb/host/xhci-ring.c | 35 +++-
|
||||
drivers/usb/host/xhci.c | 16 +-
|
||||
drivers/usb/host/xhci.h | 1 +
|
||||
8 files changed, 667 insertions(+), 8 deletions(-)
|
||||
create mode 100644 drivers/usb/host/xhci-mtk.c
|
||||
create mode 100644 drivers/usb/host/xhci-mtk.h
|
||||
|
||||
--- a/drivers/usb/host/Kconfig
|
||||
+++ b/drivers/usb/host/Kconfig
|
||||
@@ -41,6 +41,15 @@
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
+config USB_XHCI_MTK
|
||||
+ tristate "xHCI support for Mediatek MT65xx"
|
||||
+ select USB_XHCI_PLATFORM
|
||||
+ depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
+ ---help---
|
||||
+ Say 'Y' to enable the support for the xHCI host controller
|
||||
+ found in Mediatek MT65xx SoCs.
|
||||
+ If unsure, say N.
|
||||
+
|
||||
config USB_XHCI_MVEBU
|
||||
tristate "xHCI support for Marvell Armada 375/38x"
|
||||
select USB_XHCI_PLATFORM
|
||||
--- a/drivers/usb/host/Makefile
|
||||
+++ b/drivers/usb/host/Makefile
|
||||
@@ -15,6 +15,9 @@
|
||||
xhci-hcd-y += xhci-trace.o
|
||||
|
||||
xhci-plat-hcd-y := xhci-plat.o
|
||||
+ifneq ($(CONFIG_USB_XHCI_MTK), )
|
||||
+ xhci-plat-hcd-y += xhci-mtk.o
|
||||
+endif
|
||||
ifneq ($(CONFIG_USB_XHCI_MVEBU), )
|
||||
xhci-plat-hcd-y += xhci-mvebu.o
|
||||
endif
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/host/xhci-mtk.c
|
||||
@@ -0,0 +1,470 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015 MediaTek Inc.
|
||||
+ * Author:
|
||||
+ * Zhigang.Wei <zhigang.wei@mediatek.com>
|
||||
+ * Chunfeng.Yun <chunfeng.yun@mediatek.com>
|
||||
+ *
|
||||
+ * This software is licensed under the terms of the GNU General Public
|
||||
+ * License version 2, as published by the Free Software Foundation, and
|
||||
+ * may be copied, distributed, and modified under those terms.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include "xhci-mtk.h"
|
||||
+
|
||||
+
|
||||
+#define SS_BW_BOUNDARY 51000
|
||||
+/* table 5-5. High-speed Isoc Transaction Limits in usb_20 spec */
|
||||
+#define HS_BW_BOUNDARY 6144
|
||||
+/* usb2 spec section11.18.1: at most 188 FS bytes per microframe */
|
||||
+#define FS_PAYLOAD_MAX 188
|
||||
+
|
||||
+/* mtk scheduler bitmasks */
|
||||
+#define EP_BPKTS(p) ((p) & 0x3f)
|
||||
+#define EP_BCSCOUNT(p) (((p) & 0x7) << 8)
|
||||
+#define EP_BBM(p) ((p) << 11)
|
||||
+#define EP_BOFFSET(p) ((p) & 0x3fff)
|
||||
+#define EP_BREPEAT(p) (((p) & 0x7fff) << 16)
|
||||
+
|
||||
+static int is_fs_or_ls(enum usb_device_speed speed)
|
||||
+{
|
||||
+ return speed == USB_SPEED_FULL || speed == USB_SPEED_LOW;
|
||||
+}
|
||||
+
|
||||
+static int get_bw_index(struct xhci_hcd *xhci, struct usb_device *udev,
|
||||
+ struct usb_host_endpoint *ep)
|
||||
+{
|
||||
+ int bw_index;
|
||||
+ int port_id;
|
||||
+ struct xhci_virt_device *virt_dev;
|
||||
+
|
||||
+ virt_dev = xhci->devs[udev->slot_id];
|
||||
+ port_id = virt_dev->real_port;
|
||||
+
|
||||
+ if (udev->speed == USB_SPEED_SUPER) {
|
||||
+ if (usb_endpoint_dir_out(&ep->desc))
|
||||
+ bw_index = (port_id - 1) * 2;
|
||||
+ else
|
||||
+ bw_index = (port_id - 1) * 2 + 1;
|
||||
+ } else {
|
||||
+ bw_index = port_id + xhci->num_usb3_ports - 1;
|
||||
+ }
|
||||
+
|
||||
+ return bw_index;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void setup_sch_info(struct usb_device *udev,
|
||||
+ struct xhci_ep_ctx *ep_ctx, struct mu3h_sch_ep_info *sch_ep)
|
||||
+{
|
||||
+ u32 ep_type;
|
||||
+ u32 ep_interval;
|
||||
+ u32 max_packet_size;
|
||||
+ u32 max_burst;
|
||||
+ u32 mult;
|
||||
+ u32 esit_pkts;
|
||||
+
|
||||
+ ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2));
|
||||
+ ep_interval = CTX_TO_EP_INTERVAL(le32_to_cpu(ep_ctx->ep_info));
|
||||
+ max_packet_size = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2));
|
||||
+ max_burst = CTX_TO_MAX_BURST(le32_to_cpu(ep_ctx->ep_info2));
|
||||
+ mult = CTX_TO_EP_MULT(le32_to_cpu(ep_ctx->ep_info));
|
||||
+ pr_debug("%s: max_burst = %d, mult = %d\n", __func__, max_burst, mult);
|
||||
+
|
||||
+ sch_ep->ep_type = ep_type;
|
||||
+ sch_ep->max_packet_size = max_packet_size;
|
||||
+ sch_ep->esit = 1 << ep_interval;
|
||||
+ sch_ep->offset = 0;
|
||||
+ sch_ep->burst_mode = 0;
|
||||
+
|
||||
+ if (udev->speed == USB_SPEED_HIGH) {
|
||||
+ sch_ep->cs_count = 0;
|
||||
+ /*
|
||||
+ * usb_20 spec section5.9
|
||||
+ * a single microframe is enough for HS synchromous endpoints
|
||||
+ * in a interval
|
||||
+ */
|
||||
+ sch_ep->num_budget_microframes = 1;
|
||||
+ sch_ep->repeat = 0;
|
||||
+ /*
|
||||
+ * xHCI spec section6.2.3.4
|
||||
+ * @max_busrt is the number of additional transactions opportunities
|
||||
+ * per microframe
|
||||
+ */
|
||||
+ sch_ep->pkts = max_burst + 1;
|
||||
+ sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts;
|
||||
+ } else if (udev->speed == USB_SPEED_SUPER) {
|
||||
+ /* usb3_r1 spec section4.4.7 & 4.4.8 */
|
||||
+ sch_ep->cs_count = 0;
|
||||
+ esit_pkts = (mult + 1) * (max_burst + 1);
|
||||
+ if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) {
|
||||
+ sch_ep->pkts = esit_pkts;
|
||||
+ sch_ep->num_budget_microframes = 1;
|
||||
+ sch_ep->repeat = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) {
|
||||
+ if (esit_pkts <= sch_ep->esit)
|
||||
+ sch_ep->pkts = 1;
|
||||
+ else
|
||||
+ sch_ep->pkts = roundup_pow_of_two(esit_pkts)
|
||||
+ / sch_ep->esit;
|
||||
+
|
||||
+ sch_ep->num_budget_microframes =
|
||||
+ DIV_ROUND_UP(esit_pkts, sch_ep->pkts);
|
||||
+
|
||||
+ if (sch_ep->num_budget_microframes > 1)
|
||||
+ sch_ep->repeat = 1;
|
||||
+ else
|
||||
+ sch_ep->repeat = 0;
|
||||
+ }
|
||||
+ sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts;
|
||||
+ } else if (is_fs_or_ls(udev->speed)) {
|
||||
+ /*
|
||||
+ * usb_20 spec section11.18.4
|
||||
+ * assume worst cases
|
||||
+ */
|
||||
+ sch_ep->repeat = 0;
|
||||
+ sch_ep->pkts = 1; /* at most one packet for each microframe */
|
||||
+ if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) {
|
||||
+ sch_ep->cs_count = 3; /* at most need 3 CS*/
|
||||
+ /* one for SS and one for budgeted transaction */
|
||||
+ sch_ep->num_budget_microframes = sch_ep->cs_count + 2;
|
||||
+ sch_ep->bw_cost_per_microframe = max_packet_size;
|
||||
+ }
|
||||
+ if (ep_type == ISOC_OUT_EP) {
|
||||
+ /* must never schedule a cs ISOC OUT ep */
|
||||
+ sch_ep->cs_count = 0;
|
||||
+ /*
|
||||
+ * the best case FS budget assumes that 188 FS bytes
|
||||
+ * occur in each microframe
|
||||
+ */
|
||||
+ sch_ep->num_budget_microframes = DIV_ROUND_UP(
|
||||
+ sch_ep->max_packet_size, FS_PAYLOAD_MAX);
|
||||
+ sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX;
|
||||
+ }
|
||||
+ if (ep_type == ISOC_IN_EP) {
|
||||
+ /* at most need additional two CS. */
|
||||
+ sch_ep->cs_count = DIV_ROUND_UP(
|
||||
+ sch_ep->max_packet_size, FS_PAYLOAD_MAX) + 2;
|
||||
+ sch_ep->num_budget_microframes = sch_ep->cs_count + 2;
|
||||
+ sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Get maximum bandwidth when we schedule at offset slot. */
|
||||
+static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
|
||||
+ struct mu3h_sch_ep_info *sch_ep, u32 offset)
|
||||
+{
|
||||
+ u32 num_esit;
|
||||
+ u32 max_bw = 0;
|
||||
+ int i;
|
||||
+ int j;
|
||||
+
|
||||
+ num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
|
||||
+ for (i = 0; i < num_esit; i++) {
|
||||
+ u32 base = offset + i * sch_ep->esit;
|
||||
+
|
||||
+ for (j = 0; j < sch_ep->num_budget_microframes; j++) {
|
||||
+ if (sch_bw->bus_bw[base + j] > max_bw)
|
||||
+ max_bw = sch_bw->bus_bw[base + j];
|
||||
+ }
|
||||
+ }
|
||||
+ return max_bw;
|
||||
+}
|
||||
+
|
||||
+static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
|
||||
+ struct mu3h_sch_ep_info *sch_ep, int bw_cost)
|
||||
+{
|
||||
+ u32 num_esit;
|
||||
+ u32 base;
|
||||
+ int i;
|
||||
+ int j;
|
||||
+
|
||||
+ num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
|
||||
+ for (i = 0; i < num_esit; i++) {
|
||||
+ base = sch_ep->offset + i * sch_ep->esit;
|
||||
+ for (j = 0; j < sch_ep->num_budget_microframes; j++)
|
||||
+ sch_bw->bus_bw[base + j] += bw_cost;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static void debug_sch_ep(struct mu3h_sch_ep_info *sch_ep)
|
||||
+{
|
||||
+ pr_debug("sch_ep->ep_type = %d\n", sch_ep->ep_type);
|
||||
+ pr_debug("sch_ep->max_packet_size = %d\n", sch_ep->max_packet_size);
|
||||
+ pr_debug("sch_ep->esit = %d\n", sch_ep->esit);
|
||||
+ pr_debug("sch_ep->num_budget_microframes = %d\n",
|
||||
+ sch_ep->num_budget_microframes);
|
||||
+ pr_debug("sch_ep->bw_cost_per_microframe = %d\n",
|
||||
+ sch_ep->bw_cost_per_microframe);
|
||||
+ pr_debug("sch_ep->ep = %p\n", sch_ep->ep);
|
||||
+ pr_debug("sch_ep->offset = %d\n", sch_ep->offset);
|
||||
+ pr_debug("sch_ep->repeat = %d\n", sch_ep->repeat);
|
||||
+ pr_debug("sch_ep->pkts = %d\n", sch_ep->pkts);
|
||||
+ pr_debug("sch_ep->cs_count = %d\n", sch_ep->cs_count);
|
||||
+}
|
||||
+
|
||||
+static int check_sch_bw(struct usb_device *udev,
|
||||
+ struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep)
|
||||
+{
|
||||
+ u32 offset;
|
||||
+ u32 esit;
|
||||
+ u32 num_budget_microframes;
|
||||
+ u32 min_bw;
|
||||
+ u32 min_index;
|
||||
+ u32 worst_bw;
|
||||
+ u32 bw_boundary;
|
||||
+
|
||||
+ if (sch_ep->esit > XHCI_MTK_MAX_ESIT)
|
||||
+ sch_ep->esit = XHCI_MTK_MAX_ESIT;
|
||||
+
|
||||
+ esit = sch_ep->esit;
|
||||
+ num_budget_microframes = sch_ep->num_budget_microframes;
|
||||
+
|
||||
+ /*
|
||||
+ * Search through all possible schedule microframes.
|
||||
+ * and find a microframe where its worst bandwidth is minimum.
|
||||
+ */
|
||||
+ min_bw = ~0;
|
||||
+ min_index = 0;
|
||||
+ for (offset = 0; offset < esit; offset++) {
|
||||
+ if ((offset + num_budget_microframes) > sch_ep->esit)
|
||||
+ break;
|
||||
+ /*
|
||||
+ * usb_20 spec section11.18:
|
||||
+ * must never schedule Start-Split in Y6
|
||||
+ */
|
||||
+ if (is_fs_or_ls(udev->speed) && (offset % 8 == 6))
|
||||
+ continue;
|
||||
+
|
||||
+ worst_bw = get_max_bw(sch_bw, sch_ep, offset);
|
||||
+ if (min_bw > worst_bw) {
|
||||
+ min_bw = worst_bw;
|
||||
+ min_index = offset;
|
||||
+ }
|
||||
+ if (min_bw == 0)
|
||||
+ break;
|
||||
+ }
|
||||
+ sch_ep->offset = min_index;
|
||||
+
|
||||
+ debug_sch_ep(sch_ep);
|
||||
+
|
||||
+ bw_boundary = (udev->speed == USB_SPEED_SUPER)
|
||||
+ ? SS_BW_BOUNDARY : HS_BW_BOUNDARY;
|
||||
+
|
||||
+ /* check bandwidth */
|
||||
+ if (min_bw + sch_ep->bw_cost_per_microframe > bw_boundary)
|
||||
+ return -1;
|
||||
+
|
||||
+ /* update bus bandwidth info */
|
||||
+ update_bus_bw(sch_bw, sch_ep, sch_ep->bw_cost_per_microframe);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void debug_sch_bw(struct mu3h_sch_bw_info *sch_bw)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ pr_debug("xhci_mtk_scheduler :bus_bw_info\n");
|
||||
+ for (i = 0; i < XHCI_MTK_MAX_ESIT; i++)
|
||||
+ pr_debug("%d ", sch_bw->bus_bw[i]);
|
||||
+
|
||||
+ pr_debug("\n");
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int need_bw_sch(struct usb_host_endpoint *ep,
|
||||
+ enum usb_device_speed speed, int has_tt)
|
||||
+{
|
||||
+ /* only for synchronous endpoints */
|
||||
+ if (usb_endpoint_xfer_control(&ep->desc)
|
||||
+ || usb_endpoint_xfer_bulk(&ep->desc))
|
||||
+ return 0;
|
||||
+ /*
|
||||
+ * for LS & FS synchronous endpoints which its device don't attach
|
||||
+ * to TT are also ignored, root-hub will schedule them directly
|
||||
+ */
|
||||
+ if (is_fs_or_ls(speed) && !has_tt)
|
||||
+ return 0;
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+int xhci_mtk_init_quirk(struct xhci_hcd *xhci)
|
||||
+{
|
||||
+ struct usb_hcd *hcd = xhci_to_hcd(xhci);
|
||||
+ struct device *dev = hcd->self.controller;
|
||||
+ struct mu3h_sch_bw_info *sch_array;
|
||||
+ size_t array_size;
|
||||
+ int num_usb_bus;
|
||||
+ int i;
|
||||
+
|
||||
+ /* ss IN and OUT are separated */
|
||||
+ num_usb_bus = xhci->num_usb3_ports * 2 + xhci->num_usb2_ports;
|
||||
+ array_size = sizeof(*sch_array) * num_usb_bus;
|
||||
+
|
||||
+ sch_array = kzalloc(array_size, GFP_KERNEL);
|
||||
+ if (sch_array == NULL)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ for (i = 0; i < num_usb_bus; i++)
|
||||
+ INIT_LIST_HEAD(&sch_array[i].bw_ep_list);
|
||||
+
|
||||
+ dev->platform_data = sch_array;
|
||||
+ xhci->quirks |= XHCI_MTK_HOST;
|
||||
+ /*
|
||||
+ * MTK host controller gives a spurious successful event after a
|
||||
+ * short transfer. Ignore it.
|
||||
+ */
|
||||
+ xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void xhci_mtk_exit_quirk(struct xhci_hcd *xhci)
|
||||
+{
|
||||
+ struct usb_hcd *hcd = xhci_to_hcd(xhci);
|
||||
+ struct mu3h_sch_bw_info *sch_array;
|
||||
+
|
||||
+ sch_array = dev_get_platdata(hcd->self.controller);
|
||||
+ kfree(sch_array);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
+ struct usb_host_endpoint *ep)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ int port_id;
|
||||
+ int bw_index;
|
||||
+ struct xhci_hcd *xhci;
|
||||
+ unsigned int ep_index;
|
||||
+ struct xhci_ep_ctx *ep_ctx;
|
||||
+ struct xhci_slot_ctx *slot_ctx;
|
||||
+ struct xhci_virt_device *virt_dev;
|
||||
+ struct mu3h_sch_bw_info *sch_bw;
|
||||
+ struct mu3h_sch_ep_info *sch_ep;
|
||||
+ struct mu3h_sch_bw_info *sch_array;
|
||||
+
|
||||
+ xhci = hcd_to_xhci(hcd);
|
||||
+ virt_dev = xhci->devs[udev->slot_id];
|
||||
+ ep_index = xhci_get_endpoint_index(&ep->desc);
|
||||
+ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
|
||||
+ ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
|
||||
+ sch_array = dev_get_platdata(hcd->self.controller);
|
||||
+
|
||||
+ port_id = virt_dev->real_port;
|
||||
+ xhci_dbg(xhci, "%s() xfer_type: %d, speed:%d, ep:%p\n", __func__,
|
||||
+ usb_endpoint_type(&ep->desc), udev->speed, ep);
|
||||
+
|
||||
+ if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT))
|
||||
+ return 0;
|
||||
+
|
||||
+ bw_index = get_bw_index(xhci, udev, ep);
|
||||
+ sch_bw = &sch_array[bw_index];
|
||||
+
|
||||
+ sch_ep = kzalloc(sizeof(struct mu3h_sch_ep_info), GFP_KERNEL);
|
||||
+ if (!sch_ep)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ setup_sch_info(udev, ep_ctx, sch_ep);
|
||||
+
|
||||
+ ret = check_sch_bw(udev, sch_bw, sch_ep);
|
||||
+ if (ret) {
|
||||
+ xhci_err(xhci, "Not enough bandwidth!\n");
|
||||
+ kfree(sch_ep);
|
||||
+ return -ENOSPC;
|
||||
+ }
|
||||
+
|
||||
+ list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list);
|
||||
+ sch_ep->ep = ep;
|
||||
+
|
||||
+ ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts)
|
||||
+ | EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode));
|
||||
+ ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset)
|
||||
+ | EP_BREPEAT(sch_ep->repeat));
|
||||
+
|
||||
+ debug_sch_bw(sch_bw);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
+ struct usb_host_endpoint *ep)
|
||||
+{
|
||||
+ int bw_index;
|
||||
+ struct xhci_hcd *xhci;
|
||||
+ struct xhci_slot_ctx *slot_ctx;
|
||||
+ struct xhci_virt_device *virt_dev;
|
||||
+ struct mu3h_sch_bw_info *sch_array;
|
||||
+ struct mu3h_sch_bw_info *sch_bw;
|
||||
+ struct mu3h_sch_ep_info *sch_ep;
|
||||
+
|
||||
+ xhci = hcd_to_xhci(hcd);
|
||||
+ virt_dev = xhci->devs[udev->slot_id];
|
||||
+ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
|
||||
+ sch_array = dev_get_platdata(hcd->self.controller);
|
||||
+
|
||||
+ xhci_dbg(xhci, "%s() xfer_type: %d, speed:%d, ep:%p\n", __func__,
|
||||
+ usb_endpoint_type(&ep->desc), udev->speed, ep);
|
||||
+
|
||||
+ if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT))
|
||||
+ return;
|
||||
+
|
||||
+ bw_index = get_bw_index(xhci, udev, ep);
|
||||
+ sch_bw = &sch_array[bw_index];
|
||||
+
|
||||
+ list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) {
|
||||
+ if (sch_ep->ep == ep) {
|
||||
+ update_bus_bw(sch_bw, sch_ep,
|
||||
+ -sch_ep->bw_cost_per_microframe);
|
||||
+ list_del(&sch_ep->endpoint);
|
||||
+ kfree(sch_ep);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ debug_sch_bw(sch_bw);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * The TD size is the number of bytes remaining in the TD (including this TRB),
|
||||
+ * right shifted by 10.
|
||||
+ * It must fit in bits 21:17, so it can't be bigger than 31.
|
||||
+ */
|
||||
+u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total,
|
||||
+ unsigned trb_buffer_length, struct urb *urb)
|
||||
+{
|
||||
+ u32 max = 31;
|
||||
+ int remainder, td_packet_count, packet_transferred;
|
||||
+ unsigned int td_transfer_size = urb->transfer_buffer_length;
|
||||
+ unsigned int maxp;
|
||||
+
|
||||
+ maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
|
||||
+
|
||||
+ /* 0 for the last TRB */
|
||||
+ if (td_running_total + trb_buffer_length == td_transfer_size)
|
||||
+ return 0;
|
||||
+
|
||||
+ packet_transferred = td_running_total / maxp;
|
||||
+ td_packet_count = DIV_ROUND_UP(td_transfer_size, maxp);
|
||||
+ remainder = td_packet_count - packet_transferred;
|
||||
+
|
||||
+ if (remainder > max)
|
||||
+ return max << 17;
|
||||
+ else
|
||||
+ return remainder << 17;
|
||||
+}
|
||||
+
|
||||
+
|
||||
--- /dev/null
|
||||
+++ b/drivers/usb/host/xhci-mtk.h
|
||||
@@ -0,0 +1,119 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015 MediaTek Inc.
|
||||
+ * Author:
|
||||
+ * Zhigang.Wun <zhigang.wei@mediatek.com>
|
||||
+ * Chunfeng.Yun <chunfeng.yun@mediatek.com>
|
||||
+ *
|
||||
+ * This software is licensed under the terms of the GNU General Public
|
||||
+ * License version 2, as published by the Free Software Foundation, and
|
||||
+ * may be copied, distributed, and modified under those terms.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef _XHCI_MTK_H_
|
||||
+#define _XHCI_MTK_H_
|
||||
+
|
||||
+#include "xhci.h"
|
||||
+
|
||||
+/**
|
||||
+ * To simplify scheduler algorithm, set a upper limit for ESIT,
|
||||
+ * if a synchromous ep's ESIT is larger than @XHCI_MTK_MAX_ESIT,
|
||||
+ * round down to the limit value, that means allocating more
|
||||
+ * bandwidth to it.
|
||||
+ */
|
||||
+#define XHCI_MTK_MAX_ESIT 64
|
||||
+
|
||||
+/**
|
||||
+ * struct mu3h_sch_bw_info
|
||||
+ * @bus_bw: array to keep track of bandwidth already used at each uframes
|
||||
+ * @bw_ep_list: eps in the bandwidth domain
|
||||
+ *
|
||||
+ * treat a HS root port as a bandwidth domain, but treat a SS root port as
|
||||
+ * two bandwidth domains, one for IN eps and another for OUT eps.
|
||||
+ */
|
||||
+struct mu3h_sch_bw_info {
|
||||
+ u32 bus_bw[XHCI_MTK_MAX_ESIT];
|
||||
+ struct list_head bw_ep_list;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct mu3h_sch_ep_info
|
||||
+ * @esit: unit is 125us, equal to 2 << Interval field in ep-context
|
||||
+ * @num_budget_microframes: number of continuous uframes
|
||||
+ * (@repeat==1) scheduled within the interval
|
||||
+ * @ep: address of usb_host_endpoint
|
||||
+ * @offset: which uframe of the interval that transfer should be
|
||||
+ * scheduled first time within the interval
|
||||
+ * @repeat: the time gap between two uframes that transfers are
|
||||
+ * scheduled within a interval. in the simple algorithm, only
|
||||
+ * assign 0 or 1 to it; 0 means using only one uframe in a
|
||||
+ * interval, and1 means using @num_budget_microframes
|
||||
+ * continuous uframes
|
||||
+ * @pkts: number of packets to be transferred in the scheduled uframes
|
||||
+ * @cs_count: number of CS that host will trigger
|
||||
+ */
|
||||
+struct mu3h_sch_ep_info {
|
||||
+ u32 ep_type;
|
||||
+ u32 max_packet_size;
|
||||
+ u32 esit;
|
||||
+ u32 num_budget_microframes;
|
||||
+ u32 bw_cost_per_microframe;
|
||||
+ void *ep;
|
||||
+ struct list_head endpoint;
|
||||
+
|
||||
+ /* mtk xhci scheduling info */
|
||||
+ u32 offset;
|
||||
+ u32 repeat;
|
||||
+ u32 pkts;
|
||||
+ u32 cs_count;
|
||||
+ u32 burst_mode;
|
||||
+};
|
||||
+
|
||||
+
|
||||
+#if IS_ENABLED(CONFIG_USB_XHCI_MTK)
|
||||
+
|
||||
+int xhci_mtk_init_quirk(struct xhci_hcd *xhci);
|
||||
+void xhci_mtk_exit_quirk(struct xhci_hcd *xhci);
|
||||
+int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
+ struct usb_host_endpoint *ep);
|
||||
+void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
+ struct usb_host_endpoint *ep);
|
||||
+u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total,
|
||||
+ unsigned trb_buffer_length, struct urb *urb);
|
||||
+
|
||||
+#else
|
||||
+static inline int xhci_mtk_init_quirk(struct xhci_hcd *xhci)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline void xhci_mtk_exit_quirk(struct xhci_hcd *xhci)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd,
|
||||
+ struct usb_device *udev, struct usb_host_endpoint *ep)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd,
|
||||
+ struct usb_device *udev, struct usb_host_endpoint *ep)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total,
|
||||
+ unsigned trb_buffer_length, struct urb *urb)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+#endif /* _XHCI_MTK_H_ */
|
||||
--- a/drivers/usb/host/xhci-plat.c
|
||||
+++ b/drivers/usb/host/xhci-plat.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "xhci.h"
|
||||
#include "xhci-mvebu.h"
|
||||
#include "xhci-rcar.h"
|
||||
+#include "xhci-mtk.h"
|
||||
|
||||
static struct hc_driver __read_mostly xhci_plat_hc_driver;
|
||||
|
||||
@@ -49,7 +50,23 @@
|
||||
return ret;
|
||||
}
|
||||
|
||||
- return xhci_gen_setup(hcd, xhci_plat_quirks);
|
||||
+ ret = xhci_gen_setup(hcd, xhci_plat_quirks);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (of_device_is_compatible(of_node, "mediatek,mt8173-xhci")) {
|
||||
+ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
+
|
||||
+ if (!usb_hcd_is_primary_hcd(hcd))
|
||||
+ return 0;
|
||||
+ ret = xhci_mtk_init_quirk(xhci);
|
||||
+ if (ret) {
|
||||
+ kfree(xhci);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int xhci_plat_start(struct usb_hcd *hcd)
|
||||
@@ -207,6 +224,8 @@
|
||||
if (!IS_ERR(clk))
|
||||
clk_disable_unprepare(clk);
|
||||
usb_put_hcd(hcd);
|
||||
+ if (xhci->quirks & XHCI_MTK_HOST)
|
||||
+ xhci_mtk_exit_quirk(xhci);
|
||||
kfree(xhci);
|
||||
|
||||
return 0;
|
||||
@@ -253,6 +272,7 @@
|
||||
{ .compatible = "marvell,armada-380-xhci"},
|
||||
{ .compatible = "renesas,xhci-r8a7790"},
|
||||
{ .compatible = "renesas,xhci-r8a7791"},
|
||||
+ { .compatible = "mediatek,mt8173-xhci"},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, usb_xhci_of_match);
|
||||
--- a/drivers/usb/host/xhci-ring.c
|
||||
+++ b/drivers/usb/host/xhci-ring.c
|
||||
@@ -68,6 +68,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include "xhci.h"
|
||||
#include "xhci-trace.h"
|
||||
+#include "xhci-mtk.h"
|
||||
|
||||
/*
|
||||
* Returns zero if the TRB isn't in this segment, otherwise it returns the DMA
|
||||
@@ -3163,9 +3164,14 @@
|
||||
|
||||
/* Set the TRB length, TD size, and interrupter fields. */
|
||||
if (xhci->hci_version < 0x100) {
|
||||
- remainder = xhci_td_remainder(
|
||||
+ if (xhci->quirks & XHCI_MTK_HOST) {
|
||||
+ remainder = xhci_mtk_td_remainder_quirk(
|
||||
+ running_total, trb_buff_len, urb);
|
||||
+ } else {
|
||||
+ remainder = xhci_td_remainder(
|
||||
urb->transfer_buffer_length -
|
||||
running_total);
|
||||
+ }
|
||||
} else {
|
||||
remainder = xhci_v1_0_td_remainder(running_total,
|
||||
trb_buff_len, total_packet_count, urb,
|
||||
@@ -3336,9 +3342,14 @@
|
||||
|
||||
/* Set the TRB length, TD size, and interrupter fields. */
|
||||
if (xhci->hci_version < 0x100) {
|
||||
- remainder = xhci_td_remainder(
|
||||
+ if (xhci->quirks & XHCI_MTK_HOST) {
|
||||
+ remainder = xhci_mtk_td_remainder_quirk(
|
||||
+ running_total, trb_buff_len, urb);
|
||||
+ } else {
|
||||
+ remainder = xhci_td_remainder(
|
||||
urb->transfer_buffer_length -
|
||||
running_total);
|
||||
+ }
|
||||
} else {
|
||||
remainder = xhci_v1_0_td_remainder(running_total,
|
||||
trb_buff_len, total_packet_count, urb,
|
||||
@@ -3457,8 +3468,14 @@
|
||||
field = TRB_TYPE(TRB_DATA);
|
||||
|
||||
length_field = TRB_LEN(urb->transfer_buffer_length) |
|
||||
- xhci_td_remainder(urb->transfer_buffer_length) |
|
||||
TRB_INTR_TARGET(0);
|
||||
+
|
||||
+ if (xhci->quirks & XHCI_MTK_HOST)
|
||||
+ length_field |= xhci_mtk_td_remainder_quirk(0,
|
||||
+ urb->transfer_buffer_length, urb);
|
||||
+ else
|
||||
+ length_field |= xhci_td_remainder(urb->transfer_buffer_length);
|
||||
+
|
||||
if (urb->transfer_buffer_length > 0) {
|
||||
if (setup->bRequestType & USB_DIR_IN)
|
||||
field |= TRB_DIR_IN;
|
||||
@@ -3682,8 +3699,14 @@
|
||||
|
||||
/* Set the TRB length, TD size, & interrupter fields. */
|
||||
if (xhci->hci_version < 0x100) {
|
||||
- remainder = xhci_td_remainder(
|
||||
- td_len - running_total);
|
||||
+ if (xhci->quirks & XHCI_MTK_HOST) {
|
||||
+ remainder = xhci_mtk_td_remainder_quirk(
|
||||
+ running_total, trb_buff_len,
|
||||
+ urb);
|
||||
+ } else {
|
||||
+ remainder = xhci_td_remainder(
|
||||
+ td_len - running_total);
|
||||
+ }
|
||||
} else {
|
||||
remainder = xhci_v1_0_td_remainder(
|
||||
running_total, trb_buff_len,
|
||||
--- a/drivers/usb/host/xhci.c
|
||||
+++ b/drivers/usb/host/xhci.c
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include "xhci.h"
|
||||
#include "xhci-trace.h"
|
||||
+#include "xhci-mtk.h"
|
||||
|
||||
#define DRIVER_AUTHOR "Sarah Sharp"
|
||||
#define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver"
|
||||
@@ -624,7 +625,11 @@
|
||||
"// Set the interrupt modulation register");
|
||||
temp = readl(&xhci->ir_set->irq_control);
|
||||
temp &= ~ER_IRQ_INTERVAL_MASK;
|
||||
- temp |= (u32) 160;
|
||||
+ /*
|
||||
+ * the increment interval is 8 times as much as that defined
|
||||
+ * in xHCI spec on MTK's controller
|
||||
+ */
|
||||
+ temp |= (u32) ((xhci->quirks & XHCI_MTK_HOST) ? 20 : 160);
|
||||
writel(temp, &xhci->ir_set->irq_control);
|
||||
|
||||
/* Set the HCD state before we enable the irqs */
|
||||
@@ -1698,6 +1703,9 @@
|
||||
|
||||
xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep);
|
||||
|
||||
+ if (xhci->quirks & XHCI_MTK_HOST)
|
||||
+ xhci_mtk_drop_ep_quirk(hcd, udev, ep);
|
||||
+
|
||||
xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x\n",
|
||||
(unsigned int) ep->desc.bEndpointAddress,
|
||||
udev->slot_id,
|
||||
@@ -1793,6 +1801,12 @@
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
+ if (xhci->quirks & XHCI_MTK_HOST) {
|
||||
+ ret = xhci_mtk_add_ep_quirk(hcd, udev, ep);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
ctrl_ctx->add_flags |= cpu_to_le32(added_ctxs);
|
||||
new_add_flags = le32_to_cpu(ctrl_ctx->add_flags);
|
||||
|
||||
--- a/drivers/usb/host/xhci.h
|
||||
+++ b/drivers/usb/host/xhci.h
|
||||
@@ -1568,6 +1568,7 @@
|
||||
/* For controllers with a broken beyond repair streams implementation */
|
||||
#define XHCI_BROKEN_STREAMS (1 << 19)
|
||||
#define XHCI_PME_STUCK_QUIRK (1 << 20)
|
||||
+#define XHCI_MTK_HOST (1 << 21)
|
||||
unsigned int num_active_eps;
|
||||
unsigned int limit_active_eps;
|
||||
/* There are two roothubs to keep track of bus suspend info for */
|
@ -0,0 +1,46 @@
|
||||
From 69b78182d6d7777153323abe3cff8e533ca01143 Mon Sep 17 00:00:00 2001
|
||||
From: Hongzhou Yang <hongzhou.yang@mediatek.com>
|
||||
Date: Mon, 18 May 2015 23:11:12 -0700
|
||||
Subject: [PATCH 48/76] dt-bindings: mediatek: Modify pinctrl bindings for
|
||||
mt6397.
|
||||
|
||||
Since 6397 is no need to support interrupt controller,
|
||||
moving interrupt controller relate property to optional list.
|
||||
Also adding mt8173 and mt8127 to bindings.
|
||||
|
||||
Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com>
|
||||
---
|
||||
Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
|
||||
index 5868a0f..0480bc3 100644
|
||||
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
|
||||
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
|
||||
@@ -3,9 +3,11 @@
|
||||
The Mediatek's Pin controller is used to control SoC pins.
|
||||
|
||||
Required properties:
|
||||
-- compatible: value should be either of the following.
|
||||
+- compatible: value should be one of the following.
|
||||
(a) "mediatek,mt8135-pinctrl", compatible with mt8135 pinctrl.
|
||||
-- mediatek,pctl-regmap: Should be a phandle of the syscfg node.
|
||||
+ (b) "mediatek,mt8173-pinctrl", compatible with mt8173 pinctrl.
|
||||
+ (c) "mediatek,mt6397-pinctrl", compatible with mt6397 pinctrl.
|
||||
+ (d) "mediatek,mt8127-pinctrl", compatible with mt8127 pinctrl.
|
||||
- pins-are-numbered: Specify the subnodes are using numbered pinmux to
|
||||
specify pins.
|
||||
- gpio-controller : Marks the device node as a gpio controller.
|
||||
@@ -24,6 +26,9 @@ Required properties:
|
||||
Only the following flags are supported:
|
||||
0 - GPIO_ACTIVE_HIGH
|
||||
1 - GPIO_ACTIVE_LOW
|
||||
+
|
||||
+Optional properties:
|
||||
+- mediatek,pctl-regmap: Should be a phandle of the syscfg node.
|
||||
- reg: physicall address base for EINT registers
|
||||
- interrupt-controller: Marks the device node as an interrupt controller
|
||||
- #interrupt-cells: Should be two.
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,279 @@
|
||||
From 54596fafa4ce2723314d0381c7c1a525bda148ef Mon Sep 17 00:00:00 2001
|
||||
From: Hongzhou Yang <hongzhou.yang@mediatek.com>
|
||||
Date: Mon, 18 May 2015 23:11:13 -0700
|
||||
Subject: [PATCH 49/76] pinctrl: dt bindings: mt6397: Add pinfunc header file
|
||||
for mt6397.
|
||||
|
||||
Add pinfunc header file, mt8135/mt8173 relate dts will include it.
|
||||
|
||||
Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com>
|
||||
---
|
||||
include/dt-bindings/pinctrl/mt6397-pinfunc.h | 256 ++++++++++++++++++++++++++
|
||||
1 file changed, 256 insertions(+)
|
||||
create mode 100644 include/dt-bindings/pinctrl/mt6397-pinfunc.h
|
||||
|
||||
diff --git a/include/dt-bindings/pinctrl/mt6397-pinfunc.h b/include/dt-bindings/pinctrl/mt6397-pinfunc.h
|
||||
new file mode 100644
|
||||
index 0000000..85739b3
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/pinctrl/mt6397-pinfunc.h
|
||||
@@ -0,0 +1,256 @@
|
||||
+#ifndef __DTS_MT6397_PINFUNC_H
|
||||
+#define __DTS_MT6397_PINFUNC_H
|
||||
+
|
||||
+#include <dt-bindings/pinctrl/mt65xx.h>
|
||||
+
|
||||
+#define MT6397_PIN_0_INT__FUNC_GPIO0 (MTK_PIN_NO(0) | 0)
|
||||
+#define MT6397_PIN_0_INT__FUNC_INT (MTK_PIN_NO(0) | 1)
|
||||
+
|
||||
+#define MT6397_PIN_1_SRCVOLTEN__FUNC_GPIO1 (MTK_PIN_NO(1) | 0)
|
||||
+#define MT6397_PIN_1_SRCVOLTEN__FUNC_SRCVOLTEN (MTK_PIN_NO(1) | 1)
|
||||
+#define MT6397_PIN_1_SRCVOLTEN__FUNC_TEST_CK1 (MTK_PIN_NO(1) | 6)
|
||||
+
|
||||
+#define MT6397_PIN_2_SRCLKEN_PERI__FUNC_GPIO2 (MTK_PIN_NO(2) | 0)
|
||||
+#define MT6397_PIN_2_SRCLKEN_PERI__FUNC_SRCLKEN_PERI (MTK_PIN_NO(2) | 1)
|
||||
+#define MT6397_PIN_2_SRCLKEN_PERI__FUNC_TEST_CK2 (MTK_PIN_NO(2) | 6)
|
||||
+
|
||||
+#define MT6397_PIN_3_RTC_32K1V8__FUNC_GPIO3 (MTK_PIN_NO(3) | 0)
|
||||
+#define MT6397_PIN_3_RTC_32K1V8__FUNC_RTC_32K1V8 (MTK_PIN_NO(3) | 1)
|
||||
+#define MT6397_PIN_3_RTC_32K1V8__FUNC_TEST_CK3 (MTK_PIN_NO(3) | 6)
|
||||
+
|
||||
+#define MT6397_PIN_4_WRAP_EVENT__FUNC_GPIO4 (MTK_PIN_NO(4) | 0)
|
||||
+#define MT6397_PIN_4_WRAP_EVENT__FUNC_WRAP_EVENT (MTK_PIN_NO(4) | 1)
|
||||
+
|
||||
+#define MT6397_PIN_5_SPI_CLK__FUNC_GPIO5 (MTK_PIN_NO(5) | 0)
|
||||
+#define MT6397_PIN_5_SPI_CLK__FUNC_SPI_CLK (MTK_PIN_NO(5) | 1)
|
||||
+
|
||||
+#define MT6397_PIN_6_SPI_CSN__FUNC_GPIO6 (MTK_PIN_NO(6) | 0)
|
||||
+#define MT6397_PIN_6_SPI_CSN__FUNC_SPI_CSN (MTK_PIN_NO(6) | 1)
|
||||
+
|
||||
+#define MT6397_PIN_7_SPI_MOSI__FUNC_GPIO7 (MTK_PIN_NO(7) | 0)
|
||||
+#define MT6397_PIN_7_SPI_MOSI__FUNC_SPI_MOSI (MTK_PIN_NO(7) | 1)
|
||||
+
|
||||
+#define MT6397_PIN_8_SPI_MISO__FUNC_GPIO8 (MTK_PIN_NO(8) | 0)
|
||||
+#define MT6397_PIN_8_SPI_MISO__FUNC_SPI_MISO (MTK_PIN_NO(8) | 1)
|
||||
+
|
||||
+#define MT6397_PIN_9_AUD_CLK_MOSI__FUNC_GPIO9 (MTK_PIN_NO(9) | 0)
|
||||
+#define MT6397_PIN_9_AUD_CLK_MOSI__FUNC_AUD_CLK (MTK_PIN_NO(9) | 1)
|
||||
+#define MT6397_PIN_9_AUD_CLK_MOSI__FUNC_TEST_IN0 (MTK_PIN_NO(9) | 6)
|
||||
+#define MT6397_PIN_9_AUD_CLK_MOSI__FUNC_TEST_OUT0 (MTK_PIN_NO(9) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_10_AUD_DAT_MISO__FUNC_GPIO10 (MTK_PIN_NO(10) | 0)
|
||||
+#define MT6397_PIN_10_AUD_DAT_MISO__FUNC_AUD_MISO (MTK_PIN_NO(10) | 1)
|
||||
+#define MT6397_PIN_10_AUD_DAT_MISO__FUNC_TEST_IN1 (MTK_PIN_NO(10) | 6)
|
||||
+#define MT6397_PIN_10_AUD_DAT_MISO__FUNC_TEST_OUT1 (MTK_PIN_NO(10) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_11_AUD_DAT_MOSI__FUNC_GPIO11 (MTK_PIN_NO(11) | 0)
|
||||
+#define MT6397_PIN_11_AUD_DAT_MOSI__FUNC_AUD_MOSI (MTK_PIN_NO(11) | 1)
|
||||
+#define MT6397_PIN_11_AUD_DAT_MOSI__FUNC_TEST_IN2 (MTK_PIN_NO(11) | 6)
|
||||
+#define MT6397_PIN_11_AUD_DAT_MOSI__FUNC_TEST_OUT2 (MTK_PIN_NO(11) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_12_COL0__FUNC_GPIO12 (MTK_PIN_NO(12) | 0)
|
||||
+#define MT6397_PIN_12_COL0__FUNC_COL0_USBDL (MTK_PIN_NO(12) | 1)
|
||||
+#define MT6397_PIN_12_COL0__FUNC_EINT10_1X (MTK_PIN_NO(12) | 2)
|
||||
+#define MT6397_PIN_12_COL0__FUNC_PWM1_3X (MTK_PIN_NO(12) | 3)
|
||||
+#define MT6397_PIN_12_COL0__FUNC_TEST_IN3 (MTK_PIN_NO(12) | 6)
|
||||
+#define MT6397_PIN_12_COL0__FUNC_TEST_OUT3 (MTK_PIN_NO(12) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_13_COL1__FUNC_GPIO13 (MTK_PIN_NO(13) | 0)
|
||||
+#define MT6397_PIN_13_COL1__FUNC_COL1 (MTK_PIN_NO(13) | 1)
|
||||
+#define MT6397_PIN_13_COL1__FUNC_EINT11_1X (MTK_PIN_NO(13) | 2)
|
||||
+#define MT6397_PIN_13_COL1__FUNC_SCL0_2X (MTK_PIN_NO(13) | 3)
|
||||
+#define MT6397_PIN_13_COL1__FUNC_TEST_IN4 (MTK_PIN_NO(13) | 6)
|
||||
+#define MT6397_PIN_13_COL1__FUNC_TEST_OUT4 (MTK_PIN_NO(13) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_14_COL2__FUNC_GPIO14 (MTK_PIN_NO(14) | 0)
|
||||
+#define MT6397_PIN_14_COL2__FUNC_COL2 (MTK_PIN_NO(14) | 1)
|
||||
+#define MT6397_PIN_14_COL2__FUNC_EINT12_1X (MTK_PIN_NO(14) | 2)
|
||||
+#define MT6397_PIN_14_COL2__FUNC_SDA0_2X (MTK_PIN_NO(14) | 3)
|
||||
+#define MT6397_PIN_14_COL2__FUNC_TEST_IN5 (MTK_PIN_NO(14) | 6)
|
||||
+#define MT6397_PIN_14_COL2__FUNC_TEST_OUT5 (MTK_PIN_NO(14) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_15_COL3__FUNC_GPIO15 (MTK_PIN_NO(15) | 0)
|
||||
+#define MT6397_PIN_15_COL3__FUNC_COL3 (MTK_PIN_NO(15) | 1)
|
||||
+#define MT6397_PIN_15_COL3__FUNC_EINT13_1X (MTK_PIN_NO(15) | 2)
|
||||
+#define MT6397_PIN_15_COL3__FUNC_SCL1_2X (MTK_PIN_NO(15) | 3)
|
||||
+#define MT6397_PIN_15_COL3__FUNC_TEST_IN6 (MTK_PIN_NO(15) | 6)
|
||||
+#define MT6397_PIN_15_COL3__FUNC_TEST_OUT6 (MTK_PIN_NO(15) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_16_COL4__FUNC_GPIO16 (MTK_PIN_NO(16) | 0)
|
||||
+#define MT6397_PIN_16_COL4__FUNC_COL4 (MTK_PIN_NO(16) | 1)
|
||||
+#define MT6397_PIN_16_COL4__FUNC_EINT14_1X (MTK_PIN_NO(16) | 2)
|
||||
+#define MT6397_PIN_16_COL4__FUNC_SDA1_2X (MTK_PIN_NO(16) | 3)
|
||||
+#define MT6397_PIN_16_COL4__FUNC_TEST_IN7 (MTK_PIN_NO(16) | 6)
|
||||
+#define MT6397_PIN_16_COL4__FUNC_TEST_OUT7 (MTK_PIN_NO(16) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_17_COL5__FUNC_GPIO17 (MTK_PIN_NO(17) | 0)
|
||||
+#define MT6397_PIN_17_COL5__FUNC_COL5 (MTK_PIN_NO(17) | 1)
|
||||
+#define MT6397_PIN_17_COL5__FUNC_EINT15_1X (MTK_PIN_NO(17) | 2)
|
||||
+#define MT6397_PIN_17_COL5__FUNC_SCL2_2X (MTK_PIN_NO(17) | 3)
|
||||
+#define MT6397_PIN_17_COL5__FUNC_TEST_IN8 (MTK_PIN_NO(17) | 6)
|
||||
+#define MT6397_PIN_17_COL5__FUNC_TEST_OUT8 (MTK_PIN_NO(17) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_18_COL6__FUNC_GPIO18 (MTK_PIN_NO(18) | 0)
|
||||
+#define MT6397_PIN_18_COL6__FUNC_COL6 (MTK_PIN_NO(18) | 1)
|
||||
+#define MT6397_PIN_18_COL6__FUNC_EINT16_1X (MTK_PIN_NO(18) | 2)
|
||||
+#define MT6397_PIN_18_COL6__FUNC_SDA2_2X (MTK_PIN_NO(18) | 3)
|
||||
+#define MT6397_PIN_18_COL6__FUNC_GPIO32K_0 (MTK_PIN_NO(18) | 4)
|
||||
+#define MT6397_PIN_18_COL6__FUNC_GPIO26M_0 (MTK_PIN_NO(18) | 5)
|
||||
+#define MT6397_PIN_18_COL6__FUNC_TEST_IN9 (MTK_PIN_NO(18) | 6)
|
||||
+#define MT6397_PIN_18_COL6__FUNC_TEST_OUT9 (MTK_PIN_NO(18) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_19_COL7__FUNC_GPIO19 (MTK_PIN_NO(19) | 0)
|
||||
+#define MT6397_PIN_19_COL7__FUNC_COL7 (MTK_PIN_NO(19) | 1)
|
||||
+#define MT6397_PIN_19_COL7__FUNC_EINT17_1X (MTK_PIN_NO(19) | 2)
|
||||
+#define MT6397_PIN_19_COL7__FUNC_PWM2_3X (MTK_PIN_NO(19) | 3)
|
||||
+#define MT6397_PIN_19_COL7__FUNC_GPIO32K_1 (MTK_PIN_NO(19) | 4)
|
||||
+#define MT6397_PIN_19_COL7__FUNC_GPIO26M_1 (MTK_PIN_NO(19) | 5)
|
||||
+#define MT6397_PIN_19_COL7__FUNC_TEST_IN10 (MTK_PIN_NO(19) | 6)
|
||||
+#define MT6397_PIN_19_COL7__FUNC_TEST_OUT10 (MTK_PIN_NO(19) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_20_ROW0__FUNC_GPIO20 (MTK_PIN_NO(20) | 0)
|
||||
+#define MT6397_PIN_20_ROW0__FUNC_ROW0 (MTK_PIN_NO(20) | 1)
|
||||
+#define MT6397_PIN_20_ROW0__FUNC_EINT18_1X (MTK_PIN_NO(20) | 2)
|
||||
+#define MT6397_PIN_20_ROW0__FUNC_SCL0_3X (MTK_PIN_NO(20) | 3)
|
||||
+#define MT6397_PIN_20_ROW0__FUNC_TEST_IN11 (MTK_PIN_NO(20) | 6)
|
||||
+#define MT6397_PIN_20_ROW0__FUNC_TEST_OUT11 (MTK_PIN_NO(20) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_21_ROW1__FUNC_GPIO21 (MTK_PIN_NO(21) | 0)
|
||||
+#define MT6397_PIN_21_ROW1__FUNC_ROW1 (MTK_PIN_NO(21) | 1)
|
||||
+#define MT6397_PIN_21_ROW1__FUNC_EINT19_1X (MTK_PIN_NO(21) | 2)
|
||||
+#define MT6397_PIN_21_ROW1__FUNC_SDA0_3X (MTK_PIN_NO(21) | 3)
|
||||
+#define MT6397_PIN_21_ROW1__FUNC_AUD_TSTCK (MTK_PIN_NO(21) | 4)
|
||||
+#define MT6397_PIN_21_ROW1__FUNC_TEST_IN12 (MTK_PIN_NO(21) | 6)
|
||||
+#define MT6397_PIN_21_ROW1__FUNC_TEST_OUT12 (MTK_PIN_NO(21) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_22_ROW2__FUNC_GPIO22 (MTK_PIN_NO(22) | 0)
|
||||
+#define MT6397_PIN_22_ROW2__FUNC_ROW2 (MTK_PIN_NO(22) | 1)
|
||||
+#define MT6397_PIN_22_ROW2__FUNC_EINT20_1X (MTK_PIN_NO(22) | 2)
|
||||
+#define MT6397_PIN_22_ROW2__FUNC_SCL1_3X (MTK_PIN_NO(22) | 3)
|
||||
+#define MT6397_PIN_22_ROW2__FUNC_TEST_IN13 (MTK_PIN_NO(22) | 6)
|
||||
+#define MT6397_PIN_22_ROW2__FUNC_TEST_OUT13 (MTK_PIN_NO(22) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_23_ROW3__FUNC_GPIO23 (MTK_PIN_NO(23) | 0)
|
||||
+#define MT6397_PIN_23_ROW3__FUNC_ROW3 (MTK_PIN_NO(23) | 1)
|
||||
+#define MT6397_PIN_23_ROW3__FUNC_EINT21_1X (MTK_PIN_NO(23) | 2)
|
||||
+#define MT6397_PIN_23_ROW3__FUNC_SDA1_3X (MTK_PIN_NO(23) | 3)
|
||||
+#define MT6397_PIN_23_ROW3__FUNC_TEST_IN14 (MTK_PIN_NO(23) | 6)
|
||||
+#define MT6397_PIN_23_ROW3__FUNC_TEST_OUT14 (MTK_PIN_NO(23) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_24_ROW4__FUNC_GPIO24 (MTK_PIN_NO(24) | 0)
|
||||
+#define MT6397_PIN_24_ROW4__FUNC_ROW4 (MTK_PIN_NO(24) | 1)
|
||||
+#define MT6397_PIN_24_ROW4__FUNC_EINT22_1X (MTK_PIN_NO(24) | 2)
|
||||
+#define MT6397_PIN_24_ROW4__FUNC_SCL2_3X (MTK_PIN_NO(24) | 3)
|
||||
+#define MT6397_PIN_24_ROW4__FUNC_TEST_IN15 (MTK_PIN_NO(24) | 6)
|
||||
+#define MT6397_PIN_24_ROW4__FUNC_TEST_OUT15 (MTK_PIN_NO(24) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_25_ROW5__FUNC_GPIO25 (MTK_PIN_NO(25) | 0)
|
||||
+#define MT6397_PIN_25_ROW5__FUNC_ROW5 (MTK_PIN_NO(25) | 1)
|
||||
+#define MT6397_PIN_25_ROW5__FUNC_EINT23_1X (MTK_PIN_NO(25) | 2)
|
||||
+#define MT6397_PIN_25_ROW5__FUNC_SDA2_3X (MTK_PIN_NO(25) | 3)
|
||||
+#define MT6397_PIN_25_ROW5__FUNC_TEST_IN16 (MTK_PIN_NO(25) | 6)
|
||||
+#define MT6397_PIN_25_ROW5__FUNC_TEST_OUT16 (MTK_PIN_NO(25) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_26_ROW6__FUNC_GPIO26 (MTK_PIN_NO(26) | 0)
|
||||
+#define MT6397_PIN_26_ROW6__FUNC_ROW6 (MTK_PIN_NO(26) | 1)
|
||||
+#define MT6397_PIN_26_ROW6__FUNC_EINT24_1X (MTK_PIN_NO(26) | 2)
|
||||
+#define MT6397_PIN_26_ROW6__FUNC_PWM3_3X (MTK_PIN_NO(26) | 3)
|
||||
+#define MT6397_PIN_26_ROW6__FUNC_GPIO32K_2 (MTK_PIN_NO(26) | 4)
|
||||
+#define MT6397_PIN_26_ROW6__FUNC_GPIO26M_2 (MTK_PIN_NO(26) | 5)
|
||||
+#define MT6397_PIN_26_ROW6__FUNC_TEST_IN17 (MTK_PIN_NO(26) | 6)
|
||||
+#define MT6397_PIN_26_ROW6__FUNC_TEST_OUT17 (MTK_PIN_NO(26) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_27_ROW7__FUNC_GPIO27 (MTK_PIN_NO(27) | 0)
|
||||
+#define MT6397_PIN_27_ROW7__FUNC_ROW7 (MTK_PIN_NO(27) | 1)
|
||||
+#define MT6397_PIN_27_ROW7__FUNC_EINT3_1X (MTK_PIN_NO(27) | 2)
|
||||
+#define MT6397_PIN_27_ROW7__FUNC_CBUS (MTK_PIN_NO(27) | 3)
|
||||
+#define MT6397_PIN_27_ROW7__FUNC_GPIO32K_3 (MTK_PIN_NO(27) | 4)
|
||||
+#define MT6397_PIN_27_ROW7__FUNC_GPIO26M_3 (MTK_PIN_NO(27) | 5)
|
||||
+#define MT6397_PIN_27_ROW7__FUNC_TEST_IN18 (MTK_PIN_NO(27) | 6)
|
||||
+#define MT6397_PIN_27_ROW7__FUNC_TEST_OUT18 (MTK_PIN_NO(27) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_28_PWM1__FUNC_GPIO28 (MTK_PIN_NO(28) | 0)
|
||||
+#define MT6397_PIN_28_PWM1__FUNC_PWM1 (MTK_PIN_NO(28) | 1)
|
||||
+#define MT6397_PIN_28_PWM1__FUNC_EINT4_1X (MTK_PIN_NO(28) | 2)
|
||||
+#define MT6397_PIN_28_PWM1__FUNC_GPIO32K_4 (MTK_PIN_NO(28) | 4)
|
||||
+#define MT6397_PIN_28_PWM1__FUNC_GPIO26M_4 (MTK_PIN_NO(28) | 5)
|
||||
+#define MT6397_PIN_28_PWM1__FUNC_TEST_IN19 (MTK_PIN_NO(28) | 6)
|
||||
+#define MT6397_PIN_28_PWM1__FUNC_TEST_OUT19 (MTK_PIN_NO(28) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_29_PWM2__FUNC_GPIO29 (MTK_PIN_NO(29) | 0)
|
||||
+#define MT6397_PIN_29_PWM2__FUNC_PWM2 (MTK_PIN_NO(29) | 1)
|
||||
+#define MT6397_PIN_29_PWM2__FUNC_EINT5_1X (MTK_PIN_NO(29) | 2)
|
||||
+#define MT6397_PIN_29_PWM2__FUNC_GPIO32K_5 (MTK_PIN_NO(29) | 4)
|
||||
+#define MT6397_PIN_29_PWM2__FUNC_GPIO26M_5 (MTK_PIN_NO(29) | 5)
|
||||
+#define MT6397_PIN_29_PWM2__FUNC_TEST_IN20 (MTK_PIN_NO(29) | 6)
|
||||
+#define MT6397_PIN_29_PWM2__FUNC_TEST_OUT20 (MTK_PIN_NO(29) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_30_PWM3__FUNC_GPIO30 (MTK_PIN_NO(30) | 0)
|
||||
+#define MT6397_PIN_30_PWM3__FUNC_PWM3 (MTK_PIN_NO(30) | 1)
|
||||
+#define MT6397_PIN_30_PWM3__FUNC_EINT6_1X (MTK_PIN_NO(30) | 2)
|
||||
+#define MT6397_PIN_30_PWM3__FUNC_COL0 (MTK_PIN_NO(30) | 3)
|
||||
+#define MT6397_PIN_30_PWM3__FUNC_GPIO32K_6 (MTK_PIN_NO(30) | 4)
|
||||
+#define MT6397_PIN_30_PWM3__FUNC_GPIO26M_6 (MTK_PIN_NO(30) | 5)
|
||||
+#define MT6397_PIN_30_PWM3__FUNC_TEST_IN21 (MTK_PIN_NO(30) | 6)
|
||||
+#define MT6397_PIN_30_PWM3__FUNC_TEST_OUT21 (MTK_PIN_NO(30) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_31_SCL0__FUNC_GPIO31 (MTK_PIN_NO(31) | 0)
|
||||
+#define MT6397_PIN_31_SCL0__FUNC_SCL0 (MTK_PIN_NO(31) | 1)
|
||||
+#define MT6397_PIN_31_SCL0__FUNC_EINT7_1X (MTK_PIN_NO(31) | 2)
|
||||
+#define MT6397_PIN_31_SCL0__FUNC_PWM1_2X (MTK_PIN_NO(31) | 3)
|
||||
+#define MT6397_PIN_31_SCL0__FUNC_TEST_IN22 (MTK_PIN_NO(31) | 6)
|
||||
+#define MT6397_PIN_31_SCL0__FUNC_TEST_OUT22 (MTK_PIN_NO(31) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_32_SDA0__FUNC_GPIO32 (MTK_PIN_NO(32) | 0)
|
||||
+#define MT6397_PIN_32_SDA0__FUNC_SDA0 (MTK_PIN_NO(32) | 1)
|
||||
+#define MT6397_PIN_32_SDA0__FUNC_EINT8_1X (MTK_PIN_NO(32) | 2)
|
||||
+#define MT6397_PIN_32_SDA0__FUNC_TEST_IN23 (MTK_PIN_NO(32) | 6)
|
||||
+#define MT6397_PIN_32_SDA0__FUNC_TEST_OUT23 (MTK_PIN_NO(32) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_33_SCL1__FUNC_GPIO33 (MTK_PIN_NO(33) | 0)
|
||||
+#define MT6397_PIN_33_SCL1__FUNC_SCL1 (MTK_PIN_NO(33) | 1)
|
||||
+#define MT6397_PIN_33_SCL1__FUNC_EINT9_1X (MTK_PIN_NO(33) | 2)
|
||||
+#define MT6397_PIN_33_SCL1__FUNC_PWM2_2X (MTK_PIN_NO(33) | 3)
|
||||
+#define MT6397_PIN_33_SCL1__FUNC_TEST_IN24 (MTK_PIN_NO(33) | 6)
|
||||
+#define MT6397_PIN_33_SCL1__FUNC_TEST_OUT24 (MTK_PIN_NO(33) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_34_SDA1__FUNC_GPIO34 (MTK_PIN_NO(34) | 0)
|
||||
+#define MT6397_PIN_34_SDA1__FUNC_SDA1 (MTK_PIN_NO(34) | 1)
|
||||
+#define MT6397_PIN_34_SDA1__FUNC_EINT0_1X (MTK_PIN_NO(34) | 2)
|
||||
+#define MT6397_PIN_34_SDA1__FUNC_TEST_IN25 (MTK_PIN_NO(34) | 6)
|
||||
+#define MT6397_PIN_34_SDA1__FUNC_TEST_OUT25 (MTK_PIN_NO(34) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_35_SCL2__FUNC_GPIO35 (MTK_PIN_NO(35) | 0)
|
||||
+#define MT6397_PIN_35_SCL2__FUNC_SCL2 (MTK_PIN_NO(35) | 1)
|
||||
+#define MT6397_PIN_35_SCL2__FUNC_EINT1_1X (MTK_PIN_NO(35) | 2)
|
||||
+#define MT6397_PIN_35_SCL2__FUNC_PWM3_2X (MTK_PIN_NO(35) | 3)
|
||||
+#define MT6397_PIN_35_SCL2__FUNC_TEST_IN26 (MTK_PIN_NO(35) | 6)
|
||||
+#define MT6397_PIN_35_SCL2__FUNC_TEST_OUT26 (MTK_PIN_NO(35) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_36_SDA2__FUNC_GPIO36 (MTK_PIN_NO(36) | 0)
|
||||
+#define MT6397_PIN_36_SDA2__FUNC_SDA2 (MTK_PIN_NO(36) | 1)
|
||||
+#define MT6397_PIN_36_SDA2__FUNC_EINT2_1X (MTK_PIN_NO(36) | 2)
|
||||
+#define MT6397_PIN_36_SDA2__FUNC_TEST_IN27 (MTK_PIN_NO(36) | 6)
|
||||
+#define MT6397_PIN_36_SDA2__FUNC_TEST_OUT27 (MTK_PIN_NO(36) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_37_HDMISD__FUNC_GPIO37 (MTK_PIN_NO(37) | 0)
|
||||
+#define MT6397_PIN_37_HDMISD__FUNC_HDMISD (MTK_PIN_NO(37) | 1)
|
||||
+#define MT6397_PIN_37_HDMISD__FUNC_TEST_IN28 (MTK_PIN_NO(37) | 6)
|
||||
+#define MT6397_PIN_37_HDMISD__FUNC_TEST_OUT28 (MTK_PIN_NO(37) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_38_HDMISCK__FUNC_GPIO38 (MTK_PIN_NO(38) | 0)
|
||||
+#define MT6397_PIN_38_HDMISCK__FUNC_HDMISCK (MTK_PIN_NO(38) | 1)
|
||||
+#define MT6397_PIN_38_HDMISCK__FUNC_TEST_IN29 (MTK_PIN_NO(38) | 6)
|
||||
+#define MT6397_PIN_38_HDMISCK__FUNC_TEST_OUT29 (MTK_PIN_NO(38) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_39_HTPLG__FUNC_GPIO39 (MTK_PIN_NO(39) | 0)
|
||||
+#define MT6397_PIN_39_HTPLG__FUNC_HTPLG (MTK_PIN_NO(39) | 1)
|
||||
+#define MT6397_PIN_39_HTPLG__FUNC_TEST_IN30 (MTK_PIN_NO(39) | 6)
|
||||
+#define MT6397_PIN_39_HTPLG__FUNC_TEST_OUT30 (MTK_PIN_NO(39) | 7)
|
||||
+
|
||||
+#define MT6397_PIN_40_CEC__FUNC_GPIO40 (MTK_PIN_NO(40) | 0)
|
||||
+#define MT6397_PIN_40_CEC__FUNC_CEC (MTK_PIN_NO(40) | 1)
|
||||
+#define MT6397_PIN_40_CEC__FUNC_TEST_IN31 (MTK_PIN_NO(40) | 6)
|
||||
+#define MT6397_PIN_40_CEC__FUNC_TEST_OUT31 (MTK_PIN_NO(40) | 7)
|
||||
+
|
||||
+#endif /* __DTS_MT6397_PINFUNC_H */
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,116 @@
|
||||
From 3eeb897a627e26083472f14e7512f53276a5e7ce Mon Sep 17 00:00:00 2001
|
||||
From: Yingjoe Chen <yingjoe.chen@mediatek.com>
|
||||
Date: Mon, 18 May 2015 23:11:14 -0700
|
||||
Subject: [PATCH 50/76] pinctrl: mediatek: data struct optimize and remove
|
||||
unused member
|
||||
|
||||
struct mtk_desc_pin.chip, mtk_pinctrl_devdata.invser_offset
|
||||
and mtk_pinctrl_devdata.chip_type are never used in code.
|
||||
Remove them.
|
||||
|
||||
Some per-pin data are using int for pin number and offsets.
|
||||
Change to short and rearrange to reduce const data size.
|
||||
|
||||
Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
|
||||
Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com>
|
||||
---
|
||||
drivers/pinctrl/mediatek/pinctrl-mt8135.c | 10 ++++------
|
||||
drivers/pinctrl/mediatek/pinctrl-mtk-common.h | 10 ++--------
|
||||
2 files changed, 6 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8135.c b/drivers/pinctrl/mediatek/pinctrl-mt8135.c
|
||||
index f1e1e18..8e6abd5 100644
|
||||
--- a/drivers/pinctrl/mediatek/pinctrl-mt8135.c
|
||||
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8135.c
|
||||
@@ -32,12 +32,12 @@
|
||||
#define R1_BASE2 0x250
|
||||
|
||||
struct mtk_spec_pull_set {
|
||||
- unsigned int pin;
|
||||
- unsigned int pupd_offset;
|
||||
+ unsigned char pin;
|
||||
unsigned char pupd_bit;
|
||||
- unsigned int r0_offset;
|
||||
+ unsigned short pupd_offset;
|
||||
+ unsigned short r0_offset;
|
||||
+ unsigned short r1_offset;
|
||||
unsigned char r0_bit;
|
||||
- unsigned int r1_offset;
|
||||
unsigned char r1_bit;
|
||||
};
|
||||
|
||||
@@ -305,7 +305,6 @@ static const struct mtk_pinctrl_devdata mt8135_pinctrl_data = {
|
||||
.pullen_offset = 0x0200,
|
||||
.smt_offset = 0x0300,
|
||||
.pullsel_offset = 0x0400,
|
||||
- .invser_offset = 0x0600,
|
||||
.dout_offset = 0x0800,
|
||||
.din_offset = 0x0A00,
|
||||
.pinmux_offset = 0x0C00,
|
||||
@@ -314,7 +313,6 @@ static const struct mtk_pinctrl_devdata mt8135_pinctrl_data = {
|
||||
.port_shf = 4,
|
||||
.port_mask = 0xf,
|
||||
.port_align = 4,
|
||||
- .chip_type = MTK_CHIP_TYPE_BASE,
|
||||
.eint_offsets = {
|
||||
.name = "mt8135_eint",
|
||||
.stat = 0x000,
|
||||
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
|
||||
index 375771d..1508849 100644
|
||||
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
|
||||
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
|
||||
@@ -19,8 +19,6 @@
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define NO_EINT_SUPPORT 255
|
||||
-#define MTK_CHIP_TYPE_BASE 0
|
||||
-#define MTK_CHIP_TYPE_PMIC 1
|
||||
#define MT_EDGE_SENSITIVE 0
|
||||
#define MT_LEVEL_SENSITIVE 1
|
||||
#define EINT_DBNC_SET_DBNC_BITS 4
|
||||
@@ -39,7 +37,6 @@ struct mtk_desc_eint {
|
||||
|
||||
struct mtk_desc_pin {
|
||||
struct pinctrl_pin_desc pin;
|
||||
- const char *chip;
|
||||
const struct mtk_desc_eint eint;
|
||||
const struct mtk_desc_function *functions;
|
||||
};
|
||||
@@ -47,7 +44,6 @@ struct mtk_desc_pin {
|
||||
#define MTK_PIN(_pin, _pad, _chip, _eint, ...) \
|
||||
{ \
|
||||
.pin = _pin, \
|
||||
- .chip = _chip, \
|
||||
.eint = _eint, \
|
||||
.functions = (struct mtk_desc_function[]){ \
|
||||
__VA_ARGS__, { } }, \
|
||||
@@ -107,8 +103,8 @@ struct mtk_drv_group_desc {
|
||||
* @grp: The group for this pin belongs to.
|
||||
*/
|
||||
struct mtk_pin_drv_grp {
|
||||
- unsigned int pin;
|
||||
- unsigned int offset;
|
||||
+ unsigned short pin;
|
||||
+ unsigned short offset;
|
||||
unsigned char bit;
|
||||
unsigned char grp;
|
||||
};
|
||||
@@ -193,7 +189,6 @@ struct mtk_pinctrl_devdata {
|
||||
unsigned int pullen_offset;
|
||||
unsigned int pullsel_offset;
|
||||
unsigned int drv_offset;
|
||||
- unsigned int invser_offset;
|
||||
unsigned int dout_offset;
|
||||
unsigned int din_offset;
|
||||
unsigned int pinmux_offset;
|
||||
@@ -202,7 +197,6 @@ struct mtk_pinctrl_devdata {
|
||||
unsigned char port_shf;
|
||||
unsigned char port_mask;
|
||||
unsigned char port_align;
|
||||
- unsigned char chip_type;
|
||||
struct mtk_eint_offsets eint_offsets;
|
||||
unsigned int ap_num;
|
||||
unsigned int db_cnt;
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,328 @@
|
||||
From aefbeb75a32e080445d72ddd4b9ab28c258597d0 Mon Sep 17 00:00:00 2001
|
||||
From: Yingjoe Chen <yingjoe.chen@mediatek.com>
|
||||
Date: Mon, 18 May 2015 23:11:15 -0700
|
||||
Subject: [PATCH 51/76] pinctrl: mediatek: add mtk_pctrl_spec_pull_set_samereg
|
||||
common code
|
||||
|
||||
Several mediatek soc use similar pull setting procedure as mt8173,
|
||||
the pupd enable and resistance setting are in the same register.
|
||||
Add common code mtk_pctrl_spec_pull_set_samereg out of spec_pull_set
|
||||
in mt8173 to handle this case, so future soc driver can use it.
|
||||
|
||||
Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
|
||||
Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com>
|
||||
---
|
||||
drivers/pinctrl/mediatek/pinctrl-mt8173.c | 166 +++++++------------------
|
||||
drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 60 +++++++++
|
||||
drivers/pinctrl/mediatek/pinctrl-mtk-common.h | 31 +++++
|
||||
3 files changed, 136 insertions(+), 121 deletions(-)
|
||||
|
||||
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
|
||||
index 412ea84..cc44b27 100644
|
||||
--- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
|
||||
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
|
||||
@@ -47,130 +47,54 @@ struct mtk_pin_ies_smt_set {
|
||||
.offset = _offset, \
|
||||
}
|
||||
|
||||
-/**
|
||||
- * struct mtk_pin_spec_pupd_set - For special pins' pull up/down setting.
|
||||
- * @pin: The pin number.
|
||||
- * @offset: The offset of special pull up/down setting register.
|
||||
- * @pupd_bit: The pull up/down bit in this register.
|
||||
- * @r0_bit: The r0 bit of pull resistor.
|
||||
- * @r1_bit: The r1 bit of pull resistor.
|
||||
- */
|
||||
-struct mtk_pin_spec_pupd_set {
|
||||
- unsigned int pin;
|
||||
- unsigned int offset;
|
||||
- unsigned char pupd_bit;
|
||||
- unsigned char r1_bit;
|
||||
- unsigned char r0_bit;
|
||||
-};
|
||||
-
|
||||
-#define MTK_PIN_PUPD_SPEC(_pin, _offset, _pupd, _r1, _r0) \
|
||||
- { \
|
||||
- .pin = _pin, \
|
||||
- .offset = _offset, \
|
||||
- .pupd_bit = _pupd, \
|
||||
- .r1_bit = _r1, \
|
||||
- .r0_bit = _r0, \
|
||||
- }
|
||||
-
|
||||
-static const struct mtk_pin_spec_pupd_set mt8173_spec_pupd[] = {
|
||||
- MTK_PIN_PUPD_SPEC(119, 0xe00, 2, 1, 0), /* KROW0 */
|
||||
- MTK_PIN_PUPD_SPEC(120, 0xe00, 6, 5, 4), /* KROW1 */
|
||||
- MTK_PIN_PUPD_SPEC(121, 0xe00, 10, 9, 8), /* KROW2 */
|
||||
- MTK_PIN_PUPD_SPEC(122, 0xe10, 2, 1, 0), /* KCOL0 */
|
||||
- MTK_PIN_PUPD_SPEC(123, 0xe10, 6, 5, 4), /* KCOL1 */
|
||||
- MTK_PIN_PUPD_SPEC(124, 0xe10, 10, 9, 8), /* KCOL2 */
|
||||
-
|
||||
- MTK_PIN_PUPD_SPEC(67, 0xd10, 2, 1, 0), /* ms0 DS */
|
||||
- MTK_PIN_PUPD_SPEC(68, 0xd00, 2, 1, 0), /* ms0 RST */
|
||||
- MTK_PIN_PUPD_SPEC(66, 0xc10, 2, 1, 0), /* ms0 cmd */
|
||||
- MTK_PIN_PUPD_SPEC(65, 0xc00, 2, 1, 0), /* ms0 clk */
|
||||
- MTK_PIN_PUPD_SPEC(57, 0xc20, 2, 1, 0), /* ms0 data0 */
|
||||
- MTK_PIN_PUPD_SPEC(58, 0xc20, 2, 1, 0), /* ms0 data1 */
|
||||
- MTK_PIN_PUPD_SPEC(59, 0xc20, 2, 1, 0), /* ms0 data2 */
|
||||
- MTK_PIN_PUPD_SPEC(60, 0xc20, 2, 1, 0), /* ms0 data3 */
|
||||
- MTK_PIN_PUPD_SPEC(61, 0xc20, 2, 1, 0), /* ms0 data4 */
|
||||
- MTK_PIN_PUPD_SPEC(62, 0xc20, 2, 1, 0), /* ms0 data5 */
|
||||
- MTK_PIN_PUPD_SPEC(63, 0xc20, 2, 1, 0), /* ms0 data6 */
|
||||
- MTK_PIN_PUPD_SPEC(64, 0xc20, 2, 1, 0), /* ms0 data7 */
|
||||
-
|
||||
- MTK_PIN_PUPD_SPEC(78, 0xc50, 2, 1, 0), /* ms1 cmd */
|
||||
- MTK_PIN_PUPD_SPEC(73, 0xd20, 2, 1, 0), /* ms1 dat0 */
|
||||
- MTK_PIN_PUPD_SPEC(74, 0xd20, 6, 5, 4), /* ms1 dat1 */
|
||||
- MTK_PIN_PUPD_SPEC(75, 0xd20, 10, 9, 8), /* ms1 dat2 */
|
||||
- MTK_PIN_PUPD_SPEC(76, 0xd20, 14, 13, 12), /* ms1 dat3 */
|
||||
- MTK_PIN_PUPD_SPEC(77, 0xc40, 2, 1, 0), /* ms1 clk */
|
||||
-
|
||||
- MTK_PIN_PUPD_SPEC(100, 0xd40, 2, 1, 0), /* ms2 dat0 */
|
||||
- MTK_PIN_PUPD_SPEC(101, 0xd40, 6, 5, 4), /* ms2 dat1 */
|
||||
- MTK_PIN_PUPD_SPEC(102, 0xd40, 10, 9, 8), /* ms2 dat2 */
|
||||
- MTK_PIN_PUPD_SPEC(103, 0xd40, 14, 13, 12), /* ms2 dat3 */
|
||||
- MTK_PIN_PUPD_SPEC(104, 0xc80, 2, 1, 0), /* ms2 clk */
|
||||
- MTK_PIN_PUPD_SPEC(105, 0xc90, 2, 1, 0), /* ms2 cmd */
|
||||
-
|
||||
- MTK_PIN_PUPD_SPEC(22, 0xd60, 2, 1, 0), /* ms3 dat0 */
|
||||
- MTK_PIN_PUPD_SPEC(23, 0xd60, 6, 5, 4), /* ms3 dat1 */
|
||||
- MTK_PIN_PUPD_SPEC(24, 0xd60, 10, 9, 8), /* ms3 dat2 */
|
||||
- MTK_PIN_PUPD_SPEC(25, 0xd60, 14, 13, 12), /* ms3 dat3 */
|
||||
- MTK_PIN_PUPD_SPEC(26, 0xcc0, 2, 1, 0), /* ms3 clk */
|
||||
- MTK_PIN_PUPD_SPEC(27, 0xcd0, 2, 1, 0) /* ms3 cmd */
|
||||
+static const struct mtk_pin_spec_pupd_set_samereg mt8173_spec_pupd[] = {
|
||||
+ MTK_PIN_PUPD_SPEC_SR(119, 0xe00, 2, 1, 0), /* KROW0 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(120, 0xe00, 6, 5, 4), /* KROW1 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(121, 0xe00, 10, 9, 8), /* KROW2 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(122, 0xe10, 2, 1, 0), /* KCOL0 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(123, 0xe10, 6, 5, 4), /* KCOL1 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(124, 0xe10, 10, 9, 8), /* KCOL2 */
|
||||
+
|
||||
+ MTK_PIN_PUPD_SPEC_SR(67, 0xd10, 2, 1, 0), /* ms0 DS */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(68, 0xd00, 2, 1, 0), /* ms0 RST */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(66, 0xc10, 2, 1, 0), /* ms0 cmd */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(65, 0xc00, 2, 1, 0), /* ms0 clk */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(57, 0xc20, 2, 1, 0), /* ms0 data0 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(58, 0xc20, 2, 1, 0), /* ms0 data1 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(59, 0xc20, 2, 1, 0), /* ms0 data2 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(60, 0xc20, 2, 1, 0), /* ms0 data3 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(61, 0xc20, 2, 1, 0), /* ms0 data4 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(62, 0xc20, 2, 1, 0), /* ms0 data5 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(63, 0xc20, 2, 1, 0), /* ms0 data6 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(64, 0xc20, 2, 1, 0), /* ms0 data7 */
|
||||
+
|
||||
+ MTK_PIN_PUPD_SPEC_SR(78, 0xc50, 2, 1, 0), /* ms1 cmd */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(73, 0xd20, 2, 1, 0), /* ms1 dat0 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(74, 0xd20, 6, 5, 4), /* ms1 dat1 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(75, 0xd20, 10, 9, 8), /* ms1 dat2 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(76, 0xd20, 14, 13, 12), /* ms1 dat3 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(77, 0xc40, 2, 1, 0), /* ms1 clk */
|
||||
+
|
||||
+ MTK_PIN_PUPD_SPEC_SR(100, 0xd40, 2, 1, 0), /* ms2 dat0 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(101, 0xd40, 6, 5, 4), /* ms2 dat1 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(102, 0xd40, 10, 9, 8), /* ms2 dat2 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(103, 0xd40, 14, 13, 12), /* ms2 dat3 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(104, 0xc80, 2, 1, 0), /* ms2 clk */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(105, 0xc90, 2, 1, 0), /* ms2 cmd */
|
||||
+
|
||||
+ MTK_PIN_PUPD_SPEC_SR(22, 0xd60, 2, 1, 0), /* ms3 dat0 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(23, 0xd60, 6, 5, 4), /* ms3 dat1 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(24, 0xd60, 10, 9, 8), /* ms3 dat2 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(25, 0xd60, 14, 13, 12), /* ms3 dat3 */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(26, 0xcc0, 2, 1, 0), /* ms3 clk */
|
||||
+ MTK_PIN_PUPD_SPEC_SR(27, 0xcd0, 2, 1, 0) /* ms3 cmd */
|
||||
};
|
||||
|
||||
-static int spec_pull_set(struct regmap *regmap, unsigned int pin,
|
||||
+static int mt8173_spec_pull_set(struct regmap *regmap, unsigned int pin,
|
||||
unsigned char align, bool isup, unsigned int r1r0)
|
||||
{
|
||||
- unsigned int i;
|
||||
- unsigned int reg_pupd, reg_set, reg_rst;
|
||||
- unsigned int bit_pupd, bit_r0, bit_r1;
|
||||
- const struct mtk_pin_spec_pupd_set *spec_pupd_pin;
|
||||
- bool find = false;
|
||||
-
|
||||
- for (i = 0; i < ARRAY_SIZE(mt8173_spec_pupd); i++) {
|
||||
- if (pin == mt8173_spec_pupd[i].pin) {
|
||||
- find = true;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (!find)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- spec_pupd_pin = mt8173_spec_pupd + i;
|
||||
- reg_set = spec_pupd_pin->offset + align;
|
||||
- reg_rst = spec_pupd_pin->offset + (align << 1);
|
||||
-
|
||||
- if (isup)
|
||||
- reg_pupd = reg_rst;
|
||||
- else
|
||||
- reg_pupd = reg_set;
|
||||
-
|
||||
- bit_pupd = BIT(spec_pupd_pin->pupd_bit);
|
||||
- regmap_write(regmap, reg_pupd, bit_pupd);
|
||||
-
|
||||
- bit_r0 = BIT(spec_pupd_pin->r0_bit);
|
||||
- bit_r1 = BIT(spec_pupd_pin->r1_bit);
|
||||
-
|
||||
- switch (r1r0) {
|
||||
- case MTK_PUPD_SET_R1R0_00:
|
||||
- regmap_write(regmap, reg_rst, bit_r0);
|
||||
- regmap_write(regmap, reg_rst, bit_r1);
|
||||
- break;
|
||||
- case MTK_PUPD_SET_R1R0_01:
|
||||
- regmap_write(regmap, reg_set, bit_r0);
|
||||
- regmap_write(regmap, reg_rst, bit_r1);
|
||||
- break;
|
||||
- case MTK_PUPD_SET_R1R0_10:
|
||||
- regmap_write(regmap, reg_rst, bit_r0);
|
||||
- regmap_write(regmap, reg_set, bit_r1);
|
||||
- break;
|
||||
- case MTK_PUPD_SET_R1R0_11:
|
||||
- regmap_write(regmap, reg_set, bit_r0);
|
||||
- regmap_write(regmap, reg_set, bit_r1);
|
||||
- break;
|
||||
- default:
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
+ return mtk_pctrl_spec_pull_set_samereg(regmap, mt8173_spec_pupd,
|
||||
+ ARRAY_SIZE(mt8173_spec_pupd), pin, align, isup, r1r0);
|
||||
}
|
||||
|
||||
static const struct mtk_pin_ies_smt_set mt8173_ies_smt_set[] = {
|
||||
@@ -382,7 +306,7 @@ static const struct mtk_pinctrl_devdata mt8173_pinctrl_data = {
|
||||
.n_grp_cls = ARRAY_SIZE(mt8173_drv_grp),
|
||||
.pin_drv_grp = mt8173_pin_drv,
|
||||
.n_pin_drv_grps = ARRAY_SIZE(mt8173_pin_drv),
|
||||
- .spec_pull_set = spec_pull_set,
|
||||
+ .spec_pull_set = mt8173_spec_pull_set,
|
||||
.spec_ies_smt_set = spec_ies_smt_set,
|
||||
.dir_offset = 0x0000,
|
||||
.pullen_offset = 0x0100,
|
||||
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
|
||||
index 474812e..0d51145 100644
|
||||
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
|
||||
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
|
||||
@@ -186,6 +186,66 @@ static int mtk_pconf_set_driving(struct mtk_pinctrl *pctl,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+int mtk_pctrl_spec_pull_set_samereg(struct regmap *regmap,
|
||||
+ const struct mtk_pin_spec_pupd_set_samereg *pupd_infos,
|
||||
+ unsigned int info_num, unsigned int pin,
|
||||
+ unsigned char align, bool isup, unsigned int r1r0)
|
||||
+{
|
||||
+ unsigned int i;
|
||||
+ unsigned int reg_pupd, reg_set, reg_rst;
|
||||
+ unsigned int bit_pupd, bit_r0, bit_r1;
|
||||
+ const struct mtk_pin_spec_pupd_set_samereg *spec_pupd_pin;
|
||||
+ bool find = false;
|
||||
+
|
||||
+ for (i = 0; i < info_num; i++) {
|
||||
+ if (pin == pupd_infos[i].pin) {
|
||||
+ find = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!find)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ spec_pupd_pin = pupd_infos + i;
|
||||
+ reg_set = spec_pupd_pin->offset + align;
|
||||
+ reg_rst = spec_pupd_pin->offset + (align << 1);
|
||||
+
|
||||
+ if (isup)
|
||||
+ reg_pupd = reg_rst;
|
||||
+ else
|
||||
+ reg_pupd = reg_set;
|
||||
+
|
||||
+ bit_pupd = BIT(spec_pupd_pin->pupd_bit);
|
||||
+ regmap_write(regmap, reg_pupd, bit_pupd);
|
||||
+
|
||||
+ bit_r0 = BIT(spec_pupd_pin->r0_bit);
|
||||
+ bit_r1 = BIT(spec_pupd_pin->r1_bit);
|
||||
+
|
||||
+ switch (r1r0) {
|
||||
+ case MTK_PUPD_SET_R1R0_00:
|
||||
+ regmap_write(regmap, reg_rst, bit_r0);
|
||||
+ regmap_write(regmap, reg_rst, bit_r1);
|
||||
+ break;
|
||||
+ case MTK_PUPD_SET_R1R0_01:
|
||||
+ regmap_write(regmap, reg_set, bit_r0);
|
||||
+ regmap_write(regmap, reg_rst, bit_r1);
|
||||
+ break;
|
||||
+ case MTK_PUPD_SET_R1R0_10:
|
||||
+ regmap_write(regmap, reg_rst, bit_r0);
|
||||
+ regmap_write(regmap, reg_set, bit_r1);
|
||||
+ break;
|
||||
+ case MTK_PUPD_SET_R1R0_11:
|
||||
+ regmap_write(regmap, reg_set, bit_r0);
|
||||
+ regmap_write(regmap, reg_set, bit_r1);
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int mtk_pconf_set_pull_select(struct mtk_pinctrl *pctl,
|
||||
unsigned int pin, bool enable, bool isup, unsigned int arg)
|
||||
{
|
||||
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
|
||||
index 1508849..2a4b7be 100644
|
||||
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
|
||||
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
|
||||
@@ -117,6 +117,32 @@ struct mtk_pin_drv_grp {
|
||||
.grp = _grp, \
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * struct mtk_pin_spec_pupd_set_samereg
|
||||
+ * - For special pins' pull up/down setting which resides in same register
|
||||
+ * @pin: The pin number.
|
||||
+ * @offset: The offset of special pull up/down setting register.
|
||||
+ * @pupd_bit: The pull up/down bit in this register.
|
||||
+ * @r0_bit: The r0 bit of pull resistor.
|
||||
+ * @r1_bit: The r1 bit of pull resistor.
|
||||
+ */
|
||||
+struct mtk_pin_spec_pupd_set_samereg {
|
||||
+ unsigned short pin;
|
||||
+ unsigned short offset;
|
||||
+ unsigned char pupd_bit;
|
||||
+ unsigned char r1_bit;
|
||||
+ unsigned char r0_bit;
|
||||
+};
|
||||
+
|
||||
+#define MTK_PIN_PUPD_SPEC_SR(_pin, _offset, _pupd, _r1, _r0) \
|
||||
+ { \
|
||||
+ .pin = _pin, \
|
||||
+ .offset = _offset, \
|
||||
+ .pupd_bit = _pupd, \
|
||||
+ .r1_bit = _r1, \
|
||||
+ .r0_bit = _r0, \
|
||||
+ }
|
||||
+
|
||||
struct mtk_eint_offsets {
|
||||
const char *name;
|
||||
unsigned int stat;
|
||||
@@ -220,4 +246,9 @@ struct mtk_pinctrl {
|
||||
int mtk_pctrl_init(struct platform_device *pdev,
|
||||
const struct mtk_pinctrl_devdata *data);
|
||||
|
||||
+int mtk_pctrl_spec_pull_set_samereg(struct regmap *regmap,
|
||||
+ const struct mtk_pin_spec_pupd_set_samereg *pupd_infos,
|
||||
+ unsigned int info_num, unsigned int pin,
|
||||
+ unsigned char align, bool isup, unsigned int r1r0);
|
||||
+
|
||||
#endif /* __PINCTRL_MTK_COMMON_H */
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,479 @@
|
||||
From 32ea3b91046bea40cd1a7a4f16a24d75f53ca92a Mon Sep 17 00:00:00 2001
|
||||
From: Hongzhou Yang <hongzhou.yang@mediatek.com>
|
||||
Date: Mon, 18 May 2015 23:11:16 -0700
|
||||
Subject: [PATCH 52/76] pinctrl: mediatek: add ies/smt control to common code.
|
||||
|
||||
Input enable and smt setting have different register,
|
||||
modify code to fix it.
|
||||
|
||||
Several mediatek soc use similar input enable/smt setting
|
||||
procedure as mt8173, some soc use generic input enable/smt
|
||||
setting, some soc has no input enable/smt setting. Adding
|
||||
common code to handle all those cases, so future soc driver
|
||||
can use it.
|
||||
|
||||
Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com>
|
||||
---
|
||||
drivers/pinctrl/mediatek/pinctrl-mt8173.c | 201 +++++++++++++------------
|
||||
drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 82 +++++++---
|
||||
drivers/pinctrl/mediatek/pinctrl-mtk-common.h | 31 +++-
|
||||
3 files changed, 198 insertions(+), 116 deletions(-)
|
||||
|
||||
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
|
||||
index cc44b27..a7e5b24 100644
|
||||
--- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
|
||||
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/regmap.h>
|
||||
+#include <linux/pinctrl/pinconf-generic.h>
|
||||
#include <dt-bindings/pinctrl/mt65xx.h>
|
||||
|
||||
#include "pinctrl-mtk-common.h"
|
||||
@@ -25,28 +26,6 @@
|
||||
|
||||
#define DRV_BASE 0xb00
|
||||
|
||||
-/**
|
||||
- * struct mtk_pin_ies_smt_set - For special pins' ies and smt setting.
|
||||
- * @start: The start pin number of those special pins.
|
||||
- * @end: The end pin number of those special pins.
|
||||
- * @offset: The offset of special setting register.
|
||||
- * @bit: The bit of special setting register.
|
||||
- */
|
||||
-struct mtk_pin_ies_smt_set {
|
||||
- unsigned int start;
|
||||
- unsigned int end;
|
||||
- unsigned int offset;
|
||||
- unsigned char bit;
|
||||
-};
|
||||
-
|
||||
-#define MTK_PIN_IES_SMT_SET(_start, _end, _offset, _bit) \
|
||||
- { \
|
||||
- .start = _start, \
|
||||
- .end = _end, \
|
||||
- .bit = _bit, \
|
||||
- .offset = _offset, \
|
||||
- }
|
||||
-
|
||||
static const struct mtk_pin_spec_pupd_set_samereg mt8173_spec_pupd[] = {
|
||||
MTK_PIN_PUPD_SPEC_SR(119, 0xe00, 2, 1, 0), /* KROW0 */
|
||||
MTK_PIN_PUPD_SPEC_SR(120, 0xe00, 6, 5, 4), /* KROW1 */
|
||||
@@ -97,80 +76,114 @@ static int mt8173_spec_pull_set(struct regmap *regmap, unsigned int pin,
|
||||
ARRAY_SIZE(mt8173_spec_pupd), pin, align, isup, r1r0);
|
||||
}
|
||||
|
||||
-static const struct mtk_pin_ies_smt_set mt8173_ies_smt_set[] = {
|
||||
- MTK_PIN_IES_SMT_SET(0, 4, 0x930, 1),
|
||||
- MTK_PIN_IES_SMT_SET(5, 9, 0x930, 2),
|
||||
- MTK_PIN_IES_SMT_SET(10, 13, 0x930, 10),
|
||||
- MTK_PIN_IES_SMT_SET(14, 15, 0x940, 10),
|
||||
- MTK_PIN_IES_SMT_SET(16, 16, 0x930, 0),
|
||||
- MTK_PIN_IES_SMT_SET(17, 17, 0x950, 2),
|
||||
- MTK_PIN_IES_SMT_SET(18, 21, 0x940, 3),
|
||||
- MTK_PIN_IES_SMT_SET(29, 32, 0x930, 3),
|
||||
- MTK_PIN_IES_SMT_SET(33, 33, 0x930, 4),
|
||||
- MTK_PIN_IES_SMT_SET(34, 36, 0x930, 5),
|
||||
- MTK_PIN_IES_SMT_SET(37, 38, 0x930, 6),
|
||||
- MTK_PIN_IES_SMT_SET(39, 39, 0x930, 7),
|
||||
- MTK_PIN_IES_SMT_SET(40, 41, 0x930, 9),
|
||||
- MTK_PIN_IES_SMT_SET(42, 42, 0x940, 0),
|
||||
- MTK_PIN_IES_SMT_SET(43, 44, 0x930, 11),
|
||||
- MTK_PIN_IES_SMT_SET(45, 46, 0x930, 12),
|
||||
- MTK_PIN_IES_SMT_SET(57, 64, 0xc20, 13),
|
||||
- MTK_PIN_IES_SMT_SET(65, 65, 0xc10, 13),
|
||||
- MTK_PIN_IES_SMT_SET(66, 66, 0xc00, 13),
|
||||
- MTK_PIN_IES_SMT_SET(67, 67, 0xd10, 13),
|
||||
- MTK_PIN_IES_SMT_SET(68, 68, 0xd00, 13),
|
||||
- MTK_PIN_IES_SMT_SET(69, 72, 0x940, 14),
|
||||
- MTK_PIN_IES_SMT_SET(73, 76, 0xc60, 13),
|
||||
- MTK_PIN_IES_SMT_SET(77, 77, 0xc40, 13),
|
||||
- MTK_PIN_IES_SMT_SET(78, 78, 0xc50, 13),
|
||||
- MTK_PIN_IES_SMT_SET(79, 82, 0x940, 15),
|
||||
- MTK_PIN_IES_SMT_SET(83, 83, 0x950, 0),
|
||||
- MTK_PIN_IES_SMT_SET(84, 85, 0x950, 1),
|
||||
- MTK_PIN_IES_SMT_SET(86, 91, 0x950, 2),
|
||||
- MTK_PIN_IES_SMT_SET(92, 92, 0x930, 13),
|
||||
- MTK_PIN_IES_SMT_SET(93, 95, 0x930, 14),
|
||||
- MTK_PIN_IES_SMT_SET(96, 99, 0x930, 15),
|
||||
- MTK_PIN_IES_SMT_SET(100, 103, 0xca0, 13),
|
||||
- MTK_PIN_IES_SMT_SET(104, 104, 0xc80, 13),
|
||||
- MTK_PIN_IES_SMT_SET(105, 105, 0xc90, 13),
|
||||
- MTK_PIN_IES_SMT_SET(106, 107, 0x940, 4),
|
||||
- MTK_PIN_IES_SMT_SET(108, 112, 0x940, 1),
|
||||
- MTK_PIN_IES_SMT_SET(113, 116, 0x940, 2),
|
||||
- MTK_PIN_IES_SMT_SET(117, 118, 0x940, 5),
|
||||
- MTK_PIN_IES_SMT_SET(119, 124, 0x940, 6),
|
||||
- MTK_PIN_IES_SMT_SET(125, 126, 0x940, 7),
|
||||
- MTK_PIN_IES_SMT_SET(127, 127, 0x940, 0),
|
||||
- MTK_PIN_IES_SMT_SET(128, 128, 0x950, 8),
|
||||
- MTK_PIN_IES_SMT_SET(129, 130, 0x950, 9),
|
||||
- MTK_PIN_IES_SMT_SET(131, 132, 0x950, 8),
|
||||
- MTK_PIN_IES_SMT_SET(133, 134, 0x910, 8)
|
||||
+static const struct mtk_pin_ies_smt_set mt8173_smt_set[] = {
|
||||
+ MTK_PIN_IES_SMT_SPEC(0, 4, 0x930, 1),
|
||||
+ MTK_PIN_IES_SMT_SPEC(5, 9, 0x930, 2),
|
||||
+ MTK_PIN_IES_SMT_SPEC(10, 13, 0x930, 10),
|
||||
+ MTK_PIN_IES_SMT_SPEC(14, 15, 0x940, 10),
|
||||
+ MTK_PIN_IES_SMT_SPEC(16, 16, 0x930, 0),
|
||||
+ MTK_PIN_IES_SMT_SPEC(17, 17, 0x950, 2),
|
||||
+ MTK_PIN_IES_SMT_SPEC(18, 21, 0x940, 3),
|
||||
+ MTK_PIN_IES_SMT_SPEC(29, 32, 0x930, 3),
|
||||
+ MTK_PIN_IES_SMT_SPEC(33, 33, 0x930, 4),
|
||||
+ MTK_PIN_IES_SMT_SPEC(34, 36, 0x930, 5),
|
||||
+ MTK_PIN_IES_SMT_SPEC(37, 38, 0x930, 6),
|
||||
+ MTK_PIN_IES_SMT_SPEC(39, 39, 0x930, 7),
|
||||
+ MTK_PIN_IES_SMT_SPEC(40, 41, 0x930, 9),
|
||||
+ MTK_PIN_IES_SMT_SPEC(42, 42, 0x940, 0),
|
||||
+ MTK_PIN_IES_SMT_SPEC(43, 44, 0x930, 11),
|
||||
+ MTK_PIN_IES_SMT_SPEC(45, 46, 0x930, 12),
|
||||
+ MTK_PIN_IES_SMT_SPEC(57, 64, 0xc20, 13),
|
||||
+ MTK_PIN_IES_SMT_SPEC(65, 65, 0xc10, 13),
|
||||
+ MTK_PIN_IES_SMT_SPEC(66, 66, 0xc00, 13),
|
||||
+ MTK_PIN_IES_SMT_SPEC(67, 67, 0xd10, 13),
|
||||
+ MTK_PIN_IES_SMT_SPEC(68, 68, 0xd00, 13),
|
||||
+ MTK_PIN_IES_SMT_SPEC(69, 72, 0x940, 14),
|
||||
+ MTK_PIN_IES_SMT_SPEC(73, 76, 0xc60, 13),
|
||||
+ MTK_PIN_IES_SMT_SPEC(77, 77, 0xc40, 13),
|
||||
+ MTK_PIN_IES_SMT_SPEC(78, 78, 0xc50, 13),
|
||||
+ MTK_PIN_IES_SMT_SPEC(79, 82, 0x940, 15),
|
||||
+ MTK_PIN_IES_SMT_SPEC(83, 83, 0x950, 0),
|
||||
+ MTK_PIN_IES_SMT_SPEC(84, 85, 0x950, 1),
|
||||
+ MTK_PIN_IES_SMT_SPEC(86, 91, 0x950, 2),
|
||||
+ MTK_PIN_IES_SMT_SPEC(92, 92, 0x930, 13),
|
||||
+ MTK_PIN_IES_SMT_SPEC(93, 95, 0x930, 14),
|
||||
+ MTK_PIN_IES_SMT_SPEC(96, 99, 0x930, 15),
|
||||
+ MTK_PIN_IES_SMT_SPEC(100, 103, 0xca0, 13),
|
||||
+ MTK_PIN_IES_SMT_SPEC(104, 104, 0xc80, 13),
|
||||
+ MTK_PIN_IES_SMT_SPEC(105, 105, 0xc90, 13),
|
||||
+ MTK_PIN_IES_SMT_SPEC(106, 107, 0x940, 4),
|
||||
+ MTK_PIN_IES_SMT_SPEC(108, 112, 0x940, 1),
|
||||
+ MTK_PIN_IES_SMT_SPEC(113, 116, 0x940, 2),
|
||||
+ MTK_PIN_IES_SMT_SPEC(117, 118, 0x940, 5),
|
||||
+ MTK_PIN_IES_SMT_SPEC(119, 124, 0x940, 6),
|
||||
+ MTK_PIN_IES_SMT_SPEC(125, 126, 0x940, 7),
|
||||
+ MTK_PIN_IES_SMT_SPEC(127, 127, 0x940, 0),
|
||||
+ MTK_PIN_IES_SMT_SPEC(128, 128, 0x950, 8),
|
||||
+ MTK_PIN_IES_SMT_SPEC(129, 130, 0x950, 9),
|
||||
+ MTK_PIN_IES_SMT_SPEC(131, 132, 0x950, 8),
|
||||
+ MTK_PIN_IES_SMT_SPEC(133, 134, 0x910, 8)
|
||||
};
|
||||
|
||||
-static int spec_ies_smt_set(struct regmap *regmap, unsigned int pin,
|
||||
- unsigned char align, int value)
|
||||
-{
|
||||
- unsigned int i, reg_addr, bit;
|
||||
- bool find = false;
|
||||
-
|
||||
- for (i = 0; i < ARRAY_SIZE(mt8173_ies_smt_set); i++) {
|
||||
- if (pin >= mt8173_ies_smt_set[i].start &&
|
||||
- pin <= mt8173_ies_smt_set[i].end) {
|
||||
- find = true;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (!find)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- if (value)
|
||||
- reg_addr = mt8173_ies_smt_set[i].offset + align;
|
||||
- else
|
||||
- reg_addr = mt8173_ies_smt_set[i].offset + (align << 1);
|
||||
+static const struct mtk_pin_ies_smt_set mt8173_ies_set[] = {
|
||||
+ MTK_PIN_IES_SMT_SPEC(0, 4, 0x900, 1),
|
||||
+ MTK_PIN_IES_SMT_SPEC(5, 9, 0x900, 2),
|
||||
+ MTK_PIN_IES_SMT_SPEC(10, 13, 0x900, 10),
|
||||
+ MTK_PIN_IES_SMT_SPEC(14, 15, 0x910, 10),
|
||||
+ MTK_PIN_IES_SMT_SPEC(16, 16, 0x900, 0),
|
||||
+ MTK_PIN_IES_SMT_SPEC(17, 17, 0x920, 2),
|
||||
+ MTK_PIN_IES_SMT_SPEC(18, 21, 0x910, 3),
|
||||
+ MTK_PIN_IES_SMT_SPEC(29, 32, 0x900, 3),
|
||||
+ MTK_PIN_IES_SMT_SPEC(33, 33, 0x900, 4),
|
||||
+ MTK_PIN_IES_SMT_SPEC(34, 36, 0x900, 5),
|
||||
+ MTK_PIN_IES_SMT_SPEC(37, 38, 0x900, 6),
|
||||
+ MTK_PIN_IES_SMT_SPEC(39, 39, 0x900, 7),
|
||||
+ MTK_PIN_IES_SMT_SPEC(40, 41, 0x900, 9),
|
||||
+ MTK_PIN_IES_SMT_SPEC(42, 42, 0x910, 0),
|
||||
+ MTK_PIN_IES_SMT_SPEC(43, 44, 0x900, 11),
|
||||
+ MTK_PIN_IES_SMT_SPEC(45, 46, 0x900, 12),
|
||||
+ MTK_PIN_IES_SMT_SPEC(57, 64, 0xc20, 14),
|
||||
+ MTK_PIN_IES_SMT_SPEC(65, 65, 0xc10, 14),
|
||||
+ MTK_PIN_IES_SMT_SPEC(66, 66, 0xc00, 14),
|
||||
+ MTK_PIN_IES_SMT_SPEC(67, 67, 0xd10, 14),
|
||||
+ MTK_PIN_IES_SMT_SPEC(68, 68, 0xd00, 14),
|
||||
+ MTK_PIN_IES_SMT_SPEC(69, 72, 0x910, 14),
|
||||
+ MTK_PIN_IES_SMT_SPEC(73, 76, 0xc60, 14),
|
||||
+ MTK_PIN_IES_SMT_SPEC(77, 77, 0xc40, 14),
|
||||
+ MTK_PIN_IES_SMT_SPEC(78, 78, 0xc50, 14),
|
||||
+ MTK_PIN_IES_SMT_SPEC(79, 82, 0x910, 15),
|
||||
+ MTK_PIN_IES_SMT_SPEC(83, 83, 0x920, 0),
|
||||
+ MTK_PIN_IES_SMT_SPEC(84, 85, 0x920, 1),
|
||||
+ MTK_PIN_IES_SMT_SPEC(86, 91, 0x920, 2),
|
||||
+ MTK_PIN_IES_SMT_SPEC(92, 92, 0x900, 13),
|
||||
+ MTK_PIN_IES_SMT_SPEC(93, 95, 0x900, 14),
|
||||
+ MTK_PIN_IES_SMT_SPEC(96, 99, 0x900, 15),
|
||||
+ MTK_PIN_IES_SMT_SPEC(100, 103, 0xca0, 14),
|
||||
+ MTK_PIN_IES_SMT_SPEC(104, 104, 0xc80, 14),
|
||||
+ MTK_PIN_IES_SMT_SPEC(105, 105, 0xc90, 14),
|
||||
+ MTK_PIN_IES_SMT_SPEC(106, 107, 0x91, 4),
|
||||
+ MTK_PIN_IES_SMT_SPEC(108, 112, 0x910, 1),
|
||||
+ MTK_PIN_IES_SMT_SPEC(113, 116, 0x910, 2),
|
||||
+ MTK_PIN_IES_SMT_SPEC(117, 118, 0x910, 5),
|
||||
+ MTK_PIN_IES_SMT_SPEC(119, 124, 0x910, 6),
|
||||
+ MTK_PIN_IES_SMT_SPEC(125, 126, 0x910, 7),
|
||||
+ MTK_PIN_IES_SMT_SPEC(127, 127, 0x910, 0),
|
||||
+ MTK_PIN_IES_SMT_SPEC(128, 128, 0x920, 8),
|
||||
+ MTK_PIN_IES_SMT_SPEC(129, 130, 0x920, 9),
|
||||
+ MTK_PIN_IES_SMT_SPEC(131, 132, 0x920, 8),
|
||||
+ MTK_PIN_IES_SMT_SPEC(133, 134, 0x910, 8)
|
||||
+};
|
||||
|
||||
- bit = BIT(mt8173_ies_smt_set[i].bit);
|
||||
- regmap_write(regmap, reg_addr, bit);
|
||||
- return 0;
|
||||
+static int mt8173_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, mt8173_ies_set,
|
||||
+ ARRAY_SIZE(mt8173_ies_set), pin, align, value);
|
||||
+ else if (arg == PIN_CONFIG_INPUT_SCHMITT_ENABLE)
|
||||
+ return mtk_pconf_spec_set_ies_smt_range(regmap, mt8173_smt_set,
|
||||
+ ARRAY_SIZE(mt8173_smt_set), pin, align, value);
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
static const struct mtk_drv_group_desc mt8173_drv_grp[] = {
|
||||
@@ -307,7 +320,7 @@ static const struct mtk_pinctrl_devdata mt8173_pinctrl_data = {
|
||||
.pin_drv_grp = mt8173_pin_drv,
|
||||
.n_pin_drv_grps = ARRAY_SIZE(mt8173_pin_drv),
|
||||
.spec_pull_set = mt8173_spec_pull_set,
|
||||
- .spec_ies_smt_set = spec_ies_smt_set,
|
||||
+ .spec_ies_smt_set = mt8173_ies_smt_set,
|
||||
.dir_offset = 0x0000,
|
||||
.pullen_offset = 0x0100,
|
||||
.pullsel_offset = 0x0200,
|
||||
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
|
||||
index 0d51145..97fe2ab 100644
|
||||
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
|
||||
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
|
||||
@@ -107,28 +107,38 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
regmap_write(mtk_get_regmap(pctl, offset), reg_addr, bit);
|
||||
}
|
||||
|
||||
-static void mtk_pconf_set_ies_smt(struct mtk_pinctrl *pctl, unsigned pin,
|
||||
- int value, enum pin_config_param param)
|
||||
+static int mtk_pconf_set_ies_smt(struct mtk_pinctrl *pctl, unsigned pin,
|
||||
+ int value, enum pin_config_param arg)
|
||||
{
|
||||
unsigned int reg_addr, offset;
|
||||
unsigned int bit;
|
||||
- int ret;
|
||||
+
|
||||
+ /**
|
||||
+ * Due to some soc are not support ies/smt config, add this special
|
||||
+ * control to handle it.
|
||||
+ */
|
||||
+ if (!pctl->devdata->spec_ies_smt_set &&
|
||||
+ pctl->devdata->ies_offset == MTK_PINCTRL_NOT_SUPPORT &&
|
||||
+ arg == PIN_CONFIG_INPUT_ENABLE)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (!pctl->devdata->spec_ies_smt_set &&
|
||||
+ pctl->devdata->smt_offset == MTK_PINCTRL_NOT_SUPPORT &&
|
||||
+ arg == PIN_CONFIG_INPUT_SCHMITT_ENABLE)
|
||||
+ return -EINVAL;
|
||||
|
||||
/*
|
||||
* Due to some pins are irregular, their input enable and smt
|
||||
- * control register are discontinuous, but they are mapping together.
|
||||
- * So we need this special handle.
|
||||
+ * control register are discontinuous, so we need this special handle.
|
||||
*/
|
||||
if (pctl->devdata->spec_ies_smt_set) {
|
||||
- ret = pctl->devdata->spec_ies_smt_set(mtk_get_regmap(pctl, pin),
|
||||
- pin, pctl->devdata->port_align, value);
|
||||
- if (!ret)
|
||||
- return;
|
||||
+ return pctl->devdata->spec_ies_smt_set(mtk_get_regmap(pctl, pin),
|
||||
+ pin, pctl->devdata->port_align, value, arg);
|
||||
}
|
||||
|
||||
bit = BIT(pin & 0xf);
|
||||
|
||||
- if (param == PIN_CONFIG_INPUT_ENABLE)
|
||||
+ if (arg == PIN_CONFIG_INPUT_ENABLE)
|
||||
offset = pctl->devdata->ies_offset;
|
||||
else
|
||||
offset = pctl->devdata->smt_offset;
|
||||
@@ -139,6 +149,33 @@ static void mtk_pconf_set_ies_smt(struct mtk_pinctrl *pctl, unsigned pin,
|
||||
reg_addr = CLR_ADDR(mtk_get_port(pctl, pin) + offset, pctl);
|
||||
|
||||
regmap_write(mtk_get_regmap(pctl, pin), reg_addr, bit);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int mtk_pconf_spec_set_ies_smt_range(struct regmap *regmap,
|
||||
+ const struct mtk_pin_ies_smt_set *ies_smt_infos, unsigned int info_num,
|
||||
+ unsigned int pin, unsigned char align, int value)
|
||||
+{
|
||||
+ unsigned int i, reg_addr, bit;
|
||||
+
|
||||
+ for (i = 0; i < info_num; i++) {
|
||||
+ if (pin >= ies_smt_infos[i].start &&
|
||||
+ pin <= ies_smt_infos[i].end) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (i == info_num)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (value)
|
||||
+ reg_addr = ies_smt_infos[i].offset + align;
|
||||
+ else
|
||||
+ reg_addr = ies_smt_infos[i].offset + (align << 1);
|
||||
+
|
||||
+ bit = BIT(ies_smt_infos[i].bit);
|
||||
+ regmap_write(regmap, reg_addr, bit);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static const struct mtk_pin_drv_grp *mtk_find_pin_drv_grp_by_pin(
|
||||
@@ -295,36 +332,37 @@ static int mtk_pconf_parse_conf(struct pinctrl_dev *pctldev,
|
||||
unsigned int pin, enum pin_config_param param,
|
||||
enum pin_config_param arg)
|
||||
{
|
||||
+ int ret = 0;
|
||||
struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_BIAS_DISABLE:
|
||||
- mtk_pconf_set_pull_select(pctl, pin, false, false, arg);
|
||||
+ ret = mtk_pconf_set_pull_select(pctl, pin, false, false, arg);
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
- mtk_pconf_set_pull_select(pctl, pin, true, true, arg);
|
||||
+ ret = mtk_pconf_set_pull_select(pctl, pin, true, true, arg);
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
- mtk_pconf_set_pull_select(pctl, pin, true, false, arg);
|
||||
+ ret = mtk_pconf_set_pull_select(pctl, pin, true, false, arg);
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_ENABLE:
|
||||
- mtk_pconf_set_ies_smt(pctl, pin, arg, param);
|
||||
+ ret = mtk_pconf_set_ies_smt(pctl, pin, arg, param);
|
||||
break;
|
||||
case PIN_CONFIG_OUTPUT:
|
||||
mtk_gpio_set(pctl->chip, pin, arg);
|
||||
- mtk_pmx_gpio_set_direction(pctldev, NULL, pin, false);
|
||||
+ ret = mtk_pmx_gpio_set_direction(pctldev, NULL, pin, false);
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
|
||||
- mtk_pconf_set_ies_smt(pctl, pin, arg, param);
|
||||
+ ret = mtk_pconf_set_ies_smt(pctl, pin, arg, param);
|
||||
break;
|
||||
case PIN_CONFIG_DRIVE_STRENGTH:
|
||||
- mtk_pconf_set_driving(pctl, pin, arg);
|
||||
+ ret = mtk_pconf_set_driving(pctl, pin, arg);
|
||||
break;
|
||||
default:
|
||||
- return -EINVAL;
|
||||
+ ret = -EINVAL;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int mtk_pconf_group_get(struct pinctrl_dev *pctldev,
|
||||
@@ -343,12 +381,14 @@ static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group,
|
||||
{
|
||||
struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
|
||||
struct mtk_pinctrl_group *g = &pctl->groups[group];
|
||||
- int i;
|
||||
+ int i, ret;
|
||||
|
||||
for (i = 0; i < num_configs; i++) {
|
||||
- mtk_pconf_parse_conf(pctldev, g->pin,
|
||||
+ ret = mtk_pconf_parse_conf(pctldev, g->pin,
|
||||
pinconf_to_config_param(configs[i]),
|
||||
pinconf_to_config_argument(configs[i]));
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
|
||||
g->config = configs[i];
|
||||
}
|
||||
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
|
||||
index 2a4b7be..c703e7d 100644
|
||||
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
|
||||
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/regmap.h>
|
||||
+#include <linux/pinctrl/pinconf-generic.h>
|
||||
|
||||
#define NO_EINT_SUPPORT 255
|
||||
#define MT_EDGE_SENSITIVE 0
|
||||
@@ -25,6 +26,8 @@
|
||||
#define EINT_DBNC_RST_BIT (0x1 << 1)
|
||||
#define EINT_DBNC_SET_EN (0x1 << 0)
|
||||
|
||||
+#define MTK_PINCTRL_NOT_SUPPORT (0xffff)
|
||||
+
|
||||
struct mtk_desc_function {
|
||||
const char *name;
|
||||
unsigned char muxval;
|
||||
@@ -143,6 +146,28 @@ struct mtk_pin_spec_pupd_set_samereg {
|
||||
.r0_bit = _r0, \
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * struct mtk_pin_ies_set - For special pins' ies and smt setting.
|
||||
+ * @start: The start pin number of those special pins.
|
||||
+ * @end: The end pin number of those special pins.
|
||||
+ * @offset: The offset of special setting register.
|
||||
+ * @bit: The bit of special setting register.
|
||||
+ */
|
||||
+struct mtk_pin_ies_smt_set {
|
||||
+ unsigned short start;
|
||||
+ unsigned short end;
|
||||
+ unsigned short offset;
|
||||
+ unsigned char bit;
|
||||
+};
|
||||
+
|
||||
+#define MTK_PIN_IES_SMT_SPEC(_start, _end, _offset, _bit) \
|
||||
+ { \
|
||||
+ .start = _start, \
|
||||
+ .end = _end, \
|
||||
+ .bit = _bit, \
|
||||
+ .offset = _offset, \
|
||||
+ }
|
||||
+
|
||||
struct mtk_eint_offsets {
|
||||
const char *name;
|
||||
unsigned int stat;
|
||||
@@ -208,7 +233,7 @@ struct mtk_pinctrl_devdata {
|
||||
int (*spec_pull_set)(struct regmap *reg, unsigned int pin,
|
||||
unsigned char align, bool isup, unsigned int arg);
|
||||
int (*spec_ies_smt_set)(struct regmap *reg, unsigned int pin,
|
||||
- unsigned char align, int value);
|
||||
+ unsigned char align, int value, enum pin_config_param arg);
|
||||
unsigned int dir_offset;
|
||||
unsigned int ies_offset;
|
||||
unsigned int smt_offset;
|
||||
@@ -251,4 +276,8 @@ int mtk_pctrl_spec_pull_set_samereg(struct regmap *regmap,
|
||||
unsigned int info_num, unsigned int pin,
|
||||
unsigned char align, bool isup, unsigned int r1r0);
|
||||
|
||||
+int mtk_pconf_spec_set_ies_smt_range(struct regmap *regmap,
|
||||
+ const struct mtk_pin_ies_smt_set *ies_smt_infos, unsigned int info_num,
|
||||
+ unsigned int pin, unsigned char align, int value);
|
||||
+
|
||||
#endif /* __PINCTRL_MTK_COMMON_H */
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,654 @@
|
||||
From 3031cefd8cd323e04be11a8058616d8cf21c1313 Mon Sep 17 00:00:00 2001
|
||||
From: Hongzhou Yang <hongzhou.yang@mediatek.com>
|
||||
Date: Mon, 18 May 2015 23:11:17 -0700
|
||||
Subject: [PATCH 53/76] pinctrl: mediatek: Add Pinctrl/GPIO driver for mt6397.
|
||||
|
||||
Add mt6397 support using mediatek common pinctrl driver.
|
||||
|
||||
mt6397 is a PMIC, and pinctrl/GPIO is part of 6397 chip.
|
||||
Pinctrl/GPIO driver should obtain regmap from PMIC,
|
||||
so adding this support to common code.
|
||||
|
||||
Also, mt6397 is no need to support interrupt controller,
|
||||
so changing common code to skip it.
|
||||
|
||||
Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com>
|
||||
---
|
||||
drivers/pinctrl/mediatek/Kconfig | 6 +
|
||||
drivers/pinctrl/mediatek/Makefile | 1 +
|
||||
drivers/pinctrl/mediatek/pinctrl-mt6397.c | 78 +++++
|
||||
drivers/pinctrl/mediatek/pinctrl-mt8135.c | 2 +-
|
||||
drivers/pinctrl/mediatek/pinctrl-mt8173.c | 2 +-
|
||||
drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 13 +-
|
||||
drivers/pinctrl/mediatek/pinctrl-mtk-common.h | 3 +-
|
||||
drivers/pinctrl/mediatek/pinctrl-mtk-mt6397.h | 424 +++++++++++++++++++++++++
|
||||
8 files changed, 524 insertions(+), 5 deletions(-)
|
||||
create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt6397.c
|
||||
create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt6397.h
|
||||
|
||||
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
|
||||
index 6b3551c..ddae479 100644
|
||||
--- a/drivers/pinctrl/mediatek/Kconfig
|
||||
+++ b/drivers/pinctrl/mediatek/Kconfig
|
||||
@@ -23,4 +23,10 @@ config PINCTRL_MT8173
|
||||
default ARM64 && ARCH_MEDIATEK
|
||||
select PINCTRL_MTK_COMMON
|
||||
|
||||
+# For PMIC
|
||||
+config PINCTRL_MT6397
|
||||
+ bool "Mediatek MT6397 pin control" if COMPILE_TEST && !MFD_MT6397
|
||||
+ default MFD_MT6397
|
||||
+ select PINCTRL_MTK_COMMON
|
||||
+
|
||||
endif
|
||||
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
|
||||
index d8606a2..ad0180c 100644
|
||||
--- a/drivers/pinctrl/mediatek/Makefile
|
||||
+++ b/drivers/pinctrl/mediatek/Makefile
|
||||
@@ -4,3 +4,4 @@ obj-$(CONFIG_PINCTRL_MTK_COMMON) += pinctrl-mtk-common.o
|
||||
# SoC Drivers
|
||||
obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o
|
||||
obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
|
||||
+obj-$(CONFIG_PINCTRL_MT6397) += pinctrl-mt6397.o
|
||||
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6397.c b/drivers/pinctrl/mediatek/pinctrl-mt6397.c
|
||||
new file mode 100644
|
||||
index 0000000..767bbdf
|
||||
--- /dev/null
|
||||
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6397.c
|
||||
@@ -0,0 +1,78 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015 MediaTek Inc.
|
||||
+ * Author: Hongzhou.Yang <hongzhou.yang@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/pinctrl/pinctrl.h>
|
||||
+#include <linux/pinctrl/pinconf-generic.h>
|
||||
+#include <linux/mfd/mt6397/core.h>
|
||||
+
|
||||
+#include "pinctrl-mtk-common.h"
|
||||
+#include "pinctrl-mtk-mt6397.h"
|
||||
+
|
||||
+#define MT6397_PIN_REG_BASE 0xc000
|
||||
+
|
||||
+static const struct mtk_pinctrl_devdata mt6397_pinctrl_data = {
|
||||
+ .pins = mtk_pins_mt6397,
|
||||
+ .npins = ARRAY_SIZE(mtk_pins_mt6397),
|
||||
+ .dir_offset = (MT6397_PIN_REG_BASE + 0x000),
|
||||
+ .ies_offset = MTK_PINCTRL_NOT_SUPPORT,
|
||||
+ .smt_offset = MTK_PINCTRL_NOT_SUPPORT,
|
||||
+ .pullen_offset = (MT6397_PIN_REG_BASE + 0x020),
|
||||
+ .pullsel_offset = (MT6397_PIN_REG_BASE + 0x040),
|
||||
+ .dout_offset = (MT6397_PIN_REG_BASE + 0x080),
|
||||
+ .din_offset = (MT6397_PIN_REG_BASE + 0x0a0),
|
||||
+ .pinmux_offset = (MT6397_PIN_REG_BASE + 0x0c0),
|
||||
+ .type1_start = 41,
|
||||
+ .type1_end = 41,
|
||||
+ .port_shf = 3,
|
||||
+ .port_mask = 0x3,
|
||||
+ .port_align = 2,
|
||||
+};
|
||||
+
|
||||
+static int mt6397_pinctrl_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mt6397_chip *mt6397;
|
||||
+
|
||||
+ mt6397 = dev_get_drvdata(pdev->dev.parent);
|
||||
+ return mtk_pctrl_init(pdev, &mt6397_pinctrl_data, mt6397->regmap);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mt6397_pctrl_match[] = {
|
||||
+ { .compatible = "mediatek,mt6397-pinctrl", },
|
||||
+ { }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mt6397_pctrl_match);
|
||||
+
|
||||
+static struct platform_driver mtk_pinctrl_driver = {
|
||||
+ .probe = mt6397_pinctrl_probe,
|
||||
+ .driver = {
|
||||
+ .name = "mediatek-mt6397-pinctrl",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = mt6397_pctrl_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init mtk_pinctrl_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&mtk_pinctrl_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(mtk_pinctrl_init);
|
||||
+
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
+MODULE_DESCRIPTION("MediaTek MT6397 Pinctrl Driver");
|
||||
+MODULE_AUTHOR("Hongzhou Yang <hongzhou.yang@mediatek.com>");
|
||||
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8135.c b/drivers/pinctrl/mediatek/pinctrl-mt8135.c
|
||||
index 8e6abd5..203bd2a 100644
|
||||
--- a/drivers/pinctrl/mediatek/pinctrl-mt8135.c
|
||||
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8135.c
|
||||
@@ -342,7 +342,7 @@ static const struct mtk_pinctrl_devdata mt8135_pinctrl_data = {
|
||||
|
||||
static int mt8135_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
- return mtk_pctrl_init(pdev, &mt8135_pinctrl_data);
|
||||
+ return mtk_pctrl_init(pdev, &mt8135_pinctrl_data, NULL);
|
||||
}
|
||||
|
||||
static const struct of_device_id mt8135_pctrl_match[] = {
|
||||
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
|
||||
index a7e5b24..cf4ed6e 100644
|
||||
--- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
|
||||
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
|
||||
@@ -361,7 +361,7 @@ static const struct mtk_pinctrl_devdata mt8173_pinctrl_data = {
|
||||
|
||||
static int mt8173_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
- return mtk_pctrl_init(pdev, &mt8173_pinctrl_data);
|
||||
+ return mtk_pctrl_init(pdev, &mt8173_pinctrl_data, NULL);
|
||||
}
|
||||
|
||||
static const struct of_device_id mt8173_pctrl_match[] = {
|
||||
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
|
||||
index 97fe2ab..e772cef 100644
|
||||
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
|
||||
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
|
||||
@@ -1209,7 +1209,8 @@ static struct pinctrl_desc mtk_pctrl_desc = {
|
||||
};
|
||||
|
||||
int mtk_pctrl_init(struct platform_device *pdev,
|
||||
- const struct mtk_pinctrl_devdata *data)
|
||||
+ const struct mtk_pinctrl_devdata *data,
|
||||
+ struct regmap *regmap)
|
||||
{
|
||||
struct pinctrl_pin_desc *pins;
|
||||
struct mtk_pinctrl *pctl;
|
||||
@@ -1235,6 +1236,11 @@ int mtk_pctrl_init(struct platform_device *pdev,
|
||||
pctl->regmap1 = syscon_node_to_regmap(node);
|
||||
if (IS_ERR(pctl->regmap1))
|
||||
return PTR_ERR(pctl->regmap1);
|
||||
+ } else if (regmap) {
|
||||
+ pctl->regmap1 = regmap;
|
||||
+ } else {
|
||||
+ dev_err(&pdev->dev, "Pinctrl node has not register regmap.\n");
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
/* Only 8135 has two base addr, other SoCs have only one. */
|
||||
@@ -1280,7 +1286,7 @@ int mtk_pctrl_init(struct platform_device *pdev,
|
||||
pctl->chip->ngpio = pctl->devdata->npins;
|
||||
pctl->chip->label = dev_name(&pdev->dev);
|
||||
pctl->chip->dev = &pdev->dev;
|
||||
- pctl->chip->base = 0;
|
||||
+ pctl->chip->base = -1;
|
||||
|
||||
ret = gpiochip_add(pctl->chip);
|
||||
if (ret) {
|
||||
@@ -1296,6 +1302,9 @@ int mtk_pctrl_init(struct platform_device *pdev,
|
||||
goto chip_error;
|
||||
}
|
||||
|
||||
+ if (of_find_property(np, "interrupt-controller", NULL))
|
||||
+ return 0;
|
||||
+
|
||||
/* Get EINT register base from dts. */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
|
||||
index c703e7d..30213e5 100644
|
||||
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
|
||||
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
|
||||
@@ -269,7 +269,8 @@ struct mtk_pinctrl {
|
||||
};
|
||||
|
||||
int mtk_pctrl_init(struct platform_device *pdev,
|
||||
- const struct mtk_pinctrl_devdata *data);
|
||||
+ const struct mtk_pinctrl_devdata *data,
|
||||
+ struct regmap *regmap);
|
||||
|
||||
int mtk_pctrl_spec_pull_set_samereg(struct regmap *regmap,
|
||||
const struct mtk_pin_spec_pupd_set_samereg *pupd_infos,
|
||||
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-mt6397.h b/drivers/pinctrl/mediatek/pinctrl-mtk-mt6397.h
|
||||
new file mode 100644
|
||||
index 0000000..4eb98dd
|
||||
--- /dev/null
|
||||
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-mt6397.h
|
||||
@@ -0,0 +1,424 @@
|
||||
+#ifndef __PINCTRL_MTK_MT6397_H
|
||||
+#define __PINCTRL_MTK_MT6397_H
|
||||
+
|
||||
+#include <linux/pinctrl/pinctrl.h>
|
||||
+#include "pinctrl-mtk-common.h"
|
||||
+
|
||||
+static const struct mtk_desc_pin mtk_pins_mt6397[] = {
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(0, "INT"),
|
||||
+ "N2", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
|
||||
+ MTK_FUNCTION(0, "GPIO0"),
|
||||
+ MTK_FUNCTION(1, "INT")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(1, "SRCVOLTEN"),
|
||||
+ "M4", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
|
||||
+ MTK_FUNCTION(0, "GPIO1"),
|
||||
+ MTK_FUNCTION(1, "SRCVOLTEN"),
|
||||
+ MTK_FUNCTION(6, "TEST_CK1")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(2, "SRCLKEN_PERI"),
|
||||
+ "M2", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
|
||||
+ MTK_FUNCTION(0, "GPIO2"),
|
||||
+ MTK_FUNCTION(1, "SRCLKEN_PERI"),
|
||||
+ MTK_FUNCTION(6, "TEST_CK2")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(3, "RTC_32K1V8"),
|
||||
+ "K3", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
|
||||
+ MTK_FUNCTION(0, "GPIO3"),
|
||||
+ MTK_FUNCTION(1, "RTC_32K1V8"),
|
||||
+ MTK_FUNCTION(6, "TEST_CK3")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(4, "WRAP_EVENT"),
|
||||
+ "J2", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
|
||||
+ MTK_FUNCTION(0, "GPIO4"),
|
||||
+ MTK_FUNCTION(1, "WRAP_EVENT")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(5, "SPI_CLK"),
|
||||
+ "L4", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
|
||||
+ MTK_FUNCTION(0, "GPIO5"),
|
||||
+ MTK_FUNCTION(1, "SPI_CLK")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(6, "SPI_CSN"),
|
||||
+ "J3", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
|
||||
+ MTK_FUNCTION(0, "GPIO6"),
|
||||
+ MTK_FUNCTION(1, "SPI_CSN")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(7, "SPI_MOSI"),
|
||||
+ "J1", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
|
||||
+ MTK_FUNCTION(0, "GPIO7"),
|
||||
+ MTK_FUNCTION(1, "SPI_MOSI")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(8, "SPI_MISO"),
|
||||
+ "L3", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
|
||||
+ MTK_FUNCTION(0, "GPIO8"),
|
||||
+ MTK_FUNCTION(1, "SPI_MISO")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(9, "AUD_CLK_MOSI"),
|
||||
+ "H2", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
|
||||
+ MTK_FUNCTION(0, "GPIO9"),
|
||||
+ MTK_FUNCTION(1, "AUD_CLK"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN0"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT0")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(10, "AUD_DAT_MISO"),
|
||||
+ "H3", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
|
||||
+ MTK_FUNCTION(0, "GPIO10"),
|
||||
+ MTK_FUNCTION(1, "AUD_MISO"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN1"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT1")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(11, "AUD_DAT_MOSI"),
|
||||
+ "H1", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
|
||||
+ MTK_FUNCTION(0, "GPIO11"),
|
||||
+ MTK_FUNCTION(1, "AUD_MOSI"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN2"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT2")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(12, "COL0"),
|
||||
+ "F3", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 10),
|
||||
+ MTK_FUNCTION(0, "GPIO12"),
|
||||
+ MTK_FUNCTION(1, "COL0_USBDL"),
|
||||
+ MTK_FUNCTION(2, "EINT10_1X"),
|
||||
+ MTK_FUNCTION(3, "PWM1_3X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN3"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT3")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(13, "COL1"),
|
||||
+ "G8", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 11),
|
||||
+ MTK_FUNCTION(0, "GPIO13"),
|
||||
+ MTK_FUNCTION(1, "COL1"),
|
||||
+ MTK_FUNCTION(2, "EINT11_1X"),
|
||||
+ MTK_FUNCTION(3, "SCL0_2X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN4"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT4")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(14, "COL2"),
|
||||
+ "H4", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 12),
|
||||
+ MTK_FUNCTION(0, "GPIO14"),
|
||||
+ MTK_FUNCTION(1, "COL2"),
|
||||
+ MTK_FUNCTION(2, "EINT12_1X"),
|
||||
+ MTK_FUNCTION(3, "SDA0_2X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN5"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT5")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(15, "COL3"),
|
||||
+ "G2", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 13),
|
||||
+ MTK_FUNCTION(0, "GPIO15"),
|
||||
+ MTK_FUNCTION(1, "COL3"),
|
||||
+ MTK_FUNCTION(2, "EINT13_1X"),
|
||||
+ MTK_FUNCTION(3, "SCL1_2X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN6"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT6")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(16, "COL4"),
|
||||
+ "F2", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 14),
|
||||
+ MTK_FUNCTION(0, "GPIO16"),
|
||||
+ MTK_FUNCTION(1, "COL4"),
|
||||
+ MTK_FUNCTION(2, "EINT14_1X"),
|
||||
+ MTK_FUNCTION(3, "SDA1_2X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN7"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT7")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(17, "COL5"),
|
||||
+ "G7", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 15),
|
||||
+ MTK_FUNCTION(0, "GPIO17"),
|
||||
+ MTK_FUNCTION(1, "COL5"),
|
||||
+ MTK_FUNCTION(2, "EINT15_1X"),
|
||||
+ MTK_FUNCTION(3, "SCL2_2X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN8"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT8")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(18, "COL6"),
|
||||
+ "J6", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 16),
|
||||
+ MTK_FUNCTION(0, "GPIO18"),
|
||||
+ MTK_FUNCTION(1, "COL6"),
|
||||
+ MTK_FUNCTION(2, "EINT16_1X"),
|
||||
+ MTK_FUNCTION(3, "SDA2_2X"),
|
||||
+ MTK_FUNCTION(4, "GPIO32K_0"),
|
||||
+ MTK_FUNCTION(5, "GPIO26M_0"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN9"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT9")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(19, "COL7"),
|
||||
+ "J5", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 17),
|
||||
+ MTK_FUNCTION(0, "GPIO19"),
|
||||
+ MTK_FUNCTION(1, "COL7"),
|
||||
+ MTK_FUNCTION(2, "EINT17_1X"),
|
||||
+ MTK_FUNCTION(3, "PWM2_3X"),
|
||||
+ MTK_FUNCTION(4, "GPIO32K_1"),
|
||||
+ MTK_FUNCTION(5, "GPIO26M_1"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN10"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT10")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(20, "ROW0"),
|
||||
+ "L7", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 18),
|
||||
+ MTK_FUNCTION(0, "GPIO20"),
|
||||
+ MTK_FUNCTION(1, "ROW0"),
|
||||
+ MTK_FUNCTION(2, "EINT18_1X"),
|
||||
+ MTK_FUNCTION(3, "SCL0_3X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN11"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT11")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(21, "ROW1"),
|
||||
+ "P1", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 19),
|
||||
+ MTK_FUNCTION(0, "GPIO21"),
|
||||
+ MTK_FUNCTION(1, "ROW1"),
|
||||
+ MTK_FUNCTION(2, "EINT19_1X"),
|
||||
+ MTK_FUNCTION(3, "SDA0_3X"),
|
||||
+ MTK_FUNCTION(4, "AUD_TSTCK"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN12"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT12")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(22, "ROW2"),
|
||||
+ "J8", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 20),
|
||||
+ MTK_FUNCTION(0, "GPIO22"),
|
||||
+ MTK_FUNCTION(1, "ROW2"),
|
||||
+ MTK_FUNCTION(2, "EINT20_1X"),
|
||||
+ MTK_FUNCTION(3, "SCL1_3X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN13"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT13")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(23, "ROW3"),
|
||||
+ "J7", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 21),
|
||||
+ MTK_FUNCTION(0, "GPIO23"),
|
||||
+ MTK_FUNCTION(1, "ROW3"),
|
||||
+ MTK_FUNCTION(2, "EINT21_1X"),
|
||||
+ MTK_FUNCTION(3, "SDA1_3X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN14"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT14")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(24, "ROW4"),
|
||||
+ "L5", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 22),
|
||||
+ MTK_FUNCTION(0, "GPIO24"),
|
||||
+ MTK_FUNCTION(1, "ROW4"),
|
||||
+ MTK_FUNCTION(2, "EINT22_1X"),
|
||||
+ MTK_FUNCTION(3, "SCL2_3X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN15"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT15")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(25, "ROW5"),
|
||||
+ "N6", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 23),
|
||||
+ MTK_FUNCTION(0, "GPIO25"),
|
||||
+ MTK_FUNCTION(1, "ROW5"),
|
||||
+ MTK_FUNCTION(2, "EINT23_1X"),
|
||||
+ MTK_FUNCTION(3, "SDA2_3X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN16"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT16")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(26, "ROW6"),
|
||||
+ "L6", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 24),
|
||||
+ MTK_FUNCTION(0, "GPIO26"),
|
||||
+ MTK_FUNCTION(1, "ROW6"),
|
||||
+ MTK_FUNCTION(2, "EINT24_1X"),
|
||||
+ MTK_FUNCTION(3, "PWM3_3X"),
|
||||
+ MTK_FUNCTION(4, "GPIO32K_2"),
|
||||
+ MTK_FUNCTION(5, "GPIO26M_2"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN17"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT17")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(27, "ROW7"),
|
||||
+ "P2", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 3),
|
||||
+ MTK_FUNCTION(0, "GPIO27"),
|
||||
+ MTK_FUNCTION(1, "ROW7"),
|
||||
+ MTK_FUNCTION(2, "EINT3_1X"),
|
||||
+ MTK_FUNCTION(3, "CBUS"),
|
||||
+ MTK_FUNCTION(4, "GPIO32K_3"),
|
||||
+ MTK_FUNCTION(5, "GPIO26M_3"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN18"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT18")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(28, "PWM1(VMSEL1)"),
|
||||
+ "J4", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 4),
|
||||
+ MTK_FUNCTION(0, "GPIO28"),
|
||||
+ MTK_FUNCTION(1, "PWM1"),
|
||||
+ MTK_FUNCTION(2, "EINT4_1X"),
|
||||
+ MTK_FUNCTION(4, "GPIO32K_4"),
|
||||
+ MTK_FUNCTION(5, "GPIO26M_4"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN19"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT19")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(29, "PWM2(VMSEL2)"),
|
||||
+ "N5", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 5),
|
||||
+ MTK_FUNCTION(0, "GPIO29"),
|
||||
+ MTK_FUNCTION(1, "PWM2"),
|
||||
+ MTK_FUNCTION(2, "EINT5_1X"),
|
||||
+ MTK_FUNCTION(4, "GPIO32K_5"),
|
||||
+ MTK_FUNCTION(5, "GPIO26M_5"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN20"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT20")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(30, "PWM3(PWM)"),
|
||||
+ "R3", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 6),
|
||||
+ MTK_FUNCTION(0, "GPIO30"),
|
||||
+ MTK_FUNCTION(1, "PWM3"),
|
||||
+ MTK_FUNCTION(2, "EINT6_1X"),
|
||||
+ MTK_FUNCTION(3, "COL0"),
|
||||
+ MTK_FUNCTION(4, "GPIO32K_6"),
|
||||
+ MTK_FUNCTION(5, "GPIO26M_6"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN21"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT21")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(31, "SCL0"),
|
||||
+ "N1", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 7),
|
||||
+ MTK_FUNCTION(0, "GPIO31"),
|
||||
+ MTK_FUNCTION(1, "SCL0"),
|
||||
+ MTK_FUNCTION(2, "EINT7_1X"),
|
||||
+ MTK_FUNCTION(3, "PWM1_2X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN22"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT22")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(32, "SDA0"),
|
||||
+ "N3", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 8),
|
||||
+ MTK_FUNCTION(0, "GPIO32"),
|
||||
+ MTK_FUNCTION(1, "SDA0"),
|
||||
+ MTK_FUNCTION(2, "EINT8_1X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN23"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT23")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(33, "SCL1"),
|
||||
+ "T1", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 9),
|
||||
+ MTK_FUNCTION(0, "GPIO33"),
|
||||
+ MTK_FUNCTION(1, "SCL1"),
|
||||
+ MTK_FUNCTION(2, "EINT9_1X"),
|
||||
+ MTK_FUNCTION(3, "PWM2_2X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN24"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT24")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(34, "SDA1"),
|
||||
+ "T2", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 0),
|
||||
+ MTK_FUNCTION(0, "GPIO34"),
|
||||
+ MTK_FUNCTION(1, "SDA1"),
|
||||
+ MTK_FUNCTION(2, "EINT0_1X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN25"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT25")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(35, "SCL2"),
|
||||
+ "T3", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 1),
|
||||
+ MTK_FUNCTION(0, "GPIO35"),
|
||||
+ MTK_FUNCTION(1, "SCL2"),
|
||||
+ MTK_FUNCTION(2, "EINT1_1X"),
|
||||
+ MTK_FUNCTION(3, "PWM3_2X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN26"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT26")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(36, "SDA2"),
|
||||
+ "U2", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(2, 2),
|
||||
+ MTK_FUNCTION(0, "GPIO36"),
|
||||
+ MTK_FUNCTION(1, "SDA2"),
|
||||
+ MTK_FUNCTION(2, "EINT2_1X"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN27"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT27")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(37, "HDMISD"),
|
||||
+ "H6", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
|
||||
+ MTK_FUNCTION(0, "GPIO37"),
|
||||
+ MTK_FUNCTION(1, "HDMISD"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN28"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT28")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(38, "HDMISCK"),
|
||||
+ "H5", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
|
||||
+ MTK_FUNCTION(0, "GPIO38"),
|
||||
+ MTK_FUNCTION(1, "HDMISCK"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN29"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT29")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(39, "HTPLG"),
|
||||
+ "H7", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
|
||||
+ MTK_FUNCTION(0, "GPIO39"),
|
||||
+ MTK_FUNCTION(1, "HTPLG"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN30"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT30")
|
||||
+ ),
|
||||
+ MTK_PIN(
|
||||
+ PINCTRL_PIN(40, "CEC"),
|
||||
+ "J9", "mt6397",
|
||||
+ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT),
|
||||
+ MTK_FUNCTION(0, "GPIO40"),
|
||||
+ MTK_FUNCTION(1, "CEC"),
|
||||
+ MTK_FUNCTION(6, "TEST_IN31"),
|
||||
+ MTK_FUNCTION(7, "TEST_OUT31")
|
||||
+ ),
|
||||
+};
|
||||
+
|
||||
+#endif /* __PINCTRL_MTK_MT6397_H */
|
||||
--
|
||||
1.7.10.4
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,30 @@
|
||||
From e5de6556a25d4b2e2d30683d629095bce102c792 Mon Sep 17 00:00:00 2001
|
||||
From: Hongzhou Yang <hongzhou.yang@mediatek.com>
|
||||
Date: Mon, 18 May 2015 23:11:19 -0700
|
||||
Subject: [PATCH 55/76] mfd: mediatek: Add GPIO sub module support into mfd.
|
||||
|
||||
Register pinctrl subnode into 6397 mfd cell.
|
||||
|
||||
Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com>
|
||||
Acked-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
---
|
||||
drivers/mfd/mt6397-core.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
|
||||
index 09bc780..012c620 100644
|
||||
--- a/drivers/mfd/mt6397-core.c
|
||||
+++ b/drivers/mfd/mt6397-core.c
|
||||
@@ -34,6 +34,9 @@ static const struct mfd_cell mt6397_devs[] = {
|
||||
}, {
|
||||
.name = "mt6397-clk",
|
||||
.of_compatible = "mediatek,mt6397-clk",
|
||||
+ }, {
|
||||
+ .name = "mediatek-mt6397-pinctrl",
|
||||
+ .of_compatible = "mediatek,mt6397-pinctrl",
|
||||
},
|
||||
};
|
||||
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,809 @@
|
||||
From 619e31dbd73885249f3db545ed0b7678ca98c248 Mon Sep 17 00:00:00 2001
|
||||
From: Yingjoe Chen <yingjoe.chen@mediatek.com>
|
||||
Date: Mon, 18 May 2015 23:11:20 -0700
|
||||
Subject: [PATCH 56/76] ARM: dts: mt8127: add pinctrl/GPIO/EINT node for
|
||||
mt8127
|
||||
|
||||
Add pinctrl,GPIO and EINT node to mt8127.dtsi.
|
||||
|
||||
Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com>
|
||||
Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com>
|
||||
Acked-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Acked-by: Matthias Brugger <matthias.bgg@gmail.com>
|
||||
---
|
||||
arch/arm/boot/dts/mt8127-pinfunc.h | 742 ++++++++++++++++++++++++++++++++++++
|
||||
arch/arm/boot/dts/mt8127.dtsi | 22 ++
|
||||
2 files changed, 764 insertions(+)
|
||||
create mode 100644 arch/arm/boot/dts/mt8127-pinfunc.h
|
||||
|
||||
diff --git a/arch/arm/boot/dts/mt8127-pinfunc.h b/arch/arm/boot/dts/mt8127-pinfunc.h
|
||||
new file mode 100644
|
||||
index 0000000..9198331
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/mt8127-pinfunc.h
|
||||
@@ -0,0 +1,742 @@
|
||||
+#ifndef __DTS_MT8127_PINFUNC_H
|
||||
+#define __DTS_MT8127_PINFUNC_H
|
||||
+
|
||||
+#include <dt-bindings/pinctrl/mt65xx.h>
|
||||
+
|
||||
+#define MT8127_PIN_0_PWRAP_SPI0_MI__FUNC_GPIO0 (MTK_PIN_NO(0) | 0)
|
||||
+#define MT8127_PIN_0_PWRAP_SPI0_MI__FUNC_PWRAP_SPIDO (MTK_PIN_NO(0) | 1)
|
||||
+#define MT8127_PIN_0_PWRAP_SPI0_MI__FUNC_PWRAP_SPIDI (MTK_PIN_NO(0) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_1_PWRAP_SPI0_MO__FUNC_GPIO1 (MTK_PIN_NO(1) | 0)
|
||||
+#define MT8127_PIN_1_PWRAP_SPI0_MO__FUNC_PWRAP_SPIDI (MTK_PIN_NO(1) | 1)
|
||||
+#define MT8127_PIN_1_PWRAP_SPI0_MO__FUNC_PWRAP_SPIDO (MTK_PIN_NO(1) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_2_PWRAP_INT__FUNC_GPIO2 (MTK_PIN_NO(2) | 0)
|
||||
+
|
||||
+#define MT8127_PIN_3_PWRAP_SPI0_CK__FUNC_GPIO3 (MTK_PIN_NO(3) | 0)
|
||||
+#define MT8127_PIN_3_PWRAP_SPI0_CK__FUNC_PWRAP_SPICK_I (MTK_PIN_NO(3) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_4_PWRAP_SPI0_CSN__FUNC_GPIO4 (MTK_PIN_NO(4) | 0)
|
||||
+#define MT8127_PIN_4_PWRAP_SPI0_CSN__FUNC_PWRAP_SPICS_B_I (MTK_PIN_NO(4) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_5_PWRAP_SPI0_CK2__FUNC_GPIO5 (MTK_PIN_NO(5) | 0)
|
||||
+#define MT8127_PIN_5_PWRAP_SPI0_CK2__FUNC_PWRAP_SPICK2_I (MTK_PIN_NO(5) | 1)
|
||||
+#define MT8127_PIN_5_PWRAP_SPI0_CK2__FUNC_ANT_SEL1 (MTK_PIN_NO(5) | 2)
|
||||
+#define MT8127_PIN_5_PWRAP_SPI0_CK2__FUNC_VDEC_TEST_CK (MTK_PIN_NO(5) | 3)
|
||||
+#define MT8127_PIN_5_PWRAP_SPI0_CK2__FUNC_DBG_MON_B_0 (MTK_PIN_NO(5) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_6_PWRAP_SPI0_CSN2__FUNC_GPIO6 (MTK_PIN_NO(6) | 0)
|
||||
+#define MT8127_PIN_6_PWRAP_SPI0_CSN2__FUNC_PWRAP_SPICS2_B_I (MTK_PIN_NO(6) | 1)
|
||||
+#define MT8127_PIN_6_PWRAP_SPI0_CSN2__FUNC_ANT_SEL0 (MTK_PIN_NO(6) | 2)
|
||||
+#define MT8127_PIN_6_PWRAP_SPI0_CSN2__FUNC_MM_TEST_CK (MTK_PIN_NO(6) | 3)
|
||||
+#define MT8127_PIN_6_PWRAP_SPI0_CSN2__FUNC_DBG_MON_B_1 (MTK_PIN_NO(6) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_7_AUD_CLK_MOSI__FUNC_GPIO7 (MTK_PIN_NO(7) | 0)
|
||||
+#define MT8127_PIN_7_AUD_CLK_MOSI__FUNC_AUD_CLK (MTK_PIN_NO(7) | 1)
|
||||
+#define MT8127_PIN_7_AUD_CLK_MOSI__FUNC_ADC_CK (MTK_PIN_NO(7) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_8_AUD_DAT_MISO__FUNC_GPIO8 (MTK_PIN_NO(8) | 0)
|
||||
+#define MT8127_PIN_8_AUD_DAT_MISO__FUNC_AUD_MISO (MTK_PIN_NO(8) | 1)
|
||||
+#define MT8127_PIN_8_AUD_DAT_MISO__FUNC_ADC_DAT_IN (MTK_PIN_NO(8) | 2)
|
||||
+#define MT8127_PIN_8_AUD_DAT_MISO__FUNC_AUD_MOSI (MTK_PIN_NO(8) | 3)
|
||||
+
|
||||
+#define MT8127_PIN_9_AUD_DAT_MOSI__FUNC_GPIO9 (MTK_PIN_NO(9) | 0)
|
||||
+#define MT8127_PIN_9_AUD_DAT_MOSI__FUNC_AUD_MOSI (MTK_PIN_NO(9) | 1)
|
||||
+#define MT8127_PIN_9_AUD_DAT_MOSI__FUNC_ADC_WS (MTK_PIN_NO(9) | 2)
|
||||
+#define MT8127_PIN_9_AUD_DAT_MOSI__FUNC_AUD_MISO (MTK_PIN_NO(9) | 3)
|
||||
+
|
||||
+#define MT8127_PIN_10_RTC32K_CK__FUNC_GPIO10 (MTK_PIN_NO(10) | 0)
|
||||
+#define MT8127_PIN_10_RTC32K_CK__FUNC_RTC32K_CK (MTK_PIN_NO(10) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_11_WATCHDOG__FUNC_GPIO11 (MTK_PIN_NO(11) | 0)
|
||||
+#define MT8127_PIN_11_WATCHDOG__FUNC_WATCHDOG (MTK_PIN_NO(11) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_12_SRCLKENA__FUNC_GPIO12 (MTK_PIN_NO(12) | 0)
|
||||
+#define MT8127_PIN_12_SRCLKENA__FUNC_SRCLKENA (MTK_PIN_NO(12) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_13_SRCLKENAI__FUNC_GPIO13 (MTK_PIN_NO(13) | 0)
|
||||
+#define MT8127_PIN_13_SRCLKENAI__FUNC_SRCLKENAI (MTK_PIN_NO(13) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_14_URXD2__FUNC_GPIO14 (MTK_PIN_NO(14) | 0)
|
||||
+#define MT8127_PIN_14_URXD2__FUNC_URXD2 (MTK_PIN_NO(14) | 1)
|
||||
+#define MT8127_PIN_14_URXD2__FUNC_DPI_D5 (MTK_PIN_NO(14) | 2)
|
||||
+#define MT8127_PIN_14_URXD2__FUNC_UTXD2 (MTK_PIN_NO(14) | 3)
|
||||
+#define MT8127_PIN_14_URXD2__FUNC_SRCCLKENAI2 (MTK_PIN_NO(14) | 5)
|
||||
+#define MT8127_PIN_14_URXD2__FUNC_KROW4 (MTK_PIN_NO(14) | 6)
|
||||
+
|
||||
+#define MT8127_PIN_15_UTXD2__FUNC_GPIO15 (MTK_PIN_NO(15) | 0)
|
||||
+#define MT8127_PIN_15_UTXD2__FUNC_UTXD2 (MTK_PIN_NO(15) | 1)
|
||||
+#define MT8127_PIN_15_UTXD2__FUNC_DPI_HSYNC (MTK_PIN_NO(15) | 2)
|
||||
+#define MT8127_PIN_15_UTXD2__FUNC_URXD2 (MTK_PIN_NO(15) | 3)
|
||||
+#define MT8127_PIN_15_UTXD2__FUNC_KROW5 (MTK_PIN_NO(15) | 6)
|
||||
+
|
||||
+#define MT8127_PIN_16_URXD3__FUNC_GPIO16 (MTK_PIN_NO(16) | 0)
|
||||
+#define MT8127_PIN_16_URXD3__FUNC_URXD3 (MTK_PIN_NO(16) | 1)
|
||||
+#define MT8127_PIN_16_URXD3__FUNC_DPI_DE (MTK_PIN_NO(16) | 2)
|
||||
+#define MT8127_PIN_16_URXD3__FUNC_UTXD3 (MTK_PIN_NO(16) | 3)
|
||||
+#define MT8127_PIN_16_URXD3__FUNC_UCTS2 (MTK_PIN_NO(16) | 4)
|
||||
+#define MT8127_PIN_16_URXD3__FUNC_PWM3 (MTK_PIN_NO(16) | 5)
|
||||
+#define MT8127_PIN_16_URXD3__FUNC_KROW6 (MTK_PIN_NO(16) | 6)
|
||||
+
|
||||
+#define MT8127_PIN_17_UTXD3__FUNC_GPIO17 (MTK_PIN_NO(17) | 0)
|
||||
+#define MT8127_PIN_17_UTXD3__FUNC_UTXD3 (MTK_PIN_NO(17) | 1)
|
||||
+#define MT8127_PIN_17_UTXD3__FUNC_DPI_VSYNC (MTK_PIN_NO(17) | 2)
|
||||
+#define MT8127_PIN_17_UTXD3__FUNC_URXD3 (MTK_PIN_NO(17) | 3)
|
||||
+#define MT8127_PIN_17_UTXD3__FUNC_URTS2 (MTK_PIN_NO(17) | 4)
|
||||
+#define MT8127_PIN_17_UTXD3__FUNC_PWM4 (MTK_PIN_NO(17) | 5)
|
||||
+#define MT8127_PIN_17_UTXD3__FUNC_KROW7 (MTK_PIN_NO(17) | 6)
|
||||
+
|
||||
+#define MT8127_PIN_18_PCM_CLK__FUNC_GPIO18 (MTK_PIN_NO(18) | 0)
|
||||
+#define MT8127_PIN_18_PCM_CLK__FUNC_PCM_CLK0 (MTK_PIN_NO(18) | 1)
|
||||
+#define MT8127_PIN_18_PCM_CLK__FUNC_DPI_D4 (MTK_PIN_NO(18) | 2)
|
||||
+#define MT8127_PIN_18_PCM_CLK__FUNC_I2SIN1_BCK0 (MTK_PIN_NO(18) | 3)
|
||||
+#define MT8127_PIN_18_PCM_CLK__FUNC_I2SOUT_BCK (MTK_PIN_NO(18) | 4)
|
||||
+#define MT8127_PIN_18_PCM_CLK__FUNC_CONN_DSP_JCK (MTK_PIN_NO(18) | 5)
|
||||
+#define MT8127_PIN_18_PCM_CLK__FUNC_IR (MTK_PIN_NO(18) | 6)
|
||||
+#define MT8127_PIN_18_PCM_CLK__FUNC_DBG_MON_A_0 (MTK_PIN_NO(18) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_19_PCM_SYNC__FUNC_GPIO19 (MTK_PIN_NO(19) | 0)
|
||||
+#define MT8127_PIN_19_PCM_SYNC__FUNC_PCM_SYNC (MTK_PIN_NO(19) | 1)
|
||||
+#define MT8127_PIN_19_PCM_SYNC__FUNC_DPI_D3 (MTK_PIN_NO(19) | 2)
|
||||
+#define MT8127_PIN_19_PCM_SYNC__FUNC_I2SIN1_LRCK (MTK_PIN_NO(19) | 3)
|
||||
+#define MT8127_PIN_19_PCM_SYNC__FUNC_I2SOUT_LRCK (MTK_PIN_NO(19) | 4)
|
||||
+#define MT8127_PIN_19_PCM_SYNC__FUNC_CONN_DSP_JINTP (MTK_PIN_NO(19) | 5)
|
||||
+#define MT8127_PIN_19_PCM_SYNC__FUNC_EXT_COL (MTK_PIN_NO(19) | 6)
|
||||
+#define MT8127_PIN_19_PCM_SYNC__FUNC_DBG_MON_A_1 (MTK_PIN_NO(19) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_20_PCM_RX__FUNC_GPIO20 (MTK_PIN_NO(20) | 0)
|
||||
+#define MT8127_PIN_20_PCM_RX__FUNC_PCM_RX (MTK_PIN_NO(20) | 1)
|
||||
+#define MT8127_PIN_20_PCM_RX__FUNC_DPI_D1 (MTK_PIN_NO(20) | 2)
|
||||
+#define MT8127_PIN_20_PCM_RX__FUNC_I2SIN1_DATA_IN (MTK_PIN_NO(20) | 3)
|
||||
+#define MT8127_PIN_20_PCM_RX__FUNC_PCM_TX (MTK_PIN_NO(20) | 4)
|
||||
+#define MT8127_PIN_20_PCM_RX__FUNC_CONN_DSP_JDI (MTK_PIN_NO(20) | 5)
|
||||
+#define MT8127_PIN_20_PCM_RX__FUNC_EXT_MDIO (MTK_PIN_NO(20) | 6)
|
||||
+#define MT8127_PIN_20_PCM_RX__FUNC_DBG_MON_A_2 (MTK_PIN_NO(20) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_21_PCM_TX__FUNC_GPIO21 (MTK_PIN_NO(21) | 0)
|
||||
+#define MT8127_PIN_21_PCM_TX__FUNC_PCM_TX (MTK_PIN_NO(21) | 1)
|
||||
+#define MT8127_PIN_21_PCM_TX__FUNC_DPI_D2 (MTK_PIN_NO(21) | 2)
|
||||
+#define MT8127_PIN_21_PCM_TX__FUNC_I2SOUT_DATA_OUT (MTK_PIN_NO(21) | 3)
|
||||
+#define MT8127_PIN_21_PCM_TX__FUNC_PCM_RX (MTK_PIN_NO(21) | 4)
|
||||
+#define MT8127_PIN_21_PCM_TX__FUNC_CONN_DSP_JMS (MTK_PIN_NO(21) | 5)
|
||||
+#define MT8127_PIN_21_PCM_TX__FUNC_EXT_MDC (MTK_PIN_NO(21) | 6)
|
||||
+#define MT8127_PIN_21_PCM_TX__FUNC_DBG_MON_A_3 (MTK_PIN_NO(21) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_22_EINT0__FUNC_GPIO22 (MTK_PIN_NO(22) | 0)
|
||||
+#define MT8127_PIN_22_EINT0__FUNC_PWM1 (MTK_PIN_NO(22) | 1)
|
||||
+#define MT8127_PIN_22_EINT0__FUNC_DPI_CK (MTK_PIN_NO(22) | 2)
|
||||
+#define MT8127_PIN_22_EINT0__FUNC_EXT_TXD0 (MTK_PIN_NO(22) | 4)
|
||||
+#define MT8127_PIN_22_EINT0__FUNC_CONN_DSP_JDO (MTK_PIN_NO(22) | 5)
|
||||
+#define MT8127_PIN_22_EINT0__FUNC_DBG_MON_A_4 (MTK_PIN_NO(22) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_23_EINT1__FUNC_GPIO23 (MTK_PIN_NO(23) | 0)
|
||||
+#define MT8127_PIN_23_EINT1__FUNC_PWM2 (MTK_PIN_NO(23) | 1)
|
||||
+#define MT8127_PIN_23_EINT1__FUNC_DPI_D12 (MTK_PIN_NO(23) | 2)
|
||||
+#define MT8127_PIN_23_EINT1__FUNC_EXT_TXD1 (MTK_PIN_NO(23) | 4)
|
||||
+#define MT8127_PIN_23_EINT1__FUNC_CONN_MCU_TDO (MTK_PIN_NO(23) | 5)
|
||||
+#define MT8127_PIN_23_EINT1__FUNC_DBG_MON_A_5 (MTK_PIN_NO(23) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_24_EINT2__FUNC_GPIO24 (MTK_PIN_NO(24) | 0)
|
||||
+#define MT8127_PIN_24_EINT2__FUNC_CLKM0 (MTK_PIN_NO(24) | 1)
|
||||
+#define MT8127_PIN_24_EINT2__FUNC_DPI_D13 (MTK_PIN_NO(24) | 2)
|
||||
+#define MT8127_PIN_24_EINT2__FUNC_EXT_TXD2 (MTK_PIN_NO(24) | 4)
|
||||
+#define MT8127_PIN_24_EINT2__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(24) | 5)
|
||||
+#define MT8127_PIN_24_EINT2__FUNC_KCOL4 (MTK_PIN_NO(24) | 6)
|
||||
+#define MT8127_PIN_24_EINT2__FUNC_DBG_MON_A_6 (MTK_PIN_NO(24) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_25_EINT3__FUNC_GPIO25 (MTK_PIN_NO(25) | 0)
|
||||
+#define MT8127_PIN_25_EINT3__FUNC_CLKM1 (MTK_PIN_NO(25) | 1)
|
||||
+#define MT8127_PIN_25_EINT3__FUNC_DPI_D14 (MTK_PIN_NO(25) | 2)
|
||||
+#define MT8127_PIN_25_EINT3__FUNC_SPI_MI (MTK_PIN_NO(25) | 3)
|
||||
+#define MT8127_PIN_25_EINT3__FUNC_EXT_TXD3 (MTK_PIN_NO(25) | 4)
|
||||
+#define MT8127_PIN_25_EINT3__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(25) | 5)
|
||||
+#define MT8127_PIN_25_EINT3__FUNC_KCOL5 (MTK_PIN_NO(25) | 6)
|
||||
+#define MT8127_PIN_25_EINT3__FUNC_DBG_MON_A_7 (MTK_PIN_NO(25) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_26_EINT4__FUNC_GPIO26 (MTK_PIN_NO(26) | 0)
|
||||
+#define MT8127_PIN_26_EINT4__FUNC_CLKM2 (MTK_PIN_NO(26) | 1)
|
||||
+#define MT8127_PIN_26_EINT4__FUNC_DPI_D15 (MTK_PIN_NO(26) | 2)
|
||||
+#define MT8127_PIN_26_EINT4__FUNC_SPI_MO (MTK_PIN_NO(26) | 3)
|
||||
+#define MT8127_PIN_26_EINT4__FUNC_EXT_TXC (MTK_PIN_NO(26) | 4)
|
||||
+#define MT8127_PIN_26_EINT4__FUNC_CONN_MCU_TCK0 (MTK_PIN_NO(26) | 5)
|
||||
+#define MT8127_PIN_26_EINT4__FUNC_CONN_MCU_AICE_JCKC (MTK_PIN_NO(26) | 6)
|
||||
+#define MT8127_PIN_26_EINT4__FUNC_DBG_MON_A_8 (MTK_PIN_NO(26) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_27_EINT5__FUNC_GPIO27 (MTK_PIN_NO(27) | 0)
|
||||
+#define MT8127_PIN_27_EINT5__FUNC_UCTS2 (MTK_PIN_NO(27) | 1)
|
||||
+#define MT8127_PIN_27_EINT5__FUNC_DPI_D16 (MTK_PIN_NO(27) | 2)
|
||||
+#define MT8127_PIN_27_EINT5__FUNC_SPI_CS (MTK_PIN_NO(27) | 3)
|
||||
+#define MT8127_PIN_27_EINT5__FUNC_EXT_RXER (MTK_PIN_NO(27) | 4)
|
||||
+#define MT8127_PIN_27_EINT5__FUNC_CONN_MCU_TDI (MTK_PIN_NO(27) | 5)
|
||||
+#define MT8127_PIN_27_EINT5__FUNC_KCOL6 (MTK_PIN_NO(27) | 6)
|
||||
+#define MT8127_PIN_27_EINT5__FUNC_DBG_MON_A_9 (MTK_PIN_NO(27) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_28_EINT6__FUNC_GPIO28 (MTK_PIN_NO(28) | 0)
|
||||
+#define MT8127_PIN_28_EINT6__FUNC_URTS2 (MTK_PIN_NO(28) | 1)
|
||||
+#define MT8127_PIN_28_EINT6__FUNC_DPI_D17 (MTK_PIN_NO(28) | 2)
|
||||
+#define MT8127_PIN_28_EINT6__FUNC_SPI_CK (MTK_PIN_NO(28) | 3)
|
||||
+#define MT8127_PIN_28_EINT6__FUNC_EXT_RXC (MTK_PIN_NO(28) | 4)
|
||||
+#define MT8127_PIN_28_EINT6__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(28) | 5)
|
||||
+#define MT8127_PIN_28_EINT6__FUNC_KCOL7 (MTK_PIN_NO(28) | 6)
|
||||
+#define MT8127_PIN_28_EINT6__FUNC_DBG_MON_A_10 (MTK_PIN_NO(28) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_29_EINT7__FUNC_GPIO29 (MTK_PIN_NO(29) | 0)
|
||||
+#define MT8127_PIN_29_EINT7__FUNC_UCTS3 (MTK_PIN_NO(29) | 1)
|
||||
+#define MT8127_PIN_29_EINT7__FUNC_DPI_D6 (MTK_PIN_NO(29) | 2)
|
||||
+#define MT8127_PIN_29_EINT7__FUNC_SDA1 (MTK_PIN_NO(29) | 3)
|
||||
+#define MT8127_PIN_29_EINT7__FUNC_EXT_RXDV (MTK_PIN_NO(29) | 4)
|
||||
+#define MT8127_PIN_29_EINT7__FUNC_CONN_MCU_TMS (MTK_PIN_NO(29) | 5)
|
||||
+#define MT8127_PIN_29_EINT7__FUNC_CONN_MCU_AICE_JMSC (MTK_PIN_NO(29) | 6)
|
||||
+#define MT8127_PIN_29_EINT7__FUNC_DBG_MON_A_11 (MTK_PIN_NO(29) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_30_EINT8__FUNC_GPIO30 (MTK_PIN_NO(30) | 0)
|
||||
+#define MT8127_PIN_30_EINT8__FUNC_URTS3 (MTK_PIN_NO(30) | 1)
|
||||
+#define MT8127_PIN_30_EINT8__FUNC_CLKM3 (MTK_PIN_NO(30) | 2)
|
||||
+#define MT8127_PIN_30_EINT8__FUNC_SCL1 (MTK_PIN_NO(30) | 3)
|
||||
+#define MT8127_PIN_30_EINT8__FUNC_EXT_RXD0 (MTK_PIN_NO(30) | 4)
|
||||
+#define MT8127_PIN_30_EINT8__FUNC_ANT_SEL0 (MTK_PIN_NO(30) | 5)
|
||||
+#define MT8127_PIN_30_EINT8__FUNC_DPI_D7 (MTK_PIN_NO(30) | 6)
|
||||
+#define MT8127_PIN_30_EINT8__FUNC_DBG_MON_B_2 (MTK_PIN_NO(30) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_31_EINT9__FUNC_GPIO31 (MTK_PIN_NO(31) | 0)
|
||||
+#define MT8127_PIN_31_EINT9__FUNC_CLKM4 (MTK_PIN_NO(31) | 1)
|
||||
+#define MT8127_PIN_31_EINT9__FUNC_SDA2 (MTK_PIN_NO(31) | 2)
|
||||
+#define MT8127_PIN_31_EINT9__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(31) | 3)
|
||||
+#define MT8127_PIN_31_EINT9__FUNC_EXT_RXD1 (MTK_PIN_NO(31) | 4)
|
||||
+#define MT8127_PIN_31_EINT9__FUNC_ANT_SEL1 (MTK_PIN_NO(31) | 5)
|
||||
+#define MT8127_PIN_31_EINT9__FUNC_DPI_D8 (MTK_PIN_NO(31) | 6)
|
||||
+#define MT8127_PIN_31_EINT9__FUNC_DBG_MON_B_3 (MTK_PIN_NO(31) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_32_EINT10__FUNC_GPIO32 (MTK_PIN_NO(32) | 0)
|
||||
+#define MT8127_PIN_32_EINT10__FUNC_CLKM5 (MTK_PIN_NO(32) | 1)
|
||||
+#define MT8127_PIN_32_EINT10__FUNC_SCL2 (MTK_PIN_NO(32) | 2)
|
||||
+#define MT8127_PIN_32_EINT10__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(32) | 3)
|
||||
+#define MT8127_PIN_32_EINT10__FUNC_EXT_RXD2 (MTK_PIN_NO(32) | 4)
|
||||
+#define MT8127_PIN_32_EINT10__FUNC_ANT_SEL2 (MTK_PIN_NO(32) | 5)
|
||||
+#define MT8127_PIN_32_EINT10__FUNC_DPI_D9 (MTK_PIN_NO(32) | 6)
|
||||
+#define MT8127_PIN_32_EINT10__FUNC_DBG_MON_B_4 (MTK_PIN_NO(32) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_33_KPROW0__FUNC_GPIO33 (MTK_PIN_NO(33) | 0)
|
||||
+#define MT8127_PIN_33_KPROW0__FUNC_KROW0 (MTK_PIN_NO(33) | 1)
|
||||
+#define MT8127_PIN_33_KPROW0__FUNC_IMG_TEST_CK (MTK_PIN_NO(33) | 4)
|
||||
+#define MT8127_PIN_33_KPROW0__FUNC_DBG_MON_A_12 (MTK_PIN_NO(33) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_34_KPROW1__FUNC_GPIO34 (MTK_PIN_NO(34) | 0)
|
||||
+#define MT8127_PIN_34_KPROW1__FUNC_KROW1 (MTK_PIN_NO(34) | 1)
|
||||
+#define MT8127_PIN_34_KPROW1__FUNC_IDDIG (MTK_PIN_NO(34) | 2)
|
||||
+#define MT8127_PIN_34_KPROW1__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(34) | 3)
|
||||
+#define MT8127_PIN_34_KPROW1__FUNC_MFG_TEST_CK (MTK_PIN_NO(34) | 4)
|
||||
+#define MT8127_PIN_34_KPROW1__FUNC_DBG_MON_B_5 (MTK_PIN_NO(34) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_35_KPROW2__FUNC_GPIO35 (MTK_PIN_NO(35) | 0)
|
||||
+#define MT8127_PIN_35_KPROW2__FUNC_KROW2 (MTK_PIN_NO(35) | 1)
|
||||
+#define MT8127_PIN_35_KPROW2__FUNC_DRV_VBUS (MTK_PIN_NO(35) | 2)
|
||||
+#define MT8127_PIN_35_KPROW2__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(35) | 3)
|
||||
+#define MT8127_PIN_35_KPROW2__FUNC_CONN_TEST_CK (MTK_PIN_NO(35) | 4)
|
||||
+#define MT8127_PIN_35_KPROW2__FUNC_DBG_MON_B_6 (MTK_PIN_NO(35) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_36_KPCOL0__FUNC_GPIO36 (MTK_PIN_NO(36) | 0)
|
||||
+#define MT8127_PIN_36_KPCOL0__FUNC_KCOL0 (MTK_PIN_NO(36) | 1)
|
||||
+#define MT8127_PIN_36_KPCOL0__FUNC_DBG_MON_A_13 (MTK_PIN_NO(36) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_37_KPCOL1__FUNC_GPIO37 (MTK_PIN_NO(37) | 0)
|
||||
+#define MT8127_PIN_37_KPCOL1__FUNC_KCOL1 (MTK_PIN_NO(37) | 1)
|
||||
+#define MT8127_PIN_37_KPCOL1__FUNC_DBG_MON_B_7 (MTK_PIN_NO(37) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_38_KPCOL2__FUNC_GPIO38 (MTK_PIN_NO(38) | 0)
|
||||
+#define MT8127_PIN_38_KPCOL2__FUNC_KCOL2 (MTK_PIN_NO(38) | 1)
|
||||
+#define MT8127_PIN_38_KPCOL2__FUNC_IDDIG (MTK_PIN_NO(38) | 2)
|
||||
+#define MT8127_PIN_38_KPCOL2__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(38) | 3)
|
||||
+#define MT8127_PIN_38_KPCOL2__FUNC_DBG_MON_B_8 (MTK_PIN_NO(38) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_39_JTMS__FUNC_GPIO39 (MTK_PIN_NO(39) | 0)
|
||||
+#define MT8127_PIN_39_JTMS__FUNC_JTMS (MTK_PIN_NO(39) | 1)
|
||||
+#define MT8127_PIN_39_JTMS__FUNC_CONN_MCU_TMS (MTK_PIN_NO(39) | 2)
|
||||
+#define MT8127_PIN_39_JTMS__FUNC_CONN_MCU_AICE_JMSC (MTK_PIN_NO(39) | 3)
|
||||
+
|
||||
+#define MT8127_PIN_40_JTCK__FUNC_GPIO40 (MTK_PIN_NO(40) | 0)
|
||||
+#define MT8127_PIN_40_JTCK__FUNC_JTCK (MTK_PIN_NO(40) | 1)
|
||||
+#define MT8127_PIN_40_JTCK__FUNC_CONN_MCU_TCK1 (MTK_PIN_NO(40) | 2)
|
||||
+#define MT8127_PIN_40_JTCK__FUNC_CONN_MCU_AICE_JCKC (MTK_PIN_NO(40) | 3)
|
||||
+
|
||||
+#define MT8127_PIN_41_JTDI__FUNC_GPIO41 (MTK_PIN_NO(41) | 0)
|
||||
+#define MT8127_PIN_41_JTDI__FUNC_JTDI (MTK_PIN_NO(41) | 1)
|
||||
+#define MT8127_PIN_41_JTDI__FUNC_CONN_MCU_TDI (MTK_PIN_NO(41) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_42_JTDO__FUNC_GPIO42 (MTK_PIN_NO(42) | 0)
|
||||
+#define MT8127_PIN_42_JTDO__FUNC_JTDO (MTK_PIN_NO(42) | 1)
|
||||
+#define MT8127_PIN_42_JTDO__FUNC_CONN_MCU_TDO (MTK_PIN_NO(42) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_43_EINT11__FUNC_GPIO43 (MTK_PIN_NO(43) | 0)
|
||||
+#define MT8127_PIN_43_EINT11__FUNC_CLKM4 (MTK_PIN_NO(43) | 1)
|
||||
+#define MT8127_PIN_43_EINT11__FUNC_PWM2 (MTK_PIN_NO(43) | 2)
|
||||
+#define MT8127_PIN_43_EINT11__FUNC_KROW3 (MTK_PIN_NO(43) | 3)
|
||||
+#define MT8127_PIN_43_EINT11__FUNC_ANT_SEL3 (MTK_PIN_NO(43) | 4)
|
||||
+#define MT8127_PIN_43_EINT11__FUNC_DPI_D10 (MTK_PIN_NO(43) | 5)
|
||||
+#define MT8127_PIN_43_EINT11__FUNC_EXT_RXD3 (MTK_PIN_NO(43) | 6)
|
||||
+#define MT8127_PIN_43_EINT11__FUNC_DBG_MON_B_9 (MTK_PIN_NO(43) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_44_EINT12__FUNC_GPIO44 (MTK_PIN_NO(44) | 0)
|
||||
+#define MT8127_PIN_44_EINT12__FUNC_CLKM5 (MTK_PIN_NO(44) | 1)
|
||||
+#define MT8127_PIN_44_EINT12__FUNC_PWM0 (MTK_PIN_NO(44) | 2)
|
||||
+#define MT8127_PIN_44_EINT12__FUNC_KCOL3 (MTK_PIN_NO(44) | 3)
|
||||
+#define MT8127_PIN_44_EINT12__FUNC_ANT_SEL4 (MTK_PIN_NO(44) | 4)
|
||||
+#define MT8127_PIN_44_EINT12__FUNC_DPI_D11 (MTK_PIN_NO(44) | 5)
|
||||
+#define MT8127_PIN_44_EINT12__FUNC_EXT_TXEN (MTK_PIN_NO(44) | 6)
|
||||
+#define MT8127_PIN_44_EINT12__FUNC_DBG_MON_B_10 (MTK_PIN_NO(44) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_45_EINT13__FUNC_GPIO45 (MTK_PIN_NO(45) | 0)
|
||||
+#define MT8127_PIN_45_EINT13__FUNC_ANT_SEL5 (MTK_PIN_NO(45) | 4)
|
||||
+#define MT8127_PIN_45_EINT13__FUNC_DPI_D0 (MTK_PIN_NO(45) | 5)
|
||||
+#define MT8127_PIN_45_EINT13__FUNC_SPDIF (MTK_PIN_NO(45) | 6)
|
||||
+#define MT8127_PIN_45_EINT13__FUNC_DBG_MON_B_11 (MTK_PIN_NO(45) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_46_EINT14__FUNC_GPIO46 (MTK_PIN_NO(46) | 0)
|
||||
+#define MT8127_PIN_46_EINT14__FUNC_DAC_DAT_OUT (MTK_PIN_NO(46) | 2)
|
||||
+#define MT8127_PIN_46_EINT14__FUNC_ANT_SEL1 (MTK_PIN_NO(46) | 4)
|
||||
+#define MT8127_PIN_46_EINT14__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(46) | 5)
|
||||
+#define MT8127_PIN_46_EINT14__FUNC_NCLE (MTK_PIN_NO(46) | 6)
|
||||
+#define MT8127_PIN_46_EINT14__FUNC_DBG_MON_A_14 (MTK_PIN_NO(46) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_47_EINT15__FUNC_GPIO47 (MTK_PIN_NO(47) | 0)
|
||||
+#define MT8127_PIN_47_EINT15__FUNC_DAC_WS (MTK_PIN_NO(47) | 2)
|
||||
+#define MT8127_PIN_47_EINT15__FUNC_ANT_SEL2 (MTK_PIN_NO(47) | 4)
|
||||
+#define MT8127_PIN_47_EINT15__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(47) | 5)
|
||||
+#define MT8127_PIN_47_EINT15__FUNC_NCEB1 (MTK_PIN_NO(47) | 6)
|
||||
+#define MT8127_PIN_47_EINT15__FUNC_DBG_MON_A_15 (MTK_PIN_NO(47) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_48_EINT16__FUNC_GPIO48 (MTK_PIN_NO(48) | 0)
|
||||
+#define MT8127_PIN_48_EINT16__FUNC_DAC_CK (MTK_PIN_NO(48) | 2)
|
||||
+#define MT8127_PIN_48_EINT16__FUNC_ANT_SEL3 (MTK_PIN_NO(48) | 4)
|
||||
+#define MT8127_PIN_48_EINT16__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(48) | 5)
|
||||
+#define MT8127_PIN_48_EINT16__FUNC_NCEB0 (MTK_PIN_NO(48) | 6)
|
||||
+#define MT8127_PIN_48_EINT16__FUNC_DBG_MON_A_16 (MTK_PIN_NO(48) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_49_EINT17__FUNC_GPIO49 (MTK_PIN_NO(49) | 0)
|
||||
+#define MT8127_PIN_49_EINT17__FUNC_UCTS0 (MTK_PIN_NO(49) | 1)
|
||||
+#define MT8127_PIN_49_EINT17__FUNC_CLKM0 (MTK_PIN_NO(49) | 3)
|
||||
+#define MT8127_PIN_49_EINT17__FUNC_IDDIG (MTK_PIN_NO(49) | 4)
|
||||
+#define MT8127_PIN_49_EINT17__FUNC_ANT_SEL4 (MTK_PIN_NO(49) | 5)
|
||||
+#define MT8127_PIN_49_EINT17__FUNC_NREB (MTK_PIN_NO(49) | 6)
|
||||
+#define MT8127_PIN_49_EINT17__FUNC_DBG_MON_A_17 (MTK_PIN_NO(49) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_50_EINT18__FUNC_GPIO50 (MTK_PIN_NO(50) | 0)
|
||||
+#define MT8127_PIN_50_EINT18__FUNC_URTS0 (MTK_PIN_NO(50) | 1)
|
||||
+#define MT8127_PIN_50_EINT18__FUNC_CLKM3 (MTK_PIN_NO(50) | 2)
|
||||
+#define MT8127_PIN_50_EINT18__FUNC_I2SOUT_LRCK (MTK_PIN_NO(50) | 3)
|
||||
+#define MT8127_PIN_50_EINT18__FUNC_DRV_VBUS (MTK_PIN_NO(50) | 4)
|
||||
+#define MT8127_PIN_50_EINT18__FUNC_ANT_SEL3 (MTK_PIN_NO(50) | 5)
|
||||
+#define MT8127_PIN_50_EINT18__FUNC_ADC_CK (MTK_PIN_NO(50) | 6)
|
||||
+#define MT8127_PIN_50_EINT18__FUNC_DBG_MON_B_12 (MTK_PIN_NO(50) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_51_EINT19__FUNC_GPIO51 (MTK_PIN_NO(51) | 0)
|
||||
+#define MT8127_PIN_51_EINT19__FUNC_UCTS1 (MTK_PIN_NO(51) | 1)
|
||||
+#define MT8127_PIN_51_EINT19__FUNC_I2SOUT_BCK (MTK_PIN_NO(51) | 3)
|
||||
+#define MT8127_PIN_51_EINT19__FUNC_CLKM1 (MTK_PIN_NO(51) | 4)
|
||||
+#define MT8127_PIN_51_EINT19__FUNC_ANT_SEL4 (MTK_PIN_NO(51) | 5)
|
||||
+#define MT8127_PIN_51_EINT19__FUNC_ADC_DAT_IN (MTK_PIN_NO(51) | 6)
|
||||
+#define MT8127_PIN_51_EINT19__FUNC_DBG_MON_B_13 (MTK_PIN_NO(51) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_52_EINT20__FUNC_GPIO52 (MTK_PIN_NO(52) | 0)
|
||||
+#define MT8127_PIN_52_EINT20__FUNC_URTS1 (MTK_PIN_NO(52) | 1)
|
||||
+#define MT8127_PIN_52_EINT20__FUNC_PCM_TX (MTK_PIN_NO(52) | 2)
|
||||
+#define MT8127_PIN_52_EINT20__FUNC_I2SOUT_DATA_OUT (MTK_PIN_NO(52) | 3)
|
||||
+#define MT8127_PIN_52_EINT20__FUNC_CLKM2 (MTK_PIN_NO(52) | 4)
|
||||
+#define MT8127_PIN_52_EINT20__FUNC_ANT_SEL5 (MTK_PIN_NO(52) | 5)
|
||||
+#define MT8127_PIN_52_EINT20__FUNC_ADC_WS (MTK_PIN_NO(52) | 6)
|
||||
+#define MT8127_PIN_52_EINT20__FUNC_DBG_MON_B_14 (MTK_PIN_NO(52) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_53_SPI_CS__FUNC_GPIO53 (MTK_PIN_NO(53) | 0)
|
||||
+#define MT8127_PIN_53_SPI_CS__FUNC_SPI_CS (MTK_PIN_NO(53) | 1)
|
||||
+#define MT8127_PIN_53_SPI_CS__FUNC_I2SIN1_DATA_IN (MTK_PIN_NO(53) | 3)
|
||||
+#define MT8127_PIN_53_SPI_CS__FUNC_ADC_CK (MTK_PIN_NO(53) | 4)
|
||||
+#define MT8127_PIN_53_SPI_CS__FUNC_DBG_MON_B_15 (MTK_PIN_NO(53) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_54_SPI_CK__FUNC_GPIO54 (MTK_PIN_NO(54) | 0)
|
||||
+#define MT8127_PIN_54_SPI_CK__FUNC_SPI_CK (MTK_PIN_NO(54) | 1)
|
||||
+#define MT8127_PIN_54_SPI_CK__FUNC_I2SIN1_LRCK (MTK_PIN_NO(54) | 3)
|
||||
+#define MT8127_PIN_54_SPI_CK__FUNC_ADC_DAT_IN (MTK_PIN_NO(54) | 4)
|
||||
+#define MT8127_PIN_54_SPI_CK__FUNC_DBG_MON_B_16 (MTK_PIN_NO(54) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_55_SPI_MI__FUNC_GPIO55 (MTK_PIN_NO(55) | 0)
|
||||
+#define MT8127_PIN_55_SPI_MI__FUNC_SPI_MI (MTK_PIN_NO(55) | 1)
|
||||
+#define MT8127_PIN_55_SPI_MI__FUNC_SPI_MO (MTK_PIN_NO(55) | 2)
|
||||
+#define MT8127_PIN_55_SPI_MI__FUNC_I2SIN1_BCK1 (MTK_PIN_NO(55) | 3)
|
||||
+#define MT8127_PIN_55_SPI_MI__FUNC_ADC_WS (MTK_PIN_NO(55) | 4)
|
||||
+#define MT8127_PIN_55_SPI_MI__FUNC_DBG_MON_B_17 (MTK_PIN_NO(55) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_56_SPI_MO__FUNC_GPIO56 (MTK_PIN_NO(56) | 0)
|
||||
+#define MT8127_PIN_56_SPI_MO__FUNC_SPI_MO (MTK_PIN_NO(56) | 1)
|
||||
+#define MT8127_PIN_56_SPI_MO__FUNC_SPI_MI (MTK_PIN_NO(56) | 2)
|
||||
+#define MT8127_PIN_56_SPI_MO__FUNC_DBG_MON_B_18 (MTK_PIN_NO(56) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_57_SDA1__FUNC_GPIO57 (MTK_PIN_NO(57) | 0)
|
||||
+#define MT8127_PIN_57_SDA1__FUNC_SDA1 (MTK_PIN_NO(57) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_58_SCL1__FUNC_GPIO58 (MTK_PIN_NO(58) | 0)
|
||||
+#define MT8127_PIN_58_SCL1__FUNC_SCL1 (MTK_PIN_NO(58) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_59_DISP_PWM__FUNC_GPIO59 (MTK_PIN_NO(59) | 0)
|
||||
+#define MT8127_PIN_59_DISP_PWM__FUNC_DISP_PWM (MTK_PIN_NO(59) | 1)
|
||||
+#define MT8127_PIN_59_DISP_PWM__FUNC_PWM1 (MTK_PIN_NO(59) | 2)
|
||||
+#define MT8127_PIN_59_DISP_PWM__FUNC_DBG_MON_A_18 (MTK_PIN_NO(59) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_60_WB_RSTB__FUNC_GPIO60 (MTK_PIN_NO(60) | 0)
|
||||
+#define MT8127_PIN_60_WB_RSTB__FUNC_WB_RSTB (MTK_PIN_NO(60) | 1)
|
||||
+#define MT8127_PIN_60_WB_RSTB__FUNC_DBG_MON_A_19 (MTK_PIN_NO(60) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_61_F2W_DATA__FUNC_GPIO61 (MTK_PIN_NO(61) | 0)
|
||||
+#define MT8127_PIN_61_F2W_DATA__FUNC_F2W_DATA (MTK_PIN_NO(61) | 1)
|
||||
+#define MT8127_PIN_61_F2W_DATA__FUNC_DBG_MON_A_20 (MTK_PIN_NO(61) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_62_F2W_CLK__FUNC_GPIO62 (MTK_PIN_NO(62) | 0)
|
||||
+#define MT8127_PIN_62_F2W_CLK__FUNC_F2W_CK (MTK_PIN_NO(62) | 1)
|
||||
+#define MT8127_PIN_62_F2W_CLK__FUNC_DBG_MON_A_21 (MTK_PIN_NO(62) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_63_WB_SCLK__FUNC_GPIO63 (MTK_PIN_NO(63) | 0)
|
||||
+#define MT8127_PIN_63_WB_SCLK__FUNC_WB_SCLK (MTK_PIN_NO(63) | 1)
|
||||
+#define MT8127_PIN_63_WB_SCLK__FUNC_DBG_MON_A_22 (MTK_PIN_NO(63) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_64_WB_SDATA__FUNC_GPIO64 (MTK_PIN_NO(64) | 0)
|
||||
+#define MT8127_PIN_64_WB_SDATA__FUNC_WB_SDATA (MTK_PIN_NO(64) | 1)
|
||||
+#define MT8127_PIN_64_WB_SDATA__FUNC_DBG_MON_A_23 (MTK_PIN_NO(64) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_65_WB_SEN__FUNC_GPIO65 (MTK_PIN_NO(65) | 0)
|
||||
+#define MT8127_PIN_65_WB_SEN__FUNC_WB_SEN (MTK_PIN_NO(65) | 1)
|
||||
+#define MT8127_PIN_65_WB_SEN__FUNC_DBG_MON_A_24 (MTK_PIN_NO(65) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_66_WB_CRTL0__FUNC_GPIO66 (MTK_PIN_NO(66) | 0)
|
||||
+#define MT8127_PIN_66_WB_CRTL0__FUNC_WB_CRTL0 (MTK_PIN_NO(66) | 1)
|
||||
+#define MT8127_PIN_66_WB_CRTL0__FUNC_DFD_NTRST_XI (MTK_PIN_NO(66) | 2)
|
||||
+#define MT8127_PIN_66_WB_CRTL0__FUNC_DBG_MON_A_25 (MTK_PIN_NO(66) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_67_WB_CRTL1__FUNC_GPIO67 (MTK_PIN_NO(67) | 0)
|
||||
+#define MT8127_PIN_67_WB_CRTL1__FUNC_WB_CRTL1 (MTK_PIN_NO(67) | 1)
|
||||
+#define MT8127_PIN_67_WB_CRTL1__FUNC_DFD_TMS_XI (MTK_PIN_NO(67) | 2)
|
||||
+#define MT8127_PIN_67_WB_CRTL1__FUNC_DBG_MON_A_26 (MTK_PIN_NO(67) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_68_WB_CRTL2__FUNC_GPIO68 (MTK_PIN_NO(68) | 0)
|
||||
+#define MT8127_PIN_68_WB_CRTL2__FUNC_WB_CRTL2 (MTK_PIN_NO(68) | 1)
|
||||
+#define MT8127_PIN_68_WB_CRTL2__FUNC_DFD_TCK_XI (MTK_PIN_NO(68) | 2)
|
||||
+#define MT8127_PIN_68_WB_CRTL2__FUNC_DBG_MON_A_27 (MTK_PIN_NO(68) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_69_WB_CRTL3__FUNC_GPIO69 (MTK_PIN_NO(69) | 0)
|
||||
+#define MT8127_PIN_69_WB_CRTL3__FUNC_WB_CRTL3 (MTK_PIN_NO(69) | 1)
|
||||
+#define MT8127_PIN_69_WB_CRTL3__FUNC_DFD_TDI_XI (MTK_PIN_NO(69) | 2)
|
||||
+#define MT8127_PIN_69_WB_CRTL3__FUNC_DBG_MON_A_28 (MTK_PIN_NO(69) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_70_WB_CRTL4__FUNC_GPIO70 (MTK_PIN_NO(70) | 0)
|
||||
+#define MT8127_PIN_70_WB_CRTL4__FUNC_WB_CRTL4 (MTK_PIN_NO(70) | 1)
|
||||
+#define MT8127_PIN_70_WB_CRTL4__FUNC_DFD_TDO (MTK_PIN_NO(70) | 2)
|
||||
+#define MT8127_PIN_70_WB_CRTL4__FUNC_DBG_MON_A_29 (MTK_PIN_NO(70) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_71_WB_CRTL5__FUNC_GPIO71 (MTK_PIN_NO(71) | 0)
|
||||
+#define MT8127_PIN_71_WB_CRTL5__FUNC_WB_CRTL5 (MTK_PIN_NO(71) | 1)
|
||||
+#define MT8127_PIN_71_WB_CRTL5__FUNC_DBG_MON_A_30 (MTK_PIN_NO(71) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_72_I2S_DATA_IN__FUNC_GPIO72 (MTK_PIN_NO(72) | 0)
|
||||
+#define MT8127_PIN_72_I2S_DATA_IN__FUNC_I2SIN1_DATA_IN (MTK_PIN_NO(72) | 1)
|
||||
+#define MT8127_PIN_72_I2S_DATA_IN__FUNC_PCM_RX (MTK_PIN_NO(72) | 2)
|
||||
+#define MT8127_PIN_72_I2S_DATA_IN__FUNC_I2SOUT_DATA_OUT (MTK_PIN_NO(72) | 3)
|
||||
+#define MT8127_PIN_72_I2S_DATA_IN__FUNC_DAC_DAT_OUT (MTK_PIN_NO(72) | 4)
|
||||
+#define MT8127_PIN_72_I2S_DATA_IN__FUNC_PWM0 (MTK_PIN_NO(72) | 5)
|
||||
+#define MT8127_PIN_72_I2S_DATA_IN__FUNC_ADC_CK (MTK_PIN_NO(72) | 6)
|
||||
+#define MT8127_PIN_72_I2S_DATA_IN__FUNC_DBG_MON_B_19 (MTK_PIN_NO(72) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_73_I2S_LRCK__FUNC_GPIO73 (MTK_PIN_NO(73) | 0)
|
||||
+#define MT8127_PIN_73_I2S_LRCK__FUNC_I2SIN1_LRCK (MTK_PIN_NO(73) | 1)
|
||||
+#define MT8127_PIN_73_I2S_LRCK__FUNC_PCM_SYNC (MTK_PIN_NO(73) | 2)
|
||||
+#define MT8127_PIN_73_I2S_LRCK__FUNC_I2SOUT_LRCK (MTK_PIN_NO(73) | 3)
|
||||
+#define MT8127_PIN_73_I2S_LRCK__FUNC_DAC_WS (MTK_PIN_NO(73) | 4)
|
||||
+#define MT8127_PIN_73_I2S_LRCK__FUNC_PWM3 (MTK_PIN_NO(73) | 5)
|
||||
+#define MT8127_PIN_73_I2S_LRCK__FUNC_ADC_DAT_IN (MTK_PIN_NO(73) | 6)
|
||||
+#define MT8127_PIN_73_I2S_LRCK__FUNC_DBG_MON_B_20 (MTK_PIN_NO(73) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_74_I2S_BCK__FUNC_GPIO74 (MTK_PIN_NO(74) | 0)
|
||||
+#define MT8127_PIN_74_I2S_BCK__FUNC_I2SIN1_BCK2 (MTK_PIN_NO(74) | 1)
|
||||
+#define MT8127_PIN_74_I2S_BCK__FUNC_PCM_CLK1 (MTK_PIN_NO(74) | 2)
|
||||
+#define MT8127_PIN_74_I2S_BCK__FUNC_I2SOUT_BCK (MTK_PIN_NO(74) | 3)
|
||||
+#define MT8127_PIN_74_I2S_BCK__FUNC_DAC_CK (MTK_PIN_NO(74) | 4)
|
||||
+#define MT8127_PIN_74_I2S_BCK__FUNC_PWM4 (MTK_PIN_NO(74) | 5)
|
||||
+#define MT8127_PIN_74_I2S_BCK__FUNC_ADC_WS (MTK_PIN_NO(74) | 6)
|
||||
+#define MT8127_PIN_74_I2S_BCK__FUNC_DBG_MON_B_21 (MTK_PIN_NO(74) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_75_SDA0__FUNC_GPIO75 (MTK_PIN_NO(75) | 0)
|
||||
+#define MT8127_PIN_75_SDA0__FUNC_SDA0 (MTK_PIN_NO(75) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_76_SCL0__FUNC_GPIO76 (MTK_PIN_NO(76) | 0)
|
||||
+#define MT8127_PIN_76_SCL0__FUNC_SCL0 (MTK_PIN_NO(76) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_77_SDA2__FUNC_GPIO77 (MTK_PIN_NO(77) | 0)
|
||||
+#define MT8127_PIN_77_SDA2__FUNC_SDA2 (MTK_PIN_NO(77) | 1)
|
||||
+#define MT8127_PIN_77_SDA2__FUNC_PWM1 (MTK_PIN_NO(77) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_78_SCL2__FUNC_GPIO78 (MTK_PIN_NO(78) | 0)
|
||||
+#define MT8127_PIN_78_SCL2__FUNC_SCL2 (MTK_PIN_NO(78) | 1)
|
||||
+#define MT8127_PIN_78_SCL2__FUNC_PWM2 (MTK_PIN_NO(78) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_79_URXD0__FUNC_GPIO79 (MTK_PIN_NO(79) | 0)
|
||||
+#define MT8127_PIN_79_URXD0__FUNC_URXD0 (MTK_PIN_NO(79) | 1)
|
||||
+#define MT8127_PIN_79_URXD0__FUNC_UTXD0 (MTK_PIN_NO(79) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_80_UTXD0__FUNC_GPIO80 (MTK_PIN_NO(80) | 0)
|
||||
+#define MT8127_PIN_80_UTXD0__FUNC_UTXD0 (MTK_PIN_NO(80) | 1)
|
||||
+#define MT8127_PIN_80_UTXD0__FUNC_URXD0 (MTK_PIN_NO(80) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_81_URXD1__FUNC_GPIO81 (MTK_PIN_NO(81) | 0)
|
||||
+#define MT8127_PIN_81_URXD1__FUNC_URXD1 (MTK_PIN_NO(81) | 1)
|
||||
+#define MT8127_PIN_81_URXD1__FUNC_UTXD1 (MTK_PIN_NO(81) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_82_UTXD1__FUNC_GPIO82 (MTK_PIN_NO(82) | 0)
|
||||
+#define MT8127_PIN_82_UTXD1__FUNC_UTXD1 (MTK_PIN_NO(82) | 1)
|
||||
+#define MT8127_PIN_82_UTXD1__FUNC_URXD1 (MTK_PIN_NO(82) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_83_LCM_RST__FUNC_GPIO83 (MTK_PIN_NO(83) | 0)
|
||||
+#define MT8127_PIN_83_LCM_RST__FUNC_LCM_RST (MTK_PIN_NO(83) | 1)
|
||||
+#define MT8127_PIN_83_LCM_RST__FUNC_VDAC_CK_XI (MTK_PIN_NO(83) | 2)
|
||||
+#define MT8127_PIN_83_LCM_RST__FUNC_DBG_MON_A_31 (MTK_PIN_NO(83) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_84_DSI_TE__FUNC_GPIO84 (MTK_PIN_NO(84) | 0)
|
||||
+#define MT8127_PIN_84_DSI_TE__FUNC_DSI_TE (MTK_PIN_NO(84) | 1)
|
||||
+#define MT8127_PIN_84_DSI_TE__FUNC_DBG_MON_A_32 (MTK_PIN_NO(84) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_85_MSDC2_CMD__FUNC_GPIO85 (MTK_PIN_NO(85) | 0)
|
||||
+#define MT8127_PIN_85_MSDC2_CMD__FUNC_MSDC2_CMD (MTK_PIN_NO(85) | 1)
|
||||
+#define MT8127_PIN_85_MSDC2_CMD__FUNC_ANT_SEL0 (MTK_PIN_NO(85) | 2)
|
||||
+#define MT8127_PIN_85_MSDC2_CMD__FUNC_SDA1 (MTK_PIN_NO(85) | 3)
|
||||
+#define MT8127_PIN_85_MSDC2_CMD__FUNC_I2SOUT_BCK (MTK_PIN_NO(85) | 6)
|
||||
+#define MT8127_PIN_85_MSDC2_CMD__FUNC_DBG_MON_B_22 (MTK_PIN_NO(85) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_86_MSDC2_CLK__FUNC_GPIO86 (MTK_PIN_NO(86) | 0)
|
||||
+#define MT8127_PIN_86_MSDC2_CLK__FUNC_MSDC2_CLK (MTK_PIN_NO(86) | 1)
|
||||
+#define MT8127_PIN_86_MSDC2_CLK__FUNC_ANT_SEL1 (MTK_PIN_NO(86) | 2)
|
||||
+#define MT8127_PIN_86_MSDC2_CLK__FUNC_SCL1 (MTK_PIN_NO(86) | 3)
|
||||
+#define MT8127_PIN_86_MSDC2_CLK__FUNC_I2SOUT_LRCK (MTK_PIN_NO(86) | 6)
|
||||
+#define MT8127_PIN_86_MSDC2_CLK__FUNC_DBG_MON_B_23 (MTK_PIN_NO(86) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_87_MSDC2_DAT0__FUNC_GPIO87 (MTK_PIN_NO(87) | 0)
|
||||
+#define MT8127_PIN_87_MSDC2_DAT0__FUNC_MSDC2_DAT0 (MTK_PIN_NO(87) | 1)
|
||||
+#define MT8127_PIN_87_MSDC2_DAT0__FUNC_ANT_SEL2 (MTK_PIN_NO(87) | 2)
|
||||
+#define MT8127_PIN_87_MSDC2_DAT0__FUNC_UTXD0 (MTK_PIN_NO(87) | 5)
|
||||
+#define MT8127_PIN_87_MSDC2_DAT0__FUNC_I2SOUT_DATA_OUT (MTK_PIN_NO(87) | 6)
|
||||
+#define MT8127_PIN_87_MSDC2_DAT0__FUNC_DBG_MON_B_24 (MTK_PIN_NO(87) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_88_MSDC2_DAT1__FUNC_GPIO88 (MTK_PIN_NO(88) | 0)
|
||||
+#define MT8127_PIN_88_MSDC2_DAT1__FUNC_MSDC2_DAT1 (MTK_PIN_NO(88) | 1)
|
||||
+#define MT8127_PIN_88_MSDC2_DAT1__FUNC_ANT_SEL3 (MTK_PIN_NO(88) | 2)
|
||||
+#define MT8127_PIN_88_MSDC2_DAT1__FUNC_PWM0 (MTK_PIN_NO(88) | 3)
|
||||
+#define MT8127_PIN_88_MSDC2_DAT1__FUNC_URXD0 (MTK_PIN_NO(88) | 5)
|
||||
+#define MT8127_PIN_88_MSDC2_DAT1__FUNC_PWM1 (MTK_PIN_NO(88) | 6)
|
||||
+#define MT8127_PIN_88_MSDC2_DAT1__FUNC_DBG_MON_B_25 (MTK_PIN_NO(88) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_89_MSDC2_DAT2__FUNC_GPIO89 (MTK_PIN_NO(89) | 0)
|
||||
+#define MT8127_PIN_89_MSDC2_DAT2__FUNC_MSDC2_DAT2 (MTK_PIN_NO(89) | 1)
|
||||
+#define MT8127_PIN_89_MSDC2_DAT2__FUNC_ANT_SEL4 (MTK_PIN_NO(89) | 2)
|
||||
+#define MT8127_PIN_89_MSDC2_DAT2__FUNC_SDA2 (MTK_PIN_NO(89) | 3)
|
||||
+#define MT8127_PIN_89_MSDC2_DAT2__FUNC_UTXD1 (MTK_PIN_NO(89) | 5)
|
||||
+#define MT8127_PIN_89_MSDC2_DAT2__FUNC_PWM2 (MTK_PIN_NO(89) | 6)
|
||||
+#define MT8127_PIN_89_MSDC2_DAT2__FUNC_DBG_MON_B_26 (MTK_PIN_NO(89) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_90_MSDC2_DAT3__FUNC_GPIO90 (MTK_PIN_NO(90) | 0)
|
||||
+#define MT8127_PIN_90_MSDC2_DAT3__FUNC_MSDC2_DAT3 (MTK_PIN_NO(90) | 1)
|
||||
+#define MT8127_PIN_90_MSDC2_DAT3__FUNC_ANT_SEL5 (MTK_PIN_NO(90) | 2)
|
||||
+#define MT8127_PIN_90_MSDC2_DAT3__FUNC_SCL2 (MTK_PIN_NO(90) | 3)
|
||||
+#define MT8127_PIN_90_MSDC2_DAT3__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(90) | 4)
|
||||
+#define MT8127_PIN_90_MSDC2_DAT3__FUNC_URXD1 (MTK_PIN_NO(90) | 5)
|
||||
+#define MT8127_PIN_90_MSDC2_DAT3__FUNC_PWM3 (MTK_PIN_NO(90) | 6)
|
||||
+#define MT8127_PIN_90_MSDC2_DAT3__FUNC_DBG_MON_B_27 (MTK_PIN_NO(90) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_91_TDN3__FUNC_GPI91 (MTK_PIN_NO(91) | 0)
|
||||
+#define MT8127_PIN_91_TDN3__FUNC_TDN3 (MTK_PIN_NO(91) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_92_TDP3__FUNC_GPI92 (MTK_PIN_NO(92) | 0)
|
||||
+#define MT8127_PIN_92_TDP3__FUNC_TDP3 (MTK_PIN_NO(92) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_93_TDN2__FUNC_GPI93 (MTK_PIN_NO(93) | 0)
|
||||
+#define MT8127_PIN_93_TDN2__FUNC_TDN2 (MTK_PIN_NO(93) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_94_TDP2__FUNC_GPI94 (MTK_PIN_NO(94) | 0)
|
||||
+#define MT8127_PIN_94_TDP2__FUNC_TDP2 (MTK_PIN_NO(94) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_95_TCN__FUNC_GPI95 (MTK_PIN_NO(95) | 0)
|
||||
+#define MT8127_PIN_95_TCN__FUNC_TCN (MTK_PIN_NO(95) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_96_TCP__FUNC_GPI96 (MTK_PIN_NO(96) | 0)
|
||||
+#define MT8127_PIN_96_TCP__FUNC_TCP (MTK_PIN_NO(96) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_97_TDN1__FUNC_GPI97 (MTK_PIN_NO(97) | 0)
|
||||
+#define MT8127_PIN_97_TDN1__FUNC_TDN1 (MTK_PIN_NO(97) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_98_TDP1__FUNC_GPI98 (MTK_PIN_NO(98) | 0)
|
||||
+#define MT8127_PIN_98_TDP1__FUNC_TDP1 (MTK_PIN_NO(98) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_99_TDN0__FUNC_GPI99 (MTK_PIN_NO(99) | 0)
|
||||
+#define MT8127_PIN_99_TDN0__FUNC_TDN0 (MTK_PIN_NO(99) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_100_TDP0__FUNC_GPI100 (MTK_PIN_NO(100) | 0)
|
||||
+#define MT8127_PIN_100_TDP0__FUNC_TDP0 (MTK_PIN_NO(100) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_101_RDN0__FUNC_GPI101 (MTK_PIN_NO(101) | 0)
|
||||
+#define MT8127_PIN_101_RDN0__FUNC_RDN0 (MTK_PIN_NO(101) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_102_RDP0__FUNC_GPI102 (MTK_PIN_NO(102) | 0)
|
||||
+#define MT8127_PIN_102_RDP0__FUNC_RDP0 (MTK_PIN_NO(102) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_103_RDN1__FUNC_GPI103 (MTK_PIN_NO(103) | 0)
|
||||
+#define MT8127_PIN_103_RDN1__FUNC_RDN1 (MTK_PIN_NO(103) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_104_RDP1__FUNC_GPI104 (MTK_PIN_NO(104) | 0)
|
||||
+#define MT8127_PIN_104_RDP1__FUNC_RDP1 (MTK_PIN_NO(104) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_105_RCN__FUNC_GPI105 (MTK_PIN_NO(105) | 0)
|
||||
+#define MT8127_PIN_105_RCN__FUNC_RCN (MTK_PIN_NO(105) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_106_RCP__FUNC_GPI106 (MTK_PIN_NO(106) | 0)
|
||||
+#define MT8127_PIN_106_RCP__FUNC_RCP (MTK_PIN_NO(106) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_107_RDN2__FUNC_GPI107 (MTK_PIN_NO(107) | 0)
|
||||
+#define MT8127_PIN_107_RDN2__FUNC_RDN2 (MTK_PIN_NO(107) | 1)
|
||||
+#define MT8127_PIN_107_RDN2__FUNC_CMDAT8 (MTK_PIN_NO(107) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_108_RDP2__FUNC_GPI108 (MTK_PIN_NO(108) | 0)
|
||||
+#define MT8127_PIN_108_RDP2__FUNC_RDP2 (MTK_PIN_NO(108) | 1)
|
||||
+#define MT8127_PIN_108_RDP2__FUNC_CMDAT9 (MTK_PIN_NO(108) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_109_RDN3__FUNC_GPI109 (MTK_PIN_NO(109) | 0)
|
||||
+#define MT8127_PIN_109_RDN3__FUNC_RDN3 (MTK_PIN_NO(109) | 1)
|
||||
+#define MT8127_PIN_109_RDN3__FUNC_CMDAT4 (MTK_PIN_NO(109) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_110_RDP3__FUNC_GPI110 (MTK_PIN_NO(110) | 0)
|
||||
+#define MT8127_PIN_110_RDP3__FUNC_RDP3 (MTK_PIN_NO(110) | 1)
|
||||
+#define MT8127_PIN_110_RDP3__FUNC_CMDAT5 (MTK_PIN_NO(110) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_111_RCN_A__FUNC_GPI111 (MTK_PIN_NO(111) | 0)
|
||||
+#define MT8127_PIN_111_RCN_A__FUNC_RCN_A (MTK_PIN_NO(111) | 1)
|
||||
+#define MT8127_PIN_111_RCN_A__FUNC_CMDAT6 (MTK_PIN_NO(111) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_112_RCP_A__FUNC_GPI112 (MTK_PIN_NO(112) | 0)
|
||||
+#define MT8127_PIN_112_RCP_A__FUNC_RCP_A (MTK_PIN_NO(112) | 1)
|
||||
+#define MT8127_PIN_112_RCP_A__FUNC_CMDAT7 (MTK_PIN_NO(112) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_113_RDN1_A__FUNC_GPI113 (MTK_PIN_NO(113) | 0)
|
||||
+#define MT8127_PIN_113_RDN1_A__FUNC_RDN1_A (MTK_PIN_NO(113) | 1)
|
||||
+#define MT8127_PIN_113_RDN1_A__FUNC_CMDAT2 (MTK_PIN_NO(113) | 2)
|
||||
+#define MT8127_PIN_113_RDN1_A__FUNC_CMCSD2 (MTK_PIN_NO(113) | 3)
|
||||
+
|
||||
+#define MT8127_PIN_114_RDP1_A__FUNC_GPI114 (MTK_PIN_NO(114) | 0)
|
||||
+#define MT8127_PIN_114_RDP1_A__FUNC_RDP1_A (MTK_PIN_NO(114) | 1)
|
||||
+#define MT8127_PIN_114_RDP1_A__FUNC_CMDAT3 (MTK_PIN_NO(114) | 2)
|
||||
+#define MT8127_PIN_114_RDP1_A__FUNC_CMCSD3 (MTK_PIN_NO(114) | 3)
|
||||
+
|
||||
+#define MT8127_PIN_115_RDN0_A__FUNC_GPI115 (MTK_PIN_NO(115) | 0)
|
||||
+#define MT8127_PIN_115_RDN0_A__FUNC_RDN0_A (MTK_PIN_NO(115) | 1)
|
||||
+#define MT8127_PIN_115_RDN0_A__FUNC_CMHSYNC (MTK_PIN_NO(115) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_116_RDP0_A__FUNC_GPI116 (MTK_PIN_NO(116) | 0)
|
||||
+#define MT8127_PIN_116_RDP0_A__FUNC_RDP0_A (MTK_PIN_NO(116) | 1)
|
||||
+#define MT8127_PIN_116_RDP0_A__FUNC_CMVSYNC (MTK_PIN_NO(116) | 2)
|
||||
+
|
||||
+#define MT8127_PIN_117_CMDAT0__FUNC_GPIO117 (MTK_PIN_NO(117) | 0)
|
||||
+#define MT8127_PIN_117_CMDAT0__FUNC_CMDAT0 (MTK_PIN_NO(117) | 1)
|
||||
+#define MT8127_PIN_117_CMDAT0__FUNC_CMCSD0 (MTK_PIN_NO(117) | 2)
|
||||
+#define MT8127_PIN_117_CMDAT0__FUNC_ANT_SEL2 (MTK_PIN_NO(117) | 3)
|
||||
+#define MT8127_PIN_117_CMDAT0__FUNC_DBG_MON_B_28 (MTK_PIN_NO(117) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_118_CMDAT1__FUNC_GPIO118 (MTK_PIN_NO(118) | 0)
|
||||
+#define MT8127_PIN_118_CMDAT1__FUNC_CMDAT1 (MTK_PIN_NO(118) | 1)
|
||||
+#define MT8127_PIN_118_CMDAT1__FUNC_CMCSD1 (MTK_PIN_NO(118) | 2)
|
||||
+#define MT8127_PIN_118_CMDAT1__FUNC_ANT_SEL3 (MTK_PIN_NO(118) | 3)
|
||||
+#define MT8127_PIN_118_CMDAT1__FUNC_DBG_MON_B_29 (MTK_PIN_NO(118) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_119_CMMCLK__FUNC_GPIO119 (MTK_PIN_NO(119) | 0)
|
||||
+#define MT8127_PIN_119_CMMCLK__FUNC_CMMCLK (MTK_PIN_NO(119) | 1)
|
||||
+#define MT8127_PIN_119_CMMCLK__FUNC_ANT_SEL4 (MTK_PIN_NO(119) | 3)
|
||||
+#define MT8127_PIN_119_CMMCLK__FUNC_DBG_MON_B_30 (MTK_PIN_NO(119) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_120_CMPCLK__FUNC_GPIO120 (MTK_PIN_NO(120) | 0)
|
||||
+#define MT8127_PIN_120_CMPCLK__FUNC_CMPCLK (MTK_PIN_NO(120) | 1)
|
||||
+#define MT8127_PIN_120_CMPCLK__FUNC_CMCSK (MTK_PIN_NO(120) | 2)
|
||||
+#define MT8127_PIN_120_CMPCLK__FUNC_ANT_SEL5 (MTK_PIN_NO(120) | 3)
|
||||
+#define MT8127_PIN_120_CMPCLK__FUNC_DBG_MON_B_31 (MTK_PIN_NO(120) | 7)
|
||||
+
|
||||
+#define MT8127_PIN_121_MSDC1_CMD__FUNC_GPIO121 (MTK_PIN_NO(121) | 0)
|
||||
+#define MT8127_PIN_121_MSDC1_CMD__FUNC_MSDC1_CMD (MTK_PIN_NO(121) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_122_MSDC1_CLK__FUNC_GPIO122 (MTK_PIN_NO(122) | 0)
|
||||
+#define MT8127_PIN_122_MSDC1_CLK__FUNC_MSDC1_CLK (MTK_PIN_NO(122) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_123_MSDC1_DAT0__FUNC_GPIO123 (MTK_PIN_NO(123) | 0)
|
||||
+#define MT8127_PIN_123_MSDC1_DAT0__FUNC_MSDC1_DAT0 (MTK_PIN_NO(123) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_124_MSDC1_DAT1__FUNC_GPIO124 (MTK_PIN_NO(124) | 0)
|
||||
+#define MT8127_PIN_124_MSDC1_DAT1__FUNC_MSDC1_DAT1 (MTK_PIN_NO(124) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_125_MSDC1_DAT2__FUNC_GPIO125 (MTK_PIN_NO(125) | 0)
|
||||
+#define MT8127_PIN_125_MSDC1_DAT2__FUNC_MSDC1_DAT2 (MTK_PIN_NO(125) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_126_MSDC1_DAT3__FUNC_GPIO126 (MTK_PIN_NO(126) | 0)
|
||||
+#define MT8127_PIN_126_MSDC1_DAT3__FUNC_MSDC1_DAT3 (MTK_PIN_NO(126) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_127_MSDC0_DAT7__FUNC_GPIO127 (MTK_PIN_NO(127) | 0)
|
||||
+#define MT8127_PIN_127_MSDC0_DAT7__FUNC_MSDC0_DAT7 (MTK_PIN_NO(127) | 1)
|
||||
+#define MT8127_PIN_127_MSDC0_DAT7__FUNC_NLD7 (MTK_PIN_NO(127) | 4)
|
||||
+
|
||||
+#define MT8127_PIN_128_MSDC0_DAT6__FUNC_GPIO128 (MTK_PIN_NO(128) | 0)
|
||||
+#define MT8127_PIN_128_MSDC0_DAT6__FUNC_MSDC0_DAT6 (MTK_PIN_NO(128) | 1)
|
||||
+#define MT8127_PIN_128_MSDC0_DAT6__FUNC_NLD6 (MTK_PIN_NO(128) | 4)
|
||||
+
|
||||
+#define MT8127_PIN_129_MSDC0_DAT5__FUNC_GPIO129 (MTK_PIN_NO(129) | 0)
|
||||
+#define MT8127_PIN_129_MSDC0_DAT5__FUNC_MSDC0_DAT5 (MTK_PIN_NO(129) | 1)
|
||||
+#define MT8127_PIN_129_MSDC0_DAT5__FUNC_NLD4 (MTK_PIN_NO(129) | 4)
|
||||
+
|
||||
+#define MT8127_PIN_130_MSDC0_DAT4__FUNC_GPIO130 (MTK_PIN_NO(130) | 0)
|
||||
+#define MT8127_PIN_130_MSDC0_DAT4__FUNC_MSDC0_DAT4 (MTK_PIN_NO(130) | 1)
|
||||
+#define MT8127_PIN_130_MSDC0_DAT4__FUNC_NLD3 (MTK_PIN_NO(130) | 4)
|
||||
+
|
||||
+#define MT8127_PIN_131_MSDC0_RSTB__FUNC_GPIO131 (MTK_PIN_NO(131) | 0)
|
||||
+#define MT8127_PIN_131_MSDC0_RSTB__FUNC_MSDC0_RSTB (MTK_PIN_NO(131) | 1)
|
||||
+#define MT8127_PIN_131_MSDC0_RSTB__FUNC_NLD0 (MTK_PIN_NO(131) | 4)
|
||||
+
|
||||
+#define MT8127_PIN_132_MSDC0_CMD__FUNC_GPIO132 (MTK_PIN_NO(132) | 0)
|
||||
+#define MT8127_PIN_132_MSDC0_CMD__FUNC_MSDC0_CMD (MTK_PIN_NO(132) | 1)
|
||||
+#define MT8127_PIN_132_MSDC0_CMD__FUNC_NALE (MTK_PIN_NO(132) | 4)
|
||||
+
|
||||
+#define MT8127_PIN_133_MSDC0_CLK__FUNC_GPIO133 (MTK_PIN_NO(133) | 0)
|
||||
+#define MT8127_PIN_133_MSDC0_CLK__FUNC_MSDC0_CLK (MTK_PIN_NO(133) | 1)
|
||||
+#define MT8127_PIN_133_MSDC0_CLK__FUNC_NWEB (MTK_PIN_NO(133) | 4)
|
||||
+
|
||||
+#define MT8127_PIN_134_MSDC0_DAT3__FUNC_GPIO134 (MTK_PIN_NO(134) | 0)
|
||||
+#define MT8127_PIN_134_MSDC0_DAT3__FUNC_MSDC0_DAT3 (MTK_PIN_NO(134) | 1)
|
||||
+#define MT8127_PIN_134_MSDC0_DAT3__FUNC_NLD1 (MTK_PIN_NO(134) | 4)
|
||||
+
|
||||
+#define MT8127_PIN_135_MSDC0_DAT2__FUNC_GPIO135 (MTK_PIN_NO(135) | 0)
|
||||
+#define MT8127_PIN_135_MSDC0_DAT2__FUNC_MSDC0_DAT2 (MTK_PIN_NO(135) | 1)
|
||||
+#define MT8127_PIN_135_MSDC0_DAT2__FUNC_NLD5 (MTK_PIN_NO(135) | 4)
|
||||
+
|
||||
+#define MT8127_PIN_136_MSDC0_DAT1__FUNC_GPIO136 (MTK_PIN_NO(136) | 0)
|
||||
+#define MT8127_PIN_136_MSDC0_DAT1__FUNC_MSDC0_DAT1 (MTK_PIN_NO(136) | 1)
|
||||
+#define MT8127_PIN_136_MSDC0_DAT1__FUNC_NLD8 (MTK_PIN_NO(136) | 4)
|
||||
+
|
||||
+#define MT8127_PIN_137_MSDC0_DAT0__FUNC_GPIO137 (MTK_PIN_NO(137) | 0)
|
||||
+#define MT8127_PIN_137_MSDC0_DAT0__FUNC_MSDC0_DAT0 (MTK_PIN_NO(137) | 1)
|
||||
+#define MT8127_PIN_137_MSDC0_DAT0__FUNC_WATCHDOG (MTK_PIN_NO(137) | 4)
|
||||
+#define MT8127_PIN_137_MSDC0_DAT0__FUNC_NLD2 (MTK_PIN_NO(137) | 5)
|
||||
+
|
||||
+#define MT8127_PIN_138_CEC__FUNC_GPIO138 (MTK_PIN_NO(138) | 0)
|
||||
+#define MT8127_PIN_138_CEC__FUNC_CEC (MTK_PIN_NO(138) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_139_HTPLG__FUNC_GPIO139 (MTK_PIN_NO(139) | 0)
|
||||
+#define MT8127_PIN_139_HTPLG__FUNC_HTPLG (MTK_PIN_NO(139) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_140_HDMISCK__FUNC_GPIO140 (MTK_PIN_NO(140) | 0)
|
||||
+#define MT8127_PIN_140_HDMISCK__FUNC_HDMISCK (MTK_PIN_NO(140) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_141_HDMISD__FUNC_GPIO141 (MTK_PIN_NO(141) | 0)
|
||||
+#define MT8127_PIN_141_HDMISD__FUNC_HDMISD (MTK_PIN_NO(141) | 1)
|
||||
+
|
||||
+#define MT8127_PIN_142_EINT21__FUNC_GPIO142 (MTK_PIN_NO(142) | 0)
|
||||
+#define MT8127_PIN_142_EINT21__FUNC_NRNB (MTK_PIN_NO(142) | 1)
|
||||
+#define MT8127_PIN_142_EINT21__FUNC_ANT_SEL0 (MTK_PIN_NO(142) | 2)
|
||||
+#define MT8127_PIN_142_EINT21__FUNC_DBG_MON_B_32 (MTK_PIN_NO(142) | 7)
|
||||
+
|
||||
+#endif /* __DTS_MT8127_PINFUNC_H */
|
||||
diff --git a/arch/arm/boot/dts/mt8127.dtsi b/arch/arm/boot/dts/mt8127.dtsi
|
||||
index 7c2090d..1d429ed 100644
|
||||
--- a/arch/arm/boot/dts/mt8127.dtsi
|
||||
+++ b/arch/arm/boot/dts/mt8127.dtsi
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
+#include "mt8127-pinfunc.h"
|
||||
#include "skeleton64.dtsi"
|
||||
|
||||
/ {
|
||||
@@ -94,6 +95,27 @@
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
+ /*
|
||||
+ * Pinctrl access register at 0x10005000 through regmap.
|
||||
+ * Register 0x1000b000 is used by EINT.
|
||||
+ */
|
||||
+ pio: pinctrl@10005000 {
|
||||
+ compatible = "mediatek,mt8127-pinctrl";
|
||||
+ reg = <0 0x1000b000 0 0x1000>;
|
||||
+ mediatek,pctl-regmap = <&syscfg_pctl_a>;
|
||||
+ pins-are-numbered;
|
||||
+ gpio-controller;
|
||||
+ #gpio-cells = <2>;
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <2>;
|
||||
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ };
|
||||
+
|
||||
+ syscfg_pctl_a: syscfg_pctl_a@10005000 {
|
||||
+ compatible = "mediatek,mt8127-pctl-a-syscfg", "syscon";
|
||||
+ reg = <0 0x10005000 0 0x1000>;
|
||||
+ };
|
||||
+
|
||||
timer: timer@10008000 {
|
||||
compatible = "mediatek,mt8127-timer",
|
||||
"mediatek,mt6577-timer";
|
||||
--
|
||||
1.7.10.4
|
||||
|
27
target/linux/mediatek/patches/0057-thermal-oops.patch
Normal file
27
target/linux/mediatek/patches/0057-thermal-oops.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From d1a856804b84affae30274b391b3c685e901093f Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sat, 27 Jun 2015 11:35:29 +0200
|
||||
Subject: [PATCH 57/76] thermal oops
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/thermal/mtk_thermal.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
|
||||
index 27aab12..5fdcbf6 100644
|
||||
--- a/drivers/thermal/mtk_thermal.c
|
||||
+++ b/drivers/thermal/mtk_thermal.c
|
||||
@@ -394,7 +394,8 @@ static irqreturn_t mtk_thermal_irq(int irq, void *dev_id)
|
||||
|
||||
for (i = 0; i < MT8173_NUM_BANKS; i++) {
|
||||
if (!(irqstat & (1 << i)))
|
||||
- mtk_thermal_irq_bank(&mt->banks[i]);
|
||||
+ if (!IS_ERR(mt->banks[i].tz))
|
||||
+ mtk_thermal_irq_bank(&mt->banks[i]);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
--
|
||||
1.7.10.4
|
||||
|
25
target/linux/mediatek/patches/0058-dont-disable-clocks.patch
Normal file
25
target/linux/mediatek/patches/0058-dont-disable-clocks.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From b1c69201563ae3ff878abf4ba192e73031de8653 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Tue, 23 Jun 2015 23:46:00 +0200
|
||||
Subject: [PATCH 58/76] dont disable clocks
|
||||
|
||||
---
|
||||
drivers/clk/clk.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
|
||||
index 5b0f418..360e6e4 100644
|
||||
--- a/drivers/clk/clk.c
|
||||
+++ b/drivers/clk/clk.c
|
||||
@@ -541,7 +541,7 @@ unlock_out:
|
||||
clk_enable_unlock(flags);
|
||||
}
|
||||
|
||||
-static bool clk_ignore_unused;
|
||||
+static bool clk_ignore_unused = true;
|
||||
static int __init clk_ignore_unused_setup(char *__unused)
|
||||
{
|
||||
clk_ignore_unused = true;
|
||||
--
|
||||
1.7.10.4
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,26 @@
|
||||
From 46c695d8285b73d39b0e16fcfd7da332fd2398d4 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sat, 27 Jun 2015 13:00:27 +0200
|
||||
Subject: [PATCH 60/76] arm: mediatek: select the arm timer by default
|
||||
|
||||
select ARM_ARCH_TIMER inside the Kconfig
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/arm/mach-mediatek/Kconfig | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
|
||||
index 9f59e58..7704818 100644
|
||||
--- a/arch/arm/mach-mediatek/Kconfig
|
||||
+++ b/arch/arm/mach-mediatek/Kconfig
|
||||
@@ -1,5 +1,6 @@
|
||||
menuconfig ARCH_MEDIATEK
|
||||
bool "Mediatek MT65xx & MT81xx SoC" if ARCH_MULTI_V7
|
||||
+ select ARM_ARCH_TIMER
|
||||
select ARM_GIC
|
||||
select PINCTRL
|
||||
select MTK_TIMER
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,846 @@
|
||||
From 7342787e992a70443081b9203d2131cbf6bc3562 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sat, 27 Jun 2015 13:12:38 +0200
|
||||
Subject: [PATCH 61/76] arm: mediatek: add mt7623 clock
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/clk/mediatek/Makefile | 1 +
|
||||
drivers/clk/mediatek/clk-mt7623.c | 634 ++++++++++++++++++++++++++++++++
|
||||
include/dt-bindings/clock/mt7623-clk.h | 173 +++++++++
|
||||
3 files changed, 808 insertions(+)
|
||||
create mode 100644 drivers/clk/mediatek/clk-mt7623.c
|
||||
create mode 100644 include/dt-bindings/clock/mt7623-clk.h
|
||||
|
||||
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
|
||||
index 8e4b2a4..19a3763 100644
|
||||
--- a/drivers/clk/mediatek/Makefile
|
||||
+++ b/drivers/clk/mediatek/Makefile
|
||||
@@ -1,4 +1,5 @@
|
||||
obj-y += clk-mtk.o clk-pll.o clk-gate.o
|
||||
obj-$(CONFIG_RESET_CONTROLLER) += reset.o
|
||||
+obj-y += clk-mt7623.o
|
||||
obj-y += clk-mt8135.o
|
||||
obj-y += clk-mt8173.o
|
||||
diff --git a/drivers/clk/mediatek/clk-mt7623.c b/drivers/clk/mediatek/clk-mt7623.c
|
||||
new file mode 100644
|
||||
index 0000000..07843bb
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/mediatek/clk-mt7623.c
|
||||
@@ -0,0 +1,634 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2014 MediaTek Inc.
|
||||
+ * Author: James Liao <jamesjj.liao@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <dt-bindings/clock/mt7623-clk.h>
|
||||
+
|
||||
+#include "clk-mtk.h"
|
||||
+#include "clk-gate.h"
|
||||
+
|
||||
+static DEFINE_SPINLOCK(mt7623_clk_lock);
|
||||
+
|
||||
+static struct clk_onecell_data *mt7623_top_clk_data;
|
||||
+static struct clk_onecell_data *mt7623_pll_clk_data;
|
||||
+
|
||||
+static void 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_DDR_SEL]);
|
||||
+ clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_RTC_SEL]);
|
||||
+}
|
||||
+
|
||||
+static const struct mtk_fixed_factor root_clk_alias[] __initconst = {
|
||||
+ FACTOR(CLK_TOP_DSI0_LNTC_DSICLK, "dsi0_lntc_dsiclk", "clk_null", 1, 1),
|
||||
+ FACTOR(CLK_TOP_HDMITX_CLKDIG_CTS, "hdmitx_clkdig_cts", "clk_null", 1, 1),
|
||||
+ FACTOR(CLK_TOP_CLKPH_MCK, "clkph_mck", "clk_null", 1, 1),
|
||||
+ FACTOR(CLK_TOP_CPUM_TCK_IN, "cpum_tck_in", "clk_null", 1, 1),
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_fixed_factor top_divs[] __initconst = {
|
||||
+ FACTOR(CLK_TOP_MAINPLL_806M, "mainpll_650m", "mainpll", 1, 2),
|
||||
+ FACTOR(CLK_TOP_MAINPLL_537P3M, "mainpll_433p3m", "mainpll", 1, 3),
|
||||
+ FACTOR(CLK_TOP_MAINPLL_322P4M, "mainpll_260m", "mainpll", 1, 5),
|
||||
+ FACTOR(CLK_TOP_MAINPLL_230P3M, "mainpll_185p6m", "mainpll", 1, 7),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_624M, "univpll_624m", "univpll", 1, 2),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_416M, "univpll_416m", "univpll", 1, 3),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_249P6M, "univpll_249p6m", "univpll", 1, 5),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_178P3M, "univpll_178p3m", "univpll", 1, 7),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_48M, "univpll_48m", "univpll", 1, 26),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_AUDPLL_D4, "audpll_d4", "audpll", 1, 4),
|
||||
+ FACTOR(CLK_TOP_AUDPLL_D8, "audpll_d8", "audpll", 1, 8),
|
||||
+ FACTOR(CLK_TOP_AUDPLL_D16, "audpll_d16", "audpll", 1, 16),
|
||||
+ FACTOR(CLK_TOP_AUDPLL_24, "audpll_d24", "audpll", 1, 24),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2),
|
||||
+ FACTOR(CLK_TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4),
|
||||
+ FACTOR(CLK_TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8),
|
||||
+ FACTOR(CLK_TOP_LVDS_ETH, "lvdspll_eth", "lvdspll", 1, 16),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "mainpll_650m", 1, 2),
|
||||
+ FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "mainpll_650m", 1, 4),
|
||||
+ FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "mainpll_650m", 1, 8),
|
||||
+ FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "mainpll_650m", 1, 16),
|
||||
+ FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "mainpll_650m", 1, 2),
|
||||
+ FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "mainpll_650m", 1, 4),
|
||||
+ FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "mainpll_650m", 1, 8),
|
||||
+ FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "mainpll_650m", 1, 2),
|
||||
+ FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "mainpll_650m", 1, 4),
|
||||
+ FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "mainpll_650m", 1, 2),
|
||||
+ FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "mainpll_650m", 1, 4),
|
||||
+ FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll_433p3m", 1, 1),
|
||||
+ FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll_260m", 1, 1),
|
||||
+ FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll_185p6m", 1, 1),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_TVDPLL_d2, "tvdpll_d2", "tvdpll", 1, 2),
|
||||
+ FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_624m", 1, 2),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_624m", 1, 4),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_624m", 1, 8),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL1_D10, "univpll1_d10", "univpll_624m", 1, 10),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_416m", 1, 2),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_416m", 1, 4),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_416m", 1, 8),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_624m", 1, 2),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_624m", 1, 4),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL1_D6, "univpll1_d6", "univpll_624m", 1, 6),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_624m", 1, 8),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL1_D10, "univpll1_d10", "univpll_624m", 1, 10),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_416m", 1, 2),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_416m", 1, 4),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL2_D6, "univpll2_d6", "univpll_416m", 1, 6),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_416m", 1, 8),
|
||||
+
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll_249p6m", 1, 1),
|
||||
+ FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll_48m", 1, 1),
|
||||
+
|
||||
+
|
||||
+ FACTOR(CLK_TOP_MEMPLL_MCK_D4, "mempll_mck_d4", "clkph_mck", 1, 4),
|
||||
+};
|
||||
+
|
||||
+static const char * const axi_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll1_d2",
|
||||
+ "syspll_d5",
|
||||
+ "syspll1_d4",
|
||||
+ "univpll_d5",
|
||||
+ "univpll2_d2",
|
||||
+ "dmpll_ck",
|
||||
+ "dmpll_d2"
|
||||
+};
|
||||
+
|
||||
+static const char * const mem_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "dmpll_ck",
|
||||
+};
|
||||
+
|
||||
+static const char * const ddr_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll1_d8",
|
||||
+};
|
||||
+
|
||||
+static const char * const mm_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "clk26m",
|
||||
+ "vencpll_ck",
|
||||
+ "syspll1_d2",
|
||||
+ "syspll1_d4",
|
||||
+ "univpll_d5",
|
||||
+ "univpll1_d2",
|
||||
+ "univpll2_d2",
|
||||
+ "dmpll_ck"
|
||||
+};
|
||||
+
|
||||
+static const char * const pwm_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "univpll2_d4",
|
||||
+ "univpll3_d2",
|
||||
+ "univpll1_d4",
|
||||
+};
|
||||
+
|
||||
+static const char * const vdec_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll1_d2",
|
||||
+ "syspll_d5",
|
||||
+ "syspll1_d4",
|
||||
+ "univpll_d5",
|
||||
+ "univpll2_d2",
|
||||
+ "univpll2_d4",
|
||||
+ "msdcpll_d2",
|
||||
+ "mmpll_d2",
|
||||
+};
|
||||
+
|
||||
+static const char * const mfg_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "mmpll_ck",
|
||||
+ "dmpll_x2_ck",
|
||||
+ "msdcpll_ck",
|
||||
+ "clk26m",
|
||||
+ "syspll_d3",
|
||||
+ "univpll_d3",
|
||||
+ "univpll1_d2",
|
||||
+};
|
||||
+
|
||||
+static const char * const cam_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "univpll_d26",
|
||||
+ "univpll2_d2",
|
||||
+ "syspll3_d2",
|
||||
+ "syspll3_d4",
|
||||
+ "msdcpll_d2",
|
||||
+ "mmpll_d2",
|
||||
+ "clk26m",
|
||||
+};
|
||||
+
|
||||
+static const char * const uart_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "univpll2_d8",
|
||||
+};
|
||||
+
|
||||
+static const char * const spi_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll3_d2",
|
||||
+ "syspll4_d2",
|
||||
+ "univpll2_d4",
|
||||
+ "univpll1_d8",
|
||||
+};
|
||||
+
|
||||
+static const char * const usb20_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "univpll1_d8",
|
||||
+ "univpll3_d4",
|
||||
+ "clk26m",
|
||||
+};
|
||||
+
|
||||
+static const char * const msdc_30_0_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "msdcpll_d2",
|
||||
+ "syspll2_d2",
|
||||
+ "syspll1_d4",
|
||||
+ "univpll1_d4",
|
||||
+ "univpll2_d4",
|
||||
+ "clk26m",
|
||||
+ "clk26m",
|
||||
+};
|
||||
+
|
||||
+static const char * const msdc_30_1_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "msdcpll_d2",
|
||||
+ "syspll2_d2",
|
||||
+ "syspll1_d4",
|
||||
+ "univpll1_d4",
|
||||
+ "univpll2_d4",
|
||||
+ "clk26m",
|
||||
+ "clk26m",
|
||||
+};
|
||||
+
|
||||
+static const char * const msdc_30_2_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "msdcpll_d2",
|
||||
+ "syspll2_d2",
|
||||
+ "syspll1_d4",
|
||||
+ "univpll1_d4",
|
||||
+ "univpll2_d4",
|
||||
+ "clk26m",
|
||||
+ "clk26m",
|
||||
+};
|
||||
+
|
||||
+static const char * const audio_parents[] __initconst = {
|
||||
+ "f_f26m_ck",
|
||||
+ "syspll1_d16",
|
||||
+};
|
||||
+
|
||||
+static const char * const audio_intbus_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll1_d4",
|
||||
+ "syspll3_d2",
|
||||
+ "syspll4_d2",
|
||||
+ "univpll3_d2",
|
||||
+ "univpll2_d4",
|
||||
+};
|
||||
+
|
||||
+static const char * const pmic_spi_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll1_d8",
|
||||
+ "syspll2_d4",
|
||||
+ "syspll4_d2",
|
||||
+ "syspll3_d4",
|
||||
+ "syspll2_d8",
|
||||
+ "syspll1_d16",
|
||||
+ "univpll3_d4",
|
||||
+ "univpll_d26",
|
||||
+ "dmpll_d2",
|
||||
+ "dmpll_d4",
|
||||
+};
|
||||
+
|
||||
+static const char * const scp_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll1_d8",
|
||||
+ "dmpll_d2",
|
||||
+ "dmpll_d4",
|
||||
+};
|
||||
+
|
||||
+static const char * const dpi0_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "mipipll",
|
||||
+ "mipipll_d2",
|
||||
+ "mipipll_d4",
|
||||
+ "lvdspll",
|
||||
+ "lvdspll_d2",
|
||||
+ "lvdspll_d4",
|
||||
+ "lvdspll_d8",
|
||||
+};
|
||||
+
|
||||
+static const char * const dpi1_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "tvdpll",
|
||||
+ "tvdpll_d2",
|
||||
+ "tvdpll_d4",
|
||||
+};
|
||||
+
|
||||
+static const char * const tve_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "mipipll",
|
||||
+ "mipipll_d2",
|
||||
+ "mipipll_d4",
|
||||
+ "clk26m",
|
||||
+ "tvdpll",
|
||||
+ "tvdpll_d2",
|
||||
+ "tvdpll_d4",
|
||||
+};
|
||||
+
|
||||
+static const char * const apll_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "audpll",
|
||||
+ "audpll_d4",
|
||||
+ "audpll_d8",
|
||||
+ "audpll_d16",
|
||||
+ "audpll_d24",
|
||||
+ "clk26m",
|
||||
+ "clk26m",
|
||||
+};
|
||||
+
|
||||
+static const char * const dpilvds_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "lvdspll",
|
||||
+ "lvdspll_d2",
|
||||
+ "lvdspll_d4",
|
||||
+ "lvdspll_d8",
|
||||
+ "fpc_ck",
|
||||
+ "clk26m",
|
||||
+ "clk26m",
|
||||
+};
|
||||
+
|
||||
+static const char * const rtc_parents[] __initconst = {
|
||||
+ "clk32k",
|
||||
+ "external_32k",
|
||||
+ "clk26m",
|
||||
+ "univpll3_d8",
|
||||
+};
|
||||
+
|
||||
+static const char * const nfi2x_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll2_d2",
|
||||
+ "syspll_d7",
|
||||
+ "univpll3_d2",
|
||||
+ "syspll2_d4",
|
||||
+ "univpll3_d4",
|
||||
+ "syspll4_d4",
|
||||
+ "clk26m",
|
||||
+};
|
||||
+
|
||||
+static const char * const eth_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "syspll3_d4",
|
||||
+ "univpll2_d8",
|
||||
+ "lvdspll_eth",
|
||||
+ "univpll_d26",
|
||||
+ "syspll2_d8",
|
||||
+ "syspll4_d4",
|
||||
+ "univpll3_d8",
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_composite top_muxes[] __initconst = {
|
||||
+ /* CLK_CFG_0 */
|
||||
+ MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
|
||||
+ 0x0140, 0, 3, INVALID_MUX_GATE_BIT),
|
||||
+ MUX_GATE(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x0040, 8, 2, 15),
|
||||
+ MUX_GATE(CLK_TOP_DDR_SEL, "ddr_sel", ddr_parents, 0x0040, 16, 2, 23),
|
||||
+ MUX_GATE(CLK_TOP_MM_SEL, "mm_sel", mm_parents,
|
||||
+ 0x0140, 24, 3, INVALID_MUX_GATE_BIT),
|
||||
+ /* CLK_CFG_1 */
|
||||
+ MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x0050, 0, 2, 7),
|
||||
+ MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x0050, 8, 4, 15),
|
||||
+ MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0050, 16, 3, 23),
|
||||
+ MUX_GATE(CLK_TOP_CAM_SEL, "cam_sel", cam_parents, 0x0050, 24, 3, 31),
|
||||
+ /* CLK_CFG_2 */
|
||||
+ MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x0060, 0, 1, 7),
|
||||
+ MUX_GATE(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x0060, 8, 3, 15),
|
||||
+ MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x0060, 16, 2, 23),
|
||||
+ MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc_30_0_sel", msdc_30_0_parents, 0x0060, 24, 3, 31),
|
||||
+ /* CLK_CFG_3 */
|
||||
+ MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc_30_1_sel", msdc_30_1_parents, 0x0070, 0, 3, 7),
|
||||
+ MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc_30_2_sel", msdc_30_2_parents, 0x0070, 8, 3, 15),
|
||||
+ MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", audio_parents, 0x0070, 16, 1, 23),
|
||||
+ MUX_GATE(CLK_TOP_AUDIO_INTBUS_SEL,
|
||||
+ "audio_intbus_sel", audio_intbus_parents, 0x0070, 24, 3, 31),
|
||||
+ /* CLK_CFG_4 */
|
||||
+ MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmic_spi_parents, 0x0080, 0, 4, 7),
|
||||
+ MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, 0x0080, 8, 2, 15),
|
||||
+ MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents, 0x0080, 16, 3, 23),
|
||||
+ MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0080, 24, 2, 31),
|
||||
+ /* CLK_CFG_5 */
|
||||
+ MUX_GATE(CLK_TOP_TVE_SEL, "tve_sel", tve_parents, 0x0090, 0, 3, 7),
|
||||
+ MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", apll_parents, 0x0090, 16, 3, 23),
|
||||
+ MUX_GATE(CLK_TOP_DPILVDS_SEL, "dpilvds_sel", dpilvds_parents, 0x0090, 24, 3, 31),
|
||||
+ /* CLK_CFG_6 */
|
||||
+ MUX_GATE(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents, 0x00a0, 0, 2, 7),
|
||||
+ MUX_GATE(CLK_TOP_NFI2X_SEL, "nfi2x_sel", nfi2x_parents, 0x00a0, 8, 3, 15),
|
||||
+ MUX_GATE(CLK_TOP_ETH_SEL, "eth_sel", eth_parents, 0x00a0, 16, 3, 23),
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_gate_regs infra_cg_regs = {
|
||||
+ .set_ofs = 0x0040,
|
||||
+ .clr_ofs = 0x0044,
|
||||
+ .sta_ofs = 0x0048,
|
||||
+};
|
||||
+
|
||||
+#define GATE_ICG(_id, _name, _parent, _shift) { \
|
||||
+ .id = _id, \
|
||||
+ .name = _name, \
|
||||
+ .parent_name = _parent, \
|
||||
+ .regs = &infra_cg_regs, \
|
||||
+ .shift = _shift, \
|
||||
+ .ops = &mtk_clk_gate_ops_setclr, \
|
||||
+ }
|
||||
+
|
||||
+static const struct mtk_gate infra_clks[] __initconst = {
|
||||
+ GATE_ICG(CLK_INFRA_DBGCLK, "dbgclk_ck", "axi_sel", 0),
|
||||
+ GATE_ICG(CLK_INFRA_SMI, "smi_ck", "smi_sel", 1),
|
||||
+ GATE_ICG(CLK_INFRA_AUDIO, "audio_ck", "aud_intbus_sel", 5),
|
||||
+ GATE_ICG(CLK_INFRA_EFUSE, "efuse_ck", "axi_sel", 5),
|
||||
+ GATE_ICG(CLK_INFRA_EFUSE, "l2c_sram_ck", "axi_sel", 5),
|
||||
+ GATE_ICG(CLK_INFRA_M4U, "m4u_ck", "mem_sel", 8),
|
||||
+ GATE_ICG(CLK_INFRA_CONNMCU, "connmcu_ck", "axi_sel", 8),
|
||||
+ GATE_ICG(CLK_INFRA_TRNG, "trng_ck", "axi_sel", 8),
|
||||
+ GATE_ICG(CLK_INFRA_CPUM, "cpum_ck", "cpum_tck_in", 15),
|
||||
+ GATE_ICG(CLK_INFRA_KP, "kp_ck", "axi_sel", 16),
|
||||
+ GATE_ICG(CLK_INFRA_CEC, "cec_ck", "axi_sel", 16),
|
||||
+ GATE_ICG(CLK_INFRA_IRRX, "irrx_ck", "axi_sel", 16),
|
||||
+ GATE_ICG(CLK_INFRA_PMICSPI, "pmicspi_ck", "pmicspi_sel", 22),
|
||||
+ GATE_ICG(CLK_INFRA_PMIC_WRAP, "pmic_wrap_ck", "axi_sel", 23),
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_gate_regs peri0_cg_regs = {
|
||||
+ .set_ofs = 0x0008,
|
||||
+ .clr_ofs = 0x0010,
|
||||
+ .sta_ofs = 0x0018,
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_gate_regs peri1_cg_regs = {
|
||||
+ .set_ofs = 0x000c,
|
||||
+ .clr_ofs = 0x0014,
|
||||
+ .sta_ofs = 0x001c,
|
||||
+};
|
||||
+
|
||||
+#define GATE_PERI0(_id, _name, _parent, _shift) { \
|
||||
+ .id = _id, \
|
||||
+ .name = _name, \
|
||||
+ .parent_name = _parent, \
|
||||
+ .regs = &peri0_cg_regs, \
|
||||
+ .shift = _shift, \
|
||||
+ .ops = &mtk_clk_gate_ops_setclr, \
|
||||
+ }
|
||||
+
|
||||
+#define GATE_PERI1(_id, _name, _parent, _shift) { \
|
||||
+ .id = _id, \
|
||||
+ .name = _name, \
|
||||
+ .parent_name = _parent, \
|
||||
+ .regs = &peri1_cg_regs, \
|
||||
+ .shift = _shift, \
|
||||
+ .ops = &mtk_clk_gate_ops_setclr, \
|
||||
+ }
|
||||
+
|
||||
+static const struct mtk_gate peri_gates[] __initconst = {
|
||||
+ /* PERI0 */
|
||||
+ GATE_PERI0(CLK_PERI_NFI, "nfi_ck", "axi_sel", 0),
|
||||
+ GATE_PERI0(CLK_PERI_THERM, "therm_ck", "axi_sel", 1),
|
||||
+ GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axi_sel", 2),
|
||||
+ GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axi_sel", 3),
|
||||
+ GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axi_sel", 4),
|
||||
+ GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axi_sel", 5),
|
||||
+ GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axi_sel", 6),
|
||||
+ GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axi_sel", 7),
|
||||
+ GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axi_sel", 8),
|
||||
+ GATE_PERI0(CLK_PERI_PWM, "pwm_ck", "axi_sel", 9),
|
||||
+ GATE_PERI0(CLK_PERI_USB0, "usb0_ck", "usb20_sel", 10),
|
||||
+ GATE_PERI0(CLK_PERI_USB1, "usb1_ck", "usb20_sel", 11),
|
||||
+ GATE_PERI0(CLK_PERI_AP_DMA, "ap_dma_ck", "axi_sel", 12),
|
||||
+ GATE_PERI0(CLK_PERI_MSDC20_1, "msdc_20_1_ck", "msdc_30_0_sel", 13),
|
||||
+ GATE_PERI0(CLK_PERI_MSDC20_2, "msdc_20_2_ck", "msdc_30_1_sel", 14),
|
||||
+ GATE_PERI0(CLK_PERI_MSDC30_1, "msdc_30_1_ck", "msdc_30_2_sel", 15),
|
||||
+ GATE_PERI0(CLK_PERI_NLI, "nli_ck", "axi_sel", 16),
|
||||
+ GATE_PERI0(CLK_PERI_UART0, "uart0_ck", "axi_sel", 17),
|
||||
+ GATE_PERI0(CLK_PERI_UART1, "uart1_ck", "axi_sel", 18),
|
||||
+ GATE_PERI0(CLK_PERI_UART2, "uart2_ck", "axi_sel", 19),
|
||||
+ GATE_PERI0(CLK_PERI_UART3, "uart3_ck", "axi_sel", 20),
|
||||
+ GATE_PERI0(CLK_PERI_BTIF, "btif_ck", "axi_sel", 21),
|
||||
+ GATE_PERI0(CLK_PERI_I2C0, "i2c0_ck", "axi_sel", 22),
|
||||
+ GATE_PERI0(CLK_PERI_I2C1, "i2c1_ck", "axi_sel", 23),
|
||||
+ GATE_PERI0(CLK_PERI_I2C2, "i2c2_ck", "axi_sel", 24),
|
||||
+ GATE_PERI0(CLK_PERI_I2C3, "i2c3_ck", "axi_sel", 25),
|
||||
+ GATE_PERI0(CLK_PERI_AUXADC, "auxadc_ck", "axi_sel", 26),
|
||||
+ GATE_PERI0(CLK_PERI_SPI0, "spi0_ck", "spi0_sel", 27),
|
||||
+ GATE_PERI0(CLK_PERI_ETH, "eth_ck", "eth_sel", 28),
|
||||
+ GATE_PERI0(CLK_PERI_USB0_MCU, "usb0_mcu", "axi_sel", 29),
|
||||
+ GATE_PERI0(CLK_PERI_USB1_MCU, "usb1_mcu","axi_sel", 30),
|
||||
+ GATE_PERI0(CLK_PERI_USB_SLV, "usb_slv", "axi_sel", 31),
|
||||
+
|
||||
+ /* PERI1 */
|
||||
+ GATE_PERI1(CLK_PERI_GCPU, "gcpu_ck", "axi_sel", 0),
|
||||
+ GATE_PERI1(CLK_PERI_NFI_ECC, "nfi_ecc_ck", "axi_sel", 1),
|
||||
+ GATE_PERI1(CLK_PERI_NFI_PAD, "nfi_pad_ck", "axi_sel", 2),
|
||||
+};
|
||||
+
|
||||
+static const char * const uart_ck_sel_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "uart_sel",
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_composite peri_clks[] __initconst = {
|
||||
+ MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents, 0x40c, 0, 1),
|
||||
+ MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents, 0x40c, 1, 1),
|
||||
+ MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents, 0x40c, 2, 1),
|
||||
+ MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1),
|
||||
+};
|
||||
+
|
||||
+static void __init mtk_topckgen_init(struct device_node *node)
|
||||
+{
|
||||
+ struct clk_onecell_data *clk_data;
|
||||
+ void __iomem *base;
|
||||
+ int r;
|
||||
+
|
||||
+ base = of_iomap(node, 0);
|
||||
+ if (!base) {
|
||||
+ pr_err("%s(): ioremap failed\n", __func__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ mt7623_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
|
||||
+
|
||||
+ mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data);
|
||||
+ mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
|
||||
+ mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
|
||||
+ &mt7623_clk_lock, clk_data);
|
||||
+
|
||||
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
+ if (r)
|
||||
+ pr_err("%s(): could not register clock provider: %d\n",
|
||||
+ __func__, r);
|
||||
+
|
||||
+ mtk_clk_enable_critical();
|
||||
+}
|
||||
+CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt7623-topckgen", mtk_topckgen_init);
|
||||
+
|
||||
+static void __init mtk_infrasys_init(struct device_node *node)
|
||||
+{
|
||||
+ struct clk_onecell_data *clk_data;
|
||||
+ int r;
|
||||
+
|
||||
+ clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
|
||||
+
|
||||
+ mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
|
||||
+ clk_data);
|
||||
+
|
||||
+ clk_prepare_enable(clk_data->clks[CLK_INFRA_M4U]);
|
||||
+
|
||||
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
+ if (r)
|
||||
+ pr_err("%s(): could not register clock provider: %d\n",
|
||||
+ __func__, r);
|
||||
+
|
||||
+ mtk_register_reset_controller(node, 2, 0x30);
|
||||
+}
|
||||
+CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt7623-infracfg", mtk_infrasys_init);
|
||||
+
|
||||
+static void __init mtk_pericfg_init(struct device_node *node)
|
||||
+{
|
||||
+ struct clk_onecell_data *clk_data;
|
||||
+ int r;
|
||||
+ void __iomem *base;
|
||||
+
|
||||
+ base = of_iomap(node, 0);
|
||||
+ if (!base) {
|
||||
+ pr_err("%s(): ioremap failed\n", __func__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
|
||||
+
|
||||
+ mtk_clk_register_gates(node, peri_gates, ARRAY_SIZE(peri_gates),
|
||||
+ clk_data);
|
||||
+ mtk_clk_register_composites(peri_clks, ARRAY_SIZE(peri_clks), base,
|
||||
+ &mt7623_clk_lock, clk_data);
|
||||
+
|
||||
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
+ if (r)
|
||||
+ pr_err("%s(): could not register clock provider: %d\n",
|
||||
+ __func__, r);
|
||||
+
|
||||
+ mtk_register_reset_controller(node, 2, 0);
|
||||
+}
|
||||
+CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt7623-pericfg", mtk_pericfg_init);
|
||||
+
|
||||
+#define MT7623_PLL_FMAX (2000 * MHZ)
|
||||
+#define CON0_MT7623_RST_BAR BIT(27)
|
||||
+
|
||||
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \
|
||||
+ .id = _id, \
|
||||
+ .name = _name, \
|
||||
+ .reg = _reg, \
|
||||
+ .pwr_reg = _pwr_reg, \
|
||||
+ .en_mask = _en_mask, \
|
||||
+ .flags = _flags, \
|
||||
+ .rst_bar_mask = CON0_MT7623_RST_BAR, \
|
||||
+ .fmax = MT7623_PLL_FMAX, \
|
||||
+ .pcwbits = _pcwbits, \
|
||||
+ .pd_reg = _pd_reg, \
|
||||
+ .pd_shift = _pd_shift, \
|
||||
+ .tuner_reg = _tuner_reg, \
|
||||
+ .pcw_reg = _pcw_reg, \
|
||||
+ .pcw_shift = _pcw_shift, \
|
||||
+ }
|
||||
+
|
||||
+static const struct mtk_pll_data plls[] = {
|
||||
+ PLL(CLK_APMIXED_ARMPLL, "armpll", 0x200, 0x20c, 0x00000001, 0, 21, 0x204, 24, 0x0, 0x204, 0),
|
||||
+ PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x210, 0x21c, 0x78000001, HAVE_RST_BAR, 21, 0x214, 6, 0x0, 0x214, 0),
|
||||
+ PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x220, 0x22c, 0xFC000001, HAVE_RST_BAR, 7, 0x224, 6, 0x0, 0x224, 0),
|
||||
+ PLL(CLK_APMIXED_MMPLL, "mmpll", 0x230, 0x23c, 0x00000001, 0, 21, 0x254, 6, 0x0, 0x258, 0),
|
||||
+ PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x240, 0x24c, 0x00000001, 0, 21, 0x244, 6, 0x0, 0x244, 0),
|
||||
+ PLL(CLK_APMIXED_AUDPLL, "audpll", 0x250, 0x25c, 0x00000001, 0, 31, 0x2e8, 6, 0x2f8, 0x254, 0),
|
||||
+ PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x260, 0x26c, 0x00000001, 0, 31, 0x294, 6, 0x0, 0x298, 0),
|
||||
+ PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x270, 0x27c, 0x00000001, 0, 21, 0x2b0, 6, 0x0, 0x2b4, 0),
|
||||
+};
|
||||
+
|
||||
+static void __init mtk_apmixedsys_init(struct device_node *node)
|
||||
+{
|
||||
+ struct clk_onecell_data *clk_data;
|
||||
+
|
||||
+ mt7623_pll_clk_data = clk_data = mtk_alloc_clk_data(ARRAY_SIZE(plls));
|
||||
+ if (!clk_data)
|
||||
+ return;
|
||||
+
|
||||
+ mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
|
||||
+ mtk_clk_enable_critical();
|
||||
+}
|
||||
+CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt7623-apmixedsys",
|
||||
+ mtk_apmixedsys_init);
|
||||
diff --git a/include/dt-bindings/clock/mt7623-clk.h b/include/dt-bindings/clock/mt7623-clk.h
|
||||
new file mode 100644
|
||||
index 0000000..cb1e8a9
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/clock/mt7623-clk.h
|
||||
@@ -0,0 +1,173 @@
|
||||
+/*
|
||||
+ * Copyright c 2014 MediaTek Inc.
|
||||
+ * Author: James Liao <jamesjj.liao@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _DT_BINDINGS_CLK_MT7623_H
|
||||
+#define _DT_BINDINGS_CLK_MT7623_H
|
||||
+
|
||||
+/* TOPCKGEN */
|
||||
+
|
||||
+#define CLK_TOP_AUDPLL_24 1
|
||||
+#define CLK_TOP_AUDPLL_D16 2
|
||||
+#define CLK_TOP_AUDPLL_D4 3
|
||||
+#define CLK_TOP_AUDPLL_D8 4
|
||||
+#define CLK_TOP_CLKPH_MCK 5
|
||||
+#define CLK_TOP_CPUM_TCK_IN 6
|
||||
+#define CLK_TOP_DSI0_LNTC_DSICLK 7
|
||||
+#define CLK_TOP_HDMITX_CLKDIG_CTS 8
|
||||
+#define CLK_TOP_LVDS_ETH 9
|
||||
+#define CLK_TOP_LVDSPLL_D2 10
|
||||
+#define CLK_TOP_LVDSPLL_D4 11
|
||||
+#define CLK_TOP_LVDSPLL_D8 12
|
||||
+#define CLK_TOP_MAINPLL_230P3M 13
|
||||
+#define CLK_TOP_MAINPLL_322P4M 14
|
||||
+#define CLK_TOP_MAINPLL_537P3M 15
|
||||
+#define CLK_TOP_MAINPLL_806M 16
|
||||
+#define CLK_TOP_MEMPLL_MCK_D4 17
|
||||
+#define CLK_TOP_MMPLL_D2 18
|
||||
+#define CLK_TOP_MSDCPLL_D2 19
|
||||
+#define CLK_TOP_SYSPLL1_D16 20
|
||||
+#define CLK_TOP_SYSPLL1_D2 21
|
||||
+#define CLK_TOP_SYSPLL1_D4 22
|
||||
+#define CLK_TOP_SYSPLL1_D8 23
|
||||
+#define CLK_TOP_SYSPLL2_D2 24
|
||||
+#define CLK_TOP_SYSPLL2_D4 25
|
||||
+#define CLK_TOP_SYSPLL2_D8 26
|
||||
+#define CLK_TOP_SYSPLL3_D2 27
|
||||
+#define CLK_TOP_SYSPLL3_D4 28
|
||||
+#define CLK_TOP_SYSPLL4_D2 29
|
||||
+#define CLK_TOP_SYSPLL4_D4 30
|
||||
+#define CLK_TOP_SYSPLL_D3 31
|
||||
+#define CLK_TOP_SYSPLL_D5 32
|
||||
+#define CLK_TOP_SYSPLL_D7 33
|
||||
+#define CLK_TOP_TVDPLL_d2 34
|
||||
+#define CLK_TOP_TVDPLL_D4 35
|
||||
+#define CLK_TOP_UNIVPLL_178P3M 36
|
||||
+#define CLK_TOP_UNIVPLL1_D10 37
|
||||
+#define CLK_TOP_UNIVPLL1_D2 38
|
||||
+#define CLK_TOP_UNIVPLL1_D4 39
|
||||
+#define CLK_TOP_UNIVPLL1_D6 40
|
||||
+#define CLK_TOP_UNIVPLL1_D8 41
|
||||
+#define CLK_TOP_UNIVPLL_249P6M 42
|
||||
+#define CLK_TOP_UNIVPLL2_D2 43
|
||||
+#define CLK_TOP_UNIVPLL2_D4 44
|
||||
+#define CLK_TOP_UNIVPLL2_D6 45
|
||||
+#define CLK_TOP_UNIVPLL2_D8 46
|
||||
+#define CLK_TOP_UNIVPLL_416M 47
|
||||
+#define CLK_TOP_UNIVPLL_48M 48
|
||||
+#define CLK_TOP_UNIVPLL_624M 49
|
||||
+#define CLK_TOP_UNIVPLL_D26 50
|
||||
+#define CLK_TOP_UNIVPLL_D5 51
|
||||
+#define CLK_TOP_APLL_SEL 52
|
||||
+#define CLK_TOP_AUDIO_INTBUS_SEL 53
|
||||
+#define CLK_TOP_AUDIO_SEL 54
|
||||
+#define CLK_TOP_AXI_SEL 55
|
||||
+#define CLK_TOP_CAM_SEL 56
|
||||
+#define CLK_TOP_DDR_SEL 57
|
||||
+#define CLK_TOP_DPI0_SEL 58
|
||||
+#define CLK_TOP_DPI1_SEL 59
|
||||
+#define CLK_TOP_DPILVDS_SEL 60
|
||||
+#define CLK_TOP_ETH_SEL 61
|
||||
+#define CLK_TOP_MEM_SEL 62
|
||||
+#define CLK_TOP_MFG_SEL 63
|
||||
+#define CLK_TOP_MM_SEL 64
|
||||
+#define CLK_TOP_MSDC30_0_SEL 65
|
||||
+#define CLK_TOP_MSDC30_1_SEL 66
|
||||
+#define CLK_TOP_MSDC30_2_SEL 67
|
||||
+#define CLK_TOP_NFI2X_SEL 68
|
||||
+#define CLK_TOP_PMICSPI_SEL 69
|
||||
+#define CLK_TOP_PWM_SEL 70
|
||||
+#define CLK_TOP_RTC_SEL 71
|
||||
+#define CLK_TOP_SCP_SEL 72
|
||||
+#define CLK_TOP_SPI_SEL 73
|
||||
+#define CLK_TOP_TVE_SEL 74
|
||||
+#define CLK_TOP_UART_SEL 75
|
||||
+#define CLK_TOP_USB20_SEL 76
|
||||
+#define CLK_TOP_VDEC_SEL 77
|
||||
+#define CLK_TOP_NR_CLK 78
|
||||
+
|
||||
+/* APMIXED_SYS */
|
||||
+
|
||||
+#define CLK_APMIXED_ARMPLL 1
|
||||
+#define CLK_APMIXED_MAINPLL 2
|
||||
+#define CLK_APMIXED_MSDCPLL 3
|
||||
+#define CLK_APMIXED_UNIVPLL 4
|
||||
+#define CLK_APMIXED_MMPLL 5
|
||||
+#define CLK_APMIXED_VENCPLL 6
|
||||
+#define CLK_APMIXED_TVDPLL 7
|
||||
+#define CLK_APMIXED_LVDSPLL 8
|
||||
+#define CLK_APMIXED_AUDPLL 9
|
||||
+
|
||||
+/* INFRA_SYS */
|
||||
+
|
||||
+#define CLK_INFRA_DBGCLK 0
|
||||
+#define CLK_INFRA_SMI 1
|
||||
+#define CLK_INFRA_AUDIO 5
|
||||
+#define CLK_INFRA_EFUSE 6
|
||||
+#define CLK_INFRA_L2C_SRAM 7
|
||||
+#define CLK_INFRA_M4U 8
|
||||
+#define CLK_INFRA_CONNMCU 12
|
||||
+#define CLK_INFRA_TRNG 13
|
||||
+#define CLK_INFRA_CPUM 15
|
||||
+#define CLK_INFRA_KP 16
|
||||
+#define CLK_INFRA_CEC 18
|
||||
+#define CLK_INFRA_IRRX 19
|
||||
+#define CLK_INFRA_PMICSPI 22
|
||||
+#define CLK_INFRA_PMIC_WRAP 23
|
||||
+#define CLK_INFRA_NR_CLK 24
|
||||
+
|
||||
+/* PERI_SYS */
|
||||
+
|
||||
+#define CLK_PERI_NFI 0
|
||||
+#define CLK_PERI_THERM 1
|
||||
+#define CLK_PERI_PWM1 2
|
||||
+#define CLK_PERI_PWM2 3
|
||||
+#define CLK_PERI_PWM3 4
|
||||
+#define CLK_PERI_PWM4 5
|
||||
+#define CLK_PERI_PWM5 6
|
||||
+#define CLK_PERI_PWM6 7
|
||||
+#define CLK_PERI_PWM7 8
|
||||
+#define CLK_PERI_PWM 9
|
||||
+#define CLK_PERI_USB0 10
|
||||
+#define CLK_PERI_USB1 11
|
||||
+#define CLK_PERI_AP_DMA 12
|
||||
+#define CLK_PERI_MSDC20_1 13
|
||||
+#define CLK_PERI_MSDC20_2 14
|
||||
+#define CLK_PERI_MSDC30_1 15
|
||||
+#define CLK_PERI_NLI 16
|
||||
+#define CLK_PERI_UART0 17
|
||||
+#define CLK_PERI_UART1 18
|
||||
+#define CLK_PERI_UART2 19
|
||||
+#define CLK_PERI_UART3 20
|
||||
+#define CLK_PERI_BTIF 21
|
||||
+#define CLK_PERI_I2C0 22
|
||||
+#define CLK_PERI_I2C1 23
|
||||
+#define CLK_PERI_I2C2 24
|
||||
+#define CLK_PERI_I2C3 25
|
||||
+#define CLK_PERI_AUXADC 26
|
||||
+#define CLK_PERI_SPI0 27
|
||||
+#define CLK_PERI_ETH 28
|
||||
+#define CLK_PERI_USB0_MCU 29
|
||||
+#define CLK_PERI_USB1_MCU 30
|
||||
+#define CLK_PERI_USB_SLV 31
|
||||
+#define CLK_PERI_GCPU 32
|
||||
+#define CLK_PERI_NFI_ECC 33
|
||||
+#define CLK_PERI_NFI_PAD 34
|
||||
+#define CLK_PERI_UART0_SEL 35
|
||||
+#define CLK_PERI_UART1_SEL 36
|
||||
+#define CLK_PERI_UART2_SEL 37
|
||||
+#define CLK_PERI_UART3_SEL 38
|
||||
+#define CLK_PERI_NR_CLK 39
|
||||
+
|
||||
+#endif /* _DT_BINDINGS_CLK_MT7623_H */
|
||||
+
|
||||
--
|
||||
1.7.10.4
|
||||
|
File diff suppressed because it is too large
Load Diff
20654
target/linux/mediatek/patches/0063-arm-mediatek-add-SDK-ethernet.patch
Normal file
20654
target/linux/mediatek/patches/0063-arm-mediatek-add-SDK-ethernet.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,436 @@
|
||||
From 29ceb2449cb3622ccfba9eb1c77bf2ac4162464b Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sat, 27 Jun 2015 13:15:29 +0200
|
||||
Subject: [PATCH 64/76] arm: mediatek: add mt7623 pcie support
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/arm/mach-mediatek/Makefile | 2 +-
|
||||
arch/arm/mach-mediatek/pcie.c | 383 +++++++++++++++++++++++++++++++++++++++
|
||||
arch/arm/mach-mediatek/pcie.h | 14 ++
|
||||
3 files changed, 398 insertions(+), 1 deletion(-)
|
||||
create mode 100644 arch/arm/mach-mediatek/pcie.c
|
||||
create mode 100644 arch/arm/mach-mediatek/pcie.h
|
||||
|
||||
diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
|
||||
index 2116460..aca28a2 100644
|
||||
--- a/arch/arm/mach-mediatek/Makefile
|
||||
+++ b/arch/arm/mach-mediatek/Makefile
|
||||
@@ -1,4 +1,4 @@
|
||||
ifeq ($(CONFIG_SMP),y)
|
||||
obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o
|
||||
endif
|
||||
-obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
|
||||
+obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o pcie.o
|
||||
diff --git a/arch/arm/mach-mediatek/pcie.c b/arch/arm/mach-mediatek/pcie.c
|
||||
new file mode 100644
|
||||
index 0000000..8394712
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/mach-mediatek/pcie.c
|
||||
@@ -0,0 +1,383 @@
|
||||
+/*
|
||||
+ * Mediatek MT7623 SoC PCIE support
|
||||
+ *
|
||||
+ * Copyright (C) 2015 Mediatek
|
||||
+ * 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/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_irq.h>
|
||||
+#include <linux/of_pci.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#include "pcie.h"
|
||||
+
|
||||
+#define PCICFG 0x00
|
||||
+#define PCIINT 0x08
|
||||
+#define PCIENA 0x0C
|
||||
+#define CFGADDR 0x20
|
||||
+#define CFGDATA 0x24
|
||||
+#define MEMBASE 0x28
|
||||
+#define IOBASE 0x2C
|
||||
+
|
||||
+#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)
|
||||
+
|
||||
+static void __iomem *pcie_base;
|
||||
+static int pcie_card_link;
|
||||
+
|
||||
+static struct mtk_pcie_port {
|
||||
+ int id;
|
||||
+ int enable;
|
||||
+ u32 base;
|
||||
+ u32 phy_base;
|
||||
+ u32 perst_n;
|
||||
+ u32 reset;
|
||||
+ u32 interrupt;
|
||||
+ u32 link;
|
||||
+} mtk_pcie_port[] = {
|
||||
+ { 0, 1, PCIEP0_BASE, PHY_P0_CTL, BIT(1), RSTCTL_PCIE0_RST, BIT(20) },
|
||||
+ { 1, 1, PCIEP1_BASE, PHY_P1_CTL, BIT(2), RSTCTL_PCIE1_RST, BIT(21) },
|
||||
+ { 2, 0, PCIEP2_BASE, PHY_P2_CTL, BIT(3), RSTCTL_PCIE2_RST, BIT(22) },
|
||||
+};
|
||||
+
|
||||
+#define mtk_foreach_port(p) \
|
||||
+ for (p = mtk_pcie_port; p != &mtk_pcie_port[ARRAY_SIZE(mtk_pcie_port)]; p++)
|
||||
+
|
||||
+#define mtk_foreach_port_enabled(p) \
|
||||
+ mtk_foreach_port(p) \
|
||||
+ if (p->enable)
|
||||
+
|
||||
+#define mtk_foreach_port_link(p) \
|
||||
+ mtk_foreach_port(p) \
|
||||
+ if (p->link)
|
||||
+
|
||||
+static struct mtk_phy_init {
|
||||
+ uint32_t reg;
|
||||
+ uint32_t mask;
|
||||
+ uint32_t val;
|
||||
+} mtk_phy_init[] = {
|
||||
+ { 0xC00, 0x33000, 0x22000 },
|
||||
+ { 0xB04, 0xe0000000, 0x40000000 },
|
||||
+ { 0xB00, 0xe, 0x4 },
|
||||
+ { 0xC3C, 0xffff0000, 0x3c0000 },
|
||||
+ { 0xC48, 0xffff, 0x36 },
|
||||
+ { 0xC0C, 0x30000000, 0x10000000 },
|
||||
+ { 0xC08, 0x3800c0, 0xc0 },
|
||||
+ { 0xC10, 0xf0000, 0x20000 },
|
||||
+ { 0xC0C, 0xf000, 0x1000 },
|
||||
+ { 0xC14, 0xf0000, 0xa0000 },
|
||||
+};
|
||||
+
|
||||
+static inline void pcie_w32(u32 val, unsigned reg)
|
||||
+{
|
||||
+ iowrite32(val, pcie_base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline u32 pcie_r32(unsigned reg)
|
||||
+{
|
||||
+ return ioread32(pcie_base + reg);
|
||||
+}
|
||||
+
|
||||
+static inline void pcie_m32(u32 mask, u32 val, unsigned reg)
|
||||
+{
|
||||
+ u32 v = pcie_r32(reg);
|
||||
+
|
||||
+ v &= mask;
|
||||
+ v |= val;
|
||||
+ pcie_w32(v, reg);
|
||||
+}
|
||||
+
|
||||
+static int pcie_config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
|
||||
+{
|
||||
+ 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_m32(0xf0000000, address, CFGADDR);
|
||||
+ data = pcie_r32(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)
|
||||
+{
|
||||
+ 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_m32(0xf0000000, address, CFGADDR);
|
||||
+ data = pcie_r32(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(data, CFGDATA);
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+static struct pci_ops mtk_pcie_ops = {
|
||||
+ .read = pcie_config_read,
|
||||
+ .write = pcie_config_write,
|
||||
+};
|
||||
+
|
||||
+static struct resource pci_mem = {
|
||||
+ .name = "PCIe Memory space",
|
||||
+ .start = MEM_DIRECT1,
|
||||
+ .end = (u32) (MEM_DIRECT1 + (unsigned char *) 0x0fffffff),
|
||||
+ .flags = IORESOURCE_MEM,
|
||||
+};
|
||||
+
|
||||
+static struct resource pci_io = {
|
||||
+ .name = "PCIe IO space",
|
||||
+ .start = IO_WIN,
|
||||
+ .end = (u32) (IO_WIN + (unsigned char *) 0x0ffff),
|
||||
+ .flags = IORESOURCE_IO,
|
||||
+};
|
||||
+
|
||||
+static int __init mtk_pcie_setup(int nr, struct pci_sys_data *sys)
|
||||
+{
|
||||
+ sys->mem_offset = 0;
|
||||
+ sys->io_offset = 0;
|
||||
+
|
||||
+ request_resource(&ioport_resource, &pci_io);
|
||||
+ request_resource(&iomem_resource, &pci_mem);
|
||||
+
|
||||
+ pci_add_resource_offset(&sys->resources, &pci_io, sys->io_offset);
|
||||
+ pci_add_resource_offset(&sys->resources, &pci_mem, sys->mem_offset);
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static struct pci_bus * __init mtk_pcie_scan_bus(int nr, struct pci_sys_data *sys)
|
||||
+{
|
||||
+ return pci_scan_root_bus(NULL, sys->busnr, &mtk_pcie_ops, sys,
|
||||
+ &sys->resources);
|
||||
+}
|
||||
+
|
||||
+static int __init mtk_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||
+{
|
||||
+ u16 cmd;
|
||||
+ u32 val;
|
||||
+
|
||||
+ if (dev->bus->number == 0) {
|
||||
+ pcie_config_write(NULL, slot, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE);
|
||||
+ pcie_config_read(NULL, slot, 0, PCI_BASE_ADDRESS_0, &val);
|
||||
+ printk("BAR0 at bus %d, slot %d\n", dev->bus->number, slot);
|
||||
+ }
|
||||
+
|
||||
+ printk("bus=0x%x, slot = 0x%x, pin=0x%x, irq=0x%x\n", dev->bus->number, slot, pin, dev->irq);
|
||||
+
|
||||
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x14);
|
||||
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xFF);
|
||||
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
|
||||
+ cmd = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
|
||||
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
|
||||
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
|
||||
+
|
||||
+ return dev->irq;
|
||||
+}
|
||||
+
|
||||
+static void __init mtk_pcie_preinit(void)
|
||||
+{
|
||||
+ struct mtk_pcie_port *port;
|
||||
+ u32 val = 0;
|
||||
+ int i;
|
||||
+
|
||||
+ pcibios_min_io = 0;
|
||||
+ pcibios_min_mem = 0;
|
||||
+
|
||||
+#if defined (CONFIG_PCIE_PORT2)
|
||||
+ printk("%s: PCIe/USB3 combo PHY mode (%x) =%x\n", __func__, SYSCFG1, REGDATA(SYSCFG1));
|
||||
+ REGDATA(SYSCFG1) &= ~(0x300000);
|
||||
+ printk("%s: PCIe/USB3 combo PHY mode (%x) =%x\n", __func__, SYSCFG1, REGDATA(SYSCFG1));
|
||||
+#endif
|
||||
+
|
||||
+ /* PCIe RC Reset */
|
||||
+ val = 0;
|
||||
+ mtk_foreach_port_enabled(port)
|
||||
+ val |= port->reset;
|
||||
+ REGDATA(RSTCTL) |= val;
|
||||
+ mdelay(10);
|
||||
+ REGDATA(RSTCTL) &= ~val;
|
||||
+ mdelay(10);
|
||||
+
|
||||
+ /* Configure PCIe PHY */
|
||||
+ mtk_foreach_port_enabled(port) {
|
||||
+ for (i = 0; i < ARRAY_SIZE(mtk_phy_init); i++) {
|
||||
+ u32 val = pcie_r32(port->phy_base + mtk_phy_init[i].reg);
|
||||
+ val &= ~mtk_phy_init[i].mask;
|
||||
+ val |= mtk_phy_init[i].val;
|
||||
+ pcie_w32(val, port->phy_base + mtk_phy_init[i].reg);
|
||||
+ }
|
||||
+ mdelay(10);
|
||||
+ }
|
||||
+
|
||||
+ /* Enable RC */
|
||||
+ mtk_foreach_port_enabled(port) {
|
||||
+ val = 0;
|
||||
+ pcie_config_read(NULL, port->id, 0, 0x73c, &val);
|
||||
+ val &= ~(0x9fff)<<16;
|
||||
+ val |= 0x806c<<16;
|
||||
+ pcie_config_write(NULL, port->id, 0, 0x73c, val);
|
||||
+ }
|
||||
+
|
||||
+ /* PCIe EP reset */
|
||||
+ val = 0;
|
||||
+ mtk_foreach_port_enabled(port)
|
||||
+ val |= port->perst_n;
|
||||
+ val |= MTK_PCIE_HIGH_PERF;
|
||||
+ pcie_w32(pcie_r32(PCICFG) | val, PCICFG);
|
||||
+ mdelay(10);
|
||||
+ pcie_w32(pcie_r32(PCICFG) & ~val, PCICFG);
|
||||
+ mdelay(10);
|
||||
+
|
||||
+ /* check the link status */
|
||||
+ val = 0;
|
||||
+ mtk_foreach_port_enabled(port) {
|
||||
+ if ((pcie_r32(port->base + PCIE_SISTAT) & 0x1))
|
||||
+ port->link = 1;
|
||||
+ else
|
||||
+ val |= port->reset;
|
||||
+ }
|
||||
+ REGDATA(RSTCTL) |= val;
|
||||
+
|
||||
+ mtk_foreach_port_link(port)
|
||||
+ pcie_card_link++;
|
||||
+
|
||||
+ printk("PCIe Link count = %d\n", pcie_card_link);
|
||||
+ if (!pcie_card_link)
|
||||
+ return;
|
||||
+
|
||||
+ pcie_w32(MEM_WIN, MEMBASE);
|
||||
+ pcie_w32(IO_WIN, IOBASE);
|
||||
+
|
||||
+ mtk_foreach_port_link(port) {
|
||||
+ pcie_m32(0, port->interrupt, PCIENA);
|
||||
+ pcie_w32(0x7FFF0001, port->base + BAR0SETUP);
|
||||
+ pcie_w32(MEMORY_BASE, port->base + IMBASEBAR0);
|
||||
+ pcie_w32(0x06040001, port->base + PCIE_CLASS);
|
||||
+ printk("PCIE%d Setup OK\n", port->id);
|
||||
+ }
|
||||
+ val = 0;
|
||||
+
|
||||
+ pcie_config_read(NULL, pcie_card_link - 1, 0, 0x4, &val);
|
||||
+ pcie_config_write(NULL, pcie_card_link - 1, 0, 0x4, val|0x4);
|
||||
+ pcie_config_read(NULL, pcie_card_link - 1, 0, 0x70c, &val);
|
||||
+ val &= ~(0xff3) << 8;
|
||||
+ val |= 0x50 << 8;
|
||||
+ pcie_config_write(NULL, pcie_card_link - 1, 0, 0x70c, val);
|
||||
+ pcie_config_read(NULL, pcie_card_link - 1, 0, 0x70c, &val);
|
||||
+}
|
||||
+
|
||||
+static struct hw_pci mtk_pci __initdata = {
|
||||
+ .nr_controllers = 1,
|
||||
+ .map_irq = mtk_pcie_map_irq,
|
||||
+ .setup = mtk_pcie_setup,
|
||||
+ .scan = mtk_pcie_scan_bus,
|
||||
+ .preinit = mtk_pcie_preinit,
|
||||
+};
|
||||
+
|
||||
+extern void mt7623_ethifsys_init(void);
|
||||
+static int mtk_pcie_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct resource *pcie_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+
|
||||
+ pcie_base = devm_ioremap_resource(&pdev->dev, pcie_res);
|
||||
+ if (!pcie_base)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ mt7623_ethifsys_init();
|
||||
+ pci_common_init_dev(&pdev->dev, &mtk_pci);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mtk_pcie_ids[] = {
|
||||
+ { .compatible = "mediatek,mt7623-pcie" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mtk_pcie_ids);
|
||||
+
|
||||
+static struct platform_driver mtk_pcie_driver = {
|
||||
+ .probe = mtk_pcie_probe,
|
||||
+ .driver = {
|
||||
+ .name = "mt7623-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);
|
||||
+}
|
||||
+
|
||||
+late_initcall(mtk_pcie_init);
|
||||
diff --git a/arch/arm/mach-mediatek/pcie.h b/arch/arm/mach-mediatek/pcie.h
|
||||
new file mode 100644
|
||||
index 0000000..400a760e
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/mach-mediatek/pcie.h
|
||||
@@ -0,0 +1,14 @@
|
||||
+#define SYSCTL_BASE 0xFA000000
|
||||
+#define MEM_WIN 0x1A150000
|
||||
+#define IO_WIN 0x1A160000
|
||||
+#define MEM_DIRECT1 0x60000000
|
||||
+#define MEMORY_BASE 0x80000000
|
||||
+
|
||||
+#define REGADDR(x, y) (x##_BASE + y)
|
||||
+#define REGDATA(x) *((volatile unsigned int *)(x))
|
||||
+
|
||||
+#define SYSCFG1 REGADDR(SYSCTL, 0x14)
|
||||
+#define RSTCTL REGADDR(SYSCTL, 0x34)
|
||||
+
|
||||
+
|
||||
+
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,38 @@
|
||||
From 3f181d60fcd80b0d98849076ed2aa43de2cb6d8c Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sat, 27 Jun 2015 13:16:27 +0200
|
||||
Subject: [PATCH 65/76] arm: mediatek: add mt7623 smp support
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/arm/mach-mediatek/platsmp.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c
|
||||
index e266b3d..81fdcff 100644
|
||||
--- a/arch/arm/mach-mediatek/platsmp.c
|
||||
+++ b/arch/arm/mach-mediatek/platsmp.c
|
||||
@@ -45,6 +45,12 @@ static const struct mtk_smp_boot_info mtk_mt6589_boot = {
|
||||
{ 0x38, 0x3c, 0x40 },
|
||||
};
|
||||
|
||||
+static const struct mtk_smp_boot_info mtk_mt7623_boot = {
|
||||
+ 0x10202000, 0x34, 0x30,
|
||||
+ { 0x534c4131, 0x4c415332, 0x41534c33 },
|
||||
+ { 0x38, 0x3c, 0x40 },
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = {
|
||||
{ .compatible = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot },
|
||||
{ .compatible = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot },
|
||||
@@ -52,6 +58,7 @@ static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = {
|
||||
|
||||
static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
|
||||
{ .compatible = "mediatek,mt6589", .data = &mtk_mt6589_boot },
|
||||
+ { .compatible = "mediatek,mt7623", .data = &mtk_mt7623_boot },
|
||||
};
|
||||
|
||||
static void __iomem *mtk_smp_base;
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,551 @@
|
||||
From a6bf117b5fe3acd76bbc45cc87fd80f589136e59 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sat, 27 Jun 2015 13:14:42 +0200
|
||||
Subject: [PATCH 66/76] arm: mediatek: add m7623 devicetree
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/arm/boot/dts/Makefile | 1 +
|
||||
arch/arm/boot/dts/mt7623-evb.dts | 162 ++++++++++++++++++
|
||||
arch/arm/boot/dts/mt7623.dtsi | 348 ++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 511 insertions(+)
|
||||
create mode 100644 arch/arm/boot/dts/mt7623-evb.dts
|
||||
create mode 100644 arch/arm/boot/dts/mt7623.dtsi
|
||||
|
||||
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
|
||||
index 992736b..525392e 100644
|
||||
--- a/arch/arm/boot/dts/Makefile
|
||||
+++ b/arch/arm/boot/dts/Makefile
|
||||
@@ -658,6 +658,7 @@ dtb-$(CONFIG_MACH_DOVE) += \
|
||||
dtb-$(CONFIG_ARCH_MEDIATEK) += \
|
||||
mt6589-aquaris5.dtb \
|
||||
mt6592-evb.dtb \
|
||||
+ mt7623-evb.dtb \
|
||||
mt8127-moose.dtb \
|
||||
mt8135-evbp1.dtb
|
||||
endif
|
||||
diff --git a/arch/arm/boot/dts/mt7623-evb.dts b/arch/arm/boot/dts/mt7623-evb.dts
|
||||
new file mode 100644
|
||||
index 0000000..759142f
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/mt7623-evb.dts
|
||||
@@ -0,0 +1,162 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2014 MediaTek Inc.
|
||||
+ * Author: Joe.C <yingjoe.chen@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.
|
||||
+ */
|
||||
+
|
||||
+/dts-v1/;
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+#include "mt7623.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "MediaTek MT7623 Evaluation Board";
|
||||
+ compatible = "mediatek,mt7623-evb", "mediatek,mt7623";
|
||||
+
|
||||
+ chosen {
|
||||
+ stdout-path = &uart2;
|
||||
+ };
|
||||
+
|
||||
+ memory {
|
||||
+ reg = <0 0x80000000 0 0x10000000>;
|
||||
+ };
|
||||
+
|
||||
+ usb_p1_vbus: fixedregulator@0 {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "usb_vbus";
|
||||
+ regulator-min-microvolt = <5000000>;
|
||||
+ regulator-max-microvolt = <5000000>;
|
||||
+ gpio = <&pio 130 GPIO_ACTIVE_HIGH>;
|
||||
+ enable-active-high;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+
|
||||
+&pio {
|
||||
+ pinctrl_uart2_default: uart2@0 {
|
||||
+ pins {
|
||||
+ pinmux = <MT7623_PIN_14_GPIO14_FUNC_URXD2>,
|
||||
+ <MT7623_PIN_15_GPIO15_FUNC_UTXD2>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ pinctrl_i2c0_default: i2c@0 {
|
||||
+ pins {
|
||||
+ pinmux = <MT7623_PIN_75_SDA0_FUNC_SDA0>,
|
||||
+ <MT7623_PIN_76_SCL0_FUNC_SCL0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ pinctrl_pcie_default: pcie@0 {
|
||||
+ pins {
|
||||
+ pinmux = <MT7623_PIN_24_EINT2_FUNC_PCIE2_PERST_N>,
|
||||
+ <MT7623_PIN_208_AUD_EXT_CK1_FUNC_PCIE0_PERST_N>,
|
||||
+ <MT7623_PIN_209_AUD_EXT_CK2_FUNC_PCIE1_PERST_N>,
|
||||
+ <MT7623_PIN_250_GPIO250_FUNC_PCIE0_CLKREQ_N>,
|
||||
+ <MT7623_PIN_251_GPIO251_FUNC_PCIE0_WAKE_N>,
|
||||
+ <MT7623_PIN_252_GPIO252_FUNC_PCIE1_CLKREQ_N>,
|
||||
+ <MT7623_PIN_253_GPIO253_FUNC_PCIE1_WAKE_N>,
|
||||
+ <MT7623_PIN_254_GPIO254_FUNC_PCIE2_CLKREQ_N>,
|
||||
+ <MT7623_PIN_255_GPIO255_FUNC_PCIE2_WAKE_N>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ pinctrl_spi_default: spi@0 {
|
||||
+ pins {
|
||||
+ pinmux = <MT7623_PIN_7_SPI1_CSN_FUNC_SPI1_CS>,
|
||||
+ <MT7623_PIN_8_SPI1_MI_FUNC_SPI1_MI>,
|
||||
+ <MT7623_PIN_9_SPI1_MO_FUNC_SPI1_MO>,
|
||||
+ <MT7623_PIN_199_SPI1_CK_FUNC_SPI1_CK>;
|
||||
+ bias-disable;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&thermal {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&uart2 {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pinctrl_uart2_default>;
|
||||
+};
|
||||
+
|
||||
+&i2c0 {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pinctrl_i2c0_default>;
|
||||
+};
|
||||
+
|
||||
+&spi {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pinctrl_spi_default>;
|
||||
+
|
||||
+ m25p80@0 {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+ compatible = "mx25l12805d";
|
||||
+ reg = <0 0 0 0>;
|
||||
+ linux,modalias = "m25p80", "w25q128";
|
||||
+ spi-max-frequency = <10000000>;
|
||||
+
|
||||
+ partition@0 {
|
||||
+ label = "u-boot";
|
||||
+ reg = <0x0 0x30000>;
|
||||
+ read-only;
|
||||
+ };
|
||||
+
|
||||
+ partition@30000 {
|
||||
+ label = "u-boot-env";
|
||||
+ reg = <0x30000 0x10000>;
|
||||
+ read-only;
|
||||
+ };
|
||||
+
|
||||
+ factory: partition@40000 {
|
||||
+ label = "factory";
|
||||
+ reg = <0x40000 0x10000>;
|
||||
+ read-only;
|
||||
+ };
|
||||
+
|
||||
+ partition@50000 {
|
||||
+ label = "firmware";
|
||||
+ reg = <0x50000 0xfb0000>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&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 = <&mt6397_vemc_3v3_reg>;
|
||||
+// vqmmc-supply = <&mt6397_vio18_reg>;
|
||||
+ non-removable;
|
||||
+};
|
||||
+
|
||||
+&u3phy {
|
||||
+ reg-p1-vbus-supply = <&usb_p1_vbus>;
|
||||
+};
|
||||
+
|
||||
+&pcie {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pinctrl_pcie_default>;
|
||||
+};
|
||||
diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi
|
||||
new file mode 100644
|
||||
index 0000000..ba74ed9
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/mt7623.dtsi
|
||||
@@ -0,0 +1,348 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2014 MediaTek Inc.
|
||||
+ * Author: Joe.C <yingjoe.chen@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#include <dt-bindings/clock/mt7623-clk.h>
|
||||
+#include <dt-bindings/interrupt-controller/irq.h>
|
||||
+#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
+#include <dt-bindings/pinctrl/mt7623-pinfunc.h>
|
||||
+#include <dt-bindings/reset-controller/mt7623-resets.h>
|
||||
+#include "skeleton64.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ compatible = "mediatek,mt7623";
|
||||
+ interrupt-parent = <&sysirq>;
|
||||
+
|
||||
+ cpus {
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ enable-method = "mediatek,mt65xx-smp";
|
||||
+ cpu@0 {
|
||||
+ device_type = "cpu";
|
||||
+ compatible = "arm,cortex-a7";
|
||||
+ reg = <0x0>;
|
||||
+ };
|
||||
+ cpu@1 {
|
||||
+ device_type = "cpu";
|
||||
+ compatible = "arm,cortex-a7";
|
||||
+ reg = <0x1>;
|
||||
+ };
|
||||
+ cpu@2 {
|
||||
+ device_type = "cpu";
|
||||
+ compatible = "arm,cortex-a7";
|
||||
+ reg = <0x2>;
|
||||
+ };
|
||||
+ cpu@3 {
|
||||
+ device_type = "cpu";
|
||||
+ compatible = "arm,cortex-a7";
|
||||
+ reg = <0x3>;
|
||||
+ };
|
||||
+
|
||||
+ };
|
||||
+
|
||||
+ clk26m: oscillator@0 {
|
||||
+ compatible = "fixed-clock";
|
||||
+ #clock-cells = <0>;
|
||||
+ clock-frequency = <26000000>;
|
||||
+ clock-output-names = "clk26m";
|
||||
+ };
|
||||
+
|
||||
+ clk32k: oscillator@1 {
|
||||
+ compatible = "fixed-clock";
|
||||
+ #clock-cells = <0>;
|
||||
+ clock-frequency = <32000>;
|
||||
+ clock-output-names = "clk32k";
|
||||
+ };
|
||||
+
|
||||
+ timer {
|
||||
+ compatible = "arm,armv7-timer";
|
||||
+ interrupt-parent = <&gic>;
|
||||
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
|
||||
+ IRQ_TYPE_LEVEL_LOW)>,
|
||||
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) |
|
||||
+ IRQ_TYPE_LEVEL_LOW)>,
|
||||
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
|
||||
+ IRQ_TYPE_LEVEL_LOW)>,
|
||||
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
|
||||
+ IRQ_TYPE_LEVEL_LOW)>;
|
||||
+ clock-frequency = <13000000>;
|
||||
+ arm,cpu-registers-not-fw-configured;
|
||||
+ };
|
||||
+
|
||||
+ thermal-zones {
|
||||
+ cpu_thermal: cpu_thermal {
|
||||
+ polling-delay-passive = <1000>;
|
||||
+ polling-delay = <5000>;
|
||||
+
|
||||
+ thermal-sensors = <&thermal 1>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ soc {
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <2>;
|
||||
+ compatible = "simple-bus";
|
||||
+ ranges;
|
||||
+
|
||||
+ topckgen: topckgen@10000000 {
|
||||
+ compatible = "mediatek,mt7623-topckgen";
|
||||
+ reg = <0 0x10000000 0 0x1000>;
|
||||
+ #clock-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ infracfg: infracfg@10001000 {
|
||||
+ compatible = "mediatek,mt7623-infracfg", "syscon";
|
||||
+ reg = <0 0x10001000 0 0x1000>;
|
||||
+ #clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ pericfg: pericfg@10003000 {
|
||||
+ compatible = "mediatek,mt7623-pericfg", "syscon";
|
||||
+ reg = <0 0x10003000 0 0x1000>;
|
||||
+ #clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ /*
|
||||
+ * Pinctrl access register at 0x10005000 through regmap.
|
||||
+ * Register 0x1000b000 is used by EINT.
|
||||
+ */
|
||||
+ 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-cells = <2>;
|
||||
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ };
|
||||
+
|
||||
+ syscfg_pctl_a: syscfg_pctl_a@10005000 {
|
||||
+ compatible = "mediatek,mt7623-pctl-a-syscfg", "syscon";
|
||||
+ reg = <0 0x10005000 0 0x1000>;
|
||||
+ };
|
||||
+
|
||||
+ wdt: watchdog@10007000 {
|
||||
+ compatible = "mediatek,mt7623-wdt", "mediatek,mt6589-wdt";
|
||||
+ reg = <0 0x10007000 0 0x18>;
|
||||
+ };
|
||||
+
|
||||
+ timer: timer@10008000 {
|
||||
+ compatible = "mediatek,mt7623-timer",
|
||||
+ "mediatek,mt6577-timer";
|
||||
+ reg = <0 0x10008000 0 0x80>;
|
||||
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ clocks = <&topckgen CLK_TOP_AXI_SEL>,
|
||||
+ <&topckgen CLK_TOP_RTC_SEL>;
|
||||
+ clock-names = "system-clk", "rtc-clk";
|
||||
+ };
|
||||
+
|
||||
+ sysirq: interrupt-controller@10200100 {
|
||||
+ compatible = "mediatek,mt7623-sysirq",
|
||||
+ "mediatek,mt6577-sysirq";
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <3>;
|
||||
+ interrupt-parent = <&gic>;
|
||||
+ reg = <0 0x10200100 0 0x1c>;
|
||||
+ };
|
||||
+
|
||||
+ apmixedsys: apmixedsys@10209000 {
|
||||
+ compatible = "mediatek,mt7623-apmixedsys";
|
||||
+ reg = <0 0x10209000 0 0x1000>;
|
||||
+ #clock-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ gic: interrupt-controller@10211000 {
|
||||
+ compatible = "arm,cortex-a7-gic";
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <3>;
|
||||
+ interrupt-parent = <&gic>;
|
||||
+ reg = <0 0x10211000 0 0x1000>,
|
||||
+ <0 0x10212000 0 0x1000>,
|
||||
+ <0 0x10214000 0 0x2000>,
|
||||
+ <0 0x10216000 0 0x2000>;
|
||||
+ };
|
||||
+
|
||||
+ auxadc: auxadc@11001000 {
|
||||
+ compatible = "mediatek,mt7623-auxadc", "mediatek,mt8173-auxadc";
|
||||
+ reg = <0 0x11001000 0 0x1000>;
|
||||
+ };
|
||||
+
|
||||
+ uart0: serial@11006000 {
|
||||
+ 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@11007000 {
|
||||
+ 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@11008000 {
|
||||
+ 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@11009000 {
|
||||
+ compatible = "mediatek,mt7623-uart","mediatek,mt6577-uart";
|
||||
+ reg = <0 0x11005000 0 0x400>;
|
||||
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ clocks = <&pericfg CLK_PERI_UART3_SEL>, <&pericfg CLK_PERI_UART3>;
|
||||
+ clock-names = "baud", "bus";
|
||||
+
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ spi: spi@1100a000 {
|
||||
+ compatible = "medi/THEatek,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,mt7623-thermal", "mediatek,mt8173-thermal";
|
||||
+ reg = <0 0x1100b000 0 0x1000>;
|
||||
+ interrupts = <0 38 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ clocks = <&pericfg CLK_PERI_THERM>, <&pericfg CLK_PERI_AUXADC>;
|
||||
+ clock-names = "therm", "auxadc";
|
||||
+ resets = <&pericfg MT7623_PERI_THERM_SW_RST>;
|
||||
+ reset-names = "therm";
|
||||
+ auxadc = <&auxadc>;
|
||||
+ apmixedsys = <&apmixedsys>;
|
||||
+
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ i2c0: i2c@11007000 {
|
||||
+ compatible = "mediatek,mt7623-i2c", "mediatek,mt6577-i2c";
|
||||
+ reg = <0 0x11007000 0 0x70>,
|
||||
+ <0 0x11000300 0 0x80>;
|
||||
+ interrupts = <0 44 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ clock-frequency = <400000>;
|
||||
+ clock-div = <16>;
|
||||
+ clocks = <&pericfg CLK_PERI_I2C0>, <&pericfg CLK_PERI_AP_DMA>;
|
||||
+ clock-names = "main", "dma";
|
||||
+
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ mmc0: mmc@11230000 {
|
||||
+ compatible = "mediatek,mt7623-mmc",
|
||||
+ "mediatek,mt8135-mmc";
|
||||
+ reg = <0 0x11230000 0 0x1000>;
|
||||
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ clocks = <&pericfg CLK_PERI_MSDC20_1>,
|
||||
+ <&topckgen CLK_TOP_MSDC30_0_SEL>;
|
||||
+ clock-names = "source", "hclk";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ usb: usb30@11270000 {
|
||||
+ compatible = "mediatek,mt7623-xhci", "mediatek,mt8173-xhci", "generic-xhci";
|
||||
+ reg = <0 0x11270000 0 0x1000>;
|
||||
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ usb-phy = <&u3phy>;
|
||||
+ usb3-lpm-capable;
|
||||
+ };
|
||||
+
|
||||
+ u3phy: usb-phy@11271000 {
|
||||
+ compatible = "mediatek,mt7623-u3phy", "mediatek,mt8173-u3phy";
|
||||
+ reg = <0 0x11271000 0 0x3000>,
|
||||
+ <0 0x11280000 0 0x20000>;
|
||||
+// power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>;
|
||||
+// reg-vusb33-supply = <&mt6397_vusb_reg>;
|
||||
+ clocks = <&pericfg CLK_PERI_USB0>,
|
||||
+ <&pericfg CLK_PERI_USB1>,
|
||||
+ <&topckgen CLK_TOP_USB20_SEL>;
|
||||
+// <&apmixedsys CLK_APMIXED_REF2USB_TX>;
|
||||
+ clock-names = "wakeup_deb_p0",
|
||||
+ "wakeup_deb_p1",
|
||||
+ "sys_mac";
|
||||
+// "u3phya_ref";
|
||||
+ disable-usb2-p1;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ ethernet@1B100000 {
|
||||
+ compatible = "mediatek,mt7623-net";
|
||||
+ interrupts = <0 200 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ };
|
||||
+
|
||||
+ pcie: pcie@1a140000 {
|
||||
+ compatible = "mediatek,mt7623-pcie";
|
||||
+ reg = <0 0x1a140000 0 0x10000>;
|
||||
+
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+
|
||||
+ device_type = "pci";
|
||||
+
|
||||
+ bus-range = <0 255>;
|
||||
+ ranges = <
|
||||
+ 0x02000000 0 0 0x00000000 0x60000000 0 0x10000000 /* pci memory */
|
||||
+ 0x01000000 0 0 0x00000000 0x1A160000 0 0x00010000 /* io space */
|
||||
+ >;
|
||||
+
|
||||
+ pcie0 {
|
||||
+ reg = <0x0000 0 0 0 0>;
|
||||
+
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+
|
||||
+ device_type = "pci";
|
||||
+ };
|
||||
+
|
||||
+ pcie1 {
|
||||
+ reg = <0x0800 0 0 0 0>;
|
||||
+
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+
|
||||
+ device_type = "pci";
|
||||
+ };
|
||||
+
|
||||
+ pcie2 {
|
||||
+ reg = <0x1000 0 0 0 0>;
|
||||
+
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+
|
||||
+ device_type = "pci";
|
||||
+ };
|
||||
+
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+};
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,118 @@
|
||||
From 89556b1a4d98fbfe498c8f26e988cbb8266f7dfe Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sat, 27 Jun 2015 13:17:35 +0200
|
||||
Subject: [PATCH 67/76] arm: mediatek: add mt7623 support
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/arm/mach-mediatek/Kconfig | 6 ++
|
||||
arch/arm/mach-mediatek/mediatek.c | 2 +
|
||||
.../dt-bindings/reset-controller/mt7623-resets.h | 59 ++++++++++++++++++++
|
||||
3 files changed, 67 insertions(+)
|
||||
create mode 100644 include/dt-bindings/reset-controller/mt7623-resets.h
|
||||
|
||||
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
|
||||
index 7704818..5393d25 100644
|
||||
--- a/arch/arm/mach-mediatek/Kconfig
|
||||
+++ b/arch/arm/mach-mediatek/Kconfig
|
||||
@@ -17,6 +17,12 @@ config MACH_MT6592
|
||||
bool "MediaTek MT6592 SoCs support"
|
||||
default ARCH_MEDIATEK
|
||||
|
||||
+config MACH_MT7623
|
||||
+ bool "MediaTek MT7623 SoCs support"
|
||||
+ default ARCH_MEDIATEK
|
||||
+ select ARCH_HAS_PCI
|
||||
+ select PCI
|
||||
+
|
||||
config MACH_MT8127
|
||||
bool "MediaTek MT8127 SoCs support"
|
||||
default ARCH_MEDIATEK
|
||||
diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c
|
||||
index 6b38d67..ab8cf21 100644
|
||||
--- a/arch/arm/mach-mediatek/mediatek.c
|
||||
+++ b/arch/arm/mach-mediatek/mediatek.c
|
||||
@@ -29,6 +29,7 @@ static void __init mediatek_timer_init(void)
|
||||
void __iomem *gpt_base = 0;
|
||||
|
||||
if (of_machine_is_compatible("mediatek,mt6589") ||
|
||||
+ of_machine_is_compatible("mediatek,mt7623") ||
|
||||
of_machine_is_compatible("mediatek,mt8135") ||
|
||||
of_machine_is_compatible("mediatek,mt8127")) {
|
||||
/* turn on GPT6 which ungates arch timer clocks */
|
||||
@@ -48,6 +49,7 @@ static void __init mediatek_timer_init(void)
|
||||
static const char * const mediatek_board_dt_compat[] = {
|
||||
"mediatek,mt6589",
|
||||
"mediatek,mt6592",
|
||||
+ "mediatek,mt7623",
|
||||
"mediatek,mt8127",
|
||||
"mediatek,mt8135",
|
||||
NULL,
|
||||
diff --git a/include/dt-bindings/reset-controller/mt7623-resets.h b/include/dt-bindings/reset-controller/mt7623-resets.h
|
||||
new file mode 100644
|
||||
index 0000000..28a7d69
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/reset-controller/mt7623-resets.h
|
||||
@@ -0,0 +1,59 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015 OpenWrt
|
||||
+ * Author: John Crispin
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT7623
|
||||
+#define _DT_BINDINGS_RESET_CONTROLLER_MT7623
|
||||
+
|
||||
+/* INFRACFG resets */
|
||||
+#define MT7623_INFRA_EMI_REG_RST 0
|
||||
+#define MT7623_INFRA_DRAMC0_A0_RST 1
|
||||
+#define MT7623_INFRA_FHCTL_RST 2
|
||||
+#define MT7623_INFRA_APCIRQ_EINT_RST 3
|
||||
+#define MT7623_INFRA_APXGPT_RST 4
|
||||
+#define MT7623_INFRA_SCPSYS_RST 5
|
||||
+#define MT7623_INFRA_KP_RST 6
|
||||
+#define MT7623_INFRA_PMIC_WRAP_RST 7
|
||||
+#define MT7623_INFRA_MIPI_RST 8
|
||||
+#define MT7623_INFRA_IRRX_RST 9
|
||||
+#define MT7623_INFRA_CEC_RST 10
|
||||
+#define MT7623_INFRA_EMI_RST 32
|
||||
+#define MT7623_INFRA_DRAMC0_RST 34
|
||||
+#define MT7623_INFRA_SMI_RST 37
|
||||
+#define MT7623_INFRA_M4U_RST 38
|
||||
+
|
||||
+/* PERICFG resets */
|
||||
+#define MT7623_PERI_UART0_SW_RST 0
|
||||
+#define MT7623_PERI_UART1_SW_RST 1
|
||||
+#define MT7623_PERI_UART2_SW_RST 2
|
||||
+#define MT7623_PERI_UART3_SW_RST 3
|
||||
+#define MT7623_PERI_GCPU_SW_RST 5
|
||||
+#define MT7623_PERI_BTIF_SW_RST 6
|
||||
+#define MT7623_PERI_PWM_SW_RST 8
|
||||
+#define MT7623_PERI_AUXADC_SW_RST 10
|
||||
+#define MT7623_PERI_DMA_SW_RST 11
|
||||
+#define MT7623_PERI_NFI_SW_RST 14
|
||||
+#define MT7623_PERI_NLI_SW_RST 15
|
||||
+#define MT7623_PERI_THERM_SW_RST 16
|
||||
+#define MT7623_PERI_MSDC0_SW_RST 17
|
||||
+#define MT7623_PERI_MSDC1_SW_RST 19
|
||||
+#define MT7623_PERI_MSDC2_SW_RST 20
|
||||
+#define MT7623_PERI_I2C0_SW_RST 22
|
||||
+#define MT7623_PERI_I2C1_SW_RST 23
|
||||
+#define MT7623_PERI_I2C2_SW_RST 24
|
||||
+#define MT7623_PERI_I2C3_SW_RST 25
|
||||
+#define MT7623_PERI_USB_SW_RST 28
|
||||
+#define MT7623_PERI_ETH_SW_RST 29
|
||||
+#define MT7623_PERI_SPI0_SW_RST 33
|
||||
+
|
||||
+#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT7623 */
|
||||
--
|
||||
1.7.10.4
|
||||
|
1579
target/linux/mediatek/patches/0068-SDK_compat.patch
Normal file
1579
target/linux/mediatek/patches/0068-SDK_compat.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,554 @@
|
||||
From 0ec1ddd9233579b6d6dc0df325e870c5560344be Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 28 Jun 2015 19:50:51 +0200
|
||||
Subject: [PATCH 69/76] arm: mediatek: add mt7623 support to pmic-wrapper
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/soc/mediatek/mtk-pmic-wrap.c | 345 +++++++++++++++++++++++++++++-----
|
||||
1 file changed, 296 insertions(+), 49 deletions(-)
|
||||
|
||||
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
index f432291..9ff02a1 100644
|
||||
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
@@ -31,6 +31,13 @@
|
||||
#define PWRAP_MT8135_BRIDGE_WDT_UNIT 0x50
|
||||
#define PWRAP_MT8135_BRIDGE_WDT_SRC_EN 0x54
|
||||
|
||||
+#define PWRAP_MT7623_AUXADC_CON21 0x076C
|
||||
+#define PWRAP_MT7623_AUXADC_ADC12 0x072C
|
||||
+#define PWRAP_MT7623_AUXADC_ADC13 0x072E
|
||||
+#define PWRAP_MT7623_AUXADC_ADC14 0x0730
|
||||
+#define PWRAP_MT7623_AUXADC_CON2 0x0746
|
||||
+#define PWRAP_MT7623_AUXADC_CON3 0x0748
|
||||
+
|
||||
/* macro for wrapper status */
|
||||
#define PWRAP_GET_WACS_RDATA(x) (((x) >> 0) & 0x0000ffff)
|
||||
#define PWRAP_GET_WACS_FSM(x) (((x) >> 16) & 0x00000007)
|
||||
@@ -61,32 +68,104 @@
|
||||
#define PWRAP_MAN_CMD_OP_OUTQ (0xa << 8)
|
||||
|
||||
/* macro for slave device wrapper registers */
|
||||
-#define PWRAP_DEW_BASE 0xbc00
|
||||
-#define PWRAP_DEW_EVENT_OUT_EN (PWRAP_DEW_BASE + 0x0)
|
||||
-#define PWRAP_DEW_DIO_EN (PWRAP_DEW_BASE + 0x2)
|
||||
-#define PWRAP_DEW_EVENT_SRC_EN (PWRAP_DEW_BASE + 0x4)
|
||||
-#define PWRAP_DEW_EVENT_SRC (PWRAP_DEW_BASE + 0x6)
|
||||
-#define PWRAP_DEW_EVENT_FLAG (PWRAP_DEW_BASE + 0x8)
|
||||
-#define PWRAP_DEW_READ_TEST (PWRAP_DEW_BASE + 0xa)
|
||||
-#define PWRAP_DEW_WRITE_TEST (PWRAP_DEW_BASE + 0xc)
|
||||
-#define PWRAP_DEW_CRC_EN (PWRAP_DEW_BASE + 0xe)
|
||||
-#define PWRAP_DEW_CRC_VAL (PWRAP_DEW_BASE + 0x10)
|
||||
-#define PWRAP_DEW_MON_GRP_SEL (PWRAP_DEW_BASE + 0x12)
|
||||
-#define PWRAP_DEW_MON_FLAG_SEL (PWRAP_DEW_BASE + 0x14)
|
||||
-#define PWRAP_DEW_EVENT_TEST (PWRAP_DEW_BASE + 0x16)
|
||||
-#define PWRAP_DEW_CIPHER_KEY_SEL (PWRAP_DEW_BASE + 0x18)
|
||||
-#define PWRAP_DEW_CIPHER_IV_SEL (PWRAP_DEW_BASE + 0x1a)
|
||||
-#define PWRAP_DEW_CIPHER_LOAD (PWRAP_DEW_BASE + 0x1c)
|
||||
-#define PWRAP_DEW_CIPHER_START (PWRAP_DEW_BASE + 0x1e)
|
||||
-#define PWRAP_DEW_CIPHER_RDY (PWRAP_DEW_BASE + 0x20)
|
||||
-#define PWRAP_DEW_CIPHER_MODE (PWRAP_DEW_BASE + 0x22)
|
||||
-#define PWRAP_DEW_CIPHER_SWRST (PWRAP_DEW_BASE + 0x24)
|
||||
-#define PWRAP_MT8173_DEW_CIPHER_IV0 (PWRAP_DEW_BASE + 0x26)
|
||||
-#define PWRAP_MT8173_DEW_CIPHER_IV1 (PWRAP_DEW_BASE + 0x28)
|
||||
-#define PWRAP_MT8173_DEW_CIPHER_IV2 (PWRAP_DEW_BASE + 0x2a)
|
||||
-#define PWRAP_MT8173_DEW_CIPHER_IV3 (PWRAP_DEW_BASE + 0x2c)
|
||||
-#define PWRAP_MT8173_DEW_CIPHER_IV4 (PWRAP_DEW_BASE + 0x2e)
|
||||
-#define PWRAP_MT8173_DEW_CIPHER_IV5 (PWRAP_DEW_BASE + 0x30)
|
||||
+enum pwrap_dew_regs {
|
||||
+ PWRAP_DEW_EVENT_OUT_EN,
|
||||
+ PWRAP_DEW_DIO_EN,
|
||||
+ PWRAP_DEW_EVENT_SRC_EN,
|
||||
+ PWRAP_DEW_EVENT_SRC,
|
||||
+ PWRAP_DEW_EVENT_FLAG,
|
||||
+ PWRAP_DEW_READ_TEST,
|
||||
+ PWRAP_DEW_WRITE_TEST,
|
||||
+ PWRAP_DEW_CRC_EN,
|
||||
+ PWRAP_DEW_CRC_VAL,
|
||||
+ PWRAP_DEW_MON_GRP_SEL,
|
||||
+ PWRAP_DEW_MON_FLAG_SEL,
|
||||
+ PWRAP_DEW_EVENT_TEST,
|
||||
+ PWRAP_DEW_CIPHER_KEY_SEL,
|
||||
+ PWRAP_DEW_CIPHER_IV_SEL,
|
||||
+ PWRAP_DEW_CIPHER_LOAD,
|
||||
+ PWRAP_DEW_CIPHER_START,
|
||||
+ PWRAP_DEW_CIPHER_RDY,
|
||||
+ PWRAP_DEW_CIPHER_MODE,
|
||||
+ PWRAP_DEW_CIPHER_SWRST,
|
||||
+
|
||||
+ /* MT7623 only regs */
|
||||
+ PWRAP_DEW_CIPHER_EN,
|
||||
+ PWRAP_DEW_RDDMY_NO,
|
||||
+
|
||||
+ /* MT8173 only regs */
|
||||
+ PWRAP_DEW_CIPHER_IV0,
|
||||
+ PWRAP_DEW_CIPHER_IV1,
|
||||
+ PWRAP_DEW_CIPHER_IV2,
|
||||
+ PWRAP_DEW_CIPHER_IV3,
|
||||
+ PWRAP_DEW_CIPHER_IV4,
|
||||
+ PWRAP_DEW_CIPHER_IV5,
|
||||
+};
|
||||
+
|
||||
+static int mt7623_dew_regs[] = {
|
||||
+ [PWRAP_DEW_DIO_EN] = 0x18a,
|
||||
+ [PWRAP_DEW_READ_TEST] = 0x18c,
|
||||
+ [PWRAP_DEW_WRITE_TEST] = 0x18e,
|
||||
+ [PWRAP_DEW_CRC_EN] = 0x192,
|
||||
+ [PWRAP_DEW_CRC_VAL] = 0x194,
|
||||
+ [PWRAP_DEW_CIPHER_KEY_SEL] = 0x198,
|
||||
+ [PWRAP_DEW_CIPHER_IV_SEL] = 0x19a,
|
||||
+ [PWRAP_DEW_CIPHER_EN] = 0x19c,
|
||||
+ [PWRAP_DEW_CIPHER_RDY] = 0x19e,
|
||||
+ [PWRAP_DEW_CIPHER_MODE] = 0x1a0,
|
||||
+ [PWRAP_DEW_CIPHER_SWRST] = 0x1a2,
|
||||
+ [PWRAP_DEW_RDDMY_NO] = 0x1a4,
|
||||
+};
|
||||
+
|
||||
+static int mt8135_dew_regs[] = {
|
||||
+ [PWRAP_DEW_EVENT_OUT_EN] = 0x0,
|
||||
+ [PWRAP_DEW_DIO_EN] = 0x2,
|
||||
+ [PWRAP_DEW_EVENT_SRC_EN] = 0x4,
|
||||
+ [PWRAP_DEW_EVENT_SRC] = 0x6,
|
||||
+ [PWRAP_DEW_EVENT_FLAG] = 0x8,
|
||||
+ [PWRAP_DEW_READ_TEST] = 0xa,
|
||||
+ [PWRAP_DEW_WRITE_TEST] = 0xc,
|
||||
+ [PWRAP_DEW_CRC_EN] = 0xe,
|
||||
+ [PWRAP_DEW_CRC_VAL] = 0x10,
|
||||
+ [PWRAP_DEW_MON_GRP_SEL] = 0x12,
|
||||
+ [PWRAP_DEW_MON_FLAG_SEL] = 0x14,
|
||||
+ [PWRAP_DEW_EVENT_TEST] = 0x16,
|
||||
+ [PWRAP_DEW_CIPHER_KEY_SEL] = 0x18,
|
||||
+ [PWRAP_DEW_CIPHER_IV_SEL] = 0x1a,
|
||||
+ [PWRAP_DEW_CIPHER_LOAD] = 0x1c,
|
||||
+ [PWRAP_DEW_CIPHER_START] = 0x1e,
|
||||
+ [PWRAP_DEW_CIPHER_RDY] = 0x20,
|
||||
+ [PWRAP_DEW_CIPHER_MODE] = 0x22,
|
||||
+ [PWRAP_DEW_CIPHER_SWRST] = 0x24,
|
||||
+};
|
||||
+
|
||||
+static int mt8173_dew_regs[] = {
|
||||
+ [PWRAP_DEW_EVENT_OUT_EN] = 0x0,
|
||||
+ [PWRAP_DEW_DIO_EN] = 0x2,
|
||||
+ [PWRAP_DEW_EVENT_SRC_EN] = 0x4,
|
||||
+ [PWRAP_DEW_EVENT_SRC] = 0x6,
|
||||
+ [PWRAP_DEW_EVENT_FLAG] = 0x8,
|
||||
+ [PWRAP_DEW_READ_TEST] = 0xa,
|
||||
+ [PWRAP_DEW_WRITE_TEST] = 0xc,
|
||||
+ [PWRAP_DEW_CRC_EN] = 0xe,
|
||||
+ [PWRAP_DEW_CRC_VAL] = 0x10,
|
||||
+ [PWRAP_DEW_MON_GRP_SEL] = 0x12,
|
||||
+ [PWRAP_DEW_MON_FLAG_SEL] = 0x14,
|
||||
+ [PWRAP_DEW_EVENT_TEST] = 0x16,
|
||||
+ [PWRAP_DEW_CIPHER_KEY_SEL] = 0x18,
|
||||
+ [PWRAP_DEW_CIPHER_IV_SEL] = 0x1a,
|
||||
+ [PWRAP_DEW_CIPHER_LOAD] = 0x1c,
|
||||
+ [PWRAP_DEW_CIPHER_START] = 0x1e,
|
||||
+ [PWRAP_DEW_CIPHER_RDY] = 0x20,
|
||||
+ [PWRAP_DEW_CIPHER_MODE] = 0x22,
|
||||
+ [PWRAP_DEW_CIPHER_SWRST] = 0x24,
|
||||
+ [PWRAP_DEW_CIPHER_IV0] = 0x26,
|
||||
+ [PWRAP_DEW_CIPHER_IV1] = 0x28,
|
||||
+ [PWRAP_DEW_CIPHER_IV2] = 0x2a,
|
||||
+ [PWRAP_DEW_CIPHER_IV3] = 0x2c,
|
||||
+ [PWRAP_DEW_CIPHER_IV4] = 0x2e,
|
||||
+ [PWRAP_DEW_CIPHER_IV5] = 0x30,
|
||||
+};
|
||||
|
||||
enum pwrap_regs {
|
||||
PWRAP_MUX_SEL,
|
||||
@@ -162,7 +241,7 @@ enum pwrap_regs {
|
||||
PWRAP_CIPHER_LOAD,
|
||||
PWRAP_CIPHER_START,
|
||||
|
||||
- /* MT8173 only regs */
|
||||
+ /* MT7623/MT8173 only regs */
|
||||
PWRAP_RDDMY,
|
||||
PWRAP_SI_CK_CON,
|
||||
PWRAP_DVFS_ADR0,
|
||||
@@ -183,6 +262,107 @@ enum pwrap_regs {
|
||||
PWRAP_DVFS_WDATA7,
|
||||
PWRAP_SPMINF_STA,
|
||||
PWRAP_CIPHER_EN,
|
||||
+
|
||||
+ /* MT7623 only regs */
|
||||
+ PWRAP_OP_TYPE,
|
||||
+ PWRAP_MSB_FIRST,
|
||||
+ PWRAP_TOP_CKCON1,
|
||||
+ PWRAP_TOP_CKCON1_CLR,
|
||||
+ PWRAP_ADC_CMD_ADDR,
|
||||
+ PWRAP_ADC_CMD,
|
||||
+ PWRAP_ADC_RDY_ADDR,
|
||||
+ PWRAP_ADC_RDATA_ADDR1,
|
||||
+ PWRAP_ADC_RDATA_ADDR2,
|
||||
+};
|
||||
+
|
||||
+static int mt7623_regs[] = {
|
||||
+ [PWRAP_MUX_SEL] = 0x0,
|
||||
+ [PWRAP_WRAP_EN] = 0x4,
|
||||
+ [PWRAP_DIO_EN] = 0x8,
|
||||
+ [PWRAP_SIDLY] = 0xc,
|
||||
+ [PWRAP_OP_TYPE] = 0x10,
|
||||
+ [PWRAP_MSB_FIRST] = 0x14,
|
||||
+ [PWRAP_RDDMY] = 0x18,
|
||||
+ [PWRAP_SI_CK_CON] = 0x1c,
|
||||
+ [PWRAP_CSHEXT_WRITE] = 0x20,
|
||||
+ [PWRAP_CSHEXT_READ] = 0x24,
|
||||
+ [PWRAP_CSLEXT_START] = 0x28,
|
||||
+ [PWRAP_CSLEXT_END] = 0x2c,
|
||||
+ [PWRAP_STAUPD_PRD] = 0x30,
|
||||
+ [PWRAP_STAUPD_GRPEN] = 0x34,
|
||||
+ [PWRAP_STAUPD_MAN_TRIG] = 0x38,
|
||||
+ [PWRAP_STAUPD_STA] = 0x3C,
|
||||
+ [PWRAP_WRAP_STA] = 0x44,
|
||||
+ [PWRAP_HARB_INIT] = 0x48,
|
||||
+ [PWRAP_HARB_HPRIO] = 0x4c,
|
||||
+ [PWRAP_HIPRIO_ARB_EN] = 0x50,
|
||||
+ [PWRAP_HARB_STA0] = 0x54,
|
||||
+ [PWRAP_HARB_STA1] = 0x58,
|
||||
+ [PWRAP_MAN_EN] = 0x5c,
|
||||
+ [PWRAP_MAN_CMD] = 0x60,
|
||||
+ [PWRAP_MAN_RDATA] = 0x6c,
|
||||
+ [PWRAP_MAN_VLDCLR] = 0x68,
|
||||
+ [PWRAP_WACS0_EN] = 0x6c,
|
||||
+ [PWRAP_INIT_DONE0] = 0x70,
|
||||
+ [PWRAP_WACS0_CMD] = 0x74,
|
||||
+ [PWRAP_WACS0_RDATA] = 0x78,
|
||||
+ [PWRAP_WACS0_VLDCLR] = 0x7c,
|
||||
+ [PWRAP_WACS1_EN] = 0x80,
|
||||
+ [PWRAP_INIT_DONE1] = 0x84,
|
||||
+ [PWRAP_WACS1_CMD] = 0x88,
|
||||
+ [PWRAP_WACS1_RDATA] = 0x9c,
|
||||
+ [PWRAP_WACS1_VLDCLR] = 0x90,
|
||||
+ [PWRAP_WACS2_EN] = 0x94,
|
||||
+ [PWRAP_INIT_DONE2] = 0x98,
|
||||
+ [PWRAP_WACS2_CMD] = 0x9c,
|
||||
+ [PWRAP_WACS2_RDATA] = 0xa0,
|
||||
+ [PWRAP_WACS2_VLDCLR] = 0xa4,
|
||||
+ [PWRAP_INT_EN] = 0xa8,
|
||||
+ [PWRAP_INT_FLG_RAW] = 0xac,
|
||||
+ [PWRAP_INT_FLG] = 0xb0,
|
||||
+ [PWRAP_INT_CLR] = 0xb4,
|
||||
+ [PWRAP_SIG_ADR] = 0xb8,
|
||||
+ [PWRAP_SIG_MODE] = 0xbc,
|
||||
+ [PWRAP_SIG_VALUE] = 0xc0,
|
||||
+ [PWRAP_SIG_ERRVAL] = 0xc4,
|
||||
+ [PWRAP_CRC_EN] = 0xc8,
|
||||
+ [PWRAP_TIMER_EN] = 0xcc,
|
||||
+ [PWRAP_TIMER_STA] = 0xd0,
|
||||
+ [PWRAP_WDT_UNIT] = 0xd4,
|
||||
+ [PWRAP_WDT_SRC_EN] = 0xd8,
|
||||
+ [PWRAP_WDT_FLG] = 0xdc,
|
||||
+ [PWRAP_DEBUG_INT_SEL] = 0xe0,
|
||||
+ [PWRAP_DVFS_ADR0] = 0xe4,
|
||||
+ [PWRAP_DVFS_WDATA0] = 0xe8,
|
||||
+ [PWRAP_DVFS_ADR1] = 0xec,
|
||||
+ [PWRAP_DVFS_WDATA1] = 0xf0,
|
||||
+ [PWRAP_DVFS_ADR2] = 0xf4,
|
||||
+ [PWRAP_DVFS_WDATA2] = 0xf8,
|
||||
+ [PWRAP_DVFS_ADR3] = 0xfc,
|
||||
+ [PWRAP_DVFS_WDATA3] = 0x100,
|
||||
+ [PWRAP_DVFS_ADR4] = 0x104,
|
||||
+ [PWRAP_DVFS_WDATA4] = 0x108,
|
||||
+ [PWRAP_DVFS_ADR5] = 0x10c,
|
||||
+ [PWRAP_DVFS_WDATA5] = 0x110,
|
||||
+ [PWRAP_DVFS_ADR6] = 0x114,
|
||||
+ [PWRAP_DVFS_WDATA6] = 0x118,
|
||||
+ [PWRAP_DVFS_ADR7] = 0x11c,
|
||||
+ [PWRAP_DVFS_WDATA7] = 0x120,
|
||||
+ [PWRAP_CIPHER_KEY_SEL] = 0x124,
|
||||
+ [PWRAP_TOP_CKCON1] = 0x126,
|
||||
+ [PWRAP_CIPHER_IV_SEL] = 0x128,
|
||||
+ [PWRAP_TOP_CKCON1_CLR] = 0x12a,
|
||||
+ [PWRAP_CIPHER_EN] = 0x12c,
|
||||
+ [PWRAP_CIPHER_RDY] = 0x130,
|
||||
+ [PWRAP_CIPHER_MODE] = 0x134,
|
||||
+ [PWRAP_CIPHER_SWRST] = 0x138,
|
||||
+ [PWRAP_DCM_EN] = 0x13c,
|
||||
+ [PWRAP_DCM_DBC_PRD] = 0x140,
|
||||
+ [PWRAP_ADC_CMD_ADDR] = 0x144,
|
||||
+ [PWRAP_ADC_CMD] = 0x148,
|
||||
+ [PWRAP_ADC_RDY_ADDR] = 0x14C,
|
||||
+ [PWRAP_ADC_RDATA_ADDR1] = 0x150,
|
||||
+ [PWRAP_ADC_RDATA_ADDR2] = 0x154,
|
||||
};
|
||||
|
||||
static int mt8173_regs[] = {
|
||||
@@ -341,24 +521,39 @@ static int mt8135_regs[] = {
|
||||
};
|
||||
|
||||
enum pwrap_type {
|
||||
+ PWRAP_MT7623,
|
||||
PWRAP_MT8135,
|
||||
PWRAP_MT8173,
|
||||
};
|
||||
|
||||
struct pmic_wrapper_type {
|
||||
int *regs;
|
||||
+ int *dew_regs;
|
||||
+ u32 dew_base;
|
||||
enum pwrap_type type;
|
||||
u32 arb_en_all;
|
||||
};
|
||||
|
||||
+static struct pmic_wrapper_type pwrap_mt7623 = {
|
||||
+ .regs = mt7623_regs,
|
||||
+ .dew_regs = mt7623_dew_regs,
|
||||
+ .dew_base = 0x0,
|
||||
+ .type = PWRAP_MT7623,
|
||||
+ .arb_en_all = 0x3f,
|
||||
+};
|
||||
+
|
||||
static struct pmic_wrapper_type pwrap_mt8135 = {
|
||||
.regs = mt8135_regs,
|
||||
+ .dew_regs = mt8135_dew_regs,
|
||||
+ .dew_base = 0xbc00,
|
||||
.type = PWRAP_MT8135,
|
||||
.arb_en_all = 0x1ff,
|
||||
};
|
||||
|
||||
static struct pmic_wrapper_type pwrap_mt8173 = {
|
||||
.regs = mt8173_regs,
|
||||
+ .dew_regs = mt8173_dew_regs,
|
||||
+ .dew_base = 0xbc00,
|
||||
.type = PWRAP_MT8173,
|
||||
.arb_en_all = 0x3f,
|
||||
};
|
||||
@@ -368,6 +563,8 @@ struct pmic_wrapper {
|
||||
void __iomem *base;
|
||||
struct regmap *regmap;
|
||||
int *regs;
|
||||
+ int *dew_regs;
|
||||
+ u32 dew_base;
|
||||
enum pwrap_type type;
|
||||
u32 arb_en_all;
|
||||
struct clk *clk_spi;
|
||||
@@ -378,6 +575,11 @@ struct pmic_wrapper {
|
||||
void __iomem *bridge_base;
|
||||
};
|
||||
|
||||
+static inline int pwrap_is_mt7623(struct pmic_wrapper *wrp)
|
||||
+{
|
||||
+ return wrp->type == PWRAP_MT7623;
|
||||
+}
|
||||
+
|
||||
static inline int pwrap_is_mt8135(struct pmic_wrapper *wrp)
|
||||
{
|
||||
return wrp->type == PWRAP_MT8135;
|
||||
@@ -475,6 +677,16 @@ static int pwrap_read(struct pmic_wrapper *wrp, u32 adr, u32 *rdata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int pwrap_dew_write(struct pmic_wrapper *wrp, enum pwrap_dew_regs reg, u32 wdata)
|
||||
+{
|
||||
+ return pwrap_write(wrp, wrp->dew_base + wrp->dew_regs[reg], wdata);
|
||||
+}
|
||||
+
|
||||
+static int pwrap_dew_read(struct pmic_wrapper *wrp, enum pwrap_dew_regs reg, u32 *rdata)
|
||||
+{
|
||||
+ return pwrap_read(wrp, wrp->dew_base + wrp->dew_regs[reg], rdata);
|
||||
+}
|
||||
+
|
||||
static int pwrap_regmap_read(void *context, u32 adr, u32 *rdata)
|
||||
{
|
||||
return pwrap_read(context, adr, rdata);
|
||||
@@ -535,7 +747,7 @@ static int pwrap_init_sidly(struct pmic_wrapper *wrp)
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
pwrap_writel(wrp, i, PWRAP_SIDLY);
|
||||
- pwrap_read(wrp, PWRAP_DEW_READ_TEST, &rdata);
|
||||
+ pwrap_dew_read(wrp, PWRAP_DEW_READ_TEST, &rdata);
|
||||
if (rdata == PWRAP_DEW_READ_TEST_VAL) {
|
||||
dev_dbg(wrp->dev, "[Read Test] pass, SIDLY=%x\n", i);
|
||||
pass |= 1 << i;
|
||||
@@ -561,6 +773,14 @@ static int pwrap_init_reg_clock(struct pmic_wrapper *wrp)
|
||||
pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ);
|
||||
pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_START);
|
||||
pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_END);
|
||||
+ } else if (pwrap_is_mt7623(wrp)) {
|
||||
+ pwrap_writel(wrp, 0x3, PWRAP_TOP_CKCON1_CLR);
|
||||
+ pwrap_dew_write(wrp, 0x8, PWRAP_DEW_RDDMY_NO);
|
||||
+ pwrap_writel(wrp, 0x8, PWRAP_RDDMY);
|
||||
+ pwrap_writel(wrp, 0x5, PWRAP_CSHEXT_WRITE);
|
||||
+ pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_READ);
|
||||
+ pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START);
|
||||
+ pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END);
|
||||
} else {
|
||||
pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE);
|
||||
pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ);
|
||||
@@ -581,7 +801,7 @@ static bool pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp)
|
||||
u32 rdata;
|
||||
int ret;
|
||||
|
||||
- ret = pwrap_read(wrp, PWRAP_DEW_CIPHER_RDY, &rdata);
|
||||
+ ret = pwrap_dew_read(wrp, PWRAP_DEW_CIPHER_RDY, &rdata);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
@@ -606,12 +826,16 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
|
||||
}
|
||||
|
||||
/* Config cipher mode @PMIC */
|
||||
- pwrap_write(wrp, PWRAP_DEW_CIPHER_SWRST, 0x1);
|
||||
- pwrap_write(wrp, PWRAP_DEW_CIPHER_SWRST, 0x0);
|
||||
- pwrap_write(wrp, PWRAP_DEW_CIPHER_KEY_SEL, 0x1);
|
||||
- pwrap_write(wrp, PWRAP_DEW_CIPHER_IV_SEL, 0x2);
|
||||
- pwrap_write(wrp, PWRAP_DEW_CIPHER_LOAD, 0x1);
|
||||
- pwrap_write(wrp, PWRAP_DEW_CIPHER_START, 0x1);
|
||||
+ pwrap_dew_write(wrp, PWRAP_DEW_CIPHER_SWRST, 0x1);
|
||||
+ pwrap_dew_write(wrp, PWRAP_DEW_CIPHER_SWRST, 0x0);
|
||||
+ pwrap_dew_write(wrp, PWRAP_DEW_CIPHER_KEY_SEL, 0x1);
|
||||
+ pwrap_dew_write(wrp, PWRAP_DEW_CIPHER_IV_SEL, 0x2);
|
||||
+ if (pwrap_is_mt7623(wrp)) {
|
||||
+ pwrap_dew_write(wrp, PWRAP_DEW_CIPHER_EN, 0x1);
|
||||
+ } else {
|
||||
+ pwrap_dew_write(wrp, PWRAP_DEW_CIPHER_LOAD, 0x1);
|
||||
+ pwrap_dew_write(wrp, PWRAP_DEW_CIPHER_START, 0x1);
|
||||
+ }
|
||||
|
||||
/* wait for cipher data ready@AP */
|
||||
ret = pwrap_wait_for_state(wrp, pwrap_is_cipher_ready);
|
||||
@@ -628,7 +852,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
|
||||
}
|
||||
|
||||
/* wait for cipher mode idle */
|
||||
- pwrap_write(wrp, PWRAP_DEW_CIPHER_MODE, 0x1);
|
||||
+ pwrap_dew_write(wrp, PWRAP_DEW_CIPHER_MODE, 0x1);
|
||||
ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle);
|
||||
if (ret) {
|
||||
dev_err(wrp->dev, "cipher mode idle fail, ret=%d\n", ret);
|
||||
@@ -638,8 +862,8 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
|
||||
pwrap_writel(wrp, 1, PWRAP_CIPHER_MODE);
|
||||
|
||||
/* Write Test */
|
||||
- if (pwrap_write(wrp, PWRAP_DEW_WRITE_TEST, PWRAP_DEW_WRITE_TEST_VAL) ||
|
||||
- pwrap_read(wrp, PWRAP_DEW_WRITE_TEST, &rdata) ||
|
||||
+ if (pwrap_dew_write(wrp, PWRAP_DEW_WRITE_TEST, PWRAP_DEW_WRITE_TEST_VAL) ||
|
||||
+ pwrap_dew_read(wrp, PWRAP_DEW_WRITE_TEST, &rdata) ||
|
||||
(rdata != PWRAP_DEW_WRITE_TEST_VAL)) {
|
||||
dev_err(wrp->dev, "rdata=0x%04X\n", rdata);
|
||||
return -EFAULT;
|
||||
@@ -657,12 +881,17 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
if (wrp->rstc_bridge)
|
||||
reset_control_reset(wrp->rstc_bridge);
|
||||
|
||||
- if (pwrap_is_mt8173(wrp)) {
|
||||
+ if (pwrap_is_mt7623(wrp) || pwrap_is_mt8173(wrp)) {
|
||||
/* Enable DCM */
|
||||
pwrap_writel(wrp, 3, PWRAP_DCM_EN);
|
||||
pwrap_writel(wrp, 0, PWRAP_DCM_DBC_PRD);
|
||||
}
|
||||
|
||||
+ if (pwrap_is_mt7623(wrp)) {
|
||||
+ pwrap_writel(wrp, 0, PWRAP_OP_TYPE);
|
||||
+ pwrap_writel(wrp, 1, PWRAP_MSB_FIRST);
|
||||
+ }
|
||||
+
|
||||
/* Reset SPI slave */
|
||||
ret = pwrap_reset_spislave(wrp);
|
||||
if (ret)
|
||||
@@ -674,6 +903,9 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
|
||||
pwrap_writel(wrp, 1, PWRAP_WACS2_EN);
|
||||
|
||||
+ if (pwrap_is_mt7623(wrp))
|
||||
+ pwrap_writel(wrp, 0xf, PWRAP_RDDMY);
|
||||
+
|
||||
ret = pwrap_init_reg_clock(wrp);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -684,7 +916,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
return ret;
|
||||
|
||||
/* Enable dual IO mode */
|
||||
- pwrap_write(wrp, PWRAP_DEW_DIO_EN, 1);
|
||||
+ pwrap_dew_write(wrp, PWRAP_DEW_DIO_EN, 1);
|
||||
|
||||
/* Check IDLE & INIT_DONE in advance */
|
||||
ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle);
|
||||
@@ -696,7 +928,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
pwrap_writel(wrp, 1, PWRAP_DIO_EN);
|
||||
|
||||
/* Read Test */
|
||||
- pwrap_read(wrp, PWRAP_DEW_READ_TEST, &rdata);
|
||||
+ pwrap_dew_read(wrp, PWRAP_DEW_READ_TEST, &rdata);
|
||||
if (rdata != PWRAP_DEW_READ_TEST_VAL) {
|
||||
dev_err(wrp->dev, "Read test failed after switch to DIO mode: 0x%04x != 0x%04x\n",
|
||||
PWRAP_DEW_READ_TEST_VAL, rdata);
|
||||
@@ -709,12 +941,13 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
return ret;
|
||||
|
||||
/* Signature checking - using CRC */
|
||||
- if (pwrap_write(wrp, PWRAP_DEW_CRC_EN, 0x1))
|
||||
+ if (pwrap_dew_write(wrp, PWRAP_DEW_CRC_EN, 0x1))
|
||||
return -EFAULT;
|
||||
|
||||
pwrap_writel(wrp, 0x1, PWRAP_CRC_EN);
|
||||
pwrap_writel(wrp, 0x0, PWRAP_SIG_MODE);
|
||||
- pwrap_writel(wrp, PWRAP_DEW_CRC_VAL, PWRAP_SIG_ADR);
|
||||
+ pwrap_writel(wrp, wrp->dew_base + wrp->dew_regs[PWRAP_DEW_CRC_VAL],
|
||||
+ PWRAP_SIG_ADR);
|
||||
pwrap_writel(wrp, wrp->arb_en_all, PWRAP_HIPRIO_ARB_EN);
|
||||
|
||||
if (pwrap_is_mt8135(wrp))
|
||||
@@ -728,7 +961,16 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
pwrap_writel(wrp, 0xf, PWRAP_WDT_UNIT);
|
||||
pwrap_writel(wrp, 0xffffffff, PWRAP_WDT_SRC_EN);
|
||||
pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
|
||||
- pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN);
|
||||
+// pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN);
|
||||
+ pwrap_writel(wrp, ~(BIT(31) | BIT(2)), PWRAP_INT_EN);
|
||||
+
|
||||
+ if (pwrap_is_mt7623(wrp)) {
|
||||
+ pwrap_writel(wrp, PWRAP_MT7623_AUXADC_CON21, PWRAP_ADC_CMD_ADDR);
|
||||
+ pwrap_writel(wrp, 0x8000, PWRAP_ADC_CMD);
|
||||
+ pwrap_writel(wrp, PWRAP_MT7623_AUXADC_ADC12, PWRAP_ADC_RDY_ADDR);
|
||||
+ pwrap_writel(wrp, PWRAP_MT7623_AUXADC_ADC13, PWRAP_ADC_RDATA_ADDR1);
|
||||
+ pwrap_writel(wrp, PWRAP_MT7623_AUXADC_ADC14, PWRAP_ADC_RDATA_ADDR2);
|
||||
+ }
|
||||
|
||||
if (pwrap_is_mt8135(wrp)) {
|
||||
/* enable pwrap events and pwrap bridge in AP side */
|
||||
@@ -743,15 +985,15 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
writel(0x7ff, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INT_EN);
|
||||
|
||||
/* enable PMIC event out and sources */
|
||||
- if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
|
||||
- pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
|
||||
+ if (pwrap_dew_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
|
||||
+ pwrap_dew_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
|
||||
dev_err(wrp->dev, "enable dewrap fail\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
- } else {
|
||||
+ } else if (!pwrap_is_mt7623(wrp)) {
|
||||
/* PMIC_DEWRAP enables */
|
||||
- if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
|
||||
- pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
|
||||
+ if (pwrap_dew_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
|
||||
+ pwrap_dew_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
|
||||
dev_err(wrp->dev, "enable dewrap fail\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
@@ -795,6 +1037,9 @@ static const struct regmap_config pwrap_regmap_config = {
|
||||
|
||||
static struct of_device_id of_pwrap_match_tbl[] = {
|
||||
{
|
||||
+ .compatible = "mediatek,mt7623-pwrap",
|
||||
+ .data = &pwrap_mt7623,
|
||||
+ }, {
|
||||
.compatible = "mediatek,mt8135-pwrap",
|
||||
.data = &pwrap_mt8135,
|
||||
}, {
|
||||
@@ -824,6 +1069,8 @@ static int pwrap_probe(struct platform_device *pdev)
|
||||
|
||||
type = of_id->data;
|
||||
wrp->regs = type->regs;
|
||||
+ wrp->dew_regs = type->dew_regs;
|
||||
+ wrp->dew_base = type->dew_base;
|
||||
wrp->type = type->type;
|
||||
wrp->arb_en_all = type->arb_en_all;
|
||||
wrp->dev = &pdev->dev;
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,199 @@
|
||||
From ac825c0dd7370ae1b9a1a4346f895728e09d9cc7 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 1 Jul 2015 07:58:44 +0200
|
||||
Subject: [PATCH 70/76] 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.
|
||||
|
||||
Changes in v3:
|
||||
- Rebase to 4.2-rc1
|
||||
- Fix some issues of v2
|
||||
|
||||
Changes in v2:
|
||||
- Remove use of .determine_rate callback
|
||||
|
||||
Signed-off-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
|
||||
---
|
||||
drivers/clk/mediatek/Makefile | 2 +-
|
||||
drivers/clk/mediatek/clk-cpumux.c | 119 +++++++++++++++++++++++++++++++++++++
|
||||
drivers/clk/mediatek/clk-cpumux.h | 30 ++++++++++
|
||||
3 files changed, 150 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/clk/mediatek/clk-cpumux.c
|
||||
create mode 100644 drivers/clk/mediatek/clk-cpumux.h
|
||||
|
||||
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
|
||||
index 19a3763..fe07e26 100644
|
||||
--- a/drivers/clk/mediatek/Makefile
|
||||
+++ b/drivers/clk/mediatek/Makefile
|
||||
@@ -1,4 +1,4 @@
|
||||
-obj-y += clk-mtk.o clk-pll.o clk-gate.o
|
||||
+obj-y += clk-mtk.o clk-pll.o clk-gate.o clk-cpumux.o
|
||||
obj-$(CONFIG_RESET_CONTROLLER) += reset.o
|
||||
obj-y += clk-mt7623.o
|
||||
obj-y += clk-mt8135.o
|
||||
diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
|
||||
new file mode 100644
|
||||
index 0000000..593df45
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/mediatek/clk-cpumux.c
|
||||
@@ -0,0 +1,119 @@
|
||||
+/*
|
||||
+ * 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"
|
||||
+
|
||||
+static inline struct mtk_clk_cpumux *to_clk_mux(struct clk_hw *_hw)
|
||||
+{
|
||||
+ return container_of(_hw, struct mtk_clk_cpumux, hw);
|
||||
+}
|
||||
+
|
||||
+static u8 clk_cpumux_get_parent(struct clk_hw *hw)
|
||||
+{
|
||||
+ struct mtk_clk_cpumux *mux = to_clk_mux(hw);
|
||||
+ int num_parents = __clk_get_num_parents(hw->clk);
|
||||
+ unsigned int val;
|
||||
+
|
||||
+ regmap_read(mux->regmap, mux->reg, &val);
|
||||
+
|
||||
+ val >>= mux->shift;
|
||||
+ val &= mux->mask;
|
||||
+
|
||||
+ if (val >= num_parents)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return val;
|
||||
+}
|
||||
+
|
||||
+static int clk_cpumux_set_parent(struct clk_hw *hw, u8 index)
|
||||
+{
|
||||
+ struct mtk_clk_cpumux *mux = to_clk_mux(hw);
|
||||
+ u32 mask, val;
|
||||
+
|
||||
+ val = index << mux->shift;
|
||||
+ mask = mux->mask << mux->shift;
|
||||
+
|
||||
+ return regmap_update_bits(mux->regmap, mux->reg, mask, val);
|
||||
+}
|
||||
+
|
||||
+static const struct clk_ops clk_cpumux_ops = {
|
||||
+ .get_parent = clk_cpumux_get_parent,
|
||||
+ .set_parent = clk_cpumux_set_parent,
|
||||
+};
|
||||
+
|
||||
+static struct clk *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 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: %d\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;
|
||||
+}
|
||||
diff --git a/drivers/clk/mediatek/clk-cpumux.h b/drivers/clk/mediatek/clk-cpumux.h
|
||||
new file mode 100644
|
||||
index 0000000..dddaad5
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/mediatek/clk-cpumux.h
|
||||
@@ -0,0 +1,30 @@
|
||||
+/*
|
||||
+ * 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
|
||||
+
|
||||
+struct mtk_clk_cpumux {
|
||||
+ struct clk_hw hw;
|
||||
+ struct regmap *regmap;
|
||||
+ u32 reg;
|
||||
+ u32 mask;
|
||||
+ u8 shift;
|
||||
+};
|
||||
+
|
||||
+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 */
|
||||
--
|
||||
1.7.10.4
|
||||
|
342
target/linux/mediatek/patches/0071-clk.patch
Normal file
342
target/linux/mediatek/patches/0071-clk.patch
Normal file
@ -0,0 +1,342 @@
|
||||
From c3a3617a8c37b43db7ff622a31f171d3ce870173 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Fri, 3 Jul 2015 05:44:57 +0200
|
||||
Subject: [PATCH 71/76] clk
|
||||
|
||||
---
|
||||
drivers/clk/mediatek/clk-mt7623.c | 194 ++++++++++++++++---------------------
|
||||
1 file changed, 83 insertions(+), 111 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/mediatek/clk-mt7623.c b/drivers/clk/mediatek/clk-mt7623.c
|
||||
index 07843bb..d46b2ad 100644
|
||||
--- a/drivers/clk/mediatek/clk-mt7623.c
|
||||
+++ b/drivers/clk/mediatek/clk-mt7623.c
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "clk-mtk.h"
|
||||
#include "clk-gate.h"
|
||||
+#include "clk-cpumux.h"
|
||||
|
||||
static DEFINE_SPINLOCK(mt7623_clk_lock);
|
||||
|
||||
@@ -37,18 +38,11 @@ static void mtk_clk_enable_critical(void)
|
||||
clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_RTC_SEL]);
|
||||
}
|
||||
|
||||
-static const struct mtk_fixed_factor root_clk_alias[] __initconst = {
|
||||
- FACTOR(CLK_TOP_DSI0_LNTC_DSICLK, "dsi0_lntc_dsiclk", "clk_null", 1, 1),
|
||||
- FACTOR(CLK_TOP_HDMITX_CLKDIG_CTS, "hdmitx_clkdig_cts", "clk_null", 1, 1),
|
||||
- FACTOR(CLK_TOP_CLKPH_MCK, "clkph_mck", "clk_null", 1, 1),
|
||||
- FACTOR(CLK_TOP_CPUM_TCK_IN, "cpum_tck_in", "clk_null", 1, 1),
|
||||
-};
|
||||
-
|
||||
static const struct mtk_fixed_factor top_divs[] __initconst = {
|
||||
- FACTOR(CLK_TOP_MAINPLL_806M, "mainpll_650m", "mainpll", 1, 2),
|
||||
- FACTOR(CLK_TOP_MAINPLL_537P3M, "mainpll_433p3m", "mainpll", 1, 3),
|
||||
- FACTOR(CLK_TOP_MAINPLL_322P4M, "mainpll_260m", "mainpll", 1, 5),
|
||||
- FACTOR(CLK_TOP_MAINPLL_230P3M, "mainpll_185p6m", "mainpll", 1, 7),
|
||||
+ FACTOR(CLK_TOP_MAINPLL_650M, "mainpll_650m", "mainpll", 1, 2),
|
||||
+ FACTOR(CLK_TOP_MAINPLL_433P3M, "mainpll_433p3m", "mainpll", 1, 3),
|
||||
+ FACTOR(CLK_TOP_MAINPLL_260M, "mainpll_260m", "mainpll", 1, 5),
|
||||
+ FACTOR(CLK_TOP_MAINPLL_185P6M, "mainpll_185p6m", "mainpll", 1, 7),
|
||||
|
||||
FACTOR(CLK_TOP_UNIVPLL_624M, "univpll_624m", "univpll", 1, 2),
|
||||
FACTOR(CLK_TOP_UNIVPLL_416M, "univpll_416m", "univpll", 1, 3),
|
||||
@@ -61,13 +55,6 @@ static const struct mtk_fixed_factor top_divs[] __initconst = {
|
||||
FACTOR(CLK_TOP_AUDPLL_D16, "audpll_d16", "audpll", 1, 16),
|
||||
FACTOR(CLK_TOP_AUDPLL_24, "audpll_d24", "audpll", 1, 24),
|
||||
|
||||
- FACTOR(CLK_TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2),
|
||||
- FACTOR(CLK_TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4),
|
||||
- FACTOR(CLK_TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8),
|
||||
- FACTOR(CLK_TOP_LVDS_ETH, "lvdspll_eth", "lvdspll", 1, 16),
|
||||
-
|
||||
- FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
|
||||
-
|
||||
FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
|
||||
|
||||
FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "mainpll_650m", 1, 2),
|
||||
@@ -85,9 +72,6 @@ static const struct mtk_fixed_factor top_divs[] __initconst = {
|
||||
FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll_260m", 1, 1),
|
||||
FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll_185p6m", 1, 1),
|
||||
|
||||
- FACTOR(CLK_TOP_TVDPLL_d2, "tvdpll_d2", "tvdpll", 1, 2),
|
||||
- FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4),
|
||||
-
|
||||
FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_624m", 1, 2),
|
||||
FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_624m", 1, 4),
|
||||
FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_624m", 1, 8),
|
||||
@@ -110,9 +94,6 @@ static const struct mtk_fixed_factor top_divs[] __initconst = {
|
||||
|
||||
FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll_249p6m", 1, 1),
|
||||
FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll_48m", 1, 1),
|
||||
-
|
||||
-
|
||||
- FACTOR(CLK_TOP_MEMPLL_MCK_D4, "mempll_mck_d4", "clkph_mck", 1, 4),
|
||||
};
|
||||
|
||||
static const char * const axi_parents[] __initconst = {
|
||||
@@ -155,18 +136,6 @@ static const char * const pwm_parents[] __initconst = {
|
||||
"univpll1_d4",
|
||||
};
|
||||
|
||||
-static const char * const vdec_parents[] __initconst = {
|
||||
- "clk26m",
|
||||
- "syspll1_d2",
|
||||
- "syspll_d5",
|
||||
- "syspll1_d4",
|
||||
- "univpll_d5",
|
||||
- "univpll2_d2",
|
||||
- "univpll2_d4",
|
||||
- "msdcpll_d2",
|
||||
- "mmpll_d2",
|
||||
-};
|
||||
-
|
||||
static const char * const mfg_parents[] __initconst = {
|
||||
"clk26m",
|
||||
"mmpll_ck",
|
||||
@@ -178,17 +147,6 @@ static const char * const mfg_parents[] __initconst = {
|
||||
"univpll1_d2",
|
||||
};
|
||||
|
||||
-static const char * const cam_parents[] __initconst = {
|
||||
- "clk26m",
|
||||
- "univpll_d26",
|
||||
- "univpll2_d2",
|
||||
- "syspll3_d2",
|
||||
- "syspll3_d4",
|
||||
- "msdcpll_d2",
|
||||
- "mmpll_d2",
|
||||
- "clk26m",
|
||||
-};
|
||||
-
|
||||
static const char * const uart_parents[] __initconst = {
|
||||
"clk26m",
|
||||
"univpll2_d8",
|
||||
@@ -277,35 +235,6 @@ static const char * const scp_parents[] __initconst = {
|
||||
"dmpll_d4",
|
||||
};
|
||||
|
||||
-static const char * const dpi0_parents[] __initconst = {
|
||||
- "clk26m",
|
||||
- "mipipll",
|
||||
- "mipipll_d2",
|
||||
- "mipipll_d4",
|
||||
- "lvdspll",
|
||||
- "lvdspll_d2",
|
||||
- "lvdspll_d4",
|
||||
- "lvdspll_d8",
|
||||
-};
|
||||
-
|
||||
-static const char * const dpi1_parents[] __initconst = {
|
||||
- "clk26m",
|
||||
- "tvdpll",
|
||||
- "tvdpll_d2",
|
||||
- "tvdpll_d4",
|
||||
-};
|
||||
-
|
||||
-static const char * const tve_parents[] __initconst = {
|
||||
- "clk26m",
|
||||
- "mipipll",
|
||||
- "mipipll_d2",
|
||||
- "mipipll_d4",
|
||||
- "clk26m",
|
||||
- "tvdpll",
|
||||
- "tvdpll_d2",
|
||||
- "tvdpll_d4",
|
||||
-};
|
||||
-
|
||||
static const char * const apll_parents[] __initconst = {
|
||||
"clk26m",
|
||||
"audpll",
|
||||
@@ -317,17 +246,6 @@ static const char * const apll_parents[] __initconst = {
|
||||
"clk26m",
|
||||
};
|
||||
|
||||
-static const char * const dpilvds_parents[] __initconst = {
|
||||
- "clk26m",
|
||||
- "lvdspll",
|
||||
- "lvdspll_d2",
|
||||
- "lvdspll_d4",
|
||||
- "lvdspll_d8",
|
||||
- "fpc_ck",
|
||||
- "clk26m",
|
||||
- "clk26m",
|
||||
-};
|
||||
-
|
||||
static const char * const rtc_parents[] __initconst = {
|
||||
"clk32k",
|
||||
"external_32k",
|
||||
@@ -367,9 +285,7 @@ static const struct mtk_composite top_muxes[] __initconst = {
|
||||
0x0140, 24, 3, INVALID_MUX_GATE_BIT),
|
||||
/* CLK_CFG_1 */
|
||||
MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x0050, 0, 2, 7),
|
||||
- MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x0050, 8, 4, 15),
|
||||
MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0050, 16, 3, 23),
|
||||
- MUX_GATE(CLK_TOP_CAM_SEL, "cam_sel", cam_parents, 0x0050, 24, 3, 31),
|
||||
/* CLK_CFG_2 */
|
||||
MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x0060, 0, 1, 7),
|
||||
MUX_GATE(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x0060, 8, 3, 15),
|
||||
@@ -384,12 +300,8 @@ static const struct mtk_composite top_muxes[] __initconst = {
|
||||
/* CLK_CFG_4 */
|
||||
MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmic_spi_parents, 0x0080, 0, 4, 7),
|
||||
MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, 0x0080, 8, 2, 15),
|
||||
- MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents, 0x0080, 16, 3, 23),
|
||||
- MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0080, 24, 2, 31),
|
||||
/* CLK_CFG_5 */
|
||||
- MUX_GATE(CLK_TOP_TVE_SEL, "tve_sel", tve_parents, 0x0090, 0, 3, 7),
|
||||
MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", apll_parents, 0x0090, 16, 3, 23),
|
||||
- MUX_GATE(CLK_TOP_DPILVDS_SEL, "dpilvds_sel", dpilvds_parents, 0x0090, 24, 3, 31),
|
||||
/* CLK_CFG_6 */
|
||||
MUX_GATE(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents, 0x00a0, 0, 2, 7),
|
||||
MUX_GATE(CLK_TOP_NFI2X_SEL, "nfi2x_sel", nfi2x_parents, 0x00a0, 8, 3, 15),
|
||||
@@ -428,6 +340,17 @@ static const struct mtk_gate infra_clks[] __initconst = {
|
||||
GATE_ICG(CLK_INFRA_PMIC_WRAP, "pmic_wrap_ck", "axi_sel", 23),
|
||||
};
|
||||
|
||||
+static const char * const ca7_parents[] __initconst = {
|
||||
+ "clk26m",
|
||||
+ "armpll",
|
||||
+ "mainpll",
|
||||
+ "univpll"
|
||||
+};
|
||||
+
|
||||
+static struct mtk_composite cpu_muxes[] __initdata = {
|
||||
+ MUX(CLK_INFRA_CA7SEL, "infra_ca7_sel", ca7_parents, 0x0000, 2, 2),
|
||||
+};
|
||||
+
|
||||
static const struct mtk_gate_regs peri0_cg_regs = {
|
||||
.set_ofs = 0x0008,
|
||||
.clr_ofs = 0x0010,
|
||||
@@ -499,6 +422,29 @@ static const struct mtk_gate peri_gates[] __initconst = {
|
||||
GATE_PERI1(CLK_PERI_NFI_PAD, "nfi_pad_ck", "axi_sel", 2),
|
||||
};
|
||||
|
||||
+static const struct mtk_gate_regs hifsys_cg_regs = {
|
||||
+ .set_ofs = 0x0034,
|
||||
+ .clr_ofs = 0x0014,
|
||||
+ .sta_ofs = 0x0038,
|
||||
+};
|
||||
+
|
||||
+#define GATE_HIFSYS(_id, _name, _parent, _shift) { \
|
||||
+ .id = _id, \
|
||||
+ .name = _name, \
|
||||
+ .parent_name = _parent, \
|
||||
+ .regs = &hifsys_cg_regs, \
|
||||
+ .shift = _shift, \
|
||||
+ .ops = &mtk_clk_gate_ops_setclr, \
|
||||
+ }
|
||||
+
|
||||
+static const struct mtk_gate hifsys_gates[] __initconst = {
|
||||
+ GATE_HIFSYS(CLK_HIFSYS_USB0_PHY, "usb0_phy_ck", "axi_sel", 21),
|
||||
+ GATE_HIFSYS(CLK_HIFSYS_USB1_PHY, "usb1_phy_ck", "axi_sel", 22),
|
||||
+ GATE_HIFSYS(CLK_HIFSYS_PCIE0, "pcie0_ck", "axi_sel", 24),
|
||||
+ GATE_HIFSYS(CLK_HIFSYS_PCIE1, "pcie1_ck", "axi_sel", 25),
|
||||
+ GATE_HIFSYS(CLK_HIFSYS_PCIE2, "pcie2_ck", "axi_sel", 26),
|
||||
+};
|
||||
+
|
||||
static const char * const uart_ck_sel_parents[] __initconst = {
|
||||
"clk26m",
|
||||
"uart_sel",
|
||||
@@ -525,10 +471,9 @@ static void __init mtk_topckgen_init(struct device_node *node)
|
||||
|
||||
mt7623_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
|
||||
|
||||
- mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data);
|
||||
mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
|
||||
mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
|
||||
- &mt7623_clk_lock, clk_data);
|
||||
+ &mt7623_clk_lock, clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
if (r)
|
||||
@@ -547,7 +492,10 @@ static void __init mtk_infrasys_init(struct device_node *node)
|
||||
clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
|
||||
|
||||
mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
|
||||
- clk_data);
|
||||
+ clk_data);
|
||||
+
|
||||
+ mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
|
||||
+ clk_data);
|
||||
|
||||
clk_prepare_enable(clk_data->clks[CLK_INFRA_M4U]);
|
||||
|
||||
@@ -588,35 +536,59 @@ static void __init mtk_pericfg_init(struct device_node *node)
|
||||
}
|
||||
CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt7623-pericfg", mtk_pericfg_init);
|
||||
|
||||
-#define MT7623_PLL_FMAX (2000 * MHZ)
|
||||
-#define CON0_MT7623_RST_BAR BIT(27)
|
||||
+static void __init mtk_hifsys_init(struct device_node *node)
|
||||
+{
|
||||
+ struct clk_onecell_data *clk_data;
|
||||
+ int r;
|
||||
+ void __iomem *base;
|
||||
+
|
||||
+ base = of_iomap(node, 0);
|
||||
+ if (!base) {
|
||||
+ pr_err("%s(): ioremap failed\n", __func__);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ clk_data = mtk_alloc_clk_data(CLK_HIFSYS_NR_CLK);
|
||||
+
|
||||
+ mtk_clk_register_gates(node, hifsys_gates, ARRAY_SIZE(hifsys_gates),
|
||||
+ clk_data);
|
||||
+
|
||||
+ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
+ if (r)
|
||||
+ pr_err("%s(): could not register clock provider: %d\n",
|
||||
+ __func__, r);
|
||||
+
|
||||
+ mtk_register_reset_controller(node, 1, 0x34);
|
||||
+}
|
||||
+CLK_OF_DECLARE(mtk_hifsys, "mediatek,mt7623-hifsys", mtk_hifsys_init);
|
||||
+
|
||||
+#define MT7623_PLL_FMAX (1300 * MHZ)
|
||||
+#define CON0_MT7623_RST_BAR BIT(24)
|
||||
|
||||
-#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \
|
||||
+#define PLL(_id, _name, _con0_reg, _con1_reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pcw_shift, _pd_shift) { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
- .reg = _reg, \
|
||||
+ .reg = _con0_reg, \
|
||||
.pwr_reg = _pwr_reg, \
|
||||
.en_mask = _en_mask, \
|
||||
.flags = _flags, \
|
||||
.rst_bar_mask = CON0_MT7623_RST_BAR, \
|
||||
.fmax = MT7623_PLL_FMAX, \
|
||||
.pcwbits = _pcwbits, \
|
||||
- .pd_reg = _pd_reg, \
|
||||
+ .pd_reg = _con0_reg, \
|
||||
.pd_shift = _pd_shift, \
|
||||
- .tuner_reg = _tuner_reg, \
|
||||
- .pcw_reg = _pcw_reg, \
|
||||
+ .pcw_reg = _con1_reg, \
|
||||
.pcw_shift = _pcw_shift, \
|
||||
}
|
||||
|
||||
static const struct mtk_pll_data plls[] = {
|
||||
- PLL(CLK_APMIXED_ARMPLL, "armpll", 0x200, 0x20c, 0x00000001, 0, 21, 0x204, 24, 0x0, 0x204, 0),
|
||||
- PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x210, 0x21c, 0x78000001, HAVE_RST_BAR, 21, 0x214, 6, 0x0, 0x214, 0),
|
||||
- PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x220, 0x22c, 0xFC000001, HAVE_RST_BAR, 7, 0x224, 6, 0x0, 0x224, 0),
|
||||
- PLL(CLK_APMIXED_MMPLL, "mmpll", 0x230, 0x23c, 0x00000001, 0, 21, 0x254, 6, 0x0, 0x258, 0),
|
||||
- PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x240, 0x24c, 0x00000001, 0, 21, 0x244, 6, 0x0, 0x244, 0),
|
||||
- PLL(CLK_APMIXED_AUDPLL, "audpll", 0x250, 0x25c, 0x00000001, 0, 31, 0x2e8, 6, 0x2f8, 0x254, 0),
|
||||
- PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x260, 0x26c, 0x00000001, 0, 31, 0x294, 6, 0x0, 0x298, 0),
|
||||
- PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x270, 0x27c, 0x00000001, 0, 21, 0x2b0, 6, 0x0, 0x2b4, 0),
|
||||
+ PLL(CLK_APMIXED_ARMPLL, "armpll", 0x200, 0x204, 0x20c, 0x00000001, 0, 21, 0, 4 ),
|
||||
+ PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x210, 0x214, 0x21c, 0x78000001, HAVE_RST_BAR, 21, 0, 4 ),
|
||||
+ PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x220, 0x224, 0x22c, 0xFC000001, HAVE_RST_BAR, 7, 14, 4 ),
|
||||
+ PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x240, 0x244, 0x24c, 0x00000001, 0, 21, 0, 4 ),
|
||||
+ PLL(CLK_APMIXED_AUDPLL, "audpll", 0x270, 0x274, 0x27c, 0x00000001, 0, 31, 0, 4 ),
|
||||
+ PLL(CLK_APMIXED_TRGPLL, "trgpll", 0x280, 0x284, 0x28c, 0x00000001, 0, 31, 0, 4 ),
|
||||
+ PLL(CLK_APMIXED_ETHPLL, "ethpll", 0x290, 0x294, 0x29c, 0x00000001, 0, 31, 0, 4 ),
|
||||
};
|
||||
|
||||
static void __init mtk_apmixedsys_init(struct device_node *node)
|
||||
--
|
||||
1.7.10.4
|
||||
|
1591
target/linux/mediatek/patches/0072-mfd.patch
Normal file
1591
target/linux/mediatek/patches/0072-mfd.patch
Normal file
File diff suppressed because it is too large
Load Diff
200
target/linux/mediatek/patches/0073-clk.patch
Normal file
200
target/linux/mediatek/patches/0073-clk.patch
Normal file
@ -0,0 +1,200 @@
|
||||
From a4df453fbfa6199ad33435cee6ce2dfcc65321b0 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Fri, 3 Jul 2015 05:45:58 +0200
|
||||
Subject: [PATCH 73/76] clk
|
||||
|
||||
---
|
||||
include/dt-bindings/clock/mt7623-clk.h | 158 +++++++++++++++-----------------
|
||||
1 file changed, 73 insertions(+), 85 deletions(-)
|
||||
|
||||
diff --git a/include/dt-bindings/clock/mt7623-clk.h b/include/dt-bindings/clock/mt7623-clk.h
|
||||
index cb1e8a9..410ef31 100644
|
||||
--- a/include/dt-bindings/clock/mt7623-clk.h
|
||||
+++ b/include/dt-bindings/clock/mt7623-clk.h
|
||||
@@ -17,96 +17,76 @@
|
||||
|
||||
/* TOPCKGEN */
|
||||
|
||||
-#define CLK_TOP_AUDPLL_24 1
|
||||
-#define CLK_TOP_AUDPLL_D16 2
|
||||
-#define CLK_TOP_AUDPLL_D4 3
|
||||
-#define CLK_TOP_AUDPLL_D8 4
|
||||
-#define CLK_TOP_CLKPH_MCK 5
|
||||
-#define CLK_TOP_CPUM_TCK_IN 6
|
||||
-#define CLK_TOP_DSI0_LNTC_DSICLK 7
|
||||
-#define CLK_TOP_HDMITX_CLKDIG_CTS 8
|
||||
-#define CLK_TOP_LVDS_ETH 9
|
||||
-#define CLK_TOP_LVDSPLL_D2 10
|
||||
-#define CLK_TOP_LVDSPLL_D4 11
|
||||
-#define CLK_TOP_LVDSPLL_D8 12
|
||||
-#define CLK_TOP_MAINPLL_230P3M 13
|
||||
-#define CLK_TOP_MAINPLL_322P4M 14
|
||||
-#define CLK_TOP_MAINPLL_537P3M 15
|
||||
-#define CLK_TOP_MAINPLL_806M 16
|
||||
-#define CLK_TOP_MEMPLL_MCK_D4 17
|
||||
-#define CLK_TOP_MMPLL_D2 18
|
||||
-#define CLK_TOP_MSDCPLL_D2 19
|
||||
-#define CLK_TOP_SYSPLL1_D16 20
|
||||
-#define CLK_TOP_SYSPLL1_D2 21
|
||||
-#define CLK_TOP_SYSPLL1_D4 22
|
||||
-#define CLK_TOP_SYSPLL1_D8 23
|
||||
-#define CLK_TOP_SYSPLL2_D2 24
|
||||
-#define CLK_TOP_SYSPLL2_D4 25
|
||||
-#define CLK_TOP_SYSPLL2_D8 26
|
||||
-#define CLK_TOP_SYSPLL3_D2 27
|
||||
-#define CLK_TOP_SYSPLL3_D4 28
|
||||
-#define CLK_TOP_SYSPLL4_D2 29
|
||||
-#define CLK_TOP_SYSPLL4_D4 30
|
||||
-#define CLK_TOP_SYSPLL_D3 31
|
||||
-#define CLK_TOP_SYSPLL_D5 32
|
||||
-#define CLK_TOP_SYSPLL_D7 33
|
||||
-#define CLK_TOP_TVDPLL_d2 34
|
||||
-#define CLK_TOP_TVDPLL_D4 35
|
||||
-#define CLK_TOP_UNIVPLL_178P3M 36
|
||||
-#define CLK_TOP_UNIVPLL1_D10 37
|
||||
-#define CLK_TOP_UNIVPLL1_D2 38
|
||||
-#define CLK_TOP_UNIVPLL1_D4 39
|
||||
-#define CLK_TOP_UNIVPLL1_D6 40
|
||||
-#define CLK_TOP_UNIVPLL1_D8 41
|
||||
-#define CLK_TOP_UNIVPLL_249P6M 42
|
||||
-#define CLK_TOP_UNIVPLL2_D2 43
|
||||
-#define CLK_TOP_UNIVPLL2_D4 44
|
||||
-#define CLK_TOP_UNIVPLL2_D6 45
|
||||
-#define CLK_TOP_UNIVPLL2_D8 46
|
||||
-#define CLK_TOP_UNIVPLL_416M 47
|
||||
-#define CLK_TOP_UNIVPLL_48M 48
|
||||
-#define CLK_TOP_UNIVPLL_624M 49
|
||||
-#define CLK_TOP_UNIVPLL_D26 50
|
||||
-#define CLK_TOP_UNIVPLL_D5 51
|
||||
-#define CLK_TOP_APLL_SEL 52
|
||||
+#define CLK_TOP_MAINPLL_650M 1
|
||||
+#define CLK_TOP_MAINPLL_433P3M 2
|
||||
+#define CLK_TOP_MAINPLL_260M 3
|
||||
+#define CLK_TOP_MAINPLL_185P6M 4
|
||||
+#define CLK_TOP_UNIVPLL_624M 5
|
||||
+#define CLK_TOP_UNIVPLL_416M 6
|
||||
+#define CLK_TOP_UNIVPLL_249P6M 7
|
||||
+#define CLK_TOP_UNIVPLL_178P3M 8
|
||||
+#define CLK_TOP_UNIVPLL_48M 9
|
||||
+#define CLK_TOP_AUDPLL_D4 10
|
||||
+#define CLK_TOP_AUDPLL_D8 11
|
||||
+#define CLK_TOP_AUDPLL_D16 12
|
||||
+#define CLK_TOP_AUDPLL_24 13
|
||||
+#define CLK_TOP_MSDCPLL_D2 14
|
||||
+#define CLK_TOP_SYSPLL1_D2 15
|
||||
+#define CLK_TOP_SYSPLL1_D4 16
|
||||
+#define CLK_TOP_SYSPLL1_D8 17
|
||||
+#define CLK_TOP_SYSPLL1_D16 18
|
||||
+#define CLK_TOP_SYSPLL2_D2 19
|
||||
+#define CLK_TOP_SYSPLL2_D4 20
|
||||
+#define CLK_TOP_SYSPLL2_D8 21
|
||||
+#define CLK_TOP_SYSPLL3_D2 22
|
||||
+#define CLK_TOP_SYSPLL3_D4 23
|
||||
+#define CLK_TOP_SYSPLL4_D2 24
|
||||
+#define CLK_TOP_SYSPLL4_D4 25
|
||||
+#define CLK_TOP_SYSPLL_D3 26
|
||||
+#define CLK_TOP_SYSPLL_D5 27
|
||||
+#define CLK_TOP_SYSPLL_D7 28
|
||||
+#define CLK_TOP_UNIVPLL1_D2 29
|
||||
+#define CLK_TOP_UNIVPLL1_D4 30
|
||||
+#define CLK_TOP_UNIVPLL1_D6 31
|
||||
+#define CLK_TOP_UNIVPLL1_D8 32
|
||||
+#define CLK_TOP_UNIVPLL1_D10 33
|
||||
+#define CLK_TOP_UNIVPLL2_D2 34
|
||||
+#define CLK_TOP_UNIVPLL2_D4 35
|
||||
+#define CLK_TOP_UNIVPLL2_D6 36
|
||||
+#define CLK_TOP_UNIVPLL2_D8 37
|
||||
+#define CLK_TOP_UNIVPLL_D5 38
|
||||
+#define CLK_TOP_UNIVPLL_D26 39
|
||||
+#define CLK_TOP_AXI_SEL 40
|
||||
+#define CLK_TOP_MEM_SEL 41
|
||||
+#define CLK_TOP_DDR_SEL 42
|
||||
+#define CLK_TOP_MM_SEL 43
|
||||
+#define CLK_TOP_PWM_SEL 44
|
||||
+#define CLK_TOP_MFG_SEL 45
|
||||
+#define CLK_TOP_UART_SEL 46
|
||||
+#define CLK_TOP_SPI_SEL 47
|
||||
+#define CLK_TOP_USB20_SEL 48
|
||||
+#define CLK_TOP_MSDC30_0_SEL 49
|
||||
+#define CLK_TOP_MSDC30_1_SEL 50
|
||||
+#define CLK_TOP_MSDC30_2_SEL 51
|
||||
+#define CLK_TOP_AUDIO_SEL 52
|
||||
#define CLK_TOP_AUDIO_INTBUS_SEL 53
|
||||
-#define CLK_TOP_AUDIO_SEL 54
|
||||
-#define CLK_TOP_AXI_SEL 55
|
||||
-#define CLK_TOP_CAM_SEL 56
|
||||
-#define CLK_TOP_DDR_SEL 57
|
||||
-#define CLK_TOP_DPI0_SEL 58
|
||||
-#define CLK_TOP_DPI1_SEL 59
|
||||
-#define CLK_TOP_DPILVDS_SEL 60
|
||||
-#define CLK_TOP_ETH_SEL 61
|
||||
-#define CLK_TOP_MEM_SEL 62
|
||||
-#define CLK_TOP_MFG_SEL 63
|
||||
-#define CLK_TOP_MM_SEL 64
|
||||
-#define CLK_TOP_MSDC30_0_SEL 65
|
||||
-#define CLK_TOP_MSDC30_1_SEL 66
|
||||
-#define CLK_TOP_MSDC30_2_SEL 67
|
||||
-#define CLK_TOP_NFI2X_SEL 68
|
||||
-#define CLK_TOP_PMICSPI_SEL 69
|
||||
-#define CLK_TOP_PWM_SEL 70
|
||||
-#define CLK_TOP_RTC_SEL 71
|
||||
-#define CLK_TOP_SCP_SEL 72
|
||||
-#define CLK_TOP_SPI_SEL 73
|
||||
-#define CLK_TOP_TVE_SEL 74
|
||||
-#define CLK_TOP_UART_SEL 75
|
||||
-#define CLK_TOP_USB20_SEL 76
|
||||
-#define CLK_TOP_VDEC_SEL 77
|
||||
-#define CLK_TOP_NR_CLK 78
|
||||
+#define CLK_TOP_PMICSPI_SEL 54
|
||||
+#define CLK_TOP_SCP_SEL 55
|
||||
+#define CLK_TOP_APLL_SEL 56
|
||||
+#define CLK_TOP_RTC_SEL 57
|
||||
+#define CLK_TOP_NFI2X_SEL 58
|
||||
+#define CLK_TOP_ETH_SEL 59
|
||||
+#define CLK_TOP_NR_CLK 60
|
||||
|
||||
/* APMIXED_SYS */
|
||||
|
||||
#define CLK_APMIXED_ARMPLL 1
|
||||
#define CLK_APMIXED_MAINPLL 2
|
||||
-#define CLK_APMIXED_MSDCPLL 3
|
||||
-#define CLK_APMIXED_UNIVPLL 4
|
||||
-#define CLK_APMIXED_MMPLL 5
|
||||
-#define CLK_APMIXED_VENCPLL 6
|
||||
-#define CLK_APMIXED_TVDPLL 7
|
||||
-#define CLK_APMIXED_LVDSPLL 8
|
||||
-#define CLK_APMIXED_AUDPLL 9
|
||||
+#define CLK_APMIXED_UNIVPLL 3
|
||||
+#define CLK_APMIXED_MSDCPLL 4
|
||||
+#define CLK_APMIXED_AUDPLL 5
|
||||
+#define CLK_APMIXED_TRGPLL 6
|
||||
+#define CLK_APMIXED_ETHPLL 7
|
||||
|
||||
/* INFRA_SYS */
|
||||
|
||||
@@ -124,7 +104,8 @@
|
||||
#define CLK_INFRA_IRRX 19
|
||||
#define CLK_INFRA_PMICSPI 22
|
||||
#define CLK_INFRA_PMIC_WRAP 23
|
||||
-#define CLK_INFRA_NR_CLK 24
|
||||
+#define CLK_INFRA_CA7SEL 24
|
||||
+#define CLK_INFRA_NR_CLK 25
|
||||
|
||||
/* PERI_SYS */
|
||||
|
||||
@@ -169,5 +150,12 @@
|
||||
#define CLK_PERI_UART3_SEL 38
|
||||
#define CLK_PERI_NR_CLK 39
|
||||
|
||||
+#define CLK_HIFSYS_USB0_PHY 1
|
||||
+#define CLK_HIFSYS_USB1_PHY 2
|
||||
+#define CLK_HIFSYS_PCIE0 3
|
||||
+#define CLK_HIFSYS_PCIE1 4
|
||||
+#define CLK_HIFSYS_PCIE2 5
|
||||
+#define CLK_HIFSYS_NR_CLK 6
|
||||
+
|
||||
#endif /* _DT_BINDINGS_CLK_MT7623_H */
|
||||
|
||||
--
|
||||
1.7.10.4
|
||||
|
182
target/linux/mediatek/patches/0074-dts.patch
Normal file
182
target/linux/mediatek/patches/0074-dts.patch
Normal file
@ -0,0 +1,182 @@
|
||||
From df59c3b7030b6d7802fe5e5abda81467fcdf2178 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Fri, 3 Jul 2015 05:46:13 +0200
|
||||
Subject: [PATCH 74/76] dts
|
||||
|
||||
---
|
||||
arch/arm/boot/dts/mt7623-evb.dts | 124 +++++++++++++++++++++++++++++++++++++-
|
||||
arch/arm/boot/dts/mt7623.dtsi | 11 ++++
|
||||
2 files changed, 133 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/arch/arm/boot/dts/mt7623-evb.dts
|
||||
+++ b/arch/arm/boot/dts/mt7623-evb.dts
|
||||
@@ -145,8 +145,8 @@
|
||||
bus-width = <8>;
|
||||
max-frequency = <50000000>;
|
||||
cap-mmc-highspeed;
|
||||
-// vmmc-supply = <&mt6397_vemc_3v3_reg>;
|
||||
-// vqmmc-supply = <&mt6397_vio18_reg>;
|
||||
+// vmmc-supply = <&mt6323_vemc_3v3_reg>;
|
||||
+// vqmmc-supply = <&mt6323_vio18_reg>;
|
||||
non-removable;
|
||||
};
|
||||
|
||||
@@ -160,3 +160,123 @@
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_pcie_default>;
|
||||
};
|
||||
+
|
||||
+&pwrap {
|
||||
+ pmic: mt6323 {
|
||||
+ compatible = "mediatek,mt6323";
|
||||
+
|
||||
+ mt6323regulator: mt6323regulator {
|
||||
+ compatible = "mediatek,mt6323-regulator";
|
||||
+
|
||||
+ mt6323_vproc_reg: buck_vproc {
|
||||
+ regulator-compatible = "buck_vproc";
|
||||
+ regulator-name = "vproc";
|
||||
+ regulator-min-microvolt = < 700000>;
|
||||
+ regulator-max-microvolt = <1493750>;
|
||||
+ regulator-ramp-delay = <6250>;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vsys_reg: buck_vsys {
|
||||
+ regulator-compatible = "buck_vsys";
|
||||
+ regulator-name = "vsys";
|
||||
+ regulator-min-microvolt = <1400000>;
|
||||
+ regulator-max-microvolt = <3000000>;
|
||||
+ regulator-ramp-delay = <12500>;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vpa_reg: buck_vpa {
|
||||
+ regulator-compatible = "buck_vpa";
|
||||
+ regulator-name = "vpa";
|
||||
+ regulator-min-microvolt = < 500000>;
|
||||
+ regulator-max-microvolt = <3650000>;
|
||||
+ regulator-ramp-delay = <50000>;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vtcxo_reg: ldo_vtcxo {
|
||||
+ regulator-compatible = "ldo_vtcxo";
|
||||
+ regulator-name = "vtcxo";
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_va_reg: ldo_va {
|
||||
+ regulator-compatible = "ldo_va";
|
||||
+ regulator-name = "va";
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vcn28_reg: ldo_vcn28 {
|
||||
+ regulator-compatible = "ldo_vcn28";
|
||||
+ regulator-name = "vcn28";
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vcn33_reg: ldo_vcn33 {
|
||||
+ regulator-compatible = "ldo_vcn33";
|
||||
+ regulator-name = "vcn33";
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vcama_reg: ldo_vcama {
|
||||
+ regulator-compatible = "ldo_vcama";
|
||||
+ regulator-name = "vcama";
|
||||
+ regulator-min-microvolt = <1500000>;
|
||||
+ regulator-max-microvolt = <2800000>;
|
||||
+ regulator-enable-ramp-delay = <218>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vio28_reg: ldo_vio28 {
|
||||
+ regulator-compatible = "ldo_vio28";
|
||||
+ regulator-name = "vio28";
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vusb_reg: ldo_vusb {
|
||||
+ regulator-compatible = "ldo_vusb";
|
||||
+ regulator-name = "vusb";
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vmc_reg: ldo_vmc {
|
||||
+ regulator-compatible = "ldo_vmc";
|
||||
+ regulator-name = "vmc";
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-enable-ramp-delay = <218>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vmch_reg: ldo_vmch {
|
||||
+ regulator-compatible = "ldo_vmch";
|
||||
+ regulator-name = "vmch";
|
||||
+ regulator-min-microvolt = <3000000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-enable-ramp-delay = <218>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vemc_3v3_reg: ldo_vemc3v3 {
|
||||
+ regulator-compatible = "ldo_vemc3v3";
|
||||
+ regulator-name = "vemc_3v3";
|
||||
+ regulator-min-microvolt = <3000000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-enable-ramp-delay = <218>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vgp1_reg: ldo_vgp1 {
|
||||
+ regulator-compatible = "ldo_vgp1";
|
||||
+ regulator-name = "vcamd";
|
||||
+ regulator-min-microvolt = <1220000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-enable-ramp-delay = <240>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vgp2_reg: ldo_vgp2 {
|
||||
+ regulator-compatible = "ldo_vgp2";
|
||||
+ regulator-name = "vcamio";
|
||||
+ regulator-min-microvolt = <1000000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-enable-ramp-delay = <218>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
--- a/arch/arm/boot/dts/mt7623.dtsi
|
||||
+++ b/arch/arm/boot/dts/mt7623.dtsi
|
||||
@@ -150,6 +150,17 @@
|
||||
clock-names = "system-clk", "rtc-clk";
|
||||
};
|
||||
|
||||
+ pwrap: pwrap@1000f000 {
|
||||
+ compatible = "mediatek,mt7623-pwrap";
|
||||
+ reg = <0 0x1000f000 0 0x1000>;
|
||||
+ reg-names = "pwrap";
|
||||
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ resets = <&infracfg MT7623_INFRA_PMIC_WRAP_RST>;
|
||||
+ reset-names = "pwrap";
|
||||
+ clocks = <&clk26m>, <&clk26m>;
|
||||
+ clock-names = "spi", "wrap";
|
||||
+ };
|
||||
+
|
||||
sysirq: interrupt-controller@10200100 {
|
||||
compatible = "mediatek,mt7623-sysirq",
|
||||
"mediatek,mt6577-sysirq";
|
||||
@@ -311,6 +322,7 @@
|
||||
device_type = "pci";
|
||||
|
||||
bus-range = <0 255>;
|
||||
+ status = "disabled";
|
||||
ranges = <
|
||||
0x02000000 0 0 0x00000000 0x60000000 0 0x10000000 /* pci memory */
|
||||
0x01000000 0 0 0x00000000 0x1A160000 0 0x00010000 /* io space */
|
||||
@@ -343,6 +355,5 @@
|
||||
device_type = "pci";
|
||||
};
|
||||
|
||||
- status = "disabled";
|
||||
};
|
||||
};
|
55
target/linux/mediatek/patches/0075-sd.patch
Normal file
55
target/linux/mediatek/patches/0075-sd.patch
Normal file
@ -0,0 +1,55 @@
|
||||
From a5982c5e4b58c4335e789969e04f9e24b894f510 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Fri, 3 Jul 2015 05:46:39 +0200
|
||||
Subject: [PATCH 75/76] sd
|
||||
|
||||
---
|
||||
drivers/mmc/host/mtk-sd.c | 12 ++++++++----
|
||||
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
|
||||
index 7c20f28..be2b00c 100644
|
||||
--- a/drivers/mmc/host/mtk-sd.c
|
||||
+++ b/drivers/mmc/host/mtk-sd.c
|
||||
@@ -227,11 +227,13 @@ struct mt_gpdma_desc {
|
||||
#define GPDMA_DESC_BDP (0x1 << 1)
|
||||
#define GPDMA_DESC_CHECKSUM (0xff << 8) /* bit8 ~ bit15 */
|
||||
#define GPDMA_DESC_INT (0x1 << 16)
|
||||
+#define GPDMA_DESC_GPDH4B (0x1 << 24)
|
||||
+#define GPDMA_DESC_BDH4B (0x1 << 28)
|
||||
u32 next;
|
||||
u32 ptr;
|
||||
u32 gpd_data_len;
|
||||
-#define GPDMA_DESC_BUFLEN (0xffff) /* bit0 ~ bit15 */
|
||||
-#define GPDMA_DESC_EXTLEN (0xff << 16) /* bit16 ~ bit23 */
|
||||
+#define GPDMA_DESC_BUFLEN (0xffffff) /* bit0 ~ bit15 */
|
||||
+#define GPDMA_DESC_EXTLEN (0xff << 24) /* bit16 ~ bit23 */
|
||||
u32 arg;
|
||||
u32 blknum;
|
||||
u32 cmd;
|
||||
@@ -243,10 +245,12 @@ struct mt_bdma_desc {
|
||||
#define BDMA_DESC_CHECKSUM (0xff << 8) /* bit8 ~ bit15 */
|
||||
#define BDMA_DESC_BLKPAD (0x1 << 17)
|
||||
#define BDMA_DESC_DWPAD (0x1 << 18)
|
||||
+#define BDMA_DESC_GPDH4B (0x1 << 24)
|
||||
+#define BDMA_DESC_BDH4B (0x1 << 28)
|
||||
u32 next;
|
||||
u32 ptr;
|
||||
u32 bd_data_len;
|
||||
-#define BDMA_DESC_BUFLEN (0xffff) /* bit0 ~ bit15 */
|
||||
+#define BDMA_DESC_BUFLEN (0xffffff) /* bit0 ~ bit15 */
|
||||
};
|
||||
|
||||
struct msdc_dma {
|
||||
@@ -1115,7 +1119,7 @@ static void msdc_init_hw(struct msdc_host *host)
|
||||
sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 1);
|
||||
writel(0x403c004f, host->base + MSDC_PATCH_BIT);
|
||||
sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1);
|
||||
- writel(0xffff0089, host->base + MSDC_PATCH_BIT1);
|
||||
+// writel(0xffff0089, host->base + MSDC_PATCH_BIT1);
|
||||
/* Configure to enable SDIO mode.
|
||||
* it's must otherwise sdio cmd5 failed
|
||||
*/
|
||||
--
|
||||
1.7.10.4
|
||||
|
30
target/linux/mediatek/patches/0076-reset.patch
Normal file
30
target/linux/mediatek/patches/0076-reset.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From 1671d902f8dcfce70f920ad3dfebb1031a7a38de Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Fri, 3 Jul 2015 05:46:51 +0200
|
||||
Subject: [PATCH 76/76] reset
|
||||
|
||||
---
|
||||
include/dt-bindings/reset-controller/mt7623-resets.h | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/include/dt-bindings/reset-controller/mt7623-resets.h b/include/dt-bindings/reset-controller/mt7623-resets.h
|
||||
index 28a7d69..3e0f39a 100644
|
||||
--- a/include/dt-bindings/reset-controller/mt7623-resets.h
|
||||
+++ b/include/dt-bindings/reset-controller/mt7623-resets.h
|
||||
@@ -56,4 +56,13 @@
|
||||
#define MT7623_PERI_ETH_SW_RST 29
|
||||
#define MT7623_PERI_SPI0_SW_RST 33
|
||||
|
||||
+/* high speed interface resets */
|
||||
+#define MT7623_HIFSYS_UHOST0_SW_RST 3
|
||||
+#define MT7623_HIFSYS_UHOST1_SW_RST 4
|
||||
+#define MT7623_HIFSYS_UPHY0_SW_RST 21
|
||||
+#define MT7623_HIFSYS_UPHY1_SW_RST 22
|
||||
+#define MT7623_HIFSYS_PCIE0_SW_RST 24
|
||||
+#define MT7623_HIFSYS_PCIE0_SW_RST 25
|
||||
+#define MT7623_HIFSYS_PCIE0_SW_RST 26
|
||||
+
|
||||
#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT7623 */
|
||||
--
|
||||
1.7.10.4
|
||||
|
18
target/linux/mediatek/profiles/default.mk
Normal file
18
target/linux/mediatek/profiles/default.mk
Normal file
@ -0,0 +1,18 @@
|
||||
#
|
||||
# Copyright (C) 2015 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
define Profile/Default
|
||||
NAME:=Default Profile (minimum package set)
|
||||
PACKAGES:= \
|
||||
kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-ledtrig-usbdev \
|
||||
kmod-usb3
|
||||
endef
|
||||
|
||||
define Profile/Default/Description
|
||||
Default package set compatible with most boards.
|
||||
endef
|
||||
$(eval $(call Profile,Default))
|
Loading…
x
Reference in New Issue
Block a user