mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 15:32:33 +00:00
mediatek: bump to v4.4
Signed-off-by: John Crispin <blogic@openwrt.org> SVN-Revision: 49064
This commit is contained in:
parent
c8a6c583fc
commit
5d2f529c9b
@ -9,12 +9,13 @@ FEATURES:=squashfs
|
||||
CPU_TYPE:=cortex-a7
|
||||
MAINTAINER:=John Crispin <blogic@openwrt.org>
|
||||
|
||||
KERNEL_PATCHVER:=4.1
|
||||
KERNEL_PATCHVER:=4.4
|
||||
|
||||
KERNELNAME:=Image dtbs zImage
|
||||
|
||||
include $(INCLUDE_DIR)/target.mk
|
||||
DEFAULT_PACKAGES += \
|
||||
kmod-leds-gpio kmod-gpio-button-hotplug swconfig
|
||||
kmod-mt76 kmod-leds-gpio kmod-gpio-button-hotplug swconfig \
|
||||
wpad-mini
|
||||
|
||||
$(eval $(call BuildTarget))
|
||||
|
26
target/linux/mediatek/base-files/etc/board.d/02_network
Executable file
26
target/linux/mediatek/base-files/etc/board.d/02_network
Executable file
@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /lib/functions.sh
|
||||
. /lib/mediatek.sh
|
||||
. /lib/functions/uci-defaults.sh
|
||||
. /lib/functions/system.sh
|
||||
|
||||
mediatek_setup_interfaces()
|
||||
{
|
||||
local board="$1"
|
||||
|
||||
case $board in
|
||||
mt7623_evb)
|
||||
ucidef_set_interfaces_lan_wan "eth1" "eth0"
|
||||
ucidef_add_switch "switch0" \
|
||||
"0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "5@eth1" "6@eth0"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
board_config_update
|
||||
board=$(mediatek_board_name)
|
||||
mediatek_setup_interfaces $board
|
||||
board_config_flush
|
||||
|
||||
exit 0
|
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (C) 2015 OpenWrt.org
|
||||
# Copyright (C) 2016 OpenWrt.org
|
||||
#
|
||||
|
||||
mediatek_board_detect() {
|
||||
@ -10,7 +10,7 @@ mediatek_board_detect() {
|
||||
machine=$(cat /proc/device-tree/model)
|
||||
|
||||
case "$machine" in
|
||||
"MediaTek MT7623 Evaluation Board")
|
||||
"MediaTek MT7623 evaluation board")
|
||||
name="mt7623_evb"
|
||||
;;
|
||||
esac
|
||||
|
469
target/linux/mediatek/config-4.4
Normal file
469
target/linux/mediatek/config-4.4
Normal file
@ -0,0 +1,469 @@
|
||||
# CONFIG_AIO is not set
|
||||
CONFIG_ALIGNMENT_TRAP=y
|
||||
# CONFIG_APM_EMULATION is not set
|
||||
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
|
||||
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
|
||||
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
|
||||
CONFIG_ARCH_HAS_SG_CHAIN=y
|
||||
CONFIG_ARCH_HAS_TICK_BROADCAST=y
|
||||
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
|
||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
|
||||
CONFIG_ARCH_MEDIATEK=y
|
||||
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
|
||||
CONFIG_ARCH_MULTIPLATFORM=y
|
||||
# CONFIG_ARCH_MULTI_CPU_AUTO is not set
|
||||
CONFIG_ARCH_MULTI_V6_V7=y
|
||||
CONFIG_ARCH_MULTI_V7=y
|
||||
CONFIG_ARCH_NR_GPIO=0
|
||||
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
|
||||
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
|
||||
CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
|
||||
CONFIG_ARCH_SUPPORTS_UPROBES=y
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
|
||||
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
|
||||
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
|
||||
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
|
||||
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ARM_APPENDED_DTB=y
|
||||
# CONFIG_ARM_ATAG_DTB_COMPAT is not set
|
||||
CONFIG_ARM_CPU_SUSPEND=y
|
||||
# CONFIG_ARM_CPU_TOPOLOGY is not set
|
||||
CONFIG_ARM_GIC=y
|
||||
CONFIG_ARM_HAS_SG_CHAIN=y
|
||||
CONFIG_ARM_L1_CACHE_SHIFT=6
|
||||
CONFIG_ARM_L1_CACHE_SHIFT_6=y
|
||||
# CONFIG_ARM_LPAE is not set
|
||||
CONFIG_ARM_PATCH_PHYS_VIRT=y
|
||||
# CONFIG_ARM_SMMU is not set
|
||||
CONFIG_ARM_THUMB=y
|
||||
CONFIG_ARM_THUMBEE=y
|
||||
CONFIG_ARM_UNWIND=y
|
||||
CONFIG_ARM_VIRT_EXT=y
|
||||
CONFIG_ATAGS=y
|
||||
CONFIG_AUTO_ZRELADDR=y
|
||||
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
|
||||
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
|
||||
CONFIG_BOUNCE=y
|
||||
# CONFIG_CACHE_L2X0 is not set
|
||||
CONFIG_CC_STACKPROTECTOR=y
|
||||
# CONFIG_CC_STACKPROTECTOR_NONE is not set
|
||||
CONFIG_CC_STACKPROTECTOR_REGULAR=y
|
||||
CONFIG_CLEANCACHE=y
|
||||
CONFIG_CLKDEV_LOOKUP=y
|
||||
CONFIG_CLKSRC_MMIO=y
|
||||
CONFIG_CLKSRC_OF=y
|
||||
CONFIG_CLKSRC_PROBE=y
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_CMDLINE="earlyprintk console=ttyS0,115200"
|
||||
CONFIG_CMDLINE_FORCE=y
|
||||
CONFIG_COMMON_CLK=y
|
||||
CONFIG_COMMON_CLK_MEDIATEK=y
|
||||
CONFIG_COMMON_CLK_MT2701=y
|
||||
# CONFIG_COMMON_CLK_MT8135 is not set
|
||||
# CONFIG_COMMON_CLK_MT8173 is not set
|
||||
CONFIG_COMPACTION=y
|
||||
CONFIG_COREDUMP=y
|
||||
CONFIG_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_CRC_CCITT=m
|
||||
CONFIG_CROSS_MEMORY_ATTACH=y
|
||||
CONFIG_CRYPTO_AEAD=m
|
||||
CONFIG_CRYPTO_AEAD2=m
|
||||
CONFIG_CRYPTO_DRBG=m
|
||||
CONFIG_CRYPTO_DRBG_HMAC=y
|
||||
CONFIG_CRYPTO_DRBG_MENU=m
|
||||
CONFIG_CRYPTO_ECHAINIV=m
|
||||
CONFIG_CRYPTO_HASH=m
|
||||
CONFIG_CRYPTO_HASH2=m
|
||||
CONFIG_CRYPTO_HMAC=m
|
||||
CONFIG_CRYPTO_HW=y
|
||||
CONFIG_CRYPTO_JITTERENTROPY=m
|
||||
CONFIG_CRYPTO_MANAGER=m
|
||||
CONFIG_CRYPTO_MANAGER2=y
|
||||
CONFIG_CRYPTO_NULL=m
|
||||
CONFIG_CRYPTO_NULL2=m
|
||||
CONFIG_CRYPTO_RNG=m
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
CONFIG_CRYPTO_RNG_DEFAULT=m
|
||||
CONFIG_CRYPTO_SHA256=m
|
||||
CONFIG_CRYPTO_WORKQUEUE=y
|
||||
CONFIG_DCACHE_WORD_ACCESS=y
|
||||
CONFIG_DEBUG_BUGVERBOSE=y
|
||||
CONFIG_DEBUG_GPIO=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_LL=y
|
||||
CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
|
||||
CONFIG_DEBUG_MT6589_UART0=y
|
||||
# CONFIG_DEBUG_MT8127_UART0 is not set
|
||||
# CONFIG_DEBUG_MT8135_UART3 is not set
|
||||
CONFIG_DEBUG_PREEMPT=y
|
||||
CONFIG_DEBUG_UART_8250=y
|
||||
# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set
|
||||
CONFIG_DEBUG_UART_8250_SHIFT=2
|
||||
# CONFIG_DEBUG_UART_8250_WORD is not set
|
||||
CONFIG_DEBUG_UART_PHYS=0x11004000
|
||||
CONFIG_DEBUG_UART_VIRT=0xf1004000
|
||||
CONFIG_DEBUG_UNCOMPRESS=y
|
||||
# CONFIG_DEBUG_USER is not set
|
||||
CONFIG_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_EDAC_ATOMIC_SCRUB=y
|
||||
CONFIG_EDAC_SUPPORT=y
|
||||
CONFIG_ELF_CORE=y
|
||||
CONFIG_FIX_EARLYCON_MEM=y
|
||||
CONFIG_FREEZER=y
|
||||
CONFIG_GENERIC_ALLOCATOR=y
|
||||
CONFIG_GENERIC_BUG=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
|
||||
CONFIG_GENERIC_IDLE_POLL_SETUP=y
|
||||
CONFIG_GENERIC_IO=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
|
||||
CONFIG_GENERIC_MSI_IRQ=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_PHY=y
|
||||
CONFIG_GENERIC_PINCONF=y
|
||||
CONFIG_GENERIC_SCHED_CLOCK=y
|
||||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GENERIC_STRNCPY_FROM_USER=y
|
||||
CONFIG_GENERIC_STRNLEN_USER=y
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_DEVRES=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_HANDLE_DOMAIN_IRQ=y
|
||||
CONFIG_HARDIRQS_SW_RESEND=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT_MAP=y
|
||||
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
|
||||
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
|
||||
CONFIG_HAVE_ARCH_BITREVERSE=y
|
||||
CONFIG_HAVE_ARCH_JUMP_LABEL=y
|
||||
CONFIG_HAVE_ARCH_KGDB=y
|
||||
CONFIG_HAVE_ARCH_PFN_VALID=y
|
||||
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
|
||||
CONFIG_HAVE_ARCH_TRACEHOOK=y
|
||||
# CONFIG_HAVE_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_HWMON=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HZ_FIXED=0
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_MT65XX=y
|
||||
CONFIG_INITRAMFS_ROOT_GID=1000
|
||||
CONFIG_INITRAMFS_ROOT_UID=1000
|
||||
CONFIG_INITRAMFS_SOURCE="/openwrt/trunk/build_dir/target-arm_cortex-a7_musl-1.1.14_eabi/root-mediatek /openwrt/trunk/target/linux/generic/image/initramfs-base-files.txt"
|
||||
CONFIG_IOMMU_HELPER=y
|
||||
# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
|
||||
CONFIG_IOMMU_SUPPORT=y
|
||||
CONFIG_IP6_NF_FILTER=m
|
||||
CONFIG_IP6_NF_IPTABLES=m
|
||||
CONFIG_IP6_NF_MANGLE=m
|
||||
CONFIG_IP6_NF_RAW=m
|
||||
CONFIG_IP6_NF_TARGET_REJECT=m
|
||||
CONFIG_IPV6=y
|
||||
# CONFIG_IPV6_GRE is not set
|
||||
CONFIG_IPV6_MROUTE=y
|
||||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
# CONFIG_IPV6_PIMSM_V2 is not set
|
||||
CONFIG_IPV6_SUBTREES=y
|
||||
CONFIG_IP_NF_FILTER=m
|
||||
CONFIG_IP_NF_IPTABLES=m
|
||||
CONFIG_IP_NF_MANGLE=m
|
||||
CONFIG_IP_NF_NAT=m
|
||||
CONFIG_IP_NF_RAW=m
|
||||
CONFIG_IP_NF_TARGET_MASQUERADE=m
|
||||
CONFIG_IP_NF_TARGET_REDIRECT=m
|
||||
CONFIG_IP_NF_TARGET_REJECT=m
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_DOMAIN_HIERARCHY=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_KALLSYMS=y
|
||||
CONFIG_LEDS_GPIO=m
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_LOCKUP_DETECTOR=y
|
||||
CONFIG_LOCK_SPIN_ON_OWNER=y
|
||||
CONFIG_LZO_COMPRESS=y
|
||||
CONFIG_LZO_DECOMPRESS=y
|
||||
CONFIG_MACH_MT2701=y
|
||||
# CONFIG_MACH_MT6589 is not set
|
||||
# CONFIG_MACH_MT6592 is not set
|
||||
CONFIG_MACH_MT7623=y
|
||||
CONFIG_MACH_MT8127=y
|
||||
# CONFIG_MACH_MT8135 is not set
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_MDIO_BITBANG=y
|
||||
CONFIG_MDIO_BOARDINFO=y
|
||||
CONFIG_MDIO_GPIO=y
|
||||
CONFIG_MEDIATEK_WATCHDOG=y
|
||||
CONFIG_MFD_CORE=y
|
||||
CONFIG_MFD_MT6397=y
|
||||
CONFIG_MFD_SYSCON=y
|
||||
CONFIG_MIGHT_HAVE_CACHE_L2X0=y
|
||||
CONFIG_MIGHT_HAVE_PCI=y
|
||||
CONFIG_MIGRATION=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_BLOCK=y
|
||||
CONFIG_MMC_MTK=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
# CONFIG_MMC_SDHCI_PCI is not set
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
# CONFIG_MMC_TIFM_SD is not set
|
||||
CONFIG_MODULES_USE_ELF_REL=y
|
||||
CONFIG_MTD_M25P80=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_MTK_INFRACFG=y
|
||||
CONFIG_MTK_PMIC_WRAP=y
|
||||
CONFIG_MTK_SCPSYS=y
|
||||
CONFIG_MTK_SCPSYS_MT2701=y
|
||||
CONFIG_MTK_SCPSYS_MT8173=y
|
||||
CONFIG_MTK_TIMER=y
|
||||
CONFIG_MULTI_IRQ_HANDLER=y
|
||||
CONFIG_MUTEX_SPIN_ON_OWNER=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
# CONFIG_NEON is not set
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_NETFILTER_ADVANCED=y
|
||||
CONFIG_NETFILTER_INGRESS=y
|
||||
CONFIG_NETFILTER_XTABLES=m
|
||||
CONFIG_NETFILTER_XT_MARK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
|
||||
# CONFIG_NETFILTER_XT_MATCH_ID is not set
|
||||
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_MAC=m
|
||||
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_STATE=m
|
||||
CONFIG_NETFILTER_XT_MATCH_TIME=m
|
||||
CONFIG_NETFILTER_XT_NAT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_LOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_REDIRECT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NET_FLOW_LIMIT=y
|
||||
CONFIG_NET_INGRESS=y
|
||||
CONFIG_NET_MEDIATEK_SOC=y
|
||||
# CONFIG_NET_VENDOR_AURORA is not set
|
||||
CONFIG_NET_VENDOR_MEDIATEK=y
|
||||
# CONFIG_NET_VENDOR_WIZNET is not set
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NF_CONNTRACK_IPV4=m
|
||||
CONFIG_NF_CONNTRACK_IPV6=m
|
||||
# CONFIG_NF_CONNTRACK_RTCACHE is not set
|
||||
CONFIG_NF_DEFRAG_IPV4=m
|
||||
CONFIG_NF_DEFRAG_IPV6=m
|
||||
CONFIG_NF_LOG_COMMON=m
|
||||
CONFIG_NF_LOG_IPV4=m
|
||||
CONFIG_NF_LOG_IPV6=m
|
||||
CONFIG_NF_NAT=m
|
||||
CONFIG_NF_NAT_IPV4=m
|
||||
CONFIG_NF_NAT_MASQUERADE_IPV4=m
|
||||
CONFIG_NF_NAT_NEEDED=y
|
||||
CONFIG_NF_NAT_REDIRECT=m
|
||||
CONFIG_NF_REJECT_IPV4=m
|
||||
CONFIG_NF_REJECT_IPV6=m
|
||||
CONFIG_NLS=y
|
||||
CONFIG_NO_BOOTMEM=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_NO_HZ_COMMON=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_NR_CPUS=4
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_ADDRESS=y
|
||||
CONFIG_OF_ADDRESS_PCI=y
|
||||
CONFIG_OF_EARLY_FLATTREE=y
|
||||
CONFIG_OF_FLATTREE=y
|
||||
CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_MDIO=y
|
||||
CONFIG_OF_MTD=y
|
||||
CONFIG_OF_NET=y
|
||||
CONFIG_OF_PCI=y
|
||||
CONFIG_OF_PCI_IRQ=y
|
||||
CONFIG_OF_RESERVED_MEM=y
|
||||
CONFIG_OLD_SIGACTION=y
|
||||
CONFIG_OLD_SIGSUSPEND3=y
|
||||
CONFIG_PAGE_OFFSET=0xC0000000
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCIE_MTK=y
|
||||
# CONFIG_PCI_DOMAINS_GENERIC is not set
|
||||
CONFIG_PCI_MSI=y
|
||||
CONFIG_PERF_USE_VMALLOC=y
|
||||
CONFIG_PGTABLE_LEVELS=2
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHY_MT65XX_USB3=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCTRL_MT2701=y
|
||||
CONFIG_PINCTRL_MT6397=y
|
||||
CONFIG_PINCTRL_MT7623=y
|
||||
CONFIG_PINCTRL_MT8127=y
|
||||
# CONFIG_PINCTRL_MT8135 is not set
|
||||
CONFIG_PINCTRL_MTK_COMMON=y
|
||||
CONFIG_PM=y
|
||||
CONFIG_PM_CLK=y
|
||||
# CONFIG_PM_DEBUG is not set
|
||||
CONFIG_PM_GENERIC_DOMAINS=y
|
||||
CONFIG_PM_GENERIC_DOMAINS_OF=y
|
||||
CONFIG_PM_GENERIC_DOMAINS_SLEEP=y
|
||||
CONFIG_PM_SLEEP=y
|
||||
CONFIG_PM_SLEEP_SMP=y
|
||||
CONFIG_POWER_RESET=y
|
||||
CONFIG_POWER_SUPPLY=y
|
||||
CONFIG_PPP=m
|
||||
CONFIG_PPPOE=m
|
||||
CONFIG_PPP_ASYNC=m
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_PREEMPT_COUNT=y
|
||||
# CONFIG_PREEMPT_NONE is not set
|
||||
CONFIG_PREEMPT_RCU=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_RATIONAL=y
|
||||
CONFIG_RCU_CPU_STALL_TIMEOUT=21
|
||||
# CONFIG_RCU_EXPERT is not set
|
||||
CONFIG_RCU_STALL_COMMON=y
|
||||
CONFIG_REALTEK_PHY=m
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_REGMAP_MMIO=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
CONFIG_REGULATOR_GPIO=y
|
||||
CONFIG_REGULATOR_MT6323=y
|
||||
# CONFIG_REGULATOR_MT6397 is not set
|
||||
# CONFIG_REGULATOR_QCOM_SPMI is not set
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
CONFIG_RFS_ACCEL=y
|
||||
CONFIG_RPS=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
# CONFIG_RTC_DRV_CMOS is not set
|
||||
# CONFIG_RTC_DRV_MT6397 is not set
|
||||
CONFIG_RWSEM_SPIN_ON_OWNER=y
|
||||
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
|
||||
CONFIG_SCHED_HRTICK=y
|
||||
# CONFIG_SCHED_INFO is not set
|
||||
# CONFIG_SCSI_DMA is not set
|
||||
# CONFIG_SERIAL_8250_DMA is not set
|
||||
CONFIG_SERIAL_8250_FSL=y
|
||||
CONFIG_SERIAL_8250_MT6577=y
|
||||
CONFIG_SERIAL_8250_NR_UARTS=4
|
||||
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
|
||||
CONFIG_SLHC=m
|
||||
CONFIG_SMP=y
|
||||
# CONFIG_SMP_ON_UP is not set
|
||||
CONFIG_SPARSE_IRQ=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_BITBANG=y
|
||||
CONFIG_SPI_MASTER=y
|
||||
CONFIG_SPI_MT65XX=y
|
||||
CONFIG_SPMI=y
|
||||
CONFIG_SRCU=y
|
||||
# CONFIG_STRIP_ASM_SYMS is not set
|
||||
CONFIG_SUSPEND=y
|
||||
CONFIG_SUSPEND_FREEZER=y
|
||||
CONFIG_SWCONFIG=y
|
||||
CONFIG_SWIOTLB=y
|
||||
CONFIG_SWP_EMULATE=y
|
||||
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
|
||||
CONFIG_THERMAL=y
|
||||
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
|
||||
CONFIG_THERMAL_GOV_STEP_WISE=y
|
||||
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_UNCOMPRESS_INCLUDE="debug/uncompress.h"
|
||||
CONFIG_UNINLINE_SPIN_UNLOCK=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_COMMON=y
|
||||
CONFIG_USB_EHCI_HCD=m
|
||||
CONFIG_USB_EHCI_HCD_PLATFORM=m
|
||||
CONFIG_USB_EHCI_PCI=m
|
||||
CONFIG_USB_OHCI_HCD=m
|
||||
CONFIG_USB_OHCI_HCD_PLATFORM=m
|
||||
CONFIG_USB_SUPPORT=y
|
||||
# CONFIG_USB_UHCI_HCD is not set
|
||||
CONFIG_USB_XHCI_HCD=y
|
||||
CONFIG_USB_XHCI_MTK=y
|
||||
CONFIG_USB_XHCI_PCI=y
|
||||
CONFIG_USB_XHCI_PLATFORM=y
|
||||
CONFIG_USE_OF=y
|
||||
CONFIG_VECTORS_BASE=0xffff0000
|
||||
CONFIG_VFP=y
|
||||
CONFIG_VFPv3=y
|
||||
CONFIG_VM_EVENT_COUNTERS=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
||||
CONFIG_XPS=y
|
||||
CONFIG_XZ_DEC_ARM=y
|
||||
CONFIG_XZ_DEC_BCJ=y
|
||||
CONFIG_ZBOOT_ROM_BSS=0
|
||||
CONFIG_ZBOOT_ROM_TEXT=0
|
||||
CONFIG_ZONE_DMA_FLAG=0
|
@ -5,8 +5,7 @@ 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)
|
||||
mkimage -A arm -O linux -T kernel -C none -a 0x80008000 -e 0x80008000 -n 'MIPS OpenWrt Linux-$(LINUX_VERSION)' -d $(KDIR)/zImage$(1) $(KDIR)/uImage$(1)
|
||||
$(CP) $(KDIR)/uImage$(1) $(BIN_DIR)/$(IMG_PREFIX)-uImage$(1)
|
||||
endef
|
||||
|
||||
|
@ -0,0 +1,60 @@
|
||||
From c30a296646a42302065ba452abe95b0b4b550883 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 27 Jul 2014 09:38:50 +0100
|
||||
Subject: [PATCH 01/53] NET: multi phy support
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/net/phy/phy.c | 9 ++++++---
|
||||
include/linux/phy.h | 1 +
|
||||
2 files changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
|
||||
index 47cd306..f69d12f 100644
|
||||
--- a/drivers/net/phy/phy.c
|
||||
+++ b/drivers/net/phy/phy.c
|
||||
@@ -844,7 +844,8 @@ void phy_state_machine(struct work_struct *work)
|
||||
/* If the link is down, give up on negotiation for now */
|
||||
if (!phydev->link) {
|
||||
phydev->state = PHY_NOLINK;
|
||||
- netif_carrier_off(phydev->attached_dev);
|
||||
+ if (!phydev->no_auto_carrier_off)
|
||||
+ netif_carrier_off(phydev->attached_dev);
|
||||
phydev->adjust_link(phydev->attached_dev);
|
||||
break;
|
||||
}
|
||||
@@ -927,7 +928,8 @@ void phy_state_machine(struct work_struct *work)
|
||||
netif_carrier_on(phydev->attached_dev);
|
||||
} else {
|
||||
phydev->state = PHY_NOLINK;
|
||||
- netif_carrier_off(phydev->attached_dev);
|
||||
+ if (!phydev->no_auto_carrier_off)
|
||||
+ netif_carrier_off(phydev->attached_dev);
|
||||
}
|
||||
|
||||
phydev->adjust_link(phydev->attached_dev);
|
||||
@@ -939,7 +941,8 @@ void phy_state_machine(struct work_struct *work)
|
||||
case PHY_HALTED:
|
||||
if (phydev->link) {
|
||||
phydev->link = 0;
|
||||
- netif_carrier_off(phydev->attached_dev);
|
||||
+ if (!phydev->no_auto_carrier_off)
|
||||
+ netif_carrier_off(phydev->attached_dev);
|
||||
phydev->adjust_link(phydev->attached_dev);
|
||||
do_suspend = true;
|
||||
}
|
||||
diff --git a/include/linux/phy.h b/include/linux/phy.h
|
||||
index 05fde31..276ab8a 100644
|
||||
--- a/include/linux/phy.h
|
||||
+++ b/include/linux/phy.h
|
||||
@@ -377,6 +377,7 @@ struct phy_device {
|
||||
bool is_pseudo_fixed_link;
|
||||
bool has_fixups;
|
||||
bool suspended;
|
||||
+ bool no_auto_carrier_off;
|
||||
|
||||
enum phy_state state;
|
||||
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,681 @@
|
||||
From 2c93328ed05061a50e3bd4111379dbcf6946d3ac Mon Sep 17 00:00:00 2001
|
||||
From: James Liao <jamesjj.liao@mediatek.com>
|
||||
Date: Wed, 30 Dec 2015 14:41:43 +0800
|
||||
Subject: [PATCH 02/53] soc: mediatek: Separate scpsys driver common code
|
||||
|
||||
Separate scpsys driver common code to mtk-scpsys.c, and move MT8173
|
||||
platform code to mtk-scpsys-mt8173.c.
|
||||
|
||||
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
|
||||
---
|
||||
drivers/soc/mediatek/Kconfig | 13 +-
|
||||
drivers/soc/mediatek/Makefile | 1 +
|
||||
drivers/soc/mediatek/mtk-scpsys-mt8173.c | 179 ++++++++++++++++++
|
||||
drivers/soc/mediatek/mtk-scpsys.c | 301 ++++++++----------------------
|
||||
drivers/soc/mediatek/mtk-scpsys.h | 54 ++++++
|
||||
5 files changed, 320 insertions(+), 228 deletions(-)
|
||||
create mode 100644 drivers/soc/mediatek/mtk-scpsys-mt8173.c
|
||||
create mode 100644 drivers/soc/mediatek/mtk-scpsys.h
|
||||
|
||||
diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
|
||||
index 0a4ea80..eca6fb7 100644
|
||||
--- a/drivers/soc/mediatek/Kconfig
|
||||
+++ b/drivers/soc/mediatek/Kconfig
|
||||
@@ -22,11 +22,20 @@ config MTK_PMIC_WRAP
|
||||
|
||||
config MTK_SCPSYS
|
||||
bool "MediaTek SCPSYS Support"
|
||||
- depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
- default ARM64 && ARCH_MEDIATEK
|
||||
select REGMAP
|
||||
select MTK_INFRACFG
|
||||
select PM_GENERIC_DOMAINS if PM
|
||||
help
|
||||
Say yes here to add support for the MediaTek SCPSYS power domain
|
||||
driver.
|
||||
+
|
||||
+config MTK_SCPSYS_MT8173
|
||||
+ bool "MediaTek MT8173 SCPSYS Support"
|
||||
+ depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
+ select MTK_SCPSYS
|
||||
+ default ARCH_MEDIATEK
|
||||
+ help
|
||||
+ Say yes here to add support for the MT8173 SCPSYS power domain
|
||||
+ driver.
|
||||
+ The System Control Processor System (SCPSYS) has several power
|
||||
+ management related tasks in the system.
|
||||
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
|
||||
index 12998b0..3b22baa 100644
|
||||
--- a/drivers/soc/mediatek/Makefile
|
||||
+++ b/drivers/soc/mediatek/Makefile
|
||||
@@ -1,3 +1,4 @@
|
||||
obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
|
||||
obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
|
||||
obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
|
||||
+obj-$(CONFIG_MTK_SCPSYS_MT8173) += mtk-scpsys-mt8173.o
|
||||
diff --git a/drivers/soc/mediatek/mtk-scpsys-mt8173.c b/drivers/soc/mediatek/mtk-scpsys-mt8173.c
|
||||
new file mode 100644
|
||||
index 0000000..3c7b569
|
||||
--- /dev/null
|
||||
+++ b/drivers/soc/mediatek/mtk-scpsys-mt8173.c
|
||||
@@ -0,0 +1,179 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/pm_domain.h>
|
||||
+#include <linux/soc/mediatek/infracfg.h>
|
||||
+#include <dt-bindings/power/mt8173-power.h>
|
||||
+
|
||||
+#include "mtk-scpsys.h"
|
||||
+
|
||||
+#define SPM_VDE_PWR_CON 0x0210
|
||||
+#define SPM_MFG_PWR_CON 0x0214
|
||||
+#define SPM_VEN_PWR_CON 0x0230
|
||||
+#define SPM_ISP_PWR_CON 0x0238
|
||||
+#define SPM_DIS_PWR_CON 0x023c
|
||||
+#define SPM_VEN2_PWR_CON 0x0298
|
||||
+#define SPM_AUDIO_PWR_CON 0x029c
|
||||
+#define SPM_MFG_2D_PWR_CON 0x02c0
|
||||
+#define SPM_MFG_ASYNC_PWR_CON 0x02c4
|
||||
+#define SPM_USB_PWR_CON 0x02cc
|
||||
+
|
||||
+#define PWR_STATUS_DISP BIT(3)
|
||||
+#define PWR_STATUS_MFG BIT(4)
|
||||
+#define PWR_STATUS_ISP BIT(5)
|
||||
+#define PWR_STATUS_VDEC BIT(7)
|
||||
+#define PWR_STATUS_VENC_LT BIT(20)
|
||||
+#define PWR_STATUS_VENC BIT(21)
|
||||
+#define PWR_STATUS_MFG_2D BIT(22)
|
||||
+#define PWR_STATUS_MFG_ASYNC BIT(23)
|
||||
+#define PWR_STATUS_AUDIO BIT(24)
|
||||
+#define PWR_STATUS_USB BIT(25)
|
||||
+
|
||||
+static const struct scp_domain_data scp_domain_data[] __initconst = {
|
||||
+ [MT8173_POWER_DOMAIN_VDEC] = {
|
||||
+ .name = "vdec",
|
||||
+ .sta_mask = PWR_STATUS_VDEC,
|
||||
+ .ctl_offs = SPM_VDE_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
+ .clk_id = {CLK_MM},
|
||||
+ },
|
||||
+ [MT8173_POWER_DOMAIN_VENC] = {
|
||||
+ .name = "venc",
|
||||
+ .sta_mask = PWR_STATUS_VENC,
|
||||
+ .ctl_offs = SPM_VEN_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
+ .clk_id = {CLK_MM, CLK_VENC},
|
||||
+ },
|
||||
+ [MT8173_POWER_DOMAIN_ISP] = {
|
||||
+ .name = "isp",
|
||||
+ .sta_mask = PWR_STATUS_ISP,
|
||||
+ .ctl_offs = SPM_ISP_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(13, 12),
|
||||
+ .clk_id = {CLK_MM},
|
||||
+ },
|
||||
+ [MT8173_POWER_DOMAIN_MM] = {
|
||||
+ .name = "mm",
|
||||
+ .sta_mask = PWR_STATUS_DISP,
|
||||
+ .ctl_offs = SPM_DIS_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
+ .clk_id = {CLK_MM},
|
||||
+ .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
|
||||
+ MT8173_TOP_AXI_PROT_EN_MM_M1,
|
||||
+ },
|
||||
+ [MT8173_POWER_DOMAIN_VENC_LT] = {
|
||||
+ .name = "venc_lt",
|
||||
+ .sta_mask = PWR_STATUS_VENC_LT,
|
||||
+ .ctl_offs = SPM_VEN2_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
+ .clk_id = {CLK_MM, CLK_VENC_LT},
|
||||
+ },
|
||||
+ [MT8173_POWER_DOMAIN_AUDIO] = {
|
||||
+ .name = "audio",
|
||||
+ .sta_mask = PWR_STATUS_AUDIO,
|
||||
+ .ctl_offs = SPM_AUDIO_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
+ .clk_id = {CLK_NONE},
|
||||
+ },
|
||||
+ [MT8173_POWER_DOMAIN_USB] = {
|
||||
+ .name = "usb",
|
||||
+ .sta_mask = PWR_STATUS_USB,
|
||||
+ .ctl_offs = SPM_USB_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
+ .clk_id = {CLK_NONE},
|
||||
+ .active_wakeup = true,
|
||||
+ },
|
||||
+ [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
|
||||
+ .name = "mfg_async",
|
||||
+ .sta_mask = PWR_STATUS_MFG_ASYNC,
|
||||
+ .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = 0,
|
||||
+ .clk_id = {CLK_MFG},
|
||||
+ },
|
||||
+ [MT8173_POWER_DOMAIN_MFG_2D] = {
|
||||
+ .name = "mfg_2d",
|
||||
+ .sta_mask = PWR_STATUS_MFG_2D,
|
||||
+ .ctl_offs = SPM_MFG_2D_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(13, 12),
|
||||
+ .clk_id = {CLK_NONE},
|
||||
+ },
|
||||
+ [MT8173_POWER_DOMAIN_MFG] = {
|
||||
+ .name = "mfg",
|
||||
+ .sta_mask = PWR_STATUS_MFG,
|
||||
+ .ctl_offs = SPM_MFG_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(13, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(21, 16),
|
||||
+ .clk_id = {CLK_NONE},
|
||||
+ .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
|
||||
+ MT8173_TOP_AXI_PROT_EN_MFG_M0 |
|
||||
+ MT8173_TOP_AXI_PROT_EN_MFG_M1 |
|
||||
+ MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+#define NUM_DOMAINS ARRAY_SIZE(scp_domain_data)
|
||||
+
|
||||
+static int __init scpsys_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct scp *scp;
|
||||
+ struct genpd_onecell_data *pd_data;
|
||||
+ int ret;
|
||||
+
|
||||
+ scp = init_scp(pdev, scp_domain_data, NUM_DOMAINS);
|
||||
+ if (IS_ERR(scp))
|
||||
+ return PTR_ERR(scp);
|
||||
+
|
||||
+ mtk_register_power_domains(pdev, scp, NUM_DOMAINS);
|
||||
+
|
||||
+ pd_data = &scp->pd_data;
|
||||
+
|
||||
+ ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
|
||||
+ pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
|
||||
+ if (ret && IS_ENABLED(CONFIG_PM))
|
||||
+ dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
|
||||
+
|
||||
+ ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D],
|
||||
+ pd_data->domains[MT8173_POWER_DOMAIN_MFG]);
|
||||
+ if (ret && IS_ENABLED(CONFIG_PM))
|
||||
+ dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id of_scpsys_match_tbl[] = {
|
||||
+ {
|
||||
+ .compatible = "mediatek,mt8173-scpsys",
|
||||
+ }, {
|
||||
+ /* sentinel */
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static struct platform_driver scpsys_drv = {
|
||||
+ .driver = {
|
||||
+ .name = "mtk-scpsys-mt8173",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = of_match_ptr(of_scpsys_match_tbl),
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+module_platform_driver_probe(scpsys_drv, scpsys_probe);
|
||||
diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
|
||||
index 4d4203c..a0943c5 100644
|
||||
--- a/drivers/soc/mediatek/mtk-scpsys.c
|
||||
+++ b/drivers/soc/mediatek/mtk-scpsys.c
|
||||
@@ -11,28 +11,14 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#include <linux/clk.h>
|
||||
-#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
-#include <linux/kernel.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
-#include <linux/module.h>
|
||||
-#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_domain.h>
|
||||
-#include <linux/regmap.h>
|
||||
#include <linux/soc/mediatek/infracfg.h>
|
||||
-#include <dt-bindings/power/mt8173-power.h>
|
||||
-
|
||||
-#define SPM_VDE_PWR_CON 0x0210
|
||||
-#define SPM_MFG_PWR_CON 0x0214
|
||||
-#define SPM_VEN_PWR_CON 0x0230
|
||||
-#define SPM_ISP_PWR_CON 0x0238
|
||||
-#define SPM_DIS_PWR_CON 0x023c
|
||||
-#define SPM_VEN2_PWR_CON 0x0298
|
||||
-#define SPM_AUDIO_PWR_CON 0x029c
|
||||
-#define SPM_MFG_2D_PWR_CON 0x02c0
|
||||
-#define SPM_MFG_ASYNC_PWR_CON 0x02c4
|
||||
-#define SPM_USB_PWR_CON 0x02cc
|
||||
+
|
||||
+#include "mtk-scpsys.h"
|
||||
+
|
||||
#define SPM_PWR_STATUS 0x060c
|
||||
#define SPM_PWR_STATUS_2ND 0x0610
|
||||
|
||||
@@ -42,153 +28,6 @@
|
||||
#define PWR_ON_2ND_BIT BIT(3)
|
||||
#define PWR_CLK_DIS_BIT BIT(4)
|
||||
|
||||
-#define PWR_STATUS_DISP BIT(3)
|
||||
-#define PWR_STATUS_MFG BIT(4)
|
||||
-#define PWR_STATUS_ISP BIT(5)
|
||||
-#define PWR_STATUS_VDEC BIT(7)
|
||||
-#define PWR_STATUS_VENC_LT BIT(20)
|
||||
-#define PWR_STATUS_VENC BIT(21)
|
||||
-#define PWR_STATUS_MFG_2D BIT(22)
|
||||
-#define PWR_STATUS_MFG_ASYNC BIT(23)
|
||||
-#define PWR_STATUS_AUDIO BIT(24)
|
||||
-#define PWR_STATUS_USB BIT(25)
|
||||
-
|
||||
-enum clk_id {
|
||||
- MT8173_CLK_NONE,
|
||||
- MT8173_CLK_MM,
|
||||
- MT8173_CLK_MFG,
|
||||
- MT8173_CLK_VENC,
|
||||
- MT8173_CLK_VENC_LT,
|
||||
- MT8173_CLK_MAX,
|
||||
-};
|
||||
-
|
||||
-#define MAX_CLKS 2
|
||||
-
|
||||
-struct scp_domain_data {
|
||||
- const char *name;
|
||||
- u32 sta_mask;
|
||||
- int ctl_offs;
|
||||
- u32 sram_pdn_bits;
|
||||
- u32 sram_pdn_ack_bits;
|
||||
- u32 bus_prot_mask;
|
||||
- enum clk_id clk_id[MAX_CLKS];
|
||||
- bool active_wakeup;
|
||||
-};
|
||||
-
|
||||
-static const struct scp_domain_data scp_domain_data[] __initconst = {
|
||||
- [MT8173_POWER_DOMAIN_VDEC] = {
|
||||
- .name = "vdec",
|
||||
- .sta_mask = PWR_STATUS_VDEC,
|
||||
- .ctl_offs = SPM_VDE_PWR_CON,
|
||||
- .sram_pdn_bits = GENMASK(11, 8),
|
||||
- .sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
- .clk_id = {MT8173_CLK_MM},
|
||||
- },
|
||||
- [MT8173_POWER_DOMAIN_VENC] = {
|
||||
- .name = "venc",
|
||||
- .sta_mask = PWR_STATUS_VENC,
|
||||
- .ctl_offs = SPM_VEN_PWR_CON,
|
||||
- .sram_pdn_bits = GENMASK(11, 8),
|
||||
- .sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
- .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC},
|
||||
- },
|
||||
- [MT8173_POWER_DOMAIN_ISP] = {
|
||||
- .name = "isp",
|
||||
- .sta_mask = PWR_STATUS_ISP,
|
||||
- .ctl_offs = SPM_ISP_PWR_CON,
|
||||
- .sram_pdn_bits = GENMASK(11, 8),
|
||||
- .sram_pdn_ack_bits = GENMASK(13, 12),
|
||||
- .clk_id = {MT8173_CLK_MM},
|
||||
- },
|
||||
- [MT8173_POWER_DOMAIN_MM] = {
|
||||
- .name = "mm",
|
||||
- .sta_mask = PWR_STATUS_DISP,
|
||||
- .ctl_offs = SPM_DIS_PWR_CON,
|
||||
- .sram_pdn_bits = GENMASK(11, 8),
|
||||
- .sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
- .clk_id = {MT8173_CLK_MM},
|
||||
- .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
|
||||
- MT8173_TOP_AXI_PROT_EN_MM_M1,
|
||||
- },
|
||||
- [MT8173_POWER_DOMAIN_VENC_LT] = {
|
||||
- .name = "venc_lt",
|
||||
- .sta_mask = PWR_STATUS_VENC_LT,
|
||||
- .ctl_offs = SPM_VEN2_PWR_CON,
|
||||
- .sram_pdn_bits = GENMASK(11, 8),
|
||||
- .sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
- .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC_LT},
|
||||
- },
|
||||
- [MT8173_POWER_DOMAIN_AUDIO] = {
|
||||
- .name = "audio",
|
||||
- .sta_mask = PWR_STATUS_AUDIO,
|
||||
- .ctl_offs = SPM_AUDIO_PWR_CON,
|
||||
- .sram_pdn_bits = GENMASK(11, 8),
|
||||
- .sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
- .clk_id = {MT8173_CLK_NONE},
|
||||
- },
|
||||
- [MT8173_POWER_DOMAIN_USB] = {
|
||||
- .name = "usb",
|
||||
- .sta_mask = PWR_STATUS_USB,
|
||||
- .ctl_offs = SPM_USB_PWR_CON,
|
||||
- .sram_pdn_bits = GENMASK(11, 8),
|
||||
- .sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
- .clk_id = {MT8173_CLK_NONE},
|
||||
- .active_wakeup = true,
|
||||
- },
|
||||
- [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
|
||||
- .name = "mfg_async",
|
||||
- .sta_mask = PWR_STATUS_MFG_ASYNC,
|
||||
- .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
|
||||
- .sram_pdn_bits = GENMASK(11, 8),
|
||||
- .sram_pdn_ack_bits = 0,
|
||||
- .clk_id = {MT8173_CLK_MFG},
|
||||
- },
|
||||
- [MT8173_POWER_DOMAIN_MFG_2D] = {
|
||||
- .name = "mfg_2d",
|
||||
- .sta_mask = PWR_STATUS_MFG_2D,
|
||||
- .ctl_offs = SPM_MFG_2D_PWR_CON,
|
||||
- .sram_pdn_bits = GENMASK(11, 8),
|
||||
- .sram_pdn_ack_bits = GENMASK(13, 12),
|
||||
- .clk_id = {MT8173_CLK_NONE},
|
||||
- },
|
||||
- [MT8173_POWER_DOMAIN_MFG] = {
|
||||
- .name = "mfg",
|
||||
- .sta_mask = PWR_STATUS_MFG,
|
||||
- .ctl_offs = SPM_MFG_PWR_CON,
|
||||
- .sram_pdn_bits = GENMASK(13, 8),
|
||||
- .sram_pdn_ack_bits = GENMASK(21, 16),
|
||||
- .clk_id = {MT8173_CLK_NONE},
|
||||
- .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
|
||||
- MT8173_TOP_AXI_PROT_EN_MFG_M0 |
|
||||
- MT8173_TOP_AXI_PROT_EN_MFG_M1 |
|
||||
- MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
|
||||
- },
|
||||
-};
|
||||
-
|
||||
-#define NUM_DOMAINS ARRAY_SIZE(scp_domain_data)
|
||||
-
|
||||
-struct scp;
|
||||
-
|
||||
-struct scp_domain {
|
||||
- struct generic_pm_domain genpd;
|
||||
- struct scp *scp;
|
||||
- struct clk *clk[MAX_CLKS];
|
||||
- u32 sta_mask;
|
||||
- void __iomem *ctl_addr;
|
||||
- u32 sram_pdn_bits;
|
||||
- u32 sram_pdn_ack_bits;
|
||||
- u32 bus_prot_mask;
|
||||
- bool active_wakeup;
|
||||
-};
|
||||
-
|
||||
-struct scp {
|
||||
- struct scp_domain domains[NUM_DOMAINS];
|
||||
- struct genpd_onecell_data pd_data;
|
||||
- struct device *dev;
|
||||
- void __iomem *base;
|
||||
- struct regmap *infracfg;
|
||||
-};
|
||||
-
|
||||
static int scpsys_domain_is_on(struct scp_domain *scpd)
|
||||
{
|
||||
struct scp *scp = scpd->scp;
|
||||
@@ -398,63 +237,89 @@ static bool scpsys_active_wakeup(struct device *dev)
|
||||
return scpd->active_wakeup;
|
||||
}
|
||||
|
||||
-static int __init scpsys_probe(struct platform_device *pdev)
|
||||
+static void init_clks(struct platform_device *pdev, struct clk *clk[CLK_MAX])
|
||||
+{
|
||||
+ enum clk_id clk_ids[] = {
|
||||
+ CLK_MM,
|
||||
+ CLK_MFG,
|
||||
+ CLK_VENC,
|
||||
+ CLK_VENC_LT
|
||||
+ };
|
||||
+
|
||||
+ static const char * const clk_names[] = {
|
||||
+ "mm",
|
||||
+ "mfg",
|
||||
+ "venc",
|
||||
+ "venc_lt",
|
||||
+ };
|
||||
+
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(clk_ids); i++)
|
||||
+ clk[clk_ids[i]] = devm_clk_get(&pdev->dev, clk_names[i]);
|
||||
+}
|
||||
+
|
||||
+struct scp *init_scp(struct platform_device *pdev,
|
||||
+ const struct scp_domain_data *scp_domain_data, int num)
|
||||
{
|
||||
struct genpd_onecell_data *pd_data;
|
||||
struct resource *res;
|
||||
- int i, j, ret;
|
||||
+ int i, j;
|
||||
struct scp *scp;
|
||||
- struct clk *clk[MT8173_CLK_MAX];
|
||||
+ struct clk *clk[CLK_MAX];
|
||||
|
||||
scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
|
||||
if (!scp)
|
||||
- return -ENOMEM;
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
|
||||
scp->dev = &pdev->dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
scp->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(scp->base))
|
||||
- return PTR_ERR(scp->base);
|
||||
-
|
||||
- pd_data = &scp->pd_data;
|
||||
-
|
||||
- pd_data->domains = devm_kzalloc(&pdev->dev,
|
||||
- sizeof(*pd_data->domains) * NUM_DOMAINS, GFP_KERNEL);
|
||||
- if (!pd_data->domains)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- clk[MT8173_CLK_MM] = devm_clk_get(&pdev->dev, "mm");
|
||||
- if (IS_ERR(clk[MT8173_CLK_MM]))
|
||||
- return PTR_ERR(clk[MT8173_CLK_MM]);
|
||||
-
|
||||
- clk[MT8173_CLK_MFG] = devm_clk_get(&pdev->dev, "mfg");
|
||||
- if (IS_ERR(clk[MT8173_CLK_MFG]))
|
||||
- return PTR_ERR(clk[MT8173_CLK_MFG]);
|
||||
-
|
||||
- clk[MT8173_CLK_VENC] = devm_clk_get(&pdev->dev, "venc");
|
||||
- if (IS_ERR(clk[MT8173_CLK_VENC]))
|
||||
- return PTR_ERR(clk[MT8173_CLK_VENC]);
|
||||
-
|
||||
- clk[MT8173_CLK_VENC_LT] = devm_clk_get(&pdev->dev, "venc_lt");
|
||||
- if (IS_ERR(clk[MT8173_CLK_VENC_LT]))
|
||||
- return PTR_ERR(clk[MT8173_CLK_VENC_LT]);
|
||||
+ return ERR_CAST(scp->base);
|
||||
|
||||
scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
|
||||
"infracfg");
|
||||
if (IS_ERR(scp->infracfg)) {
|
||||
dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n",
|
||||
PTR_ERR(scp->infracfg));
|
||||
- return PTR_ERR(scp->infracfg);
|
||||
+ return ERR_CAST(scp->infracfg);
|
||||
}
|
||||
|
||||
- pd_data->num_domains = NUM_DOMAINS;
|
||||
+ scp->domains = devm_kzalloc(&pdev->dev,
|
||||
+ sizeof(*scp->domains) * num, GFP_KERNEL);
|
||||
+ if (!scp->domains)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ pd_data = &scp->pd_data;
|
||||
+
|
||||
+ pd_data->domains = devm_kzalloc(&pdev->dev,
|
||||
+ sizeof(*pd_data->domains) * num, GFP_KERNEL);
|
||||
+ if (!pd_data->domains)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
|
||||
- for (i = 0; i < NUM_DOMAINS; i++) {
|
||||
+ pd_data->num_domains = num;
|
||||
+
|
||||
+ init_clks(pdev, clk);
|
||||
+
|
||||
+ for (i = 0; i < num; i++) {
|
||||
struct scp_domain *scpd = &scp->domains[i];
|
||||
struct generic_pm_domain *genpd = &scpd->genpd;
|
||||
const struct scp_domain_data *data = &scp_domain_data[i];
|
||||
|
||||
+ for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) {
|
||||
+ struct clk *c = clk[data->clk_id[j]];
|
||||
+
|
||||
+ if (IS_ERR(c)) {
|
||||
+ dev_err(&pdev->dev, "%s: clk unavailable\n",
|
||||
+ data->name);
|
||||
+ return ERR_CAST(c);
|
||||
+ }
|
||||
+
|
||||
+ scpd->clk[j] = c;
|
||||
+ }
|
||||
+
|
||||
pd_data->domains[i] = genpd;
|
||||
scpd->scp = scp;
|
||||
|
||||
@@ -464,13 +329,25 @@ static int __init scpsys_probe(struct platform_device *pdev)
|
||||
scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits;
|
||||
scpd->bus_prot_mask = data->bus_prot_mask;
|
||||
scpd->active_wakeup = data->active_wakeup;
|
||||
- for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++)
|
||||
- scpd->clk[j] = clk[data->clk_id[j]];
|
||||
|
||||
genpd->name = data->name;
|
||||
genpd->power_off = scpsys_power_off;
|
||||
genpd->power_on = scpsys_power_on;
|
||||
genpd->dev_ops.active_wakeup = scpsys_active_wakeup;
|
||||
+ }
|
||||
+
|
||||
+ return scp;
|
||||
+}
|
||||
+
|
||||
+void mtk_register_power_domains(struct platform_device *pdev,
|
||||
+ struct scp *scp, int num)
|
||||
+{
|
||||
+ struct genpd_onecell_data *pd_data;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ for (i = 0; i < num; i++) {
|
||||
+ struct scp_domain *scpd = &scp->domains[i];
|
||||
+ struct generic_pm_domain *genpd = &scpd->genpd;
|
||||
|
||||
/*
|
||||
* Initially turn on all domains to make the domains usable
|
||||
@@ -489,37 +366,9 @@ static int __init scpsys_probe(struct platform_device *pdev)
|
||||
* valid.
|
||||
*/
|
||||
|
||||
- ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
|
||||
- pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
|
||||
- if (ret && IS_ENABLED(CONFIG_PM))
|
||||
- dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
|
||||
-
|
||||
- ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D],
|
||||
- pd_data->domains[MT8173_POWER_DOMAIN_MFG]);
|
||||
- if (ret && IS_ENABLED(CONFIG_PM))
|
||||
- dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
|
||||
+ pd_data = &scp->pd_data;
|
||||
|
||||
ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
|
||||
-
|
||||
- return 0;
|
||||
}
|
||||
-
|
||||
-static const struct of_device_id of_scpsys_match_tbl[] = {
|
||||
- {
|
||||
- .compatible = "mediatek,mt8173-scpsys",
|
||||
- }, {
|
||||
- /* sentinel */
|
||||
- }
|
||||
-};
|
||||
-
|
||||
-static struct platform_driver scpsys_drv = {
|
||||
- .driver = {
|
||||
- .name = "mtk-scpsys",
|
||||
- .owner = THIS_MODULE,
|
||||
- .of_match_table = of_match_ptr(of_scpsys_match_tbl),
|
||||
- },
|
||||
-};
|
||||
-
|
||||
-module_platform_driver_probe(scpsys_drv, scpsys_probe);
|
||||
diff --git a/drivers/soc/mediatek/mtk-scpsys.h b/drivers/soc/mediatek/mtk-scpsys.h
|
||||
new file mode 100644
|
||||
index 0000000..466728d
|
||||
--- /dev/null
|
||||
+++ b/drivers/soc/mediatek/mtk-scpsys.h
|
||||
@@ -0,0 +1,54 @@
|
||||
+#ifndef __DRV_SOC_MTK_H
|
||||
+#define __DRV_SOC_MTK_H
|
||||
+
|
||||
+enum clk_id {
|
||||
+ CLK_NONE,
|
||||
+ CLK_MM,
|
||||
+ CLK_MFG,
|
||||
+ CLK_VENC,
|
||||
+ CLK_VENC_LT,
|
||||
+ CLK_MAX,
|
||||
+};
|
||||
+
|
||||
+#define MAX_CLKS 2
|
||||
+
|
||||
+struct scp_domain_data {
|
||||
+ const char *name;
|
||||
+ u32 sta_mask;
|
||||
+ int ctl_offs;
|
||||
+ u32 sram_pdn_bits;
|
||||
+ u32 sram_pdn_ack_bits;
|
||||
+ u32 bus_prot_mask;
|
||||
+ enum clk_id clk_id[MAX_CLKS];
|
||||
+ bool active_wakeup;
|
||||
+};
|
||||
+
|
||||
+struct scp;
|
||||
+
|
||||
+struct scp_domain {
|
||||
+ struct generic_pm_domain genpd;
|
||||
+ struct scp *scp;
|
||||
+ struct clk *clk[MAX_CLKS];
|
||||
+ u32 sta_mask;
|
||||
+ void __iomem *ctl_addr;
|
||||
+ u32 sram_pdn_bits;
|
||||
+ u32 sram_pdn_ack_bits;
|
||||
+ u32 bus_prot_mask;
|
||||
+ bool active_wakeup;
|
||||
+};
|
||||
+
|
||||
+struct scp {
|
||||
+ struct scp_domain *domains;
|
||||
+ struct genpd_onecell_data pd_data;
|
||||
+ struct device *dev;
|
||||
+ void __iomem *base;
|
||||
+ struct regmap *infracfg;
|
||||
+};
|
||||
+
|
||||
+struct scp *init_scp(struct platform_device *pdev,
|
||||
+ const struct scp_domain_data *scp_domain_data, int num);
|
||||
+
|
||||
+void mtk_register_power_domains(struct platform_device *pdev,
|
||||
+ struct scp *scp, int num);
|
||||
+
|
||||
+#endif /* __DRV_SOC_MTK_H */
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,38 @@
|
||||
From c359272f86805259c5801385d60fdeea9d629cf9 Mon Sep 17 00:00:00 2001
|
||||
From: James Liao <jamesjj.liao@mediatek.com>
|
||||
Date: Wed, 30 Dec 2015 14:41:44 +0800
|
||||
Subject: [PATCH 03/53] soc: mediatek: Init MT8173 scpsys driver earlier
|
||||
|
||||
Some power domain comsumers may init before module_init.
|
||||
So the power domain provider (scpsys) need to be initialized
|
||||
earlier too.
|
||||
|
||||
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
|
||||
---
|
||||
drivers/soc/mediatek/mtk-scpsys-mt8173.c | 13 ++++++++++++-
|
||||
1 file changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/soc/mediatek/mtk-scpsys-mt8173.c b/drivers/soc/mediatek/mtk-scpsys-mt8173.c
|
||||
index 3c7b569..827e696 100644
|
||||
--- a/drivers/soc/mediatek/mtk-scpsys-mt8173.c
|
||||
+++ b/drivers/soc/mediatek/mtk-scpsys-mt8173.c
|
||||
@@ -176,4 +176,15 @@ static struct platform_driver scpsys_drv = {
|
||||
},
|
||||
};
|
||||
|
||||
-module_platform_driver_probe(scpsys_drv, scpsys_probe);
|
||||
+static int __init scpsys_drv_init(void)
|
||||
+{
|
||||
+ return platform_driver_probe(&scpsys_drv, scpsys_probe);
|
||||
+}
|
||||
+
|
||||
+static void __exit scpsys_drv_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&scpsys_drv);
|
||||
+}
|
||||
+
|
||||
+subsys_initcall(scpsys_drv_init);
|
||||
+module_exit(scpsys_drv_exit);
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,50 @@
|
||||
From f371844374fff273f817d6c43f679606417af59e Mon Sep 17 00:00:00 2001
|
||||
From: Shunli Wang <shunli.wang@mediatek.com>
|
||||
Date: Wed, 30 Dec 2015 14:41:45 +0800
|
||||
Subject: [PATCH 04/53] soc: mediatek: Add MT2701 power dt-bindings
|
||||
|
||||
Add power dt-bindings for MT2701.
|
||||
|
||||
Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
|
||||
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
|
||||
---
|
||||
include/dt-bindings/power/mt2701-power.h | 27 +++++++++++++++++++++++++++
|
||||
1 file changed, 27 insertions(+)
|
||||
create mode 100644 include/dt-bindings/power/mt2701-power.h
|
||||
|
||||
diff --git a/include/dt-bindings/power/mt2701-power.h b/include/dt-bindings/power/mt2701-power.h
|
||||
new file mode 100644
|
||||
index 0000000..64cc826
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/power/mt2701-power.h
|
||||
@@ -0,0 +1,27 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2015 MediaTek Inc.
|
||||
+ *
|
||||
+ * This program is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _DT_BINDINGS_POWER_MT2701_POWER_H
|
||||
+#define _DT_BINDINGS_POWER_MT2701_POWER_H
|
||||
+
|
||||
+#define MT2701_POWER_DOMAIN_CONN 0
|
||||
+#define MT2701_POWER_DOMAIN_DISP 1
|
||||
+#define MT2701_POWER_DOMAIN_MFG 2
|
||||
+#define MT2701_POWER_DOMAIN_VDEC 3
|
||||
+#define MT2701_POWER_DOMAIN_ISP 4
|
||||
+#define MT2701_POWER_DOMAIN_BDP 5
|
||||
+#define MT2701_POWER_DOMAIN_ETH 6
|
||||
+#define MT2701_POWER_DOMAIN_HIF 7
|
||||
+#define MT2701_POWER_DOMAIN_IFR_MSC 8
|
||||
+
|
||||
+#endif /* _DT_BINDINGS_POWER_MT2701_POWER_H */
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,214 @@
|
||||
From c6711565985f359d7d3c05f01f081e4c216902de Mon Sep 17 00:00:00 2001
|
||||
From: Shunli Wang <shunli.wang@mediatek.com>
|
||||
Date: Wed, 30 Dec 2015 14:41:46 +0800
|
||||
Subject: [PATCH 05/53] soc: mediatek: Add MT2701/MT7623 scpsys driver
|
||||
|
||||
Add scpsys driver for MT2701 and MT7623.
|
||||
|
||||
Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
|
||||
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
|
||||
---
|
||||
drivers/soc/mediatek/Kconfig | 11 ++
|
||||
drivers/soc/mediatek/Makefile | 1 +
|
||||
drivers/soc/mediatek/mtk-scpsys-mt2701.c | 161 ++++++++++++++++++++++++++++++
|
||||
3 files changed, 173 insertions(+)
|
||||
create mode 100644 drivers/soc/mediatek/mtk-scpsys-mt2701.c
|
||||
|
||||
diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
|
||||
index eca6fb7..92cf838 100644
|
||||
--- a/drivers/soc/mediatek/Kconfig
|
||||
+++ b/drivers/soc/mediatek/Kconfig
|
||||
@@ -39,3 +39,14 @@ config MTK_SCPSYS_MT8173
|
||||
driver.
|
||||
The System Control Processor System (SCPSYS) has several power
|
||||
management related tasks in the system.
|
||||
+
|
||||
+config MTK_SCPSYS_MT2701
|
||||
+ bool "SCPSYS Support MediaTek MT2701 and MT7623"
|
||||
+ depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
+ select MTK_SCPSYS
|
||||
+ default ARCH_MEDIATEK
|
||||
+ help
|
||||
+ Say yes here to add support for the MT2701/MT7623 SCPSYS power
|
||||
+ domain driver.
|
||||
+ The System Control Processor System (SCPSYS) has several power
|
||||
+ management related tasks in the system.
|
||||
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
|
||||
index 3b22baa..822986d 100644
|
||||
--- a/drivers/soc/mediatek/Makefile
|
||||
+++ b/drivers/soc/mediatek/Makefile
|
||||
@@ -2,3 +2,4 @@ obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
|
||||
obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
|
||||
obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
|
||||
obj-$(CONFIG_MTK_SCPSYS_MT8173) += mtk-scpsys-mt8173.o
|
||||
+obj-$(CONFIG_MTK_SCPSYS_MT2701) += mtk-scpsys-mt2701.o
|
||||
diff --git a/drivers/soc/mediatek/mtk-scpsys-mt2701.c b/drivers/soc/mediatek/mtk-scpsys-mt2701.c
|
||||
new file mode 100644
|
||||
index 0000000..339d5b8
|
||||
--- /dev/null
|
||||
+++ b/drivers/soc/mediatek/mtk-scpsys-mt2701.c
|
||||
@@ -0,0 +1,161 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015 Mediatek, Shunli Wang <shunli.wang@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/pm_domain.h>
|
||||
+#include <linux/soc/mediatek/infracfg.h>
|
||||
+#include <dt-bindings/power/mt2701-power.h>
|
||||
+
|
||||
+#include "mtk-scpsys.h"
|
||||
+
|
||||
+#define SPM_VDE_PWR_CON 0x0210
|
||||
+#define SPM_MFG_PWR_CON 0x0214
|
||||
+#define SPM_ISP_PWR_CON 0x0238
|
||||
+#define SPM_DIS_PWR_CON 0x023C
|
||||
+#define SPM_CONN_PWR_CON 0x0280
|
||||
+#define SPM_BDP_PWR_CON 0x029C
|
||||
+#define SPM_ETH_PWR_CON 0x02A0
|
||||
+#define SPM_HIF_PWR_CON 0x02A4
|
||||
+#define SPM_IFR_MSC_PWR_CON 0x02A8
|
||||
+#define SPM_PWR_STATUS 0x060c
|
||||
+#define SPM_PWR_STATUS_2ND 0x0610
|
||||
+
|
||||
+#define CONN_PWR_STA_MASK BIT(1)
|
||||
+#define DIS_PWR_STA_MASK BIT(3)
|
||||
+#define MFG_PWR_STA_MASK BIT(4)
|
||||
+#define ISP_PWR_STA_MASK BIT(5)
|
||||
+#define VDE_PWR_STA_MASK BIT(7)
|
||||
+#define BDP_PWR_STA_MASK BIT(14)
|
||||
+#define ETH_PWR_STA_MASK BIT(15)
|
||||
+#define HIF_PWR_STA_MASK BIT(16)
|
||||
+#define IFR_MSC_PWR_STA_MASK BIT(17)
|
||||
+
|
||||
+#define MT2701_TOP_AXI_PROT_EN_CONN 0x0104
|
||||
+#define MT2701_TOP_AXI_PROT_EN_DISP 0x0002
|
||||
+
|
||||
+static const struct scp_domain_data scp_domain_data[] = {
|
||||
+ [MT2701_POWER_DOMAIN_CONN] = {
|
||||
+ .name = "conn",
|
||||
+ .sta_mask = CONN_PWR_STA_MASK,
|
||||
+ .ctl_offs = SPM_CONN_PWR_CON,
|
||||
+ .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN,
|
||||
+ .active_wakeup = true,
|
||||
+ },
|
||||
+ [MT2701_POWER_DOMAIN_DISP] = {
|
||||
+ .name = "disp",
|
||||
+ .sta_mask = DIS_PWR_STA_MASK,
|
||||
+ .ctl_offs = SPM_DIS_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .clk_id = {CLK_MM},
|
||||
+ .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_DISP,
|
||||
+ .active_wakeup = true,
|
||||
+ },
|
||||
+ [MT2701_POWER_DOMAIN_MFG] = {
|
||||
+ .name = "mfg",
|
||||
+ .sta_mask = MFG_PWR_STA_MASK,
|
||||
+ .ctl_offs = SPM_MFG_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
+ .active_wakeup = true,
|
||||
+ },
|
||||
+ [MT2701_POWER_DOMAIN_VDEC] = {
|
||||
+ .name = "vdec",
|
||||
+ .sta_mask = VDE_PWR_STA_MASK,
|
||||
+ .ctl_offs = SPM_VDE_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
+ .clk_id = {CLK_MM},
|
||||
+ .active_wakeup = true,
|
||||
+ },
|
||||
+ [MT2701_POWER_DOMAIN_ISP] = {
|
||||
+ .name = "isp",
|
||||
+ .sta_mask = ISP_PWR_STA_MASK,
|
||||
+ .ctl_offs = SPM_ISP_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(13, 12),
|
||||
+ .active_wakeup = true,
|
||||
+ },
|
||||
+ [MT2701_POWER_DOMAIN_BDP] = {
|
||||
+ .name = "bdp",
|
||||
+ .sta_mask = BDP_PWR_STA_MASK,
|
||||
+ .ctl_offs = SPM_BDP_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .active_wakeup = true,
|
||||
+ },
|
||||
+ [MT2701_POWER_DOMAIN_ETH] = {
|
||||
+ .name = "eth",
|
||||
+ .sta_mask = ETH_PWR_STA_MASK,
|
||||
+ .ctl_offs = SPM_ETH_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
+ .active_wakeup = true,
|
||||
+ },
|
||||
+ [MT2701_POWER_DOMAIN_HIF] = {
|
||||
+ .name = "hif",
|
||||
+ .sta_mask = HIF_PWR_STA_MASK,
|
||||
+ .ctl_offs = SPM_HIF_PWR_CON,
|
||||
+ .sram_pdn_bits = GENMASK(11, 8),
|
||||
+ .sram_pdn_ack_bits = GENMASK(15, 12),
|
||||
+ .active_wakeup = true,
|
||||
+ },
|
||||
+ [MT2701_POWER_DOMAIN_IFR_MSC] = {
|
||||
+ .name = "ifr_msc",
|
||||
+ .sta_mask = IFR_MSC_PWR_STA_MASK,
|
||||
+ .ctl_offs = SPM_IFR_MSC_PWR_CON,
|
||||
+ .active_wakeup = true,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+#define NUM_DOMAINS ARRAY_SIZE(scp_domain_data)
|
||||
+
|
||||
+static int __init scpsys_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct scp *scp;
|
||||
+
|
||||
+ scp = init_scp(pdev, scp_domain_data, NUM_DOMAINS);
|
||||
+ if (IS_ERR(scp))
|
||||
+ return PTR_ERR(scp);
|
||||
+
|
||||
+ mtk_register_power_domains(pdev, scp, NUM_DOMAINS);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id of_scpsys_match_tbl[] = {
|
||||
+ {
|
||||
+ .compatible = "mediatek,mt2701-scpsys",
|
||||
+ }, {
|
||||
+ /* sentinel */
|
||||
+ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, of_scpsys_match_tbl);
|
||||
+
|
||||
+static struct platform_driver scpsys_drv = {
|
||||
+ .driver = {
|
||||
+ .name = "mtk-scpsys-mt2701",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = of_match_ptr(of_scpsys_match_tbl),
|
||||
+ },
|
||||
+ .probe = scpsys_probe,
|
||||
+};
|
||||
+
|
||||
+static int __init scpsys_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&scpsys_drv);
|
||||
+}
|
||||
+
|
||||
+subsys_initcall(scpsys_init);
|
||||
+
|
||||
+MODULE_DESCRIPTION("MediaTek MT2701 scpsys driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,71 @@
|
||||
From 0c39bcd17fa6ce723f56ad3756b4bb36c4690342 Mon Sep 17 00:00:00 2001
|
||||
From: James Liao <jamesjj.liao@mediatek.com>
|
||||
Date: Tue, 5 Jan 2016 14:30:17 +0800
|
||||
Subject: [PATCH 06/53] clk: mediatek: Refine the makefile to support multiple
|
||||
clock drivers
|
||||
|
||||
Add a Kconfig to define clock configuration for each SoC, and
|
||||
modify the Makefile to build drivers that only selected in config.
|
||||
|
||||
Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
|
||||
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
|
||||
---
|
||||
drivers/clk/Kconfig | 1 +
|
||||
drivers/clk/mediatek/Kconfig | 23 +++++++++++++++++++++++
|
||||
drivers/clk/mediatek/Makefile | 6 +++---
|
||||
3 files changed, 27 insertions(+), 3 deletions(-)
|
||||
create mode 100644 drivers/clk/mediatek/Kconfig
|
||||
|
||||
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
|
||||
index c3e3a02..b7a37dc 100644
|
||||
--- a/drivers/clk/Kconfig
|
||||
+++ b/drivers/clk/Kconfig
|
||||
@@ -198,3 +198,4 @@ source "drivers/clk/mvebu/Kconfig"
|
||||
|
||||
source "drivers/clk/samsung/Kconfig"
|
||||
source "drivers/clk/tegra/Kconfig"
|
||||
+source "drivers/clk/mediatek/Kconfig"
|
||||
diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
|
||||
new file mode 100644
|
||||
index 0000000..dc224e6
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/mediatek/Kconfig
|
||||
@@ -0,0 +1,23 @@
|
||||
+#
|
||||
+# MediaTek SoC drivers
|
||||
+#
|
||||
+config COMMON_CLK_MEDIATEK
|
||||
+ bool
|
||||
+ ---help---
|
||||
+ Mediatek SoCs' clock support.
|
||||
+
|
||||
+config COMMON_CLK_MT8135
|
||||
+ bool "Clock driver for Mediatek MT8135"
|
||||
+ depends on COMMON_CLK
|
||||
+ select COMMON_CLK_MEDIATEK
|
||||
+ default ARCH_MEDIATEK
|
||||
+ ---help---
|
||||
+ This driver supports Mediatek MT8135 clocks.
|
||||
+
|
||||
+config COMMON_CLK_MT8173
|
||||
+ bool "Clock driver for Mediatek MT8173"
|
||||
+ depends on COMMON_CLK
|
||||
+ select COMMON_CLK_MEDIATEK
|
||||
+ default ARCH_MEDIATEK
|
||||
+ ---help---
|
||||
+ This driver supports Mediatek MT8173 clocks.
|
||||
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
|
||||
index 95fdfac..32e7222 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 clk-apmixed.o
|
||||
+obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o
|
||||
obj-$(CONFIG_RESET_CONTROLLER) += reset.o
|
||||
-obj-y += clk-mt8135.o
|
||||
-obj-y += clk-mt8173.o
|
||||
+obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
|
||||
+obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,198 @@
|
||||
From d7e96f87f66c571e9f4171ecd89c656fbd2de89b Mon Sep 17 00:00:00 2001
|
||||
From: James Liao <jamesjj.liao@mediatek.com>
|
||||
Date: Tue, 5 Jan 2016 14:30:18 +0800
|
||||
Subject: [PATCH 07/53] dt-bindings: ARM: Mediatek: Document bindings for
|
||||
MT2701
|
||||
|
||||
This patch adds the binding documentation for apmixedsys, bdpsys,
|
||||
ethsys, hifsys, imgsys, infracfg, mmsys, pericfg, topckgen and
|
||||
vdecsys for Mediatek MT2701.
|
||||
|
||||
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
|
||||
---
|
||||
.../bindings/arm/mediatek/mediatek,apmixedsys.txt | 1 +
|
||||
.../bindings/arm/mediatek/mediatek,bdpsys.txt | 22 ++++++++++++++++++++
|
||||
.../bindings/arm/mediatek/mediatek,ethsys.txt | 22 ++++++++++++++++++++
|
||||
.../bindings/arm/mediatek/mediatek,hifsys.txt | 22 ++++++++++++++++++++
|
||||
.../bindings/arm/mediatek/mediatek,imgsys.txt | 1 +
|
||||
.../bindings/arm/mediatek/mediatek,infracfg.txt | 1 +
|
||||
.../bindings/arm/mediatek/mediatek,mmsys.txt | 1 +
|
||||
.../bindings/arm/mediatek/mediatek,pericfg.txt | 1 +
|
||||
.../bindings/arm/mediatek/mediatek,topckgen.txt | 1 +
|
||||
.../bindings/arm/mediatek/mediatek,vdecsys.txt | 1 +
|
||||
10 files changed, 73 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt
|
||||
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
|
||||
create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
|
||||
index 936166f..a701e19 100644
|
||||
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
|
||||
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
|
||||
@@ -6,6 +6,7 @@ The Mediatek apmixedsys controller provides the PLLs to the system.
|
||||
Required Properties:
|
||||
|
||||
- compatible: Should be:
|
||||
+ - "mediatek,mt2701-apmixedsys"
|
||||
- "mediatek,mt8135-apmixedsys"
|
||||
- "mediatek,mt8173-apmixedsys"
|
||||
- #clock-cells: Must be 1
|
||||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt
|
||||
new file mode 100644
|
||||
index 0000000..4137196
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt
|
||||
@@ -0,0 +1,22 @@
|
||||
+Mediatek bdpsys controller
|
||||
+============================
|
||||
+
|
||||
+The Mediatek bdpsys controller provides various clocks to the system.
|
||||
+
|
||||
+Required Properties:
|
||||
+
|
||||
+- compatible: Should be:
|
||||
+ - "mediatek,mt2701-bdpsys", "syscon"
|
||||
+- #clock-cells: Must be 1
|
||||
+
|
||||
+The bdpsys controller uses the common clk binding from
|
||||
+Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+bdpsys: clock-controller@1c000000 {
|
||||
+ compatible = "mediatek,mt2701-bdpsys", "syscon";
|
||||
+ reg = <0 0x1c000000 0 0x1000>;
|
||||
+ #clock-cells = <1>;
|
||||
+};
|
||||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
|
||||
new file mode 100644
|
||||
index 0000000..768f3a5
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
|
||||
@@ -0,0 +1,22 @@
|
||||
+Mediatek ethsys controller
|
||||
+============================
|
||||
+
|
||||
+The Mediatek ethsys controller provides various clocks to the system.
|
||||
+
|
||||
+Required Properties:
|
||||
+
|
||||
+- compatible: Should be:
|
||||
+ - "mediatek,mt2701-ethsys", "syscon"
|
||||
+- #clock-cells: Must be 1
|
||||
+
|
||||
+The ethsys controller uses the common clk binding from
|
||||
+Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+ethsys: clock-controller@1b000000 {
|
||||
+ compatible = "mediatek,mt2701-ethsys", "syscon";
|
||||
+ reg = <0 0x1b000000 0 0x1000>;
|
||||
+ #clock-cells = <1>;
|
||||
+};
|
||||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
|
||||
new file mode 100644
|
||||
index 0000000..b7a39b6
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
|
||||
@@ -0,0 +1,22 @@
|
||||
+Mediatek hifsys controller
|
||||
+============================
|
||||
+
|
||||
+The Mediatek hifsys controller provides various clocks to the system.
|
||||
+
|
||||
+Required Properties:
|
||||
+
|
||||
+- compatible: Should be:
|
||||
+ - "mediatek,mt2701-hifsys", "syscon"
|
||||
+- #clock-cells: Must be 1
|
||||
+
|
||||
+The hifsys controller uses the common clk binding from
|
||||
+Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+hifsys: clock-controller@1a000000 {
|
||||
+ compatible = "mediatek,mt2701-hifsys", "syscon";
|
||||
+ reg = <0 0x1a000000 0 0x1000>;
|
||||
+ #clock-cells = <1>;
|
||||
+};
|
||||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
|
||||
index b1f2ce1..9bda7f7 100644
|
||||
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
|
||||
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
|
||||
@@ -6,6 +6,7 @@ The Mediatek imgsys controller provides various clocks to the system.
|
||||
Required Properties:
|
||||
|
||||
- compatible: Should be:
|
||||
+ - "mediatek,mt2701-imgsys", "syscon"
|
||||
- "mediatek,mt8173-imgsys", "syscon"
|
||||
- #clock-cells: Must be 1
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
|
||||
index f6cd3e4..2f11a69 100644
|
||||
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
|
||||
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
|
||||
@@ -7,6 +7,7 @@ outputs to the system.
|
||||
Required Properties:
|
||||
|
||||
- compatible: Should be:
|
||||
+ - "mediatek,mt2701-infracfg", "syscon"
|
||||
- "mediatek,mt8135-infracfg", "syscon"
|
||||
- "mediatek,mt8173-infracfg", "syscon"
|
||||
- #clock-cells: Must be 1
|
||||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
|
||||
index 4385946..c9d9d43 100644
|
||||
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
|
||||
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
|
||||
@@ -6,6 +6,7 @@ The Mediatek mmsys controller provides various clocks to the system.
|
||||
Required Properties:
|
||||
|
||||
- compatible: Should be:
|
||||
+ - "mediatek,mt2701-mmsys", "syscon"
|
||||
- "mediatek,mt8173-mmsys", "syscon"
|
||||
- #clock-cells: Must be 1
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
|
||||
index f25b854..d3454cd 100644
|
||||
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
|
||||
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
|
||||
@@ -7,6 +7,7 @@ outputs to the system.
|
||||
Required Properties:
|
||||
|
||||
- compatible: Should be:
|
||||
+ - "mediatek,mt2701-pericfg", "syscon"
|
||||
- "mediatek,mt8135-pericfg", "syscon"
|
||||
- "mediatek,mt8173-pericfg", "syscon"
|
||||
- #clock-cells: Must be 1
|
||||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
|
||||
index f9e9179..602e5bc 100644
|
||||
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
|
||||
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
|
||||
@@ -6,6 +6,7 @@ The Mediatek topckgen controller provides various clocks to the system.
|
||||
Required Properties:
|
||||
|
||||
- compatible: Should be:
|
||||
+ - "mediatek,mt2701-topckgen"
|
||||
- "mediatek,mt8135-topckgen"
|
||||
- "mediatek,mt8173-topckgen"
|
||||
- #clock-cells: Must be 1
|
||||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
|
||||
index 1faacf1..f5b1e7d 100644
|
||||
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
|
||||
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
|
||||
@@ -6,6 +6,7 @@ The Mediatek vdecsys controller provides various clocks to the system.
|
||||
Required Properties:
|
||||
|
||||
- compatible: Should be:
|
||||
+ - "mediatek,mt2701-vdecsys", "syscon"
|
||||
- "mediatek,mt8173-vdecsys", "syscon"
|
||||
- #clock-cells: Must be 1
|
||||
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,505 @@
|
||||
From 2fcbc15da2f13164e0851b9c7fae290249f0b44d Mon Sep 17 00:00:00 2001
|
||||
From: Shunli Wang <shunli.wang@mediatek.com>
|
||||
Date: Tue, 5 Jan 2016 14:30:19 +0800
|
||||
Subject: [PATCH 08/53] clk: mediatek: Add dt-bindings for MT2701 clocks
|
||||
|
||||
Add MT2701 clock dt-bindings, include topckgen, apmixedsys,
|
||||
infracfg, pericfg and subsystem clocks.
|
||||
|
||||
Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
|
||||
Signed-off-by: James Liao <jamesjj.liao@mediatek.com>
|
||||
---
|
||||
include/dt-bindings/clock/mt2701-clk.h | 481 ++++++++++++++++++++++++++++++++
|
||||
1 file changed, 481 insertions(+)
|
||||
create mode 100644 include/dt-bindings/clock/mt2701-clk.h
|
||||
|
||||
diff --git a/include/dt-bindings/clock/mt2701-clk.h b/include/dt-bindings/clock/mt2701-clk.h
|
||||
new file mode 100644
|
||||
index 0000000..50972d1
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/clock/mt2701-clk.h
|
||||
@@ -0,0 +1,481 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2014 MediaTek Inc.
|
||||
+ * Author: Shunli Wang <shunli.wang@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _DT_BINDINGS_CLK_MT2701_H
|
||||
+#define _DT_BINDINGS_CLK_MT2701_H
|
||||
+
|
||||
+/* TOPCKGEN */
|
||||
+#define CLK_TOP_SYSPLL 1
|
||||
+#define CLK_TOP_SYSPLL_D2 2
|
||||
+#define CLK_TOP_SYSPLL_D3 3
|
||||
+#define CLK_TOP_SYSPLL_D5 4
|
||||
+#define CLK_TOP_SYSPLL_D7 5
|
||||
+#define CLK_TOP_SYSPLL1_D2 6
|
||||
+#define CLK_TOP_SYSPLL1_D4 7
|
||||
+#define CLK_TOP_SYSPLL1_D8 8
|
||||
+#define CLK_TOP_SYSPLL1_D16 9
|
||||
+#define CLK_TOP_SYSPLL2_D2 10
|
||||
+#define CLK_TOP_SYSPLL2_D4 11
|
||||
+#define CLK_TOP_SYSPLL2_D8 12
|
||||
+#define CLK_TOP_SYSPLL3_D2 13
|
||||
+#define CLK_TOP_SYSPLL3_D4 14
|
||||
+#define CLK_TOP_SYSPLL4_D2 15
|
||||
+#define CLK_TOP_SYSPLL4_D4 16
|
||||
+#define CLK_TOP_UNIVPLL 17
|
||||
+#define CLK_TOP_UNIVPLL_D2 18
|
||||
+#define CLK_TOP_UNIVPLL_D3 19
|
||||
+#define CLK_TOP_UNIVPLL_D5 20
|
||||
+#define CLK_TOP_UNIVPLL_D7 21
|
||||
+#define CLK_TOP_UNIVPLL_D26 22
|
||||
+#define CLK_TOP_UNIVPLL_D52 23
|
||||
+#define CLK_TOP_UNIVPLL_D108 24
|
||||
+#define CLK_TOP_USB_PHY48M 25
|
||||
+#define CLK_TOP_UNIVPLL1_D2 26
|
||||
+#define CLK_TOP_UNIVPLL1_D4 27
|
||||
+#define CLK_TOP_UNIVPLL1_D8 28
|
||||
+#define CLK_TOP_UNIVPLL2_D2 29
|
||||
+#define CLK_TOP_UNIVPLL2_D4 30
|
||||
+#define CLK_TOP_UNIVPLL2_D8 31
|
||||
+#define CLK_TOP_UNIVPLL2_D16 32
|
||||
+#define CLK_TOP_UNIVPLL2_D32 33
|
||||
+#define CLK_TOP_UNIVPLL3_D2 34
|
||||
+#define CLK_TOP_UNIVPLL3_D4 35
|
||||
+#define CLK_TOP_UNIVPLL3_D8 36
|
||||
+#define CLK_TOP_MSDCPLL 37
|
||||
+#define CLK_TOP_MSDCPLL_D2 38
|
||||
+#define CLK_TOP_MSDCPLL_D4 39
|
||||
+#define CLK_TOP_MSDCPLL_D8 40
|
||||
+#define CLK_TOP_MMPLL 41
|
||||
+#define CLK_TOP_MMPLL_D2 42
|
||||
+#define CLK_TOP_DMPLL 43
|
||||
+#define CLK_TOP_DMPLL_D2 44
|
||||
+#define CLK_TOP_DMPLL_D4 45
|
||||
+#define CLK_TOP_DMPLL_X2 46
|
||||
+#define CLK_TOP_TVDPLL 47
|
||||
+#define CLK_TOP_TVDPLL_D2 48
|
||||
+#define CLK_TOP_TVDPLL_D4 49
|
||||
+#define CLK_TOP_TVD2PLL 50
|
||||
+#define CLK_TOP_TVD2PLL_D2 51
|
||||
+#define CLK_TOP_HADDS2PLL_98M 52
|
||||
+#define CLK_TOP_HADDS2PLL_294M 53
|
||||
+#define CLK_TOP_HADDS2_FB 54
|
||||
+#define CLK_TOP_MIPIPLL_D2 55
|
||||
+#define CLK_TOP_MIPIPLL_D4 56
|
||||
+#define CLK_TOP_HDMIPLL 57
|
||||
+#define CLK_TOP_HDMIPLL_D2 58
|
||||
+#define CLK_TOP_HDMIPLL_D3 59
|
||||
+#define CLK_TOP_HDMI_SCL_RX 60
|
||||
+#define CLK_TOP_HDMI_0_PIX340M 61
|
||||
+#define CLK_TOP_HDMI_0_DEEP340M 62
|
||||
+#define CLK_TOP_HDMI_0_PLL340M 63
|
||||
+#define CLK_TOP_AUD1PLL_98M 64
|
||||
+#define CLK_TOP_AUD2PLL_90M 65
|
||||
+#define CLK_TOP_AUDPLL 66
|
||||
+#define CLK_TOP_AUDPLL_D4 67
|
||||
+#define CLK_TOP_AUDPLL_D8 68
|
||||
+#define CLK_TOP_AUDPLL_D16 69
|
||||
+#define CLK_TOP_AUDPLL_D24 70
|
||||
+#define CLK_TOP_ETHPLL_500M 71
|
||||
+#define CLK_TOP_VDECPLL 72
|
||||
+#define CLK_TOP_VENCPLL 73
|
||||
+#define CLK_TOP_MIPIPLL 74
|
||||
+#define CLK_TOP_ARMPLL_1P3G 75
|
||||
+
|
||||
+#define CLK_TOP_MM_SEL 76
|
||||
+#define CLK_TOP_DDRPHYCFG_SEL 77
|
||||
+#define CLK_TOP_MEM_SEL 78
|
||||
+#define CLK_TOP_AXI_SEL 79
|
||||
+#define CLK_TOP_CAMTG_SEL 80
|
||||
+#define CLK_TOP_MFG_SEL 81
|
||||
+#define CLK_TOP_VDEC_SEL 82
|
||||
+#define CLK_TOP_PWM_SEL 83
|
||||
+#define CLK_TOP_MSDC30_0_SEL 84
|
||||
+#define CLK_TOP_USB20_SEL 85
|
||||
+#define CLK_TOP_SPI0_SEL 86
|
||||
+#define CLK_TOP_UART_SEL 87
|
||||
+#define CLK_TOP_AUDINTBUS_SEL 88
|
||||
+#define CLK_TOP_AUDIO_SEL 89
|
||||
+#define CLK_TOP_MSDC30_2_SEL 90
|
||||
+#define CLK_TOP_MSDC30_1_SEL 91
|
||||
+#define CLK_TOP_DPI1_SEL 92
|
||||
+#define CLK_TOP_DPI0_SEL 93
|
||||
+#define CLK_TOP_SCP_SEL 94
|
||||
+#define CLK_TOP_PMICSPI_SEL 95
|
||||
+#define CLK_TOP_APLL_SEL 96
|
||||
+#define CLK_TOP_HDMI_SEL 97
|
||||
+#define CLK_TOP_TVE_SEL 98
|
||||
+#define CLK_TOP_EMMC_HCLK_SEL 99
|
||||
+#define CLK_TOP_NFI2X_SEL 100
|
||||
+#define CLK_TOP_RTC_SEL 101
|
||||
+#define CLK_TOP_OSD_SEL 102
|
||||
+#define CLK_TOP_NR_SEL 103
|
||||
+#define CLK_TOP_DI_SEL 104
|
||||
+#define CLK_TOP_FLASH_SEL 105
|
||||
+#define CLK_TOP_ASM_M_SEL 106
|
||||
+#define CLK_TOP_ASM_I_SEL 107
|
||||
+#define CLK_TOP_INTDIR_SEL 108
|
||||
+#define CLK_TOP_HDMIRX_BIST_SEL 109
|
||||
+#define CLK_TOP_ETHIF_SEL 110
|
||||
+#define CLK_TOP_MS_CARD_SEL 111
|
||||
+#define CLK_TOP_ASM_H_SEL 112
|
||||
+#define CLK_TOP_SPI1_SEL 113
|
||||
+#define CLK_TOP_CMSYS_SEL 114
|
||||
+#define CLK_TOP_MSDC30_3_SEL 115
|
||||
+#define CLK_TOP_HDMIRX26_24_SEL 116
|
||||
+#define CLK_TOP_AUD2DVD_SEL 117
|
||||
+#define CLK_TOP_8BDAC_SEL 118
|
||||
+#define CLK_TOP_SPI2_SEL 119
|
||||
+#define CLK_TOP_AUD_MUX1_SEL 120
|
||||
+#define CLK_TOP_AUD_MUX2_SEL 121
|
||||
+#define CLK_TOP_AUDPLL_MUX_SEL 122
|
||||
+#define CLK_TOP_AUD_K1_SRC_SEL 123
|
||||
+#define CLK_TOP_AUD_K2_SRC_SEL 124
|
||||
+#define CLK_TOP_AUD_K3_SRC_SEL 125
|
||||
+#define CLK_TOP_AUD_K4_SRC_SEL 126
|
||||
+#define CLK_TOP_AUD_K5_SRC_SEL 127
|
||||
+#define CLK_TOP_AUD_K6_SRC_SEL 128
|
||||
+#define CLK_TOP_PADMCLK_SEL 129
|
||||
+#define CLK_TOP_AUD_EXTCK1_DIV 130
|
||||
+#define CLK_TOP_AUD_EXTCK2_DIV 131
|
||||
+#define CLK_TOP_AUD_MUX1_DIV 132
|
||||
+#define CLK_TOP_AUD_MUX2_DIV 133
|
||||
+#define CLK_TOP_AUD_K1_SRC_DIV 134
|
||||
+#define CLK_TOP_AUD_K2_SRC_DIV 135
|
||||
+#define CLK_TOP_AUD_K3_SRC_DIV 136
|
||||
+#define CLK_TOP_AUD_K4_SRC_DIV 137
|
||||
+#define CLK_TOP_AUD_K5_SRC_DIV 138
|
||||
+#define CLK_TOP_AUD_K6_SRC_DIV 139
|
||||
+#define CLK_TOP_AUD_I2S1_MCLK 140
|
||||
+#define CLK_TOP_AUD_I2S2_MCLK 141
|
||||
+#define CLK_TOP_AUD_I2S3_MCLK 142
|
||||
+#define CLK_TOP_AUD_I2S4_MCLK 143
|
||||
+#define CLK_TOP_AUD_I2S5_MCLK 144
|
||||
+#define CLK_TOP_AUD_I2S6_MCLK 145
|
||||
+#define CLK_TOP_AUD_48K_TIMING 146
|
||||
+#define CLK_TOP_AUD_44K_TIMING 147
|
||||
+
|
||||
+#define CLK_TOP_32K_INTERNAL 148
|
||||
+#define CLK_TOP_32K_EXTERNAL 149
|
||||
+#define CLK_TOP_CLK26M_D8 150
|
||||
+#define CLK_TOP_8BDAC 151
|
||||
+#define CLK_TOP_WBG_DIG_416M 152
|
||||
+#define CLK_TOP_DPI 153
|
||||
+#define CLK_TOP_HDMITX_CLKDIG_CTS 154
|
||||
+#define CLK_TOP_NR 155
|
||||
+
|
||||
+/* APMIXEDSYS */
|
||||
+
|
||||
+#define CLK_APMIXED_ARMPLL 1
|
||||
+#define CLK_APMIXED_MAINPLL 2
|
||||
+#define CLK_APMIXED_UNIVPLL 3
|
||||
+#define CLK_APMIXED_MMPLL 4
|
||||
+#define CLK_APMIXED_MSDCPLL 5
|
||||
+#define CLK_APMIXED_TVDPLL 6
|
||||
+#define CLK_APMIXED_AUD1PLL 7
|
||||
+#define CLK_APMIXED_TRGPLL 8
|
||||
+#define CLK_APMIXED_ETHPLL 9
|
||||
+#define CLK_APMIXED_VDECPLL 10
|
||||
+#define CLK_APMIXED_HADDS2PLL 11
|
||||
+#define CLK_APMIXED_AUD2PLL 12
|
||||
+#define CLK_APMIXED_TVD2PLL 13
|
||||
+#define CLK_APMIXED_NR 14
|
||||
+
|
||||
+/* DDRPHY */
|
||||
+
|
||||
+#define CLK_DDRPHY_VENCPLL 1
|
||||
+#define CLK_DDRPHY_NR 2
|
||||
+
|
||||
+/* INFRACFG */
|
||||
+
|
||||
+#define CLK_INFRA_DBG 1
|
||||
+#define CLK_INFRA_SMI 2
|
||||
+#define CLK_INFRA_QAXI_CM4 3
|
||||
+#define CLK_INFRA_AUD_SPLIN_B 4
|
||||
+#define CLK_INFRA_AUDIO 5
|
||||
+#define CLK_INFRA_EFUSE 6
|
||||
+#define CLK_INFRA_L2C_SRAM 7
|
||||
+#define CLK_INFRA_M4U 8
|
||||
+#define CLK_INFRA_CONNMCU 9
|
||||
+#define CLK_INFRA_TRNG 10
|
||||
+#define CLK_INFRA_RAMBUFIF 11
|
||||
+#define CLK_INFRA_CPUM 12
|
||||
+#define CLK_INFRA_KP 13
|
||||
+#define CLK_INFRA_CEC 14
|
||||
+#define CLK_INFRA_IRRX 15
|
||||
+#define CLK_INFRA_PMICSPI 16
|
||||
+#define CLK_INFRA_PMICWRAP 17
|
||||
+#define CLK_INFRA_DDCCI 18
|
||||
+#define CLK_INFRA_CLK_13M 19
|
||||
+#define CLK_INFRA_NR 20
|
||||
+
|
||||
+/* PERICFG */
|
||||
+
|
||||
+#define CLK_PERI_NFI 1
|
||||
+#define CLK_PERI_THERM 2
|
||||
+#define CLK_PERI_PWM1 3
|
||||
+#define CLK_PERI_PWM2 4
|
||||
+#define CLK_PERI_PWM3 5
|
||||
+#define CLK_PERI_PWM4 6
|
||||
+#define CLK_PERI_PWM5 7
|
||||
+#define CLK_PERI_PWM6 8
|
||||
+#define CLK_PERI_PWM7 9
|
||||
+#define CLK_PERI_PWM 10
|
||||
+#define CLK_PERI_USB0 11
|
||||
+#define CLK_PERI_USB1 12
|
||||
+#define CLK_PERI_AP_DMA 13
|
||||
+#define CLK_PERI_MSDC30_0 14
|
||||
+#define CLK_PERI_MSDC30_1 15
|
||||
+#define CLK_PERI_MSDC30_2 16
|
||||
+#define CLK_PERI_MSDC30_3 17
|
||||
+#define CLK_PERI_MSDC50_3 18
|
||||
+#define CLK_PERI_NLI 19
|
||||
+#define CLK_PERI_UART0 20
|
||||
+#define CLK_PERI_UART1 21
|
||||
+#define CLK_PERI_UART2 22
|
||||
+#define CLK_PERI_UART3 23
|
||||
+#define CLK_PERI_BTIF 24
|
||||
+#define CLK_PERI_I2C0 25
|
||||
+#define CLK_PERI_I2C1 26
|
||||
+#define CLK_PERI_I2C2 27
|
||||
+#define CLK_PERI_I2C3 28
|
||||
+#define CLK_PERI_AUXADC 29
|
||||
+#define CLK_PERI_SPI0 30
|
||||
+#define CLK_PERI_ETH 31
|
||||
+#define CLK_PERI_USB0_MCU 32
|
||||
+
|
||||
+#define CLK_PERI_USB1_MCU 33
|
||||
+#define CLK_PERI_USB_SLV 34
|
||||
+#define CLK_PERI_GCPU 35
|
||||
+#define CLK_PERI_NFI_ECC 36
|
||||
+#define CLK_PERI_NFI_PAD 37
|
||||
+#define CLK_PERI_FLASH 38
|
||||
+#define CLK_PERI_HOST89_INT 39
|
||||
+#define CLK_PERI_HOST89_SPI 40
|
||||
+#define CLK_PERI_HOST89_DVD 41
|
||||
+#define CLK_PERI_SPI1 42
|
||||
+#define CLK_PERI_SPI2 43
|
||||
+#define CLK_PERI_FCI 44
|
||||
+
|
||||
+#define CLK_PERI_UART0_SEL 45
|
||||
+#define CLK_PERI_UART1_SEL 46
|
||||
+#define CLK_PERI_UART2_SEL 47
|
||||
+#define CLK_PERI_UART3_SEL 48
|
||||
+#define CLK_PERI_NR 49
|
||||
+
|
||||
+/* AUDIO */
|
||||
+
|
||||
+#define CLK_AUD_AFE 1
|
||||
+#define CLK_AUD_LRCK_DETECT 2
|
||||
+#define CLK_AUD_I2S 3
|
||||
+#define CLK_AUD_APLL_TUNER 4
|
||||
+#define CLK_AUD_HDMI 5
|
||||
+#define CLK_AUD_SPDF 6
|
||||
+#define CLK_AUD_SPDF2 7
|
||||
+#define CLK_AUD_APLL 8
|
||||
+#define CLK_AUD_TML 9
|
||||
+#define CLK_AUD_AHB_IDLE_EXT 10
|
||||
+#define CLK_AUD_AHB_IDLE_INT 11
|
||||
+
|
||||
+#define CLK_AUD_I2SIN1 12
|
||||
+#define CLK_AUD_I2SIN2 13
|
||||
+#define CLK_AUD_I2SIN3 14
|
||||
+#define CLK_AUD_I2SIN4 15
|
||||
+#define CLK_AUD_I2SIN5 16
|
||||
+#define CLK_AUD_I2SIN6 17
|
||||
+#define CLK_AUD_I2SO1 18
|
||||
+#define CLK_AUD_I2SO2 19
|
||||
+#define CLK_AUD_I2SO3 20
|
||||
+#define CLK_AUD_I2SO4 21
|
||||
+#define CLK_AUD_I2SO5 22
|
||||
+#define CLK_AUD_I2SO6 23
|
||||
+#define CLK_AUD_ASRCI1 24
|
||||
+#define CLK_AUD_ASRCI2 25
|
||||
+#define CLK_AUD_ASRCO1 26
|
||||
+#define CLK_AUD_ASRCO2 27
|
||||
+#define CLK_AUD_ASRC11 28
|
||||
+#define CLK_AUD_ASRC12 29
|
||||
+#define CLK_AUD_HDMIRX 30
|
||||
+#define CLK_AUD_INTDIR 31
|
||||
+#define CLK_AUD_A1SYS 32
|
||||
+#define CLK_AUD_A2SYS 33
|
||||
+#define CLK_AUD_AFE_CONN 34
|
||||
+#define CLK_AUD_AFE_PCMIF 35
|
||||
+#define CLK_AUD_AFE_MRGIF 36
|
||||
+
|
||||
+#define CLK_AUD_MMIF_UL1 37
|
||||
+#define CLK_AUD_MMIF_UL2 38
|
||||
+#define CLK_AUD_MMIF_UL3 39
|
||||
+#define CLK_AUD_MMIF_UL4 40
|
||||
+#define CLK_AUD_MMIF_UL5 41
|
||||
+#define CLK_AUD_MMIF_UL6 42
|
||||
+#define CLK_AUD_MMIF_DL1 43
|
||||
+#define CLK_AUD_MMIF_DL2 44
|
||||
+#define CLK_AUD_MMIF_DL3 45
|
||||
+#define CLK_AUD_MMIF_DL4 46
|
||||
+#define CLK_AUD_MMIF_DL5 47
|
||||
+#define CLK_AUD_MMIF_DL6 48
|
||||
+#define CLK_AUD_MMIF_DLMCH 49
|
||||
+#define CLK_AUD_MMIF_ARB1 50
|
||||
+#define CLK_AUD_MMIF_AWB1 51
|
||||
+#define CLK_AUD_MMIF_AWB2 52
|
||||
+#define CLK_AUD_MMIF_DAI 53
|
||||
+
|
||||
+#define CLK_AUD_DMIC1 54
|
||||
+#define CLK_AUD_DMIC2 55
|
||||
+#define CLK_AUD_ASRCI3 56
|
||||
+#define CLK_AUD_ASRCI4 57
|
||||
+#define CLK_AUD_ASRCI5 58
|
||||
+#define CLK_AUD_ASRCI6 59
|
||||
+#define CLK_AUD_ASRCO3 60
|
||||
+#define CLK_AUD_ASRCO4 61
|
||||
+#define CLK_AUD_ASRCO5 62
|
||||
+#define CLK_AUD_ASRCO6 63
|
||||
+#define CLK_AUD_MEM_ASRC1 64
|
||||
+#define CLK_AUD_MEM_ASRC2 65
|
||||
+#define CLK_AUD_MEM_ASRC3 66
|
||||
+#define CLK_AUD_MEM_ASRC4 67
|
||||
+#define CLK_AUD_MEM_ASRC5 68
|
||||
+#define CLK_AUD_DSD_ENC 69
|
||||
+#define CLK_AUD_ASRC_BRG 70
|
||||
+#define CLK_AUD_NR 71
|
||||
+
|
||||
+/* MMSYS */
|
||||
+
|
||||
+#define CLK_MM_SMI_COMMON 1
|
||||
+#define CLK_MM_SMI_LARB0 2
|
||||
+#define CLK_MM_CMDQ 3
|
||||
+#define CLK_MM_MUTEX 4
|
||||
+#define CLK_MM_DISP_COLOR 5
|
||||
+#define CLK_MM_DISP_BLS 6
|
||||
+#define CLK_MM_DISP_WDMA 7
|
||||
+#define CLK_MM_DISP_RDMA 8
|
||||
+#define CLK_MM_DISP_OVL 9
|
||||
+#define CLK_MM_MDP_TDSHP 10
|
||||
+#define CLK_MM_MDP_WROT 11
|
||||
+#define CLK_MM_MDP_WDMA 12
|
||||
+#define CLK_MM_MDP_RSZ1 13
|
||||
+#define CLK_MM_MDP_RSZ0 14
|
||||
+#define CLK_MM_MDP_RDMA 15
|
||||
+#define CLK_MM_MDP_BLS_26M 16
|
||||
+#define CLK_MM_CAM_MDP 17
|
||||
+#define CLK_MM_FAKE_ENG 18
|
||||
+#define CLK_MM_MUTEX_32K 19
|
||||
+#define CLK_MM_DISP_RDMA1 20
|
||||
+#define CLK_MM_DISP_UFOE 21
|
||||
+
|
||||
+#define CLK_MM_DSI_ENGINE 22
|
||||
+#define CLK_MM_DSI_DIG 23
|
||||
+#define CLK_MM_DPI_DIGL 24
|
||||
+#define CLK_MM_DPI_ENGINE 25
|
||||
+#define CLK_MM_DPI1_DIGL 26
|
||||
+#define CLK_MM_DPI1_ENGINE 27
|
||||
+#define CLK_MM_TVE_OUTPUT 28
|
||||
+#define CLK_MM_TVE_INPUT 29
|
||||
+#define CLK_MM_HDMI_PIXEL 30
|
||||
+#define CLK_MM_HDMI_PLL 31
|
||||
+#define CLK_MM_HDMI_AUDIO 32
|
||||
+#define CLK_MM_HDMI_SPDIF 33
|
||||
+#define CLK_MM_TVE_FMM 34
|
||||
+#define CLK_MM_NR 35
|
||||
+
|
||||
+/* IMGSYS */
|
||||
+
|
||||
+#define CLK_IMG_SMI_COMM 1
|
||||
+#define CLK_IMG_RESZ 2
|
||||
+#define CLK_IMG_JPGDEC 3
|
||||
+#define CLK_IMG_VENC_LT 4
|
||||
+#define CLK_IMG_VENC 5
|
||||
+#define CLK_IMG_NR 6
|
||||
+
|
||||
+/* VDEC */
|
||||
+
|
||||
+#define CLK_VDEC_CKGEN 1
|
||||
+#define CLK_VDEC_LARB 2
|
||||
+#define CLK_VDEC_NR 3
|
||||
+
|
||||
+/* HIFSYS */
|
||||
+
|
||||
+#define CLK_HIFSYS_USB0PHY 1
|
||||
+#define CLK_HIFSYS_USB1PHY 2
|
||||
+#define CLK_HIFSYS_PCIE0 3
|
||||
+#define CLK_HIFSYS_PCIE1 4
|
||||
+#define CLK_HIFSYS_PCIE2 5
|
||||
+#define CLK_HIFSYS_NR 6
|
||||
+
|
||||
+/* ETHSYS */
|
||||
+#define CLK_ETHSYS_HSDMA 1
|
||||
+#define CLK_ETHSYS_ESW 2
|
||||
+#define CLK_ETHSYS_GP2 3
|
||||
+#define CLK_ETHSYS_GP1 4
|
||||
+#define CLK_ETHSYS_PCM 5
|
||||
+#define CLK_ETHSYS_GDMA 6
|
||||
+#define CLK_ETHSYS_I2S 7
|
||||
+#define CLK_ETHSYS_CRYPTO 8
|
||||
+#define CLK_ETHSYS_NR 9
|
||||
+
|
||||
+/* BDP */
|
||||
+
|
||||
+#define CLK_BDP_BRG_BA 1
|
||||
+#define CLK_BDP_BRG_DRAM 2
|
||||
+#define CLK_BDP_LARB_DRAM 3
|
||||
+#define CLK_BDP_WR_VDI_PXL 4
|
||||
+#define CLK_BDP_WR_VDI_DRAM 5
|
||||
+#define CLK_BDP_WR_B 6
|
||||
+#define CLK_BDP_DGI_IN 7
|
||||
+#define CLK_BDP_DGI_OUT 8
|
||||
+#define CLK_BDP_FMT_MAST_27 9
|
||||
+#define CLK_BDP_FMT_B 10
|
||||
+#define CLK_BDP_OSD_B 11
|
||||
+#define CLK_BDP_OSD_DRAM 12
|
||||
+#define CLK_BDP_OSD_AGENT 13
|
||||
+#define CLK_BDP_OSD_PXL 14
|
||||
+#define CLK_BDP_RLE_B 15
|
||||
+#define CLK_BDP_RLE_AGENT 16
|
||||
+#define CLK_BDP_RLE_DRAM 17
|
||||
+#define CLK_BDP_F27M 18
|
||||
+#define CLK_BDP_F27M_VDOUT 19
|
||||
+#define CLK_BDP_F27_74_74 20
|
||||
+#define CLK_BDP_F2FS 21
|
||||
+#define CLK_BDP_F2FS74_148 22
|
||||
+#define CLK_BDP_FB 23
|
||||
+#define CLK_BDP_VDO_DRAM 24
|
||||
+#define CLK_BDP_VDO_2FS 25
|
||||
+#define CLK_BDP_VDO_B 26
|
||||
+#define CLK_BDP_WR_DI_PXL 27
|
||||
+#define CLK_BDP_WR_DI_DRAM 28
|
||||
+#define CLK_BDP_WR_DI_B 29
|
||||
+#define CLK_BDP_NR_PXL 30
|
||||
+#define CLK_BDP_NR_DRAM 31
|
||||
+#define CLK_BDP_NR_B 32
|
||||
+
|
||||
+#define CLK_BDP_RX_F 33
|
||||
+#define CLK_BDP_RX_X 34
|
||||
+#define CLK_BDP_RXPDT 35
|
||||
+#define CLK_BDP_RX_CSCL_N 36
|
||||
+#define CLK_BDP_RX_CSCL 37
|
||||
+#define CLK_BDP_RX_DDCSCL_N 38
|
||||
+#define CLK_BDP_RX_DDCSCL 39
|
||||
+#define CLK_BDP_RX_VCO 40
|
||||
+#define CLK_BDP_RX_DP 41
|
||||
+#define CLK_BDP_RX_P 42
|
||||
+#define CLK_BDP_RX_M 43
|
||||
+#define CLK_BDP_RX_PLL 44
|
||||
+#define CLK_BDP_BRG_RT_B 45
|
||||
+#define CLK_BDP_BRG_RT_DRAM 46
|
||||
+#define CLK_BDP_LARBRT_DRAM 47
|
||||
+#define CLK_BDP_TMDS_SYN 48
|
||||
+#define CLK_BDP_HDMI_MON 49
|
||||
+#define CLK_BDP_NR 50
|
||||
+
|
||||
+#endif /* _DT_BINDINGS_CLK_MT2701_H */
|
||||
--
|
||||
1.7.10.4
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,99 @@
|
||||
From 8d134cbe750b59d15c591622d81e2e9daa09f0c4 Mon Sep 17 00:00:00 2001
|
||||
From: Shunli Wang <shunli.wang@mediatek.com>
|
||||
Date: Tue, 5 Jan 2016 14:30:21 +0800
|
||||
Subject: [PATCH 10/53] reset: mediatek: mt2701 reset controller dt-binding
|
||||
file
|
||||
|
||||
Dt-binding file about reset controller is used to provide
|
||||
kinds of definition, which is referenced by dts file and
|
||||
IC-specified reset controller driver code.
|
||||
|
||||
Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
|
||||
---
|
||||
.../dt-bindings/reset-controller/mt2701-resets.h | 74 ++++++++++++++++++++
|
||||
1 file changed, 74 insertions(+)
|
||||
create mode 100644 include/dt-bindings/reset-controller/mt2701-resets.h
|
||||
|
||||
diff --git a/include/dt-bindings/reset-controller/mt2701-resets.h b/include/dt-bindings/reset-controller/mt2701-resets.h
|
||||
new file mode 100644
|
||||
index 0000000..00efeb0
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/reset-controller/mt2701-resets.h
|
||||
@@ -0,0 +1,74 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015 MediaTek, Shunli Wang <shunli.wang@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT2701
|
||||
+#define _DT_BINDINGS_RESET_CONTROLLER_MT2701
|
||||
+
|
||||
+/* INFRACFG resets */
|
||||
+#define MT2701_INFRA_EMI_REG_RST 0
|
||||
+#define MT2701_INFRA_DRAMC0_A0_RST 1
|
||||
+#define MT2701_INFRA_FHCTL_RST 2
|
||||
+#define MT2701_INFRA_APCIRQ_EINT_RST 3
|
||||
+#define MT2701_INFRA_APXGPT_RST 4
|
||||
+#define MT2701_INFRA_SCPSYS_RST 5
|
||||
+#define MT2701_INFRA_KP_RST 6
|
||||
+#define MT2701_INFRA_PMIC_WRAP_RST 7
|
||||
+#define MT2701_INFRA_MIPI_RST 8
|
||||
+#define MT2701_INFRA_IRRX_RST 9
|
||||
+#define MT2701_INFRA_CEC_RST 10
|
||||
+#define MT2701_INFRA_EMI_RST 32
|
||||
+#define MT2701_INFRA_DRAMC0_RST 34
|
||||
+#define MT2701_INFRA_TRNG_RST 37
|
||||
+#define MT2701_INFRA_SYSIRQ_RST 38
|
||||
+
|
||||
+/* PERICFG resets */
|
||||
+#define MT2701_PERI_UART0_SW_RST 0
|
||||
+#define MT2701_PERI_UART1_SW_RST 1
|
||||
+#define MT2701_PERI_UART2_SW_RST 2
|
||||
+#define MT2701_PERI_UART3_SW_RST 3
|
||||
+#define MT2701_PERI_GCPU_SW_RST 5
|
||||
+#define MT2701_PERI_BTIF_SW_RST 6
|
||||
+#define MT2701_PERI_PWM_SW_RST 8
|
||||
+#define MT2701_PERI_AUXADC_SW_RST 10
|
||||
+#define MT2701_PERI_DMA_SW_RST 11
|
||||
+#define MT2701_PERI_NFI_SW_RST 14
|
||||
+#define MT2701_PERI_NLI_SW_RST 15
|
||||
+#define MT2701_PERI_THERM_SW_RST 16
|
||||
+#define MT2701_PERI_MSDC2_SW_RST 17
|
||||
+#define MT2701_PERI_MSDC0_SW_RST 19
|
||||
+#define MT2701_PERI_MSDC1_SW_RST 20
|
||||
+#define MT2701_PERI_I2C0_SW_RST 22
|
||||
+#define MT2701_PERI_I2C1_SW_RST 23
|
||||
+#define MT2701_PERI_I2C2_SW_RST 24
|
||||
+#define MT2701_PERI_I2C3_SW_RST 25
|
||||
+#define MT2701_PERI_USB_SW_RST 28
|
||||
+#define MT2701_PERI_ETH_SW_RST 29
|
||||
+#define MT2701_PERI_SPI0_SW_RST 33
|
||||
+
|
||||
+/* TOPRGU resets */
|
||||
+#define MT2701_TOPRGU_INFRA_RST 0
|
||||
+#define MT2701_TOPRGU_MM_RST 1
|
||||
+#define MT2701_TOPRGU_MFG_RST 2
|
||||
+#define MT2701_TOPRGU_ETHDMA_RST 3
|
||||
+#define MT2701_TOPRGU_VDEC_RST 4
|
||||
+#define MT2701_TOPRGU_VENC_IMG_RST 5
|
||||
+#define MT2701_TOPRGU_DDRPHY_RST 6
|
||||
+#define MT2701_TOPRGU_MD_RST 7
|
||||
+#define MT2701_TOPRGU_INFRA_AO_RST 8
|
||||
+#define MT2701_TOPRGU_CONN_RST 9
|
||||
+#define MT2701_TOPRGU_APMIXED_RST 10
|
||||
+#define MT2701_TOPRGU_HIFSYS_RST 11
|
||||
+#define MT2701_TOPRGU_CONN_MCU_RST 12
|
||||
+#define MT2701_TOPRGU_BDP_DISP_RST 13
|
||||
+
|
||||
+#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT2701 */
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,41 @@
|
||||
From b86d3303db25a8296e4c3de46ee1470f60f71b0c Mon Sep 17 00:00:00 2001
|
||||
From: Shunli Wang <shunli.wang@mediatek.com>
|
||||
Date: Tue, 5 Jan 2016 14:30:22 +0800
|
||||
Subject: [PATCH 11/53] reset: mediatek: mt2701 reset driver
|
||||
|
||||
In infrasys and perifsys, there are many reset
|
||||
control bits for kinds of modules. These bits are
|
||||
used as actual reset controllers to be registered
|
||||
into kernel's generic reset controller framework.
|
||||
|
||||
Signed-off-by: Shunli Wang <shunli.wang@mediatek.com>
|
||||
Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
|
||||
---
|
||||
drivers/clk/mediatek/clk-mt2701.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c
|
||||
index 2f521f4..39472e4 100644
|
||||
--- a/drivers/clk/mediatek/clk-mt2701.c
|
||||
+++ b/drivers/clk/mediatek/clk-mt2701.c
|
||||
@@ -665,6 +665,8 @@ static void __init mtk_infrasys_init(struct device_node *node)
|
||||
if (r)
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
+
|
||||
+ mtk_register_reset_controller(node, 2, 0x30);
|
||||
}
|
||||
CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt2701-infracfg", mtk_infrasys_init);
|
||||
|
||||
@@ -782,6 +784,8 @@ static void __init mtk_pericfg_init(struct device_node *node)
|
||||
if (r)
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
+
|
||||
+ mtk_register_reset_controller(node, 2, 0x0);
|
||||
}
|
||||
CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt2701-pericfg", mtk_pericfg_init);
|
||||
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,34 @@
|
||||
From 3b5df542d52b13a1b20d25311fa4c4029a3b83af Mon Sep 17 00:00:00 2001
|
||||
From: Erin Lo <erin.lo@mediatek.com>
|
||||
Date: Mon, 28 Dec 2015 15:09:02 +0800
|
||||
Subject: [PATCH 12/53] ARM: mediatek: Add MT2701 config options for mediatek
|
||||
SoCs.
|
||||
|
||||
The upcoming MTK pinctrl driver have a big pin table for each SoC
|
||||
and we don't want to bloat the kernel binary if we don't need it.
|
||||
Add config options so we can build for one SoC only. Add MT2701.
|
||||
|
||||
Signed-off-by: Erin Lo <erin.lo@mediatek.com>
|
||||
Acked-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
---
|
||||
arch/arm/mach-mediatek/Kconfig | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
|
||||
index aeece17..37dd438 100644
|
||||
--- a/arch/arm/mach-mediatek/Kconfig
|
||||
+++ b/arch/arm/mach-mediatek/Kconfig
|
||||
@@ -9,6 +9,10 @@ menuconfig ARCH_MEDIATEK
|
||||
|
||||
if ARCH_MEDIATEK
|
||||
|
||||
+config MACH_MT2701
|
||||
+ bool "MediaTek MT2701 SoCs support"
|
||||
+ default ARCH_MEDIATEK
|
||||
+
|
||||
config MACH_MT6589
|
||||
bool "MediaTek MT6589 SoCs support"
|
||||
default ARCH_MEDIATEK
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,36 @@
|
||||
From 1a254735cad9db5c8605c972b0f16b3929dc0d6e Mon Sep 17 00:00:00 2001
|
||||
From: Biao Huang <biao.huang@mediatek.com>
|
||||
Date: Mon, 28 Dec 2015 15:09:03 +0800
|
||||
Subject: [PATCH 13/53] dt-bindings: mediatek: Modify pinctrl bindings for
|
||||
mt2701
|
||||
|
||||
Signed-off-by: Biao Huang <biao.huang@mediatek.com>
|
||||
Acked-by: Rob Herring <robh@kernel.org>
|
||||
Reviewed-by: Mathias Brugger <matthias.bgg@gmail.com>
|
||||
---
|
||||
Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
|
||||
index 0480bc3..9ffb0b2 100644
|
||||
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
|
||||
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
|
||||
@@ -4,10 +4,11 @@ The Mediatek's Pin controller is used to control SoC pins.
|
||||
|
||||
Required properties:
|
||||
- compatible: value should be one of the following.
|
||||
- (a) "mediatek,mt8135-pinctrl", compatible with mt8135 pinctrl.
|
||||
- (b) "mediatek,mt8173-pinctrl", compatible with mt8173 pinctrl.
|
||||
- (c) "mediatek,mt6397-pinctrl", compatible with mt6397 pinctrl.
|
||||
- (d) "mediatek,mt8127-pinctrl", compatible with mt8127 pinctrl.
|
||||
+ "mediatek,mt2701-pinctrl", compatible with mt2701 pinctrl.
|
||||
+ "mediatek,mt6397-pinctrl", compatible with mt6397 pinctrl.
|
||||
+ "mediatek,mt8127-pinctrl", compatible with mt8127 pinctrl.
|
||||
+ "mediatek,mt8135-pinctrl", compatible with mt8135 pinctrl.
|
||||
+ "mediatek,mt8173-pinctrl", compatible with mt8173 pinctrl.
|
||||
- pins-are-numbered: Specify the subnodes are using numbered pinmux to
|
||||
specify pins.
|
||||
- gpio-controller : Marks the device node as a gpio controller.
|
||||
--
|
||||
1.7.10.4
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,555 @@
|
||||
From ddc72b659b3642d0496dee4e1ee39416ca008053 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Thu, 7 Jan 2016 23:42:06 +0100
|
||||
Subject: [PATCH 15/53] dt-bindings: mediatek: Modify pinctrl bindings for
|
||||
mt7623
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
.../devicetree/bindings/pinctrl/pinctrl-mt65xx.txt | 1 +
|
||||
include/dt-bindings/pinctrl/mt7623-pinfunc.h | 521 ++++++++++++++++++++
|
||||
2 files changed, 522 insertions(+)
|
||||
create mode 100644 include/dt-bindings/pinctrl/mt7623-pinfunc.h
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
|
||||
index 9ffb0b2..17631d0 100644
|
||||
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
|
||||
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
|
||||
@@ -6,6 +6,7 @@ Required properties:
|
||||
- compatible: value should be one of the following.
|
||||
"mediatek,mt2701-pinctrl", compatible with mt2701 pinctrl.
|
||||
"mediatek,mt6397-pinctrl", compatible with mt6397 pinctrl.
|
||||
+ "mediatek,mt7623-pinctrl", compatible with mt7623 pinctrl.
|
||||
"mediatek,mt8127-pinctrl", compatible with mt8127 pinctrl.
|
||||
"mediatek,mt8135-pinctrl", compatible with mt8135 pinctrl.
|
||||
"mediatek,mt8173-pinctrl", compatible with mt8173 pinctrl.
|
||||
diff --git a/include/dt-bindings/pinctrl/mt7623-pinfunc.h b/include/dt-bindings/pinctrl/mt7623-pinfunc.h
|
||||
new file mode 100644
|
||||
index 0000000..891b173
|
||||
--- /dev/null
|
||||
+++ b/include/dt-bindings/pinctrl/mt7623-pinfunc.h
|
||||
@@ -0,0 +1,521 @@
|
||||
+#ifndef __DTS_MT7623_PINFUNC_H
|
||||
+#define __DTS_MT7623_PINFUNC_H
|
||||
+
|
||||
+#include <dt-bindings/pinctrl/mt65xx.h>
|
||||
+
|
||||
+#define MT7623_PIN_0_PWRAP_SPI0_MI_FUNC_GPIO0 (MTK_PIN_NO(0) | 0)
|
||||
+#define MT7623_PIN_0_PWRAP_SPI0_MI_FUNC_PWRAP_SPIDO (MTK_PIN_NO(0) | 1)
|
||||
+#define MT7623_PIN_0_PWRAP_SPI0_MI_FUNC_PWRAP_SPIDI (MTK_PIN_NO(0) | 2)
|
||||
+
|
||||
+#define MT7623_PIN_1_PWRAP_SPI0_MO_FUNC_GPIO1 (MTK_PIN_NO(1) | 0)
|
||||
+#define MT7623_PIN_1_PWRAP_SPI0_MO_FUNC_PWRAP_SPIDI (MTK_PIN_NO(1) | 1)
|
||||
+#define MT7623_PIN_1_PWRAP_SPI0_MO_FUNC_PWRAP_SPIDO (MTK_PIN_NO(1) | 2)
|
||||
+
|
||||
+#define MT7623_PIN_2_PWRAP_INT_FUNC_GPIO2 (MTK_PIN_NO(2) | 0)
|
||||
+#define MT7623_PIN_2_PWRAP_INT_FUNC_PWRAP_INT (MTK_PIN_NO(2) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_3_PWRAP_SPI0_CK_FUNC_GPIO3 (MTK_PIN_NO(3) | 0)
|
||||
+#define MT7623_PIN_3_PWRAP_SPI0_CK_FUNC_PWRAP_SPICK_I (MTK_PIN_NO(3) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_4_PWRAP_SPI0_CSN_FUNC_GPIO4 (MTK_PIN_NO(4) | 0)
|
||||
+#define MT7623_PIN_4_PWRAP_SPI0_CSN_FUNC_PWRAP_SPICS_B_I (MTK_PIN_NO(4) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_5_PWRAP_SPI0_CK2_FUNC_GPIO5 (MTK_PIN_NO(5) | 0)
|
||||
+#define MT7623_PIN_5_PWRAP_SPI0_CK2_FUNC_PWRAP_SPICK2_I (MTK_PIN_NO(5) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_6_PWRAP_SPI0_CSN2_FUNC_GPIO6 (MTK_PIN_NO(6) | 0)
|
||||
+#define MT7623_PIN_6_PWRAP_SPI0_CSN2_FUNC_PWRAP_SPICS2_B_I (MTK_PIN_NO(6) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_7_SPI1_CSN_FUNC_GPIO7 (MTK_PIN_NO(7) | 0)
|
||||
+#define MT7623_PIN_7_SPI1_CSN_FUNC_SPI1_CS (MTK_PIN_NO(7) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_8_SPI1_MI_FUNC_GPIO8 (MTK_PIN_NO(8) | 0)
|
||||
+#define MT7623_PIN_8_SPI1_MI_FUNC_SPI1_MI (MTK_PIN_NO(8) | 1)
|
||||
+#define MT7623_PIN_8_SPI1_MI_FUNC_SPI1_MO (MTK_PIN_NO(8) | 2)
|
||||
+
|
||||
+#define MT7623_PIN_9_SPI1_MO_FUNC_GPIO9 (MTK_PIN_NO(9) | 0)
|
||||
+#define MT7623_PIN_9_SPI1_MO_FUNC_SPI1_MO (MTK_PIN_NO(9) | 1)
|
||||
+#define MT7623_PIN_9_SPI1_MO_FUNC_SPI1_MI (MTK_PIN_NO(9) | 2)
|
||||
+
|
||||
+#define MT7623_PIN_10_RTC32K_CK_FUNC_GPIO10 (MTK_PIN_NO(10) | 0)
|
||||
+#define MT7623_PIN_10_RTC32K_CK_FUNC_RTC32K_CK (MTK_PIN_NO(10) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_11_WATCHDOG_FUNC_GPIO11 (MTK_PIN_NO(11) | 0)
|
||||
+#define MT7623_PIN_11_WATCHDOG_FUNC_WATCHDOG (MTK_PIN_NO(11) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_12_SRCLKENA_FUNC_GPIO12 (MTK_PIN_NO(12) | 0)
|
||||
+#define MT7623_PIN_12_SRCLKENA_FUNC_SRCLKENA (MTK_PIN_NO(12) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_13_SRCLKENAI_FUNC_GPIO13 (MTK_PIN_NO(13) | 0)
|
||||
+#define MT7623_PIN_13_SRCLKENAI_FUNC_SRCLKENAI (MTK_PIN_NO(13) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_14_GPIO14_FUNC_GPIO14 (MTK_PIN_NO(14) | 0)
|
||||
+#define MT7623_PIN_14_GPIO14_FUNC_URXD2 (MTK_PIN_NO(14) | 1)
|
||||
+#define MT7623_PIN_14_GPIO14_FUNC_UTXD2 (MTK_PIN_NO(14) | 2)
|
||||
+
|
||||
+#define MT7623_PIN_15_GPIO15_FUNC_GPIO15 (MTK_PIN_NO(15) | 0)
|
||||
+#define MT7623_PIN_15_GPIO15_FUNC_UTXD2 (MTK_PIN_NO(15) | 1)
|
||||
+#define MT7623_PIN_15_GPIO15_FUNC_URXD2 (MTK_PIN_NO(15) | 2)
|
||||
+
|
||||
+#define MT7623_PIN_18_PCM_CLK_FUNC_GPIO18 (MTK_PIN_NO(18) | 0)
|
||||
+#define MT7623_PIN_18_PCM_CLK_FUNC_PCM_CLK0 (MTK_PIN_NO(18) | 1)
|
||||
+#define MT7623_PIN_18_PCM_CLK_FUNC_AP_PCM_CLKO (MTK_PIN_NO(18) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_19_PCM_SYNC_FUNC_GPIO19 (MTK_PIN_NO(19) | 0)
|
||||
+#define MT7623_PIN_19_PCM_SYNC_FUNC_PCM_SYNC (MTK_PIN_NO(19) | 1)
|
||||
+#define MT7623_PIN_19_PCM_SYNC_FUNC_AP_PCM_SYNC (MTK_PIN_NO(19) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_20_PCM_RX_FUNC_GPIO20 (MTK_PIN_NO(20) | 0)
|
||||
+#define MT7623_PIN_20_PCM_RX_FUNC_PCM_RX (MTK_PIN_NO(20) | 1)
|
||||
+#define MT7623_PIN_20_PCM_RX_FUNC_PCM_TX (MTK_PIN_NO(20) | 4)
|
||||
+#define MT7623_PIN_20_PCM_RX_FUNC_AP_PCM_RX (MTK_PIN_NO(20) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_21_PCM_TX_FUNC_GPIO21 (MTK_PIN_NO(21) | 0)
|
||||
+#define MT7623_PIN_21_PCM_TX_FUNC_PCM_TX (MTK_PIN_NO(21) | 1)
|
||||
+#define MT7623_PIN_21_PCM_TX_FUNC_PCM_RX (MTK_PIN_NO(21) | 4)
|
||||
+#define MT7623_PIN_21_PCM_TX_FUNC_AP_PCM_TX (MTK_PIN_NO(21) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_22_EINT0_FUNC_GPIO22 (MTK_PIN_NO(22) | 0)
|
||||
+#define MT7623_PIN_22_EINT0_FUNC_UCTS0 (MTK_PIN_NO(22) | 1)
|
||||
+#define MT7623_PIN_22_EINT0_FUNC_PCIE0_PERST_N (MTK_PIN_NO(22) | 2)
|
||||
+
|
||||
+#define MT7623_PIN_23_EINT1_FUNC_GPIO23 (MTK_PIN_NO(23) | 0)
|
||||
+#define MT7623_PIN_23_EINT1_FUNC_URTS0 (MTK_PIN_NO(23) | 1)
|
||||
+#define MT7623_PIN_23_EINT1_FUNC_PCIE1_PERST_N (MTK_PIN_NO(23) | 2)
|
||||
+
|
||||
+#define MT7623_PIN_24_EINT2_FUNC_GPIO24 (MTK_PIN_NO(24) | 0)
|
||||
+#define MT7623_PIN_24_EINT2_FUNC_UCTS1 (MTK_PIN_NO(24) | 1)
|
||||
+#define MT7623_PIN_24_EINT2_FUNC_PCIE2_PERST_N (MTK_PIN_NO(24) | 2)
|
||||
+
|
||||
+#define MT7623_PIN_25_EINT3_FUNC_GPIO25 (MTK_PIN_NO(25) | 0)
|
||||
+#define MT7623_PIN_25_EINT3_FUNC_URTS1 (MTK_PIN_NO(25) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_26_EINT4_FUNC_GPIO26 (MTK_PIN_NO(26) | 0)
|
||||
+#define MT7623_PIN_26_EINT4_FUNC_UCTS3 (MTK_PIN_NO(26) | 1)
|
||||
+#define MT7623_PIN_26_EINT4_FUNC_PCIE2_WAKE_N (MTK_PIN_NO(26) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_27_EINT5_FUNC_GPIO27 (MTK_PIN_NO(27) | 0)
|
||||
+#define MT7623_PIN_27_EINT5_FUNC_URTS3 (MTK_PIN_NO(27) | 1)
|
||||
+#define MT7623_PIN_27_EINT5_FUNC_PCIE1_WAKE_N (MTK_PIN_NO(27) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_28_EINT6_FUNC_GPIO28 (MTK_PIN_NO(28) | 0)
|
||||
+#define MT7623_PIN_28_EINT6_FUNC_DRV_VBUS (MTK_PIN_NO(28) | 1)
|
||||
+#define MT7623_PIN_28_EINT6_FUNC_PCIE0_WAKE_N (MTK_PIN_NO(28) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_29_EINT7_FUNC_GPIO29 (MTK_PIN_NO(29) | 0)
|
||||
+#define MT7623_PIN_29_EINT7_FUNC_IDDIG (MTK_PIN_NO(29) | 1)
|
||||
+#define MT7623_PIN_29_EINT7_FUNC_MSDC1_WP (MTK_PIN_NO(29) | 2)
|
||||
+#define MT7623_PIN_29_EINT7_FUNC_PCIE2_PERST_N (MTK_PIN_NO(29) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_33_I2S1_DATA_FUNC_GPIO33 (MTK_PIN_NO(33) | 0)
|
||||
+#define MT7623_PIN_33_I2S1_DATA_FUNC_I2S1_DATA (MTK_PIN_NO(33) | 1)
|
||||
+#define MT7623_PIN_33_I2S1_DATA_FUNC_PCM_TX (MTK_PIN_NO(33) | 3)
|
||||
+#define MT7623_PIN_33_I2S1_DATA_FUNC_AP_PCM_TX (MTK_PIN_NO(33) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_34_I2S1_DATA_IN_FUNC_GPIO34 (MTK_PIN_NO(34) | 0)
|
||||
+#define MT7623_PIN_34_I2S1_DATA_IN_FUNC_I2S1_DATA_IN (MTK_PIN_NO(34) | 1)
|
||||
+#define MT7623_PIN_34_I2S1_DATA_IN_FUNC_PCM_RX (MTK_PIN_NO(34) | 3)
|
||||
+#define MT7623_PIN_34_I2S1_DATA_IN_FUNC_AP_PCM_RX (MTK_PIN_NO(34) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_35_I2S1_BCK_FUNC_GPIO35 (MTK_PIN_NO(35) | 0)
|
||||
+#define MT7623_PIN_35_I2S1_BCK_FUNC_I2S1_BCK (MTK_PIN_NO(35) | 1)
|
||||
+#define MT7623_PIN_35_I2S1_BCK_FUNC_PCM_CLK0 (MTK_PIN_NO(35) | 3)
|
||||
+#define MT7623_PIN_35_I2S1_BCK_FUNC_AP_PCM_CLKO (MTK_PIN_NO(35) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_36_I2S1_LRCK_FUNC_GPIO36 (MTK_PIN_NO(36) | 0)
|
||||
+#define MT7623_PIN_36_I2S1_LRCK_FUNC_I2S1_LRCK (MTK_PIN_NO(36) | 1)
|
||||
+#define MT7623_PIN_36_I2S1_LRCK_FUNC_PCM_SYNC (MTK_PIN_NO(36) | 3)
|
||||
+#define MT7623_PIN_36_I2S1_LRCK_FUNC_AP_PCM_SYNC (MTK_PIN_NO(36) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_37_I2S1_MCLK_FUNC_GPIO37 (MTK_PIN_NO(37) | 0)
|
||||
+#define MT7623_PIN_37_I2S1_MCLK_FUNC_I2S1_MCLK (MTK_PIN_NO(37) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_39_JTMS_FUNC_GPIO39 (MTK_PIN_NO(39) | 0)
|
||||
+#define MT7623_PIN_39_JTMS_FUNC_JTMS (MTK_PIN_NO(39) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_40_JTCK_FUNC_GPIO40 (MTK_PIN_NO(40) | 0)
|
||||
+#define MT7623_PIN_40_JTCK_FUNC_JTCK (MTK_PIN_NO(40) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_41_JTDI_FUNC_GPIO41 (MTK_PIN_NO(41) | 0)
|
||||
+#define MT7623_PIN_41_JTDI_FUNC_JTDI (MTK_PIN_NO(41) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_42_JTDO_FUNC_GPIO42 (MTK_PIN_NO(42) | 0)
|
||||
+#define MT7623_PIN_42_JTDO_FUNC_JTDO (MTK_PIN_NO(42) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_43_NCLE_FUNC_GPIO43 (MTK_PIN_NO(43) | 0)
|
||||
+#define MT7623_PIN_43_NCLE_FUNC_NCLE (MTK_PIN_NO(43) | 1)
|
||||
+#define MT7623_PIN_43_NCLE_FUNC_EXT_XCS2 (MTK_PIN_NO(43) | 2)
|
||||
+
|
||||
+#define MT7623_PIN_44_NCEB1_FUNC_GPIO44 (MTK_PIN_NO(44) | 0)
|
||||
+#define MT7623_PIN_44_NCEB1_FUNC_NCEB1 (MTK_PIN_NO(44) | 1)
|
||||
+#define MT7623_PIN_44_NCEB1_FUNC_IDDIG (MTK_PIN_NO(44) | 2)
|
||||
+
|
||||
+#define MT7623_PIN_45_NCEB0_FUNC_GPIO45 (MTK_PIN_NO(45) | 0)
|
||||
+#define MT7623_PIN_45_NCEB0_FUNC_NCEB0 (MTK_PIN_NO(45) | 1)
|
||||
+#define MT7623_PIN_45_NCEB0_FUNC_DRV_VBUS (MTK_PIN_NO(45) | 2)
|
||||
+
|
||||
+#define MT7623_PIN_46_IR_FUNC_GPIO46 (MTK_PIN_NO(46) | 0)
|
||||
+#define MT7623_PIN_46_IR_FUNC_IR (MTK_PIN_NO(46) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_47_NREB_FUNC_GPIO47 (MTK_PIN_NO(47) | 0)
|
||||
+#define MT7623_PIN_47_NREB_FUNC_NREB (MTK_PIN_NO(47) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_48_NRNB_FUNC_GPIO48 (MTK_PIN_NO(48) | 0)
|
||||
+#define MT7623_PIN_48_NRNB_FUNC_NRNB (MTK_PIN_NO(48) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_49_I2S0_DATA_FUNC_GPIO49 (MTK_PIN_NO(49) | 0)
|
||||
+#define MT7623_PIN_49_I2S0_DATA_FUNC_I2S0_DATA (MTK_PIN_NO(49) | 1)
|
||||
+#define MT7623_PIN_49_I2S0_DATA_FUNC_PCM_TX (MTK_PIN_NO(49) | 3)
|
||||
+#define MT7623_PIN_49_I2S0_DATA_FUNC_AP_I2S_DO (MTK_PIN_NO(49) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_53_SPI0_CSN_FUNC_GPIO53 (MTK_PIN_NO(53) | 0)
|
||||
+#define MT7623_PIN_53_SPI0_CSN_FUNC_SPI0_CS (MTK_PIN_NO(53) | 1)
|
||||
+#define MT7623_PIN_53_SPI0_CSN_FUNC_PWM1 (MTK_PIN_NO(53) | 5)
|
||||
+
|
||||
+#define MT7623_PIN_54_SPI0_CK_FUNC_GPIO54 (MTK_PIN_NO(54) | 0)
|
||||
+#define MT7623_PIN_54_SPI0_CK_FUNC_SPI0_CK (MTK_PIN_NO(54) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_55_SPI0_MI_FUNC_GPIO55 (MTK_PIN_NO(55) | 0)
|
||||
+#define MT7623_PIN_55_SPI0_MI_FUNC_SPI0_MI (MTK_PIN_NO(55) | 1)
|
||||
+#define MT7623_PIN_55_SPI0_MI_FUNC_SPI0_MO (MTK_PIN_NO(55) | 2)
|
||||
+#define MT7623_PIN_55_SPI0_MI_FUNC_MSDC1_WP (MTK_PIN_NO(55) | 3)
|
||||
+#define MT7623_PIN_55_SPI0_MI_FUNC_PWM2 (MTK_PIN_NO(55) | 5)
|
||||
+
|
||||
+#define MT7623_PIN_56_SPI0_MO_FUNC_GPIO56 (MTK_PIN_NO(56) | 0)
|
||||
+#define MT7623_PIN_56_SPI0_MO_FUNC_SPI0_MO (MTK_PIN_NO(56) | 1)
|
||||
+#define MT7623_PIN_56_SPI0_MO_FUNC_SPI0_MI (MTK_PIN_NO(56) | 2)
|
||||
+
|
||||
+#define MT7623_PIN_60_WB_RSTB_FUNC_GPIO60 (MTK_PIN_NO(60) | 0)
|
||||
+#define MT7623_PIN_60_WB_RSTB_FUNC_WB_RSTB (MTK_PIN_NO(60) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_61_GPIO61_FUNC_GPIO61 (MTK_PIN_NO(61) | 0)
|
||||
+#define MT7623_PIN_61_GPIO61_FUNC_TEST_FD (MTK_PIN_NO(61) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_62_GPIO62_FUNC_GPIO62 (MTK_PIN_NO(62) | 0)
|
||||
+#define MT7623_PIN_62_GPIO62_FUNC_TEST_FC (MTK_PIN_NO(62) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_63_WB_SCLK_FUNC_GPIO63 (MTK_PIN_NO(63) | 0)
|
||||
+#define MT7623_PIN_63_WB_SCLK_FUNC_WB_SCLK (MTK_PIN_NO(63) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_64_WB_SDATA_FUNC_GPIO64 (MTK_PIN_NO(64) | 0)
|
||||
+#define MT7623_PIN_64_WB_SDATA_FUNC_WB_SDATA (MTK_PIN_NO(64) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_65_WB_SEN_FUNC_GPIO65 (MTK_PIN_NO(65) | 0)
|
||||
+#define MT7623_PIN_65_WB_SEN_FUNC_WB_SEN (MTK_PIN_NO(65) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_66_WB_CRTL0_FUNC_GPIO66 (MTK_PIN_NO(66) | 0)
|
||||
+#define MT7623_PIN_66_WB_CRTL0_FUNC_WB_CRTL0 (MTK_PIN_NO(66) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_67_WB_CRTL1_FUNC_GPIO67 (MTK_PIN_NO(67) | 0)
|
||||
+#define MT7623_PIN_67_WB_CRTL1_FUNC_WB_CRTL1 (MTK_PIN_NO(67) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_68_WB_CRTL2_FUNC_GPIO68 (MTK_PIN_NO(68) | 0)
|
||||
+#define MT7623_PIN_68_WB_CRTL2_FUNC_WB_CRTL2 (MTK_PIN_NO(68) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_69_WB_CRTL3_FUNC_GPIO69 (MTK_PIN_NO(69) | 0)
|
||||
+#define MT7623_PIN_69_WB_CRTL3_FUNC_WB_CRTL3 (MTK_PIN_NO(69) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_70_WB_CRTL4_FUNC_GPIO70 (MTK_PIN_NO(70) | 0)
|
||||
+#define MT7623_PIN_70_WB_CRTL4_FUNC_WB_CRTL4 (MTK_PIN_NO(70) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_71_WB_CRTL5_FUNC_GPIO71 (MTK_PIN_NO(71) | 0)
|
||||
+#define MT7623_PIN_71_WB_CRTL5_FUNC_WB_CRTL5 (MTK_PIN_NO(71) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_GPIO72 (MTK_PIN_NO(72) | 0)
|
||||
+#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_I2S0_DATA_IN (MTK_PIN_NO(72) | 1)
|
||||
+#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_PCM_RX (MTK_PIN_NO(72) | 3)
|
||||
+#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_PWM0 (MTK_PIN_NO(72) | 4)
|
||||
+#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_DISP_PWM (MTK_PIN_NO(72) | 5)
|
||||
+#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_AP_I2S_DI (MTK_PIN_NO(72) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_73_I2S0_LRCK_FUNC_GPIO73 (MTK_PIN_NO(73) | 0)
|
||||
+#define MT7623_PIN_73_I2S0_LRCK_FUNC_I2S0_LRCK (MTK_PIN_NO(73) | 1)
|
||||
+#define MT7623_PIN_73_I2S0_LRCK_FUNC_PCM_SYNC (MTK_PIN_NO(73) | 3)
|
||||
+#define MT7623_PIN_73_I2S0_LRCK_FUNC_AP_I2S_LRCK (MTK_PIN_NO(73) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_74_I2S0_BCK_FUNC_GPIO74 (MTK_PIN_NO(74) | 0)
|
||||
+#define MT7623_PIN_74_I2S0_BCK_FUNC_I2S0_BCK (MTK_PIN_NO(74) | 1)
|
||||
+#define MT7623_PIN_74_I2S0_BCK_FUNC_PCM_CLK0 (MTK_PIN_NO(74) | 3)
|
||||
+#define MT7623_PIN_74_I2S0_BCK_FUNC_AP_I2S_BCK (MTK_PIN_NO(74) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_75_SDA0_FUNC_GPIO75 (MTK_PIN_NO(75) | 0)
|
||||
+#define MT7623_PIN_75_SDA0_FUNC_SDA0 (MTK_PIN_NO(75) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_76_SCL0_FUNC_GPIO76 (MTK_PIN_NO(76) | 0)
|
||||
+#define MT7623_PIN_76_SCL0_FUNC_SCL0 (MTK_PIN_NO(76) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_83_LCM_RST_FUNC_GPIO83 (MTK_PIN_NO(83) | 0)
|
||||
+#define MT7623_PIN_83_LCM_RST_FUNC_LCM_RST (MTK_PIN_NO(83) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_84_DSI_TE_FUNC_GPIO84 (MTK_PIN_NO(84) | 0)
|
||||
+#define MT7623_PIN_84_DSI_TE_FUNC_DSI_TE (MTK_PIN_NO(84) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_95_MIPI_TCN_FUNC_GPIO95 (MTK_PIN_NO(95) | 0)
|
||||
+#define MT7623_PIN_95_MIPI_TCN_FUNC_TCN (MTK_PIN_NO(95) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_96_MIPI_TCP_FUNC_GPIO96 (MTK_PIN_NO(96) | 0)
|
||||
+#define MT7623_PIN_96_MIPI_TCP_FUNC_TCP (MTK_PIN_NO(96) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_97_MIPI_TDN1_FUNC_GPIO97 (MTK_PIN_NO(97) | 0)
|
||||
+#define MT7623_PIN_97_MIPI_TDN1_FUNC_TDN1 (MTK_PIN_NO(97) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_98_MIPI_TDP1_FUNC_GPIO98 (MTK_PIN_NO(98) | 0)
|
||||
+#define MT7623_PIN_98_MIPI_TDP1_FUNC_TDP1 (MTK_PIN_NO(98) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_99_MIPI_TDN0_FUNC_GPIO99 (MTK_PIN_NO(99) | 0)
|
||||
+#define MT7623_PIN_99_MIPI_TDN0_FUNC_TDN0 (MTK_PIN_NO(99) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_100_MIPI_TDP0_FUNC_GPIO100 (MTK_PIN_NO(100) | 0)
|
||||
+#define MT7623_PIN_100_MIPI_TDP0_FUNC_TDP0 (MTK_PIN_NO(100) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_105_MSDC1_CMD_FUNC_GPIO105 (MTK_PIN_NO(105) | 0)
|
||||
+#define MT7623_PIN_105_MSDC1_CMD_FUNC_MSDC1_CMD (MTK_PIN_NO(105) | 1)
|
||||
+#define MT7623_PIN_105_MSDC1_CMD_FUNC_SDA1 (MTK_PIN_NO(105) | 3)
|
||||
+#define MT7623_PIN_105_MSDC1_CMD_FUNC_I2SOUT_BCK (MTK_PIN_NO(105) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_106_MSDC1_CLK_FUNC_GPIO106 (MTK_PIN_NO(106) | 0)
|
||||
+#define MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK (MTK_PIN_NO(106) | 1)
|
||||
+#define MT7623_PIN_106_MSDC1_CLK_FUNC_SCL1 (MTK_PIN_NO(106) | 3)
|
||||
+#define MT7623_PIN_106_MSDC1_CLK_FUNC_I2SOUT_LRCK (MTK_PIN_NO(106) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_107_MSDC1_DAT0_FUNC_GPIO107 (MTK_PIN_NO(107) | 0)
|
||||
+#define MT7623_PIN_107_MSDC1_DAT0_FUNC_MSDC1_DAT0 (MTK_PIN_NO(107) | 1)
|
||||
+#define MT7623_PIN_107_MSDC1_DAT0_FUNC_UTXD0 (MTK_PIN_NO(107) | 5)
|
||||
+#define MT7623_PIN_107_MSDC1_DAT0_FUNC_I2SOUT_DATA_OUT (MTK_PIN_NO(107) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_108_MSDC1_DAT1_FUNC_GPIO108 (MTK_PIN_NO(108) | 0)
|
||||
+#define MT7623_PIN_108_MSDC1_DAT1_FUNC_MSDC1_DAT1 (MTK_PIN_NO(108) | 1)
|
||||
+#define MT7623_PIN_108_MSDC1_DAT1_FUNC_PWM0 (MTK_PIN_NO(108) | 3)
|
||||
+#define MT7623_PIN_108_MSDC1_DAT1_FUNC_URXD0 (MTK_PIN_NO(108) | 5)
|
||||
+#define MT7623_PIN_108_MSDC1_DAT1_FUNC_PWM1 (MTK_PIN_NO(108) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_109_MSDC1_DAT2_FUNC_GPIO109 (MTK_PIN_NO(109) | 0)
|
||||
+#define MT7623_PIN_109_MSDC1_DAT2_FUNC_MSDC1_DAT2 (MTK_PIN_NO(109) | 1)
|
||||
+#define MT7623_PIN_109_MSDC1_DAT2_FUNC_SDA2 (MTK_PIN_NO(109) | 3)
|
||||
+#define MT7623_PIN_109_MSDC1_DAT2_FUNC_UTXD1 (MTK_PIN_NO(109) | 5)
|
||||
+#define MT7623_PIN_109_MSDC1_DAT2_FUNC_PWM2 (MTK_PIN_NO(109) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_110_MSDC1_DAT3_FUNC_GPIO110 (MTK_PIN_NO(110) | 0)
|
||||
+#define MT7623_PIN_110_MSDC1_DAT3_FUNC_MSDC1_DAT3 (MTK_PIN_NO(110) | 1)
|
||||
+#define MT7623_PIN_110_MSDC1_DAT3_FUNC_SCL2 (MTK_PIN_NO(110) | 3)
|
||||
+#define MT7623_PIN_110_MSDC1_DAT3_FUNC_URXD1 (MTK_PIN_NO(110) | 5)
|
||||
+#define MT7623_PIN_110_MSDC1_DAT3_FUNC_PWM3 (MTK_PIN_NO(110) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_111_MSDC0_DAT7_FUNC_GPIO111 (MTK_PIN_NO(111) | 0)
|
||||
+#define MT7623_PIN_111_MSDC0_DAT7_FUNC_MSDC0_DAT7 (MTK_PIN_NO(111) | 1)
|
||||
+#define MT7623_PIN_111_MSDC0_DAT7_FUNC_NLD7 (MTK_PIN_NO(111) | 4)
|
||||
+
|
||||
+#define MT7623_PIN_112_MSDC0_DAT6_FUNC_GPIO112 (MTK_PIN_NO(112) | 0)
|
||||
+#define MT7623_PIN_112_MSDC0_DAT6_FUNC_MSDC0_DAT6 (MTK_PIN_NO(112) | 1)
|
||||
+#define MT7623_PIN_112_MSDC0_DAT6_FUNC_NLD6 (MTK_PIN_NO(112) | 4)
|
||||
+
|
||||
+#define MT7623_PIN_113_MSDC0_DAT5_FUNC_GPIO113 (MTK_PIN_NO(113) | 0)
|
||||
+#define MT7623_PIN_113_MSDC0_DAT5_FUNC_MSDC0_DAT5 (MTK_PIN_NO(113) | 1)
|
||||
+#define MT7623_PIN_113_MSDC0_DAT5_FUNC_NLD5 (MTK_PIN_NO(113) | 4)
|
||||
+
|
||||
+#define MT7623_PIN_114_MSDC0_DAT4_FUNC_GPIO114 (MTK_PIN_NO(114) | 0)
|
||||
+#define MT7623_PIN_114_MSDC0_DAT4_FUNC_MSDC0_DAT4 (MTK_PIN_NO(114) | 1)
|
||||
+#define MT7623_PIN_114_MSDC0_DAT4_FUNC_NLD4 (MTK_PIN_NO(114) | 4)
|
||||
+
|
||||
+#define MT7623_PIN_115_MSDC0_RSTB_FUNC_GPIO115 (MTK_PIN_NO(115) | 0)
|
||||
+#define MT7623_PIN_115_MSDC0_RSTB_FUNC_MSDC0_RSTB (MTK_PIN_NO(115) | 1)
|
||||
+#define MT7623_PIN_115_MSDC0_RSTB_FUNC_NLD8 (MTK_PIN_NO(115) | 4)
|
||||
+
|
||||
+#define MT7623_PIN_116_MSDC0_CMD_FUNC_GPIO116 (MTK_PIN_NO(116) | 0)
|
||||
+#define MT7623_PIN_116_MSDC0_CMD_FUNC_MSDC0_CMD (MTK_PIN_NO(116) | 1)
|
||||
+#define MT7623_PIN_116_MSDC0_CMD_FUNC_NALE (MTK_PIN_NO(116) | 4)
|
||||
+
|
||||
+#define MT7623_PIN_117_MSDC0_CLK_FUNC_GPIO117 (MTK_PIN_NO(117) | 0)
|
||||
+#define MT7623_PIN_117_MSDC0_CLK_FUNC_MSDC0_CLK (MTK_PIN_NO(117) | 1)
|
||||
+#define MT7623_PIN_117_MSDC0_CLK_FUNC_NWEB (MTK_PIN_NO(117) | 4)
|
||||
+
|
||||
+#define MT7623_PIN_118_MSDC0_DAT3_FUNC_GPIO118 (MTK_PIN_NO(118) | 0)
|
||||
+#define MT7623_PIN_118_MSDC0_DAT3_FUNC_MSDC0_DAT3 (MTK_PIN_NO(118) | 1)
|
||||
+#define MT7623_PIN_118_MSDC0_DAT3_FUNC_NLD3 (MTK_PIN_NO(118) | 4)
|
||||
+
|
||||
+#define MT7623_PIN_119_MSDC0_DAT2_FUNC_GPIO119 (MTK_PIN_NO(119) | 0)
|
||||
+#define MT7623_PIN_119_MSDC0_DAT2_FUNC_MSDC0_DAT2 (MTK_PIN_NO(119) | 1)
|
||||
+#define MT7623_PIN_119_MSDC0_DAT2_FUNC_NLD2 (MTK_PIN_NO(119) | 4)
|
||||
+
|
||||
+#define MT7623_PIN_120_MSDC0_DAT1_FUNC_GPIO120 (MTK_PIN_NO(120) | 0)
|
||||
+#define MT7623_PIN_120_MSDC0_DAT1_FUNC_MSDC0_DAT1 (MTK_PIN_NO(120) | 1)
|
||||
+#define MT7623_PIN_120_MSDC0_DAT1_FUNC_NLD1 (MTK_PIN_NO(120) | 4)
|
||||
+
|
||||
+#define MT7623_PIN_121_MSDC0_DAT0_FUNC_GPIO121 (MTK_PIN_NO(121) | 0)
|
||||
+#define MT7623_PIN_121_MSDC0_DAT0_FUNC_MSDC0_DAT0 (MTK_PIN_NO(121) | 1)
|
||||
+#define MT7623_PIN_121_MSDC0_DAT0_FUNC_NLD0 (MTK_PIN_NO(121) | 4)
|
||||
+#define MT7623_PIN_121_MSDC0_DAT0_FUNC_WATCHDOG (MTK_PIN_NO(121) | 5)
|
||||
+
|
||||
+#define MT7623_PIN_122_GPIO122_FUNC_GPIO122 (MTK_PIN_NO(122) | 0)
|
||||
+#define MT7623_PIN_122_GPIO122_FUNC_TEST (MTK_PIN_NO(122) | 1)
|
||||
+#define MT7623_PIN_122_GPIO122_FUNC_SDA2 (MTK_PIN_NO(122) | 4)
|
||||
+#define MT7623_PIN_122_GPIO122_FUNC_URXD0 (MTK_PIN_NO(122) | 5)
|
||||
+
|
||||
+#define MT7623_PIN_123_GPIO123_FUNC_GPIO123 (MTK_PIN_NO(123) | 0)
|
||||
+#define MT7623_PIN_123_GPIO123_FUNC_TEST (MTK_PIN_NO(123) | 1)
|
||||
+#define MT7623_PIN_123_GPIO123_FUNC_SCL2 (MTK_PIN_NO(123) | 4)
|
||||
+#define MT7623_PIN_123_GPIO123_FUNC_UTXD0 (MTK_PIN_NO(123) | 5)
|
||||
+
|
||||
+#define MT7623_PIN_124_GPIO124_FUNC_GPIO124 (MTK_PIN_NO(124) | 0)
|
||||
+#define MT7623_PIN_124_GPIO124_FUNC_TEST (MTK_PIN_NO(124) | 1)
|
||||
+#define MT7623_PIN_124_GPIO124_FUNC_SDA1 (MTK_PIN_NO(124) | 4)
|
||||
+#define MT7623_PIN_124_GPIO124_FUNC_PWM3 (MTK_PIN_NO(124) | 5)
|
||||
+
|
||||
+#define MT7623_PIN_125_GPIO125_FUNC_GPIO125 (MTK_PIN_NO(125) | 0)
|
||||
+#define MT7623_PIN_125_GPIO125_FUNC_TEST (MTK_PIN_NO(125) | 1)
|
||||
+#define MT7623_PIN_125_GPIO125_FUNC_SCL1 (MTK_PIN_NO(125) | 4)
|
||||
+#define MT7623_PIN_125_GPIO125_FUNC_PWM4 (MTK_PIN_NO(125) | 5)
|
||||
+
|
||||
+#define MT7623_PIN_126_I2S0_MCLK_FUNC_GPIO126 (MTK_PIN_NO(126) | 0)
|
||||
+#define MT7623_PIN_126_I2S0_MCLK_FUNC_I2S0_MCLK (MTK_PIN_NO(126) | 1)
|
||||
+#define MT7623_PIN_126_I2S0_MCLK_FUNC_AP_I2S_MCLK (MTK_PIN_NO(126) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_199_SPI1_CK_FUNC_GPIO199 (MTK_PIN_NO(199) | 0)
|
||||
+#define MT7623_PIN_199_SPI1_CK_FUNC_SPI1_CK (MTK_PIN_NO(199) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_200_URXD2_FUNC_GPIO200 (MTK_PIN_NO(200) | 0)
|
||||
+#define MT7623_PIN_200_URXD2_FUNC_URXD2 (MTK_PIN_NO(200) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_201_UTXD2_FUNC_GPIO201 (MTK_PIN_NO(201) | 0)
|
||||
+#define MT7623_PIN_201_UTXD2_FUNC_UTXD2 (MTK_PIN_NO(201) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_203_PWM0_FUNC_GPIO203 (MTK_PIN_NO(203) | 0)
|
||||
+#define MT7623_PIN_203_PWM0_FUNC_PWM0 (MTK_PIN_NO(203) | 1)
|
||||
+#define MT7623_PIN_203_PWM0_FUNC_DISP_PWM (MTK_PIN_NO(203) | 2)
|
||||
+
|
||||
+#define MT7623_PIN_204_PWM1_FUNC_GPIO204 (MTK_PIN_NO(204) | 0)
|
||||
+#define MT7623_PIN_204_PWM1_FUNC_PWM1 (MTK_PIN_NO(204) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_205_PWM2_FUNC_GPIO205 (MTK_PIN_NO(205) | 0)
|
||||
+#define MT7623_PIN_205_PWM2_FUNC_PWM2 (MTK_PIN_NO(205) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_206_PWM3_FUNC_GPIO206 (MTK_PIN_NO(206) | 0)
|
||||
+#define MT7623_PIN_206_PWM3_FUNC_PWM3 (MTK_PIN_NO(206) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_207_PWM4_FUNC_GPIO207 (MTK_PIN_NO(207) | 0)
|
||||
+#define MT7623_PIN_207_PWM4_FUNC_PWM4 (MTK_PIN_NO(207) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_208_AUD_EXT_CK1_FUNC_GPIO208 (MTK_PIN_NO(208) | 0)
|
||||
+#define MT7623_PIN_208_AUD_EXT_CK1_FUNC_AUD_EXT_CK1 (MTK_PIN_NO(208) | 1)
|
||||
+#define MT7623_PIN_208_AUD_EXT_CK1_FUNC_PWM0 (MTK_PIN_NO(208) | 2)
|
||||
+#define MT7623_PIN_208_AUD_EXT_CK1_FUNC_PCIE0_PERST_N (MTK_PIN_NO(208) | 3)
|
||||
+#define MT7623_PIN_208_AUD_EXT_CK1_FUNC_DISP_PWM (MTK_PIN_NO(208) | 5)
|
||||
+
|
||||
+#define MT7623_PIN_209_AUD_EXT_CK2_FUNC_GPIO209 (MTK_PIN_NO(209) | 0)
|
||||
+#define MT7623_PIN_209_AUD_EXT_CK2_FUNC_AUD_EXT_CK2 (MTK_PIN_NO(209) | 1)
|
||||
+#define MT7623_PIN_209_AUD_EXT_CK2_FUNC_MSDC1_WP (MTK_PIN_NO(209) | 2)
|
||||
+#define MT7623_PIN_209_AUD_EXT_CK2_FUNC_PCIE1_PERST_N (MTK_PIN_NO(209) | 3)
|
||||
+#define MT7623_PIN_209_AUD_EXT_CK2_FUNC_PWM1 (MTK_PIN_NO(209) | 5)
|
||||
+
|
||||
+#define MT7623_PIN_236_EXT_SDIO3_FUNC_GPIO236 (MTK_PIN_NO(236) | 0)
|
||||
+#define MT7623_PIN_236_EXT_SDIO3_FUNC_EXT_SDIO3 (MTK_PIN_NO(236) | 1)
|
||||
+#define MT7623_PIN_236_EXT_SDIO3_FUNC_IDDIG (MTK_PIN_NO(236) | 2)
|
||||
+
|
||||
+#define MT7623_PIN_237_EXT_SDIO2_FUNC_GPIO237 (MTK_PIN_NO(237) | 0)
|
||||
+#define MT7623_PIN_237_EXT_SDIO2_FUNC_EXT_SDIO2 (MTK_PIN_NO(237) | 1)
|
||||
+#define MT7623_PIN_237_EXT_SDIO2_FUNC_DRV_VBUS (MTK_PIN_NO(237) | 2)
|
||||
+
|
||||
+#define MT7623_PIN_238_EXT_SDIO1_FUNC_GPIO238 (MTK_PIN_NO(238) | 0)
|
||||
+#define MT7623_PIN_238_EXT_SDIO1_FUNC_EXT_SDIO1 (MTK_PIN_NO(238) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_239_EXT_SDIO0_FUNC_GPIO239 (MTK_PIN_NO(239) | 0)
|
||||
+#define MT7623_PIN_239_EXT_SDIO0_FUNC_EXT_SDIO0 (MTK_PIN_NO(239) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_240_EXT_XCS_FUNC_GPIO240 (MTK_PIN_NO(240) | 0)
|
||||
+#define MT7623_PIN_240_EXT_XCS_FUNC_EXT_XCS (MTK_PIN_NO(240) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_241_EXT_SCK_FUNC_GPIO241 (MTK_PIN_NO(241) | 0)
|
||||
+#define MT7623_PIN_241_EXT_SCK_FUNC_EXT_SCK (MTK_PIN_NO(241) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_242_URTS2_FUNC_GPIO242 (MTK_PIN_NO(242) | 0)
|
||||
+#define MT7623_PIN_242_URTS2_FUNC_URTS2 (MTK_PIN_NO(242) | 1)
|
||||
+#define MT7623_PIN_242_URTS2_FUNC_UTXD3 (MTK_PIN_NO(242) | 2)
|
||||
+#define MT7623_PIN_242_URTS2_FUNC_URXD3 (MTK_PIN_NO(242) | 3)
|
||||
+#define MT7623_PIN_242_URTS2_FUNC_SCL1 (MTK_PIN_NO(242) | 4)
|
||||
+
|
||||
+#define MT7623_PIN_243_UCTS2_FUNC_GPIO243 (MTK_PIN_NO(243) | 0)
|
||||
+#define MT7623_PIN_243_UCTS2_FUNC_UCTS2 (MTK_PIN_NO(243) | 1)
|
||||
+#define MT7623_PIN_243_UCTS2_FUNC_URXD3 (MTK_PIN_NO(243) | 2)
|
||||
+#define MT7623_PIN_243_UCTS2_FUNC_UTXD3 (MTK_PIN_NO(243) | 3)
|
||||
+#define MT7623_PIN_243_UCTS2_FUNC_SDA1 (MTK_PIN_NO(243) | 4)
|
||||
+
|
||||
+#define MT7623_PIN_250_GPIO250_FUNC_GPIO250 (MTK_PIN_NO(250) | 0)
|
||||
+#define MT7623_PIN_250_GPIO250_FUNC_TEST_MD7 (MTK_PIN_NO(250) | 1)
|
||||
+#define MT7623_PIN_250_GPIO250_FUNC_PCIE0_CLKREQ_N (MTK_PIN_NO(250) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_251_GPIO251_FUNC_GPIO251 (MTK_PIN_NO(251) | 0)
|
||||
+#define MT7623_PIN_251_GPIO251_FUNC_TEST_MD6 (MTK_PIN_NO(251) | 1)
|
||||
+#define MT7623_PIN_251_GPIO251_FUNC_PCIE0_WAKE_N (MTK_PIN_NO(251) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_252_GPIO252_FUNC_GPIO252 (MTK_PIN_NO(252) | 0)
|
||||
+#define MT7623_PIN_252_GPIO252_FUNC_TEST_MD5 (MTK_PIN_NO(252) | 1)
|
||||
+#define MT7623_PIN_252_GPIO252_FUNC_PCIE1_CLKREQ_N (MTK_PIN_NO(252) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_253_GPIO253_FUNC_GPIO253 (MTK_PIN_NO(253) | 0)
|
||||
+#define MT7623_PIN_253_GPIO253_FUNC_TEST_MD4 (MTK_PIN_NO(253) | 1)
|
||||
+#define MT7623_PIN_253_GPIO253_FUNC_PCIE1_WAKE_N (MTK_PIN_NO(253) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_254_GPIO254_FUNC_GPIO254 (MTK_PIN_NO(254) | 0)
|
||||
+#define MT7623_PIN_254_GPIO254_FUNC_TEST_MD3 (MTK_PIN_NO(254) | 1)
|
||||
+#define MT7623_PIN_254_GPIO254_FUNC_PCIE2_CLKREQ_N (MTK_PIN_NO(254) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_255_GPIO255_FUNC_GPIO255 (MTK_PIN_NO(255) | 0)
|
||||
+#define MT7623_PIN_255_GPIO255_FUNC_TEST_MD2 (MTK_PIN_NO(255) | 1)
|
||||
+#define MT7623_PIN_255_GPIO255_FUNC_PCIE2_WAKE_N (MTK_PIN_NO(255) | 6)
|
||||
+
|
||||
+#define MT7623_PIN_256_GPIO256_FUNC_GPIO256 (MTK_PIN_NO(256) | 0)
|
||||
+#define MT7623_PIN_256_GPIO256_FUNC_TEST_MD1 (MTK_PIN_NO(256) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_257_GPIO257_FUNC_GPIO257 (MTK_PIN_NO(257) | 0)
|
||||
+#define MT7623_PIN_257_GPIO257_FUNC_TEST_MD0 (MTK_PIN_NO(257) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_261_MSDC1_INS_FUNC_GPIO261 (MTK_PIN_NO(261) | 0)
|
||||
+#define MT7623_PIN_261_MSDC1_INS_FUNC_MSDC1_INS (MTK_PIN_NO(261) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_262_G2_TXEN_FUNC_GPIO262 (MTK_PIN_NO(262) | 0)
|
||||
+#define MT7623_PIN_262_G2_TXEN_FUNC_G2_TXEN (MTK_PIN_NO(262) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_263_G2_TXD3_FUNC_GPIO263 (MTK_PIN_NO(263) | 0)
|
||||
+#define MT7623_PIN_263_G2_TXD3_FUNC_G2_TXD3 (MTK_PIN_NO(263) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_264_G2_TXD2_FUNC_GPIO264 (MTK_PIN_NO(264) | 0)
|
||||
+#define MT7623_PIN_264_G2_TXD2_FUNC_G2_TXD2 (MTK_PIN_NO(264) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_265_G2_TXD1_FUNC_GPIO265 (MTK_PIN_NO(265) | 0)
|
||||
+#define MT7623_PIN_265_G2_TXD1_FUNC_G2_TXD1 (MTK_PIN_NO(265) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_266_G2_TXD0_FUNC_GPIO266 (MTK_PIN_NO(266) | 0)
|
||||
+#define MT7623_PIN_266_G2_TXD0_FUNC_G2_TXD0 (MTK_PIN_NO(266) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_267_G2_TXCLK_FUNC_GPIO267 (MTK_PIN_NO(267) | 0)
|
||||
+#define MT7623_PIN_267_G2_TXCLK_FUNC_G2_TXC (MTK_PIN_NO(267) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_268_G2_RXCLK_FUNC_GPIO268 (MTK_PIN_NO(268) | 0)
|
||||
+#define MT7623_PIN_268_G2_RXCLK_FUNC_G2_RXC (MTK_PIN_NO(268) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_269_G2_RXD0_FUNC_GPIO269 (MTK_PIN_NO(269) | 0)
|
||||
+#define MT7623_PIN_269_G2_RXD0_FUNC_G2_RXD0 (MTK_PIN_NO(269) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_270_G2_RXD1_FUNC_GPIO270 (MTK_PIN_NO(270) | 0)
|
||||
+#define MT7623_PIN_270_G2_RXD1_FUNC_G2_RXD1 (MTK_PIN_NO(270) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_271_G2_RXD2_FUNC_GPIO271 (MTK_PIN_NO(271) | 0)
|
||||
+#define MT7623_PIN_271_G2_RXD2_FUNC_G2_RXD2 (MTK_PIN_NO(271) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_272_G2_RXD3_FUNC_GPIO272 (MTK_PIN_NO(272) | 0)
|
||||
+#define MT7623_PIN_272_G2_RXD3_FUNC_G2_RXD3 (MTK_PIN_NO(272) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_274_G2_RXDV_FUNC_GPIO274 (MTK_PIN_NO(274) | 0)
|
||||
+#define MT7623_PIN_274_G2_RXDV_FUNC_G2_RXDV (MTK_PIN_NO(274) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_275_G2_MDC_FUNC_GPIO275 (MTK_PIN_NO(275) | 0)
|
||||
+#define MT7623_PIN_275_G2_MDC_FUNC_MDC (MTK_PIN_NO(275) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_276_G2_MDIO_FUNC_GPIO276 (MTK_PIN_NO(276) | 0)
|
||||
+#define MT7623_PIN_276_G2_MDIO_FUNC_MDIO (MTK_PIN_NO(276) | 1)
|
||||
+
|
||||
+#define MT7623_PIN_278_JTAG_RESET_FUNC_GPIO278 (MTK_PIN_NO(278) | 0)
|
||||
+#define MT7623_PIN_278_JTAG_RESET_FUNC_JTAG_RESET (MTK_PIN_NO(278) | 1)
|
||||
+
|
||||
+#endif /* __DTS_MT7623_PINFUNC_H */
|
||||
+
|
||||
--
|
||||
1.7.10.4
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,54 @@
|
||||
From 294cf90337d70ad74edf147180bbeef837298bd0 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 6 Jan 2016 20:06:49 +0100
|
||||
Subject: [PATCH 17/53] clk: add hifsys reset
|
||||
|
||||
Hi,
|
||||
|
||||
small patch to add hifsys reset bits. Maybe you could add it to the next
|
||||
version of your patch series. i have teste scpsys and clk on mt7623 today
|
||||
and it works well.
|
||||
|
||||
thanks,
|
||||
John
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/clk/mediatek/clk-mt2701.c | 2 ++
|
||||
include/dt-bindings/reset-controller/mt2701-resets.h | 9 +++++++++
|
||||
2 files changed, 11 insertions(+)
|
||||
|
||||
diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c
|
||||
index 39472e4..0e40bb8 100644
|
||||
--- a/drivers/clk/mediatek/clk-mt2701.c
|
||||
+++ b/drivers/clk/mediatek/clk-mt2701.c
|
||||
@@ -1000,6 +1000,8 @@ static void __init mtk_hifsys_init(struct device_node *node)
|
||||
if (r)
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
+
|
||||
+ mtk_register_reset_controller(node, 1, 0x34);
|
||||
}
|
||||
CLK_OF_DECLARE(mtk_hifsys, "mediatek,mt2701-hifsys", mtk_hifsys_init);
|
||||
|
||||
diff --git a/include/dt-bindings/reset-controller/mt2701-resets.h b/include/dt-bindings/reset-controller/mt2701-resets.h
|
||||
index 00efeb0..aaf0305 100644
|
||||
--- a/include/dt-bindings/reset-controller/mt2701-resets.h
|
||||
+++ b/include/dt-bindings/reset-controller/mt2701-resets.h
|
||||
@@ -71,4 +71,13 @@
|
||||
#define MT2701_TOPRGU_CONN_MCU_RST 12
|
||||
#define MT2701_TOPRGU_BDP_DISP_RST 13
|
||||
|
||||
+/* HIFSYS resets */
|
||||
+#define MT2701_HIFSYS_UHOST0_RST 3
|
||||
+#define MT2701_HIFSYS_UHOST1_RST 4
|
||||
+#define MT2701_HIFSYS_UPHY0_RST 21
|
||||
+#define MT2701_HIFSYS_UPHY1_RST 22
|
||||
+#define MT2701_HIFSYS_PCIE0_RST 24
|
||||
+#define MT2701_HIFSYS_PCIE1_RST 25
|
||||
+#define MT2701_HIFSYS_PCIE2_RST 26
|
||||
+
|
||||
#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT2701 */
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,75 @@
|
||||
From 84d37aeef94deae3ce87e677f6016a5d980429e8 Mon Sep 17 00:00:00 2001
|
||||
From: "chunfeng.yun@mediatek.com" <chunfeng.yun@mediatek.com>
|
||||
Date: Tue, 17 Nov 2015 17:18:39 +0800
|
||||
Subject: [PATCH 18/53] dt-bindings: Add a binding for Mediatek xHCI host
|
||||
controller
|
||||
|
||||
add a DT binding documentation of xHCI host controller for the
|
||||
MT8173 SoC from Mediatek.
|
||||
|
||||
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
|
||||
---
|
||||
.../devicetree/bindings/usb/mt8173-xhci.txt | 51 ++++++++++++++++++++
|
||||
1 file changed, 51 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/usb/mt8173-xhci.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/usb/mt8173-xhci.txt b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt
|
||||
new file mode 100644
|
||||
index 0000000..a78f20b
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt
|
||||
@@ -0,0 +1,51 @@
|
||||
+MT8173 xHCI
|
||||
+
|
||||
+The device node for Mediatek SOC USB3.0 host controller
|
||||
+
|
||||
+Required properties:
|
||||
+ - compatible : should contain "mediatek,mt8173-xhci"
|
||||
+ - reg : specifies physical base address and size of the registers,
|
||||
+ the first one for MAC, the second for IPPC
|
||||
+ - interrupts : interrupt used by the controller
|
||||
+ - power-domains : a phandle to USB power domain node to control USB's
|
||||
+ mtcmos
|
||||
+ - vusb33-supply : regulator of USB avdd3.3v
|
||||
+
|
||||
+ - clocks : a list of phandle + clock-specifier pairs, one for each
|
||||
+ entry in clock-names
|
||||
+ - clock-names : must contain
|
||||
+ "sys_ck": for clock of xHCI MAC
|
||||
+ "wakeup_deb_p0": for USB wakeup debounce clock of port0
|
||||
+ "wakeup_deb_p0": for USB wakeup debounce clock of port1
|
||||
+
|
||||
+ - phys : a list of phandle + phy specifier pairs
|
||||
+
|
||||
+Optional properties:
|
||||
+ - mediatek,wakeup-src : 1: ip sleep wakeup mode; 2: line state wakeup
|
||||
+ mode;
|
||||
+ - mediatek,syscon-wakeup : phandle to syscon used to access USB wakeup
|
||||
+ control register, it depends on "mediatek,wakeup-src".
|
||||
+ - vbus-supply : reference to the VBUS regulator;
|
||||
+ - usb3-lpm-capable : supports USB3.0 LPM
|
||||
+
|
||||
+Example:
|
||||
+usb30: usb@11270000 {
|
||||
+ compatible = "mediatek,mt8173-xhci";
|
||||
+ reg = <0 0x11270000 0 0x1000>,
|
||||
+ <0 0x11280700 0 0x0100>;
|
||||
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>;
|
||||
+ clocks = <&topckgen CLK_TOP_USB30_SEL>,
|
||||
+ <&pericfg CLK_PERI_USB0>,
|
||||
+ <&pericfg CLK_PERI_USB1>;
|
||||
+ clock-names = "sys_ck",
|
||||
+ "wakeup_deb_p0",
|
||||
+ "wakeup_deb_p1";
|
||||
+ phys = <&phy_port0 PHY_TYPE_USB3>,
|
||||
+ <&phy_port1 PHY_TYPE_USB2>;
|
||||
+ vusb33-supply = <&mt6397_vusb_reg>;
|
||||
+ vbus-supply = <&usb_p1_vbus>;
|
||||
+ usb3-lpm-capable;
|
||||
+ mediatek,syscon-wakeup = <&pericfg>;
|
||||
+ mediatek,wakeup-src = <1>;
|
||||
+};
|
||||
--
|
||||
1.7.10.4
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,114 @@
|
||||
From 31a22fbd0d3b187be61c4c5d22b19c95abb327c3 Mon Sep 17 00:00:00 2001
|
||||
From: "chunfeng.yun@mediatek.com" <chunfeng.yun@mediatek.com>
|
||||
Date: Tue, 17 Nov 2015 17:18:41 +0800
|
||||
Subject: [PATCH 20/53] arm64: dts: mediatek: add xHCI & usb phy for mt8173
|
||||
|
||||
add xHCI and phy drivers for MT8173-EVB
|
||||
|
||||
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
|
||||
---
|
||||
arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 16 ++++++++++
|
||||
arch/arm64/boot/dts/mediatek/mt8173.dtsi | 42 +++++++++++++++++++++++++++
|
||||
2 files changed, 58 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
|
||||
index 811cb76..9b1482a 100644
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
|
||||
@@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
#include "mt8173.dtsi"
|
||||
|
||||
/ {
|
||||
@@ -32,6 +33,15 @@
|
||||
};
|
||||
|
||||
chosen { };
|
||||
+
|
||||
+ usb_p1_vbus: regulator@0 {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "usb_vbus";
|
||||
+ regulator-min-microvolt = <5000000>;
|
||||
+ regulator-max-microvolt = <5000000>;
|
||||
+ gpio = <&pio 130 GPIO_ACTIVE_HIGH>;
|
||||
+ enable-active-high;
|
||||
+ };
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
@@ -408,3 +418,9 @@
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
+
|
||||
+&usb30 {
|
||||
+ vusb33-supply = <&mt6397_vusb_reg>;
|
||||
+ vbus-supply = <&usb_p1_vbus>;
|
||||
+ mediatek,wakeup-src = <1>;
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
|
||||
index 4dd5f93..c1fd275 100644
|
||||
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
|
||||
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <dt-bindings/clock/mt8173-clk.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
+#include <dt-bindings/phy/phy.h>
|
||||
#include <dt-bindings/power/mt8173-power.h>
|
||||
#include <dt-bindings/reset-controller/mt8173-resets.h>
|
||||
#include "mt8173-pinfunc.h"
|
||||
@@ -510,6 +511,47 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ usb30: usb@11270000 {
|
||||
+ compatible = "mediatek,mt8173-xhci";
|
||||
+ reg = <0 0x11270000 0 0x1000>,
|
||||
+ <0 0x11280700 0 0x0100>;
|
||||
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>;
|
||||
+ clocks = <&topckgen CLK_TOP_USB30_SEL>,
|
||||
+ <&pericfg CLK_PERI_USB0>,
|
||||
+ <&pericfg CLK_PERI_USB1>;
|
||||
+ clock-names = "sys_ck",
|
||||
+ "wakeup_deb_p0",
|
||||
+ "wakeup_deb_p1";
|
||||
+ phys = <&phy_port0 PHY_TYPE_USB3>,
|
||||
+ <&phy_port1 PHY_TYPE_USB2>;
|
||||
+ mediatek,syscon-wakeup = <&pericfg>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ u3phy: usb-phy@11290000 {
|
||||
+ compatible = "mediatek,mt8173-u3phy";
|
||||
+ reg = <0 0x11290000 0 0x800>;
|
||||
+ clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>;
|
||||
+ clock-names = "u3phya_ref";
|
||||
+ #address-cells = <2>;
|
||||
+ #size-cells = <2>;
|
||||
+ ranges;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ phy_port0: port@11290800 {
|
||||
+ reg = <0 0x11290800 0 0x800>;
|
||||
+ #phy-cells = <1>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+
|
||||
+ phy_port1: port@11291000 {
|
||||
+ reg = <0 0x11291000 0 0x800>;
|
||||
+ #phy-cells = <1>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
mmsys: clock-controller@14000000 {
|
||||
compatible = "mediatek,mt8173-mmsys", "syscon";
|
||||
reg = <0 0x14000000 0 0x1000>;
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,64 @@
|
||||
From 162deec293400cb132161606629654acaec7cb4b Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Tue, 5 Jan 2016 12:13:54 +0100
|
||||
Subject: [PATCH 21/53] Document: DT: Add bindings for mediatek MT7623 SoC
|
||||
Platform
|
||||
|
||||
This adds a DT binding documentation for the MT7623 SoC from Mediatek.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
Documentation/devicetree/bindings/arm/mediatek.txt | 4 ++++
|
||||
Documentation/devicetree/bindings/serial/mtk-uart.txt | 1 +
|
||||
Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt | 1 +
|
||||
3 files changed, 6 insertions(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/arm/mediatek.txt b/Documentation/devicetree/bindings/arm/mediatek.txt
|
||||
index 618a9199..40e9d32 100644
|
||||
--- a/Documentation/devicetree/bindings/arm/mediatek.txt
|
||||
+++ b/Documentation/devicetree/bindings/arm/mediatek.txt
|
||||
@@ -10,6 +10,7 @@ compatible: Must contain one of
|
||||
"mediatek,mt6589"
|
||||
"mediatek,mt6592"
|
||||
"mediatek,mt6795"
|
||||
+ "mediatek,mt7623"
|
||||
"mediatek,mt8127"
|
||||
"mediatek,mt8135"
|
||||
"mediatek,mt8173"
|
||||
@@ -29,6 +30,9 @@ Supported boards:
|
||||
- Evaluation board for MT6795(Helio X10):
|
||||
Required root node properties:
|
||||
- compatible = "mediatek,mt6795-evb", "mediatek,mt6795";
|
||||
+- Evaluation board for MT7623:
|
||||
+ Required root node properties:
|
||||
+ - compatible = "mediatek,mt7623-evb", "mediatek,mt7623";
|
||||
- MTK mt8127 tablet moose EVB:
|
||||
Required root node properties:
|
||||
- compatible = "mediatek,mt8127-moose", "mediatek,mt8127";
|
||||
diff --git a/Documentation/devicetree/bindings/serial/mtk-uart.txt b/Documentation/devicetree/bindings/serial/mtk-uart.txt
|
||||
index 2d47add..474f0cf 100644
|
||||
--- a/Documentation/devicetree/bindings/serial/mtk-uart.txt
|
||||
+++ b/Documentation/devicetree/bindings/serial/mtk-uart.txt
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Required properties:
|
||||
- compatible should contain:
|
||||
+ * "mediatek,mt7623-uart" for MT7623 compatible UARTS
|
||||
* "mediatek,mt8135-uart" for MT8135 compatible UARTS
|
||||
* "mediatek,mt8127-uart" for MT8127 compatible UARTS
|
||||
* "mediatek,mt8173-uart" for MT8173 compatible UARTS
|
||||
diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
|
||||
index 64083bc..6bacda1b3 100644
|
||||
--- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
|
||||
+++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
|
||||
@@ -5,6 +5,7 @@ Required properties:
|
||||
- compatible should contain:
|
||||
* "mediatek,mt6580-timer" for MT6580 compatible timers
|
||||
* "mediatek,mt6589-timer" for MT6589 compatible timers
|
||||
+ * "mediatek,mt7623-timer" for MT7623 compatible timers
|
||||
* "mediatek,mt8127-timer" for MT8127 compatible timers
|
||||
* "mediatek,mt8135-timer" for MT8135 compatible timers
|
||||
* "mediatek,mt8173-timer" for MT8173 compatible timers
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,26 @@
|
||||
From fa5d94d6b4b314f751b1c32bb5a87a80b866d05e Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Tue, 5 Jan 2016 16:52:31 +0100
|
||||
Subject: [PATCH 22/53] soc: mediatek: add compat string for mt7623 to scpsys
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/soc/mediatek/mtk-scpsys-mt2701.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/soc/mediatek/mtk-scpsys-mt2701.c b/drivers/soc/mediatek/mtk-scpsys-mt2701.c
|
||||
index 339d5b8..3a31946 100644
|
||||
--- a/drivers/soc/mediatek/mtk-scpsys-mt2701.c
|
||||
+++ b/drivers/soc/mediatek/mtk-scpsys-mt2701.c
|
||||
@@ -136,6 +136,8 @@ static const struct of_device_id of_scpsys_match_tbl[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt2701-scpsys",
|
||||
}, {
|
||||
+ .compatible = "mediatek,mt7623-scpsys",
|
||||
+ }, {
|
||||
/* sentinel */
|
||||
}
|
||||
};
|
||||
--
|
||||
1.7.10.4
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,160 @@
|
||||
From 5b51a1e93ccaaec4cd90b73ee20cea219af2f151 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 6 Jan 2016 21:55:10 +0100
|
||||
Subject: [PATCH 24/53] dt-bindings: add MediaTek PCIe binding documentation
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
.../devicetree/bindings/pci/mediatek-pcie.txt | 140 ++++++++++++++++++++
|
||||
1 file changed, 140 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/pci/mediatek-pcie.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt
|
||||
new file mode 100644
|
||||
index 0000000..8fea3ed
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt
|
||||
@@ -0,0 +1,140 @@
|
||||
+Mediatek PCIe controller
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible: Should be one of:
|
||||
+ - "mediatek,mt2701-pcie"
|
||||
+ - "mediatek,mt7623-pcie"
|
||||
+- device_type: Must be "pci"
|
||||
+- reg: A list of physical base address and length for each set of controller
|
||||
+ registers. A list of register ranges to use. Must contain an
|
||||
+ entry for each entry in the reg-names property.
|
||||
+- reg-names: Must include the following entries:
|
||||
+ "pcie": PCIe registers
|
||||
+ "pcie phy0": PCIe PHY0 registers
|
||||
+ "pcie phy1": PCIe PHY0 registers
|
||||
+ "pcie phy2": PCIe PHY0 registers
|
||||
+- interrupts: A list of interrupt outputs of the controller. Must contain an
|
||||
+ entry for each entry in the interrupt-names property.
|
||||
+- interrupt-names: Must include the following entries:
|
||||
+ "pcie0": The interrupt that is asserted for port0
|
||||
+ "pcie1": The interrupt that is asserted for port1
|
||||
+ "pcie2": The interrupt that is asserted for port2
|
||||
+- bus-range: Range of bus numbers associated with this controller
|
||||
+- #address-cells: Address representation for root ports (must be 3)
|
||||
+- #size-cells: Size representation for root ports (must be 2)
|
||||
+- ranges: Describes the translation of addresses for root ports and standard
|
||||
+ PCI regions. The entries must be 6 cells each.
|
||||
+ Please refer to the standard PCI bus binding document for a more detailed
|
||||
+ explanation.
|
||||
+- #interrupt-cells: Size representation for interrupts (must be 1)
|
||||
+- clocks: Must contain an entry for each entry in clock-names.
|
||||
+ See ../clocks/clock-bindings.txt for details.
|
||||
+- clock-names: Must include the following entries:
|
||||
+ - pcie0
|
||||
+ - pcie1
|
||||
+ - pcie2
|
||||
+- resets: Must contain an entry for each entry in reset-names.
|
||||
+ See ../reset/reset.txt for details.
|
||||
+- reset-names: Must include the following entries:
|
||||
+ - pcie0
|
||||
+ - pcie1
|
||||
+ - pcie2
|
||||
+- mediatek,hifsys: Must contain a phandle to the HIFSYS syscon range.
|
||||
+Root ports are defined as subnodes of the PCIe controller node.
|
||||
+
|
||||
+Required properties:
|
||||
+- device_type: Must be "pci"
|
||||
+- assigned-addresses: Address and size of the port configuration registers
|
||||
+- reg: PCI bus address of the root port
|
||||
+- #address-cells: Must be 3
|
||||
+- #size-cells: Must be 2
|
||||
+- ranges: Sub-ranges distributed from the PCIe controller node. An empty
|
||||
+ property is sufficient.
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+SoC DTSI:
|
||||
+
|
||||
+ hifsys: clock-controller@1a000000 {
|
||||
+ compatible = "mediatek,mt7623-hifsys",
|
||||
+ "mediatek,mt2701-hifsys",
|
||||
+ "syscon";
|
||||
+ reg = <0 0x1a000000 0 0x1000>;
|
||||
+ #clock-cells = <1>;
|
||||
+ #reset-cells = <1>;
|
||||
+ };
|
||||
+
|
||||
+ pcie-controller@1a140000 {
|
||||
+ compatible = "mediatek,mt7623-pcie";
|
||||
+ device_type = "pci";
|
||||
+ reg = <0 0x1a140000 0 0x8000>, /* PCI-Express registers */
|
||||
+ <0 0x1a149000 0 0x1000>, /* PCI-Express PHY0 */
|
||||
+ <0 0x1a14a000 0 0x1000>, /* PCI-Express PHY1 */
|
||||
+ <0 0x1a244000 0 0x1000>; /* PCI-Express PHY2 */
|
||||
+ reg-names = "pcie", "pcie phy0", "pcie phy1", "pcie phy2";
|
||||
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>,
|
||||
+ <GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>,
|
||||
+ <GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-names = "pcie0", "pcie1", "pcie2";
|
||||
+ clocks = <&topckgen CLK_TOP_ETHIF_SEL>;
|
||||
+ clock-names = "pcie";
|
||||
+ power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>;
|
||||
+ resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>,
|
||||
+ <&hifsys MT2701_HIFSYS_PCIE1_RST>,
|
||||
+ <&hifsys MT2701_HIFSYS_PCIE2_RST>;
|
||||
+ reset-names = "pcie0", "pice1", "pcie2";
|
||||
+
|
||||
+ bus-range = <0x00 0xff>;
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+
|
||||
+ mediatek,hifsys = <&hifsys>;
|
||||
+
|
||||
+ ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000 /* io space */
|
||||
+ 0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* pci memory */
|
||||
+
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ pcie@1,0 {
|
||||
+ device_type = "pci";
|
||||
+ reg = <0x0800 0 0 0 0>;
|
||||
+
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+ ranges;
|
||||
+
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ pcie@2,0{
|
||||
+ device_type = "pci";
|
||||
+ reg = <0x1000 0 0 0 0>;
|
||||
+
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+ ranges;
|
||||
+
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ pcie@3,0{
|
||||
+ device_type = "pci";
|
||||
+ reg = <0x1800 0 0 0 0>;
|
||||
+
|
||||
+ #address-cells = <3>;
|
||||
+ #size-cells = <2>;
|
||||
+ ranges;
|
||||
+
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+Board DTS:
|
||||
+
|
||||
+ pcie-controller {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ pci@1,0 {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,710 @@
|
||||
From fc6d1a9f37cddd79c0c149e3f1394d393ac05772 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Tue, 5 Jan 2016 20:20:04 +0100
|
||||
Subject: [PATCH 25/53] PCI: mediatek: add support for PCIe found on
|
||||
MT7623/MT2701
|
||||
|
||||
Add PCIe controller support on MediaTek MT2701/MT7623. The driver supports
|
||||
a single Root complex (RC) with 3 Root Ports. The SoCs supports a Gen2
|
||||
1-lan Link on each port.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
arch/arm/mach-mediatek/Kconfig | 1 +
|
||||
drivers/pci/host/Kconfig | 11 +
|
||||
drivers/pci/host/Makefile | 1 +
|
||||
drivers/pci/host/pcie-mediatek.c | 641 ++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 654 insertions(+)
|
||||
create mode 100644 drivers/pci/host/pcie-mediatek.c
|
||||
|
||||
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
|
||||
index 7fb605e..a7fef77 100644
|
||||
--- a/arch/arm/mach-mediatek/Kconfig
|
||||
+++ b/arch/arm/mach-mediatek/Kconfig
|
||||
@@ -24,6 +24,7 @@ config MACH_MT6592
|
||||
config MACH_MT7623
|
||||
bool "MediaTek MT7623 SoCs support"
|
||||
default ARCH_MEDIATEK
|
||||
+ select MIGHT_HAVE_PCI
|
||||
|
||||
config MACH_MT8127
|
||||
bool "MediaTek MT8127 SoCs support"
|
||||
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
|
||||
index f131ba9..912f0e1 100644
|
||||
--- a/drivers/pci/host/Kconfig
|
||||
+++ b/drivers/pci/host/Kconfig
|
||||
@@ -172,4 +172,15 @@ config PCI_HISI
|
||||
help
|
||||
Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC
|
||||
|
||||
+config PCIE_MTK
|
||||
+ bool "Mediatek PCIe Controller"
|
||||
+ depends on MACH_MT2701 || MACH_MT7623
|
||||
+ depends on OF
|
||||
+ depends on PCI
|
||||
+ help
|
||||
+ Say Y here if you want to enable PCI controller support on Mediatek MT7623.
|
||||
+ MT7623 PCIe supports single Root complex (RC) with 3 Root Ports.
|
||||
+ Each port supports a Gen2 1-lan Link.
|
||||
+ PCIe include one Host/PCI bridge and 3 PCIe MAC.
|
||||
+
|
||||
endmenu
|
||||
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
|
||||
index 9d4d3c6..3b53374 100644
|
||||
--- a/drivers/pci/host/Makefile
|
||||
+++ b/drivers/pci/host/Makefile
|
||||
@@ -20,3 +20,4 @@ obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
|
||||
obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
|
||||
obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
|
||||
obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
|
||||
+obj-$(CONFIG_PCIE_MTK) += pcie-mediatek.o
|
||||
diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c
|
||||
new file mode 100644
|
||||
index 0000000..ef03952
|
||||
--- /dev/null
|
||||
+++ b/drivers/pci/host/pcie-mediatek.c
|
||||
@@ -0,0 +1,641 @@
|
||||
+/*
|
||||
+ * Mediatek MT2701/MT7623 SoC PCIE support
|
||||
+ *
|
||||
+ * Copyright (C) 2015 Mediatek
|
||||
+ * Copyright (C) 2015 Ziv Huang <ziv.huang@mediatek.com>
|
||||
+ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms of the GNU General Public License version 2 as published
|
||||
+ * by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/pci.h>
|
||||
+#include <linux/ioport.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <asm/irq.h>
|
||||
+#include <asm/mach/pci.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/of_pci.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/regulator/consumer.h>
|
||||
+#include <linux/pm_runtime.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+
|
||||
+#define MEMORY_BASE 0x80000000
|
||||
+
|
||||
+/* PCIE Registers */
|
||||
+#define PCICFG 0x00
|
||||
+#define PCIINT 0x08
|
||||
+#define PCIENA 0x0c
|
||||
+#define CFGADDR 0x20
|
||||
+#define CFGDATA 0x24
|
||||
+#define MEMBASE 0x28
|
||||
+#define IOBASE 0x2c
|
||||
+
|
||||
+/* per Port Registers */
|
||||
+#define BAR0SETUP 0x10
|
||||
+#define IMBASEBAR0 0x18
|
||||
+#define PCIE_CLASS 0x34
|
||||
+#define PCIE_SISTAT 0x50
|
||||
+
|
||||
+#define MTK_PCIE_HIGH_PERF BIT(14)
|
||||
+#define PCIEP0_BASE 0x2000
|
||||
+#define PCIEP1_BASE 0x3000
|
||||
+#define PCIEP2_BASE 0x4000
|
||||
+
|
||||
+#define PHY_P0_CTL 0x9000
|
||||
+#define PHY_P1_CTL 0xa000
|
||||
+#define PHY_P2_CTL 0x4000
|
||||
+
|
||||
+#define RSTCTL_PCIE0_RST BIT(24)
|
||||
+#define RSTCTL_PCIE1_RST BIT(25)
|
||||
+#define RSTCTL_PCIE2_RST BIT(26)
|
||||
+
|
||||
+#define HIFSYS_SYSCFG1 0x14
|
||||
+#define HIFSYS_SYSCFG1_PHY2_MASK (0x3 << 20)
|
||||
+
|
||||
+#define MTK_PHY_CLK 0xb00
|
||||
+#define MTK_PHY_CLKDRV_OFFSET BIT(2)
|
||||
+#define MTK_PHY_CLKDRV_OFFSET_MASK 0xe
|
||||
+#define MTK_PHY_PLL 0xb04
|
||||
+#define MTK_PHY_CLKDRV_AMP BIT(30)
|
||||
+#define MTK_PHY_CLKDRV_AMP_MASK 0xe0000000
|
||||
+#define MTK_PHY_REFCLK_SEL 0xc00
|
||||
+#define MTK_PHY_XTAL_EXT_EN (BIT(17) | BIT(12))
|
||||
+#define MTK_PHY_XTAL_EXT_EN_MASK 0x33000
|
||||
+#define MTK_PHY_PLL_BC 0xc08
|
||||
+#define MTK_PHY_PLL_BC_PE2H 0xc0
|
||||
+#define MTK_PHY_PLL_BC_PE2H_MASK 0x380000
|
||||
+#define MTK_PHY_PLL_IC 0xc0c
|
||||
+#define MTK_PHY_PLL_IC_BR_PE2H BIT(28)
|
||||
+#define MTK_PHY_PLL_IC_BR_PE2H_MASK 0x30000000
|
||||
+#define MTK_PHY_PLL_IC_PE2H BIT(12)
|
||||
+#define MTK_PHY_PLL_IC_PE2H_MASK 0xf000
|
||||
+#define MTK_PHY_PLL_IR 0xc10
|
||||
+#define MTK_PHY_PLL_IR_PE2H BIT(17)
|
||||
+#define MTK_PHY_PLL_IR_PE2H_MASK 0xf0000
|
||||
+#define MTK_PHY_PLL_BP 0xc14
|
||||
+#define MTK_PHY_PLL_BP_PE2H (BIT(19) | BIT(17))
|
||||
+#define MTK_PHY_PLL_BP_PE2H_MASK 0xf0000
|
||||
+#define MTK_PHY_SSC_DELTA1 0xc3c
|
||||
+#define MTK_PHY_SSC_DELTA1_PE2H (0x3c << 16)
|
||||
+#define MTK_PHY_SSC_DELTA1_PE2H_MASK 0xffff0000
|
||||
+#define MTK_PHY_SSC_DELTA 0xc48
|
||||
+#define MTK_PHY_SSC_DELTA_PE2H 0x36
|
||||
+#define MTK_PHY_SSC_DELTA_PE2H_MASK 0xffff
|
||||
+
|
||||
+#define MAX_PORT_NUM 3
|
||||
+
|
||||
+struct mtk_pcie_port {
|
||||
+ int id;
|
||||
+ int enable;
|
||||
+ int irq;
|
||||
+ u32 link;
|
||||
+ void __iomem *phy_base;
|
||||
+ struct reset_control *rstc;
|
||||
+};
|
||||
+
|
||||
+#define mtk_foreach_port(pcie, p) \
|
||||
+ for ((p) = pcie->port; \
|
||||
+ (p) != &pcie->port[MAX_PORT_NUM]; (p)++)
|
||||
+
|
||||
+struct mtk_pcie {
|
||||
+ struct device *dev;
|
||||
+ void __iomem *pcie_base;
|
||||
+ struct regmap *hifsys;
|
||||
+
|
||||
+ struct resource io;
|
||||
+ struct resource pio;
|
||||
+ struct resource mem;
|
||||
+ struct resource prefetch;
|
||||
+ struct resource busn;
|
||||
+
|
||||
+ u32 io_bus_addr;
|
||||
+ u32 mem_bus_addr;
|
||||
+
|
||||
+ struct clk *clk;
|
||||
+
|
||||
+ struct mtk_pcie_port port[MAX_PORT_NUM];
|
||||
+ int pcie_card_link;
|
||||
+};
|
||||
+
|
||||
+static struct mtk_pcie_port_data {
|
||||
+ u32 base;
|
||||
+ u32 perst_n;
|
||||
+ u32 interrupt_en;
|
||||
+} mtk_pcie_port_data[MAX_PORT_NUM] = {
|
||||
+ { PCIEP0_BASE, BIT(1), BIT(20) },
|
||||
+ { PCIEP1_BASE, BIT(2), BIT(21) },
|
||||
+ { PCIEP2_BASE, BIT(3), BIT(22) },
|
||||
+};
|
||||
+
|
||||
+static const struct mtk_phy_init {
|
||||
+ uint32_t reg;
|
||||
+ uint32_t mask;
|
||||
+ uint32_t val;
|
||||
+} mtk_phy_init[] = {
|
||||
+ { MTK_PHY_REFCLK_SEL, MTK_PHY_XTAL_EXT_EN_MASK, MTK_PHY_XTAL_EXT_EN },
|
||||
+ { MTK_PHY_PLL, MTK_PHY_CLKDRV_AMP_MASK, MTK_PHY_CLKDRV_AMP },
|
||||
+ { MTK_PHY_CLK, MTK_PHY_CLKDRV_OFFSET_MASK, MTK_PHY_CLKDRV_OFFSET },
|
||||
+ { MTK_PHY_SSC_DELTA1, MTK_PHY_SSC_DELTA1_PE2H_MASK, MTK_PHY_SSC_DELTA1_PE2H },
|
||||
+ { MTK_PHY_SSC_DELTA, MTK_PHY_SSC_DELTA_PE2H_MASK, MTK_PHY_SSC_DELTA_PE2H },
|
||||
+ { MTK_PHY_PLL_IC, MTK_PHY_PLL_IC_BR_PE2H_MASK, MTK_PHY_PLL_IC_BR_PE2H },
|
||||
+ { MTK_PHY_PLL_BC, MTK_PHY_PLL_BC_PE2H_MASK, MTK_PHY_PLL_BC_PE2H },
|
||||
+ { MTK_PHY_PLL_IR, MTK_PHY_PLL_IR_PE2H_MASK, MTK_PHY_PLL_IR_PE2H },
|
||||
+ { MTK_PHY_PLL_IC, MTK_PHY_PLL_IC_PE2H_MASK, MTK_PHY_PLL_IC_PE2H },
|
||||
+ { MTK_PHY_PLL_BP, MTK_PHY_PLL_BP_PE2H_MASK, MTK_PHY_PLL_BP_PE2H },
|
||||
+};
|
||||
+
|
||||
+static struct mtk_pcie *sys_to_pcie(struct pci_sys_data *sys)
|
||||
+{
|
||||
+ return sys->private_data;
|
||||
+}
|
||||
+
|
||||
+static void pcie_w32(struct mtk_pcie *pcie, u32 val, unsigned reg)
|
||||
+{
|
||||
+ iowrite32(val, pcie->pcie_base + reg);
|
||||
+}
|
||||
+
|
||||
+static u32 pcie_r32(struct mtk_pcie *pcie, unsigned reg)
|
||||
+{
|
||||
+ return ioread32(pcie->pcie_base + reg);
|
||||
+}
|
||||
+
|
||||
+static void pcie_m32(struct mtk_pcie *pcie, u32 mask, u32 val, unsigned reg)
|
||||
+{
|
||||
+ u32 v = pcie_r32(pcie, reg);
|
||||
+
|
||||
+ v &= mask;
|
||||
+ v |= val;
|
||||
+ pcie_w32(pcie, v, reg);
|
||||
+}
|
||||
+
|
||||
+static int pcie_config_read(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
+ int size, u32 *val)
|
||||
+{
|
||||
+ struct mtk_pcie *pcie = sys_to_pcie(bus->sysdata);
|
||||
+ unsigned int slot = PCI_SLOT(devfn);
|
||||
+ u8 func = PCI_FUNC(devfn);
|
||||
+ u32 address;
|
||||
+ u32 data;
|
||||
+ u32 num = 0;
|
||||
+
|
||||
+ if (bus)
|
||||
+ num = bus->number;
|
||||
+
|
||||
+ address = (((where & 0xf00) >> 8) << 24) |
|
||||
+ (num << 16) |
|
||||
+ (slot << 11) |
|
||||
+ (func << 8) |
|
||||
+ (where & 0xfc);
|
||||
+
|
||||
+ pcie_w32(pcie, address, CFGADDR);
|
||||
+ data = pcie_r32(pcie, CFGDATA);
|
||||
+
|
||||
+ switch (size) {
|
||||
+ case 1:
|
||||
+ *val = (data >> ((where & 3) << 3)) & 0xff;
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ *val = data;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+static int pcie_config_write(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
+ int size, u32 val)
|
||||
+{
|
||||
+ struct mtk_pcie *pcie = sys_to_pcie(bus->sysdata);
|
||||
+ unsigned int slot = PCI_SLOT(devfn);
|
||||
+ u8 func = PCI_FUNC(devfn);
|
||||
+ u32 address;
|
||||
+ u32 data;
|
||||
+ u32 num = 0;
|
||||
+
|
||||
+ if (bus)
|
||||
+ num = bus->number;
|
||||
+
|
||||
+ address = (((where & 0xf00) >> 8) << 24) |
|
||||
+ (num << 16) | (slot << 11) | (func << 8) | (where & 0xfc);
|
||||
+ pcie_w32(pcie, address, CFGADDR);
|
||||
+ data = pcie_r32(pcie, CFGDATA);
|
||||
+
|
||||
+ switch (size) {
|
||||
+ case 1:
|
||||
+ data = (data & ~(0xff << ((where & 3) << 3))) |
|
||||
+ (val << ((where & 3) << 3));
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
|
||||
+ (val << ((where & 3) << 3));
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ data = val;
|
||||
+ break;
|
||||
+ }
|
||||
+ pcie_w32(pcie, data, CFGDATA);
|
||||
+
|
||||
+ return PCIBIOS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+static struct pci_ops mtk_pcie_ops = {
|
||||
+ .read = pcie_config_read,
|
||||
+ .write = pcie_config_write,
|
||||
+};
|
||||
+
|
||||
+static int __init mtk_pcie_setup(int nr, struct pci_sys_data *sys)
|
||||
+{
|
||||
+ struct mtk_pcie *pcie = sys_to_pcie(sys);
|
||||
+
|
||||
+ request_resource(&ioport_resource, &pcie->pio);
|
||||
+ request_resource(&iomem_resource, &pcie->mem);
|
||||
+
|
||||
+ pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
|
||||
+ pci_add_resource_offset(&sys->resources, &pcie->pio, sys->io_offset);
|
||||
+ pci_add_resource(&sys->resources, &pcie->busn);
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static struct pci_bus * __init mtk_pcie_scan_bus(int nr,
|
||||
+ struct pci_sys_data *sys)
|
||||
+{
|
||||
+ struct mtk_pcie *pcie = sys_to_pcie(sys);
|
||||
+ struct pci_bus *bus;
|
||||
+
|
||||
+ bus = pci_create_root_bus(pcie->dev, sys->busnr, &mtk_pcie_ops, sys,
|
||||
+ &sys->resources);
|
||||
+ if (!bus)
|
||||
+ return NULL;
|
||||
+
|
||||
+ pci_scan_child_bus(bus);
|
||||
+
|
||||
+ return bus;
|
||||
+}
|
||||
+
|
||||
+static int __init mtk_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||
+{
|
||||
+ struct mtk_pcie *pcie = sys_to_pcie(dev->bus->sysdata);
|
||||
+ struct mtk_pcie_port *port;
|
||||
+ int irq = -1;
|
||||
+
|
||||
+ mtk_foreach_port(pcie, port)
|
||||
+ if (port->id == slot)
|
||||
+ irq = port->irq;
|
||||
+
|
||||
+ return irq;
|
||||
+}
|
||||
+
|
||||
+static void mtk_pcie_configure_phy(struct mtk_pcie *pcie,
|
||||
+ struct mtk_pcie_port *port)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(mtk_phy_init); i++) {
|
||||
+ void __iomem *phy_addr = port->phy_base + mtk_phy_init[i].reg;
|
||||
+ u32 val = ioread32(phy_addr);
|
||||
+
|
||||
+ val &= ~mtk_phy_init[i].mask;
|
||||
+ val |= mtk_phy_init[i].val;
|
||||
+ iowrite32(val, phy_addr);
|
||||
+ }
|
||||
+ usleep_range(5000, 6000);
|
||||
+}
|
||||
+
|
||||
+static void mtk_pcie_configure_rc(struct mtk_pcie *pcie,
|
||||
+ struct mtk_pcie_port *port,
|
||||
+ struct pci_bus *bus)
|
||||
+{
|
||||
+ u32 val = 0;
|
||||
+
|
||||
+ pcie_config_write(bus,
|
||||
+ port->id << 3,
|
||||
+ PCI_BASE_ADDRESS_0, 4, MEMORY_BASE);
|
||||
+
|
||||
+ pcie_config_read(bus,
|
||||
+ port->id << 3, PCI_BASE_ADDRESS_0, 4, &val);
|
||||
+
|
||||
+ /* Configure RC Credit */
|
||||
+ pcie_config_read(bus, port->id << 3, 0x73c, 4, &val);
|
||||
+ val &= ~(0x9fff) << 16;
|
||||
+ val |= 0x806c << 16;
|
||||
+ pcie_config_write(bus, port->id << 3, 0x73c, 4, val);
|
||||
+
|
||||
+ /* Configure RC FTS number */
|
||||
+ pcie_config_read(bus, port->id << 3, 0x70c, 4, &val);
|
||||
+ val &= ~(0xff3) << 8;
|
||||
+ val |= 0x50 << 8;
|
||||
+ pcie_config_write(bus, port->id << 3, 0x70c, 4, val);
|
||||
+}
|
||||
+
|
||||
+static int mtk_pcie_preinit(struct mtk_pcie *pcie)
|
||||
+{
|
||||
+ struct mtk_pcie_port *port;
|
||||
+ u32 val = 0;
|
||||
+ struct pci_bus bus;
|
||||
+ struct pci_sys_data sys;
|
||||
+
|
||||
+ memset(&bus, 0, sizeof(bus));
|
||||
+ memset(&sys, 0, sizeof(sys));
|
||||
+ bus.sysdata = (void *)&sys;
|
||||
+ sys.private_data = (void *)pcie;
|
||||
+
|
||||
+ pcibios_min_io = 0;
|
||||
+ pcibios_min_mem = 0;
|
||||
+
|
||||
+ /* The PHY on Port 2 is shared with USB */
|
||||
+ if (pcie->port[2].enable)
|
||||
+ regmap_update_bits(pcie->hifsys, HIFSYS_SYSCFG1,
|
||||
+ HIFSYS_SYSCFG1_PHY2_MASK, 0x0);
|
||||
+
|
||||
+ /* PCIe RC Reset */
|
||||
+ mtk_foreach_port(pcie, port)
|
||||
+ if (port->enable)
|
||||
+ reset_control_assert(port->rstc);
|
||||
+ usleep_range(1000, 2000);
|
||||
+ mtk_foreach_port(pcie, port)
|
||||
+ if (port->enable)
|
||||
+ reset_control_deassert(port->rstc);
|
||||
+ usleep_range(1000, 2000);
|
||||
+
|
||||
+ /* Configure PCIe PHY */
|
||||
+ mtk_foreach_port(pcie, port)
|
||||
+ if (port->enable)
|
||||
+ mtk_pcie_configure_phy(pcie, port);
|
||||
+
|
||||
+ /* PCIe EP reset */
|
||||
+ val = 0;
|
||||
+ mtk_foreach_port(pcie, port)
|
||||
+ if (port->enable)
|
||||
+ val |= mtk_pcie_port_data[port->id].perst_n;
|
||||
+ pcie_w32(pcie, pcie_r32(pcie, PCICFG) | val, PCICFG);
|
||||
+ usleep_range(1000, 2000);
|
||||
+ pcie_w32(pcie, pcie_r32(pcie, PCICFG) & ~val, PCICFG);
|
||||
+ usleep_range(1000, 2000);
|
||||
+ msleep(100);
|
||||
+
|
||||
+ /* check the link status */
|
||||
+ val = 0;
|
||||
+ mtk_foreach_port(pcie, port) {
|
||||
+ if (port->enable) {
|
||||
+ u32 base = mtk_pcie_port_data[port->id].base;
|
||||
+
|
||||
+ if ((pcie_r32(pcie, base + PCIE_SISTAT) & 0x1))
|
||||
+ port->link = 1;
|
||||
+ else
|
||||
+ reset_control_assert(port->rstc);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ mtk_foreach_port(pcie, port)
|
||||
+ if (port->link)
|
||||
+ pcie->pcie_card_link++;
|
||||
+
|
||||
+ if (!pcie->pcie_card_link)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ pcie_w32(pcie, pcie->mem_bus_addr, MEMBASE);
|
||||
+ pcie_w32(pcie, pcie->io_bus_addr, IOBASE);
|
||||
+
|
||||
+ mtk_foreach_port(pcie, port) {
|
||||
+ if (port->link) {
|
||||
+ u32 base = mtk_pcie_port_data[port->id].base;
|
||||
+ u32 inte = mtk_pcie_port_data[port->id].interrupt_en;
|
||||
+
|
||||
+ pcie_m32(pcie, 0, inte, PCIENA);
|
||||
+ pcie_w32(pcie, 0x7fff0001, base + BAR0SETUP);
|
||||
+ pcie_w32(pcie, MEMORY_BASE, base + IMBASEBAR0);
|
||||
+ pcie_w32(pcie, 0x06040001, base + PCIE_CLASS);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ mtk_foreach_port(pcie, port)
|
||||
+ if (port->link)
|
||||
+ mtk_pcie_configure_rc(pcie, port, &bus);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mtk_pcie_parse_dt(struct mtk_pcie *pcie)
|
||||
+{
|
||||
+ struct device_node *np = pcie->dev->of_node, *port;
|
||||
+ struct of_pci_range_parser parser;
|
||||
+ struct of_pci_range range;
|
||||
+ struct resource res;
|
||||
+ int err;
|
||||
+
|
||||
+ pcie->hifsys = syscon_regmap_lookup_by_phandle(np, "mediatek,hifsys");
|
||||
+ if (IS_ERR(pcie->hifsys)) {
|
||||
+ dev_err(pcie->dev, "missing \"mediatek,hifsys\" phandle\n");
|
||||
+ return PTR_ERR(pcie->hifsys);
|
||||
+ }
|
||||
+
|
||||
+ if (of_pci_range_parser_init(&parser, np)) {
|
||||
+ dev_err(pcie->dev, "missing \"ranges\" property\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ for_each_of_pci_range(&parser, &range) {
|
||||
+ err = of_pci_range_to_resource(&range, np, &res);
|
||||
+ if (err < 0) {
|
||||
+ dev_err(pcie->dev, "failed to read resource range\n");
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ switch (res.flags & IORESOURCE_TYPE_BITS) {
|
||||
+ case IORESOURCE_IO:
|
||||
+ memcpy(&pcie->pio, &res, sizeof(res));
|
||||
+ pcie->pio.start = (resource_size_t)range.pci_addr;
|
||||
+ pcie->pio.end = (resource_size_t)
|
||||
+ (range.pci_addr + range.size - 1);
|
||||
+ pcie->io_bus_addr = (resource_size_t)range.cpu_addr;
|
||||
+ break;
|
||||
+
|
||||
+ case IORESOURCE_MEM:
|
||||
+ if (res.flags & IORESOURCE_PREFETCH) {
|
||||
+ memcpy(&pcie->prefetch, &res, sizeof(res));
|
||||
+ pcie->prefetch.name = "prefetchable";
|
||||
+ pcie->prefetch.start =
|
||||
+ (resource_size_t)range.pci_addr;
|
||||
+ pcie->prefetch.end = (resource_size_t)
|
||||
+ (range.pci_addr + range.size - 1);
|
||||
+ } else {
|
||||
+ memcpy(&pcie->mem, &res, sizeof(res));
|
||||
+ pcie->mem.name = "non-prefetchable";
|
||||
+ pcie->mem.start = (resource_size_t)
|
||||
+ range.pci_addr;
|
||||
+ pcie->prefetch.end = (resource_size_t)
|
||||
+ (range.pci_addr + range.size - 1);
|
||||
+ pcie->mem_bus_addr = (resource_size_t)
|
||||
+ range.cpu_addr;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ err = of_pci_parse_bus_range(np, &pcie->busn);
|
||||
+ if (err < 0) {
|
||||
+ dev_err(pcie->dev, "failed to parse ranges property: %d\n",
|
||||
+ err);
|
||||
+ pcie->busn.name = np->name;
|
||||
+ pcie->busn.start = 0;
|
||||
+ pcie->busn.end = 0xff;
|
||||
+ pcie->busn.flags = IORESOURCE_BUS;
|
||||
+ }
|
||||
+
|
||||
+ /* parse root ports */
|
||||
+ for_each_child_of_node(np, port) {
|
||||
+ unsigned int index;
|
||||
+ char rst[] = "pcie0";
|
||||
+
|
||||
+ err = of_pci_get_devfn(port);
|
||||
+ if (err < 0) {
|
||||
+ dev_err(pcie->dev, "failed to parse address: %d\n",
|
||||
+ err);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ index = PCI_SLOT(err);
|
||||
+ if (index > MAX_PORT_NUM) {
|
||||
+ dev_err(pcie->dev, "invalid port number: %d\n", index);
|
||||
+ continue;
|
||||
+ }
|
||||
+ index--;
|
||||
+ pcie->port[index].id = index;
|
||||
+
|
||||
+ if (!of_device_is_available(port))
|
||||
+ continue;
|
||||
+
|
||||
+ rst[4] += index;
|
||||
+ pcie->port[index].rstc = devm_reset_control_get(pcie->dev,
|
||||
+ rst);
|
||||
+ if (!IS_ERR(pcie->port[index].rstc))
|
||||
+ pcie->port[index].enable = 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mtk_pcie_get_resources(struct mtk_pcie *pcie)
|
||||
+{
|
||||
+ struct platform_device *pdev = to_platform_device(pcie->dev);
|
||||
+ struct mtk_pcie_port *port;
|
||||
+ struct resource *res;
|
||||
+
|
||||
+ pcie->clk = devm_clk_get(&pdev->dev, "pcie");
|
||||
+ if (IS_ERR(pcie->clk)) {
|
||||
+ dev_err(&pdev->dev, "Failed to get pcie clk\n");
|
||||
+ return PTR_ERR(pcie->clk);
|
||||
+ }
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ pcie->pcie_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (IS_ERR(pcie->pcie_base)) {
|
||||
+ dev_err(&pdev->dev, "Failed to get pcie range\n");
|
||||
+ return PTR_ERR(pcie->pcie_base);
|
||||
+ }
|
||||
+
|
||||
+ mtk_foreach_port(pcie, port) {
|
||||
+ if (!port->enable)
|
||||
+ continue;
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, port->id + 1);
|
||||
+ port->phy_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (IS_ERR(port->phy_base)) {
|
||||
+ dev_err(&pdev->dev, "Failed to get pcie phy%d range %p\n",
|
||||
+ port->id, port->phy_base);
|
||||
+ return PTR_ERR(port->phy_base);
|
||||
+ }
|
||||
+ port->irq = platform_get_irq(pdev, port->id);
|
||||
+ }
|
||||
+
|
||||
+ return clk_prepare_enable(pcie->clk);
|
||||
+}
|
||||
+
|
||||
+static int mtk_pcie_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mtk_pcie *pcie;
|
||||
+ struct hw_pci hw;
|
||||
+ int ret;
|
||||
+
|
||||
+ pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
|
||||
+ if (!pcie)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ pcie->dev = &pdev->dev;
|
||||
+ ret = mtk_pcie_parse_dt(pcie);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ pm_runtime_enable(&pdev->dev);
|
||||
+ pm_runtime_get_sync(&pdev->dev);
|
||||
+
|
||||
+ ret = mtk_pcie_get_resources(pcie);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&pdev->dev, "failed to request resources: %d\n", ret);
|
||||
+ goto err_out;
|
||||
+ }
|
||||
+
|
||||
+ ret = mtk_pcie_preinit(pcie);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ memset(&hw, 0, sizeof(hw));
|
||||
+ hw.nr_controllers = 1;
|
||||
+ hw.private_data = (void **)&pcie;
|
||||
+ hw.setup = mtk_pcie_setup;
|
||||
+ hw.map_irq = mtk_pcie_map_irq;
|
||||
+ hw.scan = mtk_pcie_scan_bus;
|
||||
+
|
||||
+ pci_common_init_dev(pcie->dev, &hw);
|
||||
+ platform_set_drvdata(pdev, pcie);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_out:
|
||||
+ clk_disable_unprepare(pcie->clk);
|
||||
+ pm_runtime_put_sync(&pdev->dev);
|
||||
+ pm_runtime_disable(&pdev->dev);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mtk_pcie_ids[] = {
|
||||
+ { .compatible = "mediatek,mt2701-pcie" },
|
||||
+ { .compatible = "mediatek,mt7623-pcie" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mtk_pcie_ids);
|
||||
+
|
||||
+static struct platform_driver mtk_pcie_driver = {
|
||||
+ .probe = mtk_pcie_probe,
|
||||
+ .driver = {
|
||||
+ .name = "mediatek-pcie",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = of_match_ptr(mtk_pcie_ids),
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init mtk_pcie_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&mtk_pcie_driver);
|
||||
+}
|
||||
+
|
||||
+module_init(mtk_pcie_init);
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,65 @@
|
||||
From f027ce51ff728a22428fb0b7107edf9e1bd61712 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 21 Feb 2016 13:52:12 +0100
|
||||
Subject: [PATCH 26/53] scpsys: various fixes
|
||||
|
||||
---
|
||||
drivers/clk/mediatek/clk-mt2701.c | 2 ++
|
||||
drivers/soc/mediatek/mtk-scpsys-mt2701.c | 8 --------
|
||||
include/dt-bindings/power/mt2701-power.h | 4 ++--
|
||||
3 files changed, 4 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c
|
||||
index 0e40bb8..812b347 100644
|
||||
--- a/drivers/clk/mediatek/clk-mt2701.c
|
||||
+++ b/drivers/clk/mediatek/clk-mt2701.c
|
||||
@@ -1043,6 +1043,8 @@ static void __init mtk_ethsys_init(struct device_node *node)
|
||||
if (r)
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
+
|
||||
+ mtk_register_reset_controller(node, 1, 0x34);
|
||||
}
|
||||
CLK_OF_DECLARE(mtk_ethsys, "mediatek,mt2701-ethsys", mtk_ethsys_init);
|
||||
|
||||
diff --git a/drivers/soc/mediatek/mtk-scpsys-mt2701.c b/drivers/soc/mediatek/mtk-scpsys-mt2701.c
|
||||
index 3a31946..19489bc 100644
|
||||
--- a/drivers/soc/mediatek/mtk-scpsys-mt2701.c
|
||||
+++ b/drivers/soc/mediatek/mtk-scpsys-mt2701.c
|
||||
@@ -61,14 +61,6 @@ static const struct scp_domain_data scp_domain_data[] = {
|
||||
.bus_prot_mask = MT2701_TOP_AXI_PROT_EN_DISP,
|
||||
.active_wakeup = true,
|
||||
},
|
||||
- [MT2701_POWER_DOMAIN_MFG] = {
|
||||
- .name = "mfg",
|
||||
- .sta_mask = MFG_PWR_STA_MASK,
|
||||
- .ctl_offs = SPM_MFG_PWR_CON,
|
||||
- .sram_pdn_bits = GENMASK(11, 8),
|
||||
- .sram_pdn_ack_bits = GENMASK(12, 12),
|
||||
- .active_wakeup = true,
|
||||
- },
|
||||
[MT2701_POWER_DOMAIN_VDEC] = {
|
||||
.name = "vdec",
|
||||
.sta_mask = VDE_PWR_STA_MASK,
|
||||
diff --git a/include/dt-bindings/power/mt2701-power.h b/include/dt-bindings/power/mt2701-power.h
|
||||
index 64cc826..c168597 100644
|
||||
--- a/include/dt-bindings/power/mt2701-power.h
|
||||
+++ b/include/dt-bindings/power/mt2701-power.h
|
||||
@@ -16,12 +16,12 @@
|
||||
|
||||
#define MT2701_POWER_DOMAIN_CONN 0
|
||||
#define MT2701_POWER_DOMAIN_DISP 1
|
||||
-#define MT2701_POWER_DOMAIN_MFG 2
|
||||
+//#define MT2701_POWER_DOMAIN_MFG 2
|
||||
#define MT2701_POWER_DOMAIN_VDEC 3
|
||||
#define MT2701_POWER_DOMAIN_ISP 4
|
||||
#define MT2701_POWER_DOMAIN_BDP 5
|
||||
#define MT2701_POWER_DOMAIN_ETH 6
|
||||
#define MT2701_POWER_DOMAIN_HIF 7
|
||||
-#define MT2701_POWER_DOMAIN_IFR_MSC 8
|
||||
+#define MT2701_POWER_DOMAIN_IFR_MSC 2
|
||||
|
||||
#endif /* _DT_BINDINGS_POWER_MT2701_POWER_H */
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,74 @@
|
||||
From af4a99b856b584b2426757e905e9b6f39906ce05 Mon Sep 17 00:00:00 2001
|
||||
From: Henry Chen <henryc.chen@mediatek.com>
|
||||
Date: Mon, 4 Jan 2016 20:02:52 +0800
|
||||
Subject: [PATCH 27/53] soc: mediatek: PMIC wrap: Clear the vldclr if state
|
||||
machine stay on FSM_VLDCLR state.
|
||||
|
||||
Sometimes PMIC is too busy to send data in time to cause pmic wrap timeout,
|
||||
because pmic wrap is waiting for FSM_VLDCLR after finishing WACS2_CMD. It
|
||||
just return error when issue happened, so the state machine will stay on
|
||||
FSM_VLDCLR state when data send back later by PMIC and timeout again in next
|
||||
time because pmic wrap waiting for FSM_IDLE state at the beginning of the
|
||||
read/write function.
|
||||
|
||||
Clear the vldclr when timeout if state machine stay on FSM_VLDCLR.
|
||||
|
||||
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
|
||||
Tested-by: Ricky Liang <jcliang@chromium.org>
|
||||
Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
|
||||
---
|
||||
drivers/soc/mediatek/mtk-pmic-wrap.c | 22 ++++++++++++++++++++--
|
||||
1 file changed, 20 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
index 105597a..696071b 100644
|
||||
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
@@ -412,6 +412,20 @@ static bool pwrap_is_fsm_vldclr(struct pmic_wrapper *wrp)
|
||||
return PWRAP_GET_WACS_FSM(val) == PWRAP_WACS_FSM_WFVLDCLR;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Timeout issue sometimes caused by the last read command
|
||||
+ * failed because pmic wrap could not got the FSM_VLDCLR
|
||||
+ * in time after finishing WACS2_CMD. It made state machine
|
||||
+ * still on FSM_VLDCLR and timeout next time.
|
||||
+ * Check the status of FSM and clear the vldclr to recovery the
|
||||
+ * error.
|
||||
+ */
|
||||
+static inline void pwrap_leave_fsm_vldclr(struct pmic_wrapper *wrp)
|
||||
+{
|
||||
+ if (pwrap_is_fsm_vldclr(wrp))
|
||||
+ pwrap_writel(wrp, 1, PWRAP_WACS2_VLDCLR);
|
||||
+}
|
||||
+
|
||||
static bool pwrap_is_sync_idle(struct pmic_wrapper *wrp)
|
||||
{
|
||||
return pwrap_readl(wrp, PWRAP_WACS2_RDATA) & PWRAP_STATE_SYNC_IDLE0;
|
||||
@@ -445,8 +459,10 @@ static int pwrap_write(struct pmic_wrapper *wrp, u32 adr, u32 wdata)
|
||||
int ret;
|
||||
|
||||
ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle);
|
||||
- if (ret)
|
||||
+ if (ret) {
|
||||
+ pwrap_leave_fsm_vldclr(wrp);
|
||||
return ret;
|
||||
+ }
|
||||
|
||||
pwrap_writel(wrp, (1 << 31) | ((adr >> 1) << 16) | wdata,
|
||||
PWRAP_WACS2_CMD);
|
||||
@@ -459,8 +475,10 @@ static int pwrap_read(struct pmic_wrapper *wrp, u32 adr, u32 *rdata)
|
||||
int ret;
|
||||
|
||||
ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle);
|
||||
- if (ret)
|
||||
+ if (ret) {
|
||||
+ pwrap_leave_fsm_vldclr(wrp);
|
||||
return ret;
|
||||
+ }
|
||||
|
||||
pwrap_writel(wrp, (adr >> 1) << 16, PWRAP_WACS2_CMD);
|
||||
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -1,21 +1,26 @@
|
||||
From 3f181d60fcd80b0d98849076ed2aa43de2cb6d8c Mon Sep 17 00:00:00 2001
|
||||
From 0742887b1d36913ccd5f6fa85649ad5eb0bfb200 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
|
||||
Date: Tue, 5 Jan 2016 17:24:28 +0100
|
||||
Subject: [PATCH 28/53] ARM: mediatek: add MT7623 smp bringup code
|
||||
|
||||
Add support for booting secondary CPUs on MT7623.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
|
||||
---
|
||||
arch/arm/mach-mediatek/platsmp.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c
|
||||
index 8141f3f..8151400 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 mt
|
||||
@@ -44,6 +44,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,
|
||||
+ 0x10202000, 0x34,
|
||||
+ { 0x534c4131, 0x4c415332, 0x41534c33 },
|
||||
+ { 0x38, 0x3c, 0x40 },
|
||||
+};
|
||||
@ -23,7 +28,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
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_
|
||||
@@ -51,6 +57,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 },
|
||||
@ -31,3 +36,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
};
|
||||
|
||||
static void __iomem *mtk_smp_base;
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,63 @@
|
||||
From 5d75662fcdfef08d82710f8c4b71c58d618d4171 Mon Sep 17 00:00:00 2001
|
||||
From: Henry Chen <henryc.chen@mediatek.com>
|
||||
Date: Thu, 21 Jan 2016 19:04:00 +0800
|
||||
Subject: [PATCH 29/53] soc: mediatek: PMIC wrap: clear the STAUPD_TRIG bit of
|
||||
WDT_SRC_EN
|
||||
|
||||
Since STAUPD interrupts aren't handled on mt8173, disable watchdog timeout
|
||||
monitor of STAUPD to avoid WDT_INT triggered by STAUPD.
|
||||
|
||||
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
|
||||
Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
|
||||
Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
|
||||
---
|
||||
drivers/soc/mediatek/mtk-pmic-wrap.c | 19 +++++++++++++++++--
|
||||
1 file changed, 17 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
index 696071b..0d9b19a 100644
|
||||
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
@@ -60,6 +60,15 @@
|
||||
#define PWRAP_MAN_CMD_OP_OUTD (0x9 << 8)
|
||||
#define PWRAP_MAN_CMD_OP_OUTQ (0xa << 8)
|
||||
|
||||
+/* macro for Watch Dog Timer Source */
|
||||
+#define PWRAP_WDT_SRC_EN_STAUPD_TRIG (1 << 25)
|
||||
+#define PWRAP_WDT_SRC_EN_HARB_STAUPD_DLE (1 << 20)
|
||||
+#define PWRAP_WDT_SRC_EN_HARB_STAUPD_ALE (1 << 6)
|
||||
+#define PWRAP_WDT_SRC_MASK_ALL 0xffffffff
|
||||
+#define PWRAP_WDT_SRC_MASK_NO_STAUPD ~(PWRAP_WDT_SRC_EN_STAUPD_TRIG | \
|
||||
+ PWRAP_WDT_SRC_EN_HARB_STAUPD_DLE | \
|
||||
+ PWRAP_WDT_SRC_EN_HARB_STAUPD_ALE)
|
||||
+
|
||||
/* macro for slave device wrapper registers */
|
||||
#define PWRAP_DEW_BASE 0xbc00
|
||||
#define PWRAP_DEW_EVENT_OUT_EN (PWRAP_DEW_BASE + 0x0)
|
||||
@@ -822,7 +831,7 @@ MODULE_DEVICE_TABLE(of, of_pwrap_match_tbl);
|
||||
|
||||
static int pwrap_probe(struct platform_device *pdev)
|
||||
{
|
||||
- int ret, irq;
|
||||
+ int ret, irq, wdt_src;
|
||||
struct pmic_wrapper *wrp;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
const struct of_device_id *of_id =
|
||||
@@ -912,7 +921,13 @@ static int pwrap_probe(struct platform_device *pdev)
|
||||
|
||||
/* Initialize watchdog, may not be done by the bootloader */
|
||||
pwrap_writel(wrp, 0xf, PWRAP_WDT_UNIT);
|
||||
- pwrap_writel(wrp, 0xffffffff, PWRAP_WDT_SRC_EN);
|
||||
+ /*
|
||||
+ * Since STAUPD was not used on mt8173 platform,
|
||||
+ * so STAUPD of WDT_SRC which should be turned off
|
||||
+ */
|
||||
+ wdt_src = pwrap_is_mt8173(wrp) ?
|
||||
+ PWRAP_WDT_SRC_MASK_NO_STAUPD : PWRAP_WDT_SRC_MASK_ALL;
|
||||
+ pwrap_writel(wrp, wdt_src, PWRAP_WDT_SRC_EN);
|
||||
pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
|
||||
pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN);
|
||||
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,28 @@
|
||||
From f6e138ee1a8ddba7b512cafc2ecc7cd1b41781dc Mon Sep 17 00:00:00 2001
|
||||
From: Louis Yu <louis.yu@mediatek.com>
|
||||
Date: Thu, 7 Jan 2016 20:09:43 +0800
|
||||
Subject: [PATCH 30/53] ARM: mediatek: add mt2701 smp bringup code
|
||||
|
||||
Add support for booting secondary CPUs on mt2701.
|
||||
|
||||
Signed-off-by: Louis Yu <louis.yu@mediatek.com>
|
||||
Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
|
||||
---
|
||||
arch/arm/mach-mediatek/platsmp.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c
|
||||
index 8151400..2078f92d5 100644
|
||||
--- a/arch/arm/mach-mediatek/platsmp.c
|
||||
+++ b/arch/arm/mach-mediatek/platsmp.c
|
||||
@@ -53,6 +53,7 @@ static const struct mtk_smp_boot_info mtk_mt7623_boot = {
|
||||
static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = {
|
||||
{ .compatible = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot },
|
||||
{ .compatible = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot },
|
||||
+ { .compatible = "mediatek,mt2701", .data = &mtk_mt8135_tz_boot },
|
||||
};
|
||||
|
||||
static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,28 @@
|
||||
From 2e4a714f60266098a2b3553d1b1f83732da90abd Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 20 Jan 2016 13:12:19 +0100
|
||||
Subject: [PATCH 31/53] dt-bindings: ARM: Mediatek: add MT2701/7623 string to
|
||||
the PMIC wrapper doc
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Acked-by: Rob Herring <robh@kernel.org>
|
||||
Cc: devicetree@vger.kernel.org
|
||||
---
|
||||
Documentation/devicetree/bindings/soc/mediatek/pwrap.txt | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt b/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
|
||||
index ddeb5b6..107700d 100644
|
||||
--- a/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
|
||||
+++ b/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
|
||||
@@ -18,6 +18,7 @@ IP Pairing
|
||||
|
||||
Required properties in pwrap device node.
|
||||
- compatible:
|
||||
+ "mediatek,mt2701-pwrap" for MT2701/7623 SoCs
|
||||
"mediatek,mt8135-pwrap" for MT8135 SoCs
|
||||
"mediatek,mt8173-pwrap" for MT8173 SoCs
|
||||
- interrupts: IRQ for pwrap in SOC
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,98 @@
|
||||
From b68e33cc67465ad99299947916678f8ea4418b1c Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 20 Jan 2016 06:42:01 +0100
|
||||
Subject: [PATCH 32/53] soc: mediatek: PMIC wrap: don't duplicate the wrapper
|
||||
data
|
||||
|
||||
As we add support for more devices struct pmic_wrapper_type will grow and
|
||||
we do not really want to start duplicating all the elements in
|
||||
struct pmic_wrapper.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/soc/mediatek/mtk-pmic-wrap.c | 22 ++++++++--------------
|
||||
1 file changed, 8 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
index 0d9b19a..340c4b5 100644
|
||||
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
@@ -376,9 +376,7 @@ struct pmic_wrapper {
|
||||
struct device *dev;
|
||||
void __iomem *base;
|
||||
struct regmap *regmap;
|
||||
- int *regs;
|
||||
- enum pwrap_type type;
|
||||
- u32 arb_en_all;
|
||||
+ const struct pmic_wrapper_type *master;
|
||||
struct clk *clk_spi;
|
||||
struct clk *clk_wrap;
|
||||
struct reset_control *rstc;
|
||||
@@ -389,22 +387,22 @@ struct pmic_wrapper {
|
||||
|
||||
static inline int pwrap_is_mt8135(struct pmic_wrapper *wrp)
|
||||
{
|
||||
- return wrp->type == PWRAP_MT8135;
|
||||
+ return wrp->master->type == PWRAP_MT8135;
|
||||
}
|
||||
|
||||
static inline int pwrap_is_mt8173(struct pmic_wrapper *wrp)
|
||||
{
|
||||
- return wrp->type == PWRAP_MT8173;
|
||||
+ return wrp->master->type == PWRAP_MT8173;
|
||||
}
|
||||
|
||||
static u32 pwrap_readl(struct pmic_wrapper *wrp, enum pwrap_regs reg)
|
||||
{
|
||||
- return readl(wrp->base + wrp->regs[reg]);
|
||||
+ return readl(wrp->base + wrp->master->regs[reg]);
|
||||
}
|
||||
|
||||
static void pwrap_writel(struct pmic_wrapper *wrp, u32 val, enum pwrap_regs reg)
|
||||
{
|
||||
- writel(val, wrp->base + wrp->regs[reg]);
|
||||
+ writel(val, wrp->base + wrp->master->regs[reg]);
|
||||
}
|
||||
|
||||
static bool pwrap_is_fsm_idle(struct pmic_wrapper *wrp)
|
||||
@@ -697,7 +695,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
|
||||
pwrap_writel(wrp, 1, PWRAP_WRAP_EN);
|
||||
|
||||
- pwrap_writel(wrp, wrp->arb_en_all, PWRAP_HIPRIO_ARB_EN);
|
||||
+ pwrap_writel(wrp, wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN);
|
||||
|
||||
pwrap_writel(wrp, 1, PWRAP_WACS2_EN);
|
||||
|
||||
@@ -742,7 +740,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
pwrap_writel(wrp, 0x1, PWRAP_CRC_EN);
|
||||
pwrap_writel(wrp, 0x0, PWRAP_SIG_MODE);
|
||||
pwrap_writel(wrp, PWRAP_DEW_CRC_VAL, PWRAP_SIG_ADR);
|
||||
- pwrap_writel(wrp, wrp->arb_en_all, PWRAP_HIPRIO_ARB_EN);
|
||||
+ pwrap_writel(wrp, wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN);
|
||||
|
||||
if (pwrap_is_mt8135(wrp))
|
||||
pwrap_writel(wrp, 0x7, PWRAP_RRARB_EN);
|
||||
@@ -836,7 +834,6 @@ static int pwrap_probe(struct platform_device *pdev)
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
const struct of_device_id *of_id =
|
||||
of_match_device(of_pwrap_match_tbl, &pdev->dev);
|
||||
- const struct pmic_wrapper_type *type;
|
||||
struct resource *res;
|
||||
|
||||
wrp = devm_kzalloc(&pdev->dev, sizeof(*wrp), GFP_KERNEL);
|
||||
@@ -845,10 +842,7 @@ static int pwrap_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, wrp);
|
||||
|
||||
- type = of_id->data;
|
||||
- wrp->regs = type->regs;
|
||||
- wrp->type = type->type;
|
||||
- wrp->arb_en_all = type->arb_en_all;
|
||||
+ wrp->master = of_id->data;
|
||||
wrp->dev = &pdev->dev;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwrap");
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,127 @@
|
||||
From 45ead148322ba7be9de970a2ab6be4ed3f7ca184 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 20 Jan 2016 05:27:17 +0100
|
||||
Subject: [PATCH 33/53] soc: mediatek: PMIC wrap: add wrapper callbacks for
|
||||
init_reg_clock
|
||||
|
||||
Split init_reg_clock up into SoC specific callbacks. The patch also
|
||||
reorders the code to avoid the need for callback function prototypes.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/soc/mediatek/mtk-pmic-wrap.c | 70 ++++++++++++++++++----------------
|
||||
1 file changed, 38 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
index 340c4b5..b22b664 100644
|
||||
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
@@ -354,24 +354,6 @@ enum pwrap_type {
|
||||
PWRAP_MT8173,
|
||||
};
|
||||
|
||||
-struct pmic_wrapper_type {
|
||||
- int *regs;
|
||||
- enum pwrap_type type;
|
||||
- u32 arb_en_all;
|
||||
-};
|
||||
-
|
||||
-static struct pmic_wrapper_type pwrap_mt8135 = {
|
||||
- .regs = mt8135_regs,
|
||||
- .type = PWRAP_MT8135,
|
||||
- .arb_en_all = 0x1ff,
|
||||
-};
|
||||
-
|
||||
-static struct pmic_wrapper_type pwrap_mt8173 = {
|
||||
- .regs = mt8173_regs,
|
||||
- .type = PWRAP_MT8173,
|
||||
- .arb_en_all = 0x3f,
|
||||
-};
|
||||
-
|
||||
struct pmic_wrapper {
|
||||
struct device *dev;
|
||||
void __iomem *base;
|
||||
@@ -385,6 +367,13 @@ struct pmic_wrapper {
|
||||
void __iomem *bridge_base;
|
||||
};
|
||||
|
||||
+struct pmic_wrapper_type {
|
||||
+ int *regs;
|
||||
+ enum pwrap_type type;
|
||||
+ u32 arb_en_all;
|
||||
+ int (*init_reg_clock)(struct pmic_wrapper *wrp);
|
||||
+};
|
||||
+
|
||||
static inline int pwrap_is_mt8135(struct pmic_wrapper *wrp)
|
||||
{
|
||||
return wrp->master->type == PWRAP_MT8135;
|
||||
@@ -578,20 +567,23 @@ static int pwrap_init_sidly(struct pmic_wrapper *wrp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int pwrap_init_reg_clock(struct pmic_wrapper *wrp)
|
||||
+static int pwrap_mt8135_init_reg_clock(struct pmic_wrapper *wrp)
|
||||
{
|
||||
- if (pwrap_is_mt8135(wrp)) {
|
||||
- pwrap_writel(wrp, 0x4, PWRAP_CSHEXT);
|
||||
- pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE);
|
||||
- pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ);
|
||||
- pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_START);
|
||||
- pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_END);
|
||||
- } else {
|
||||
- pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE);
|
||||
- pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ);
|
||||
- pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START);
|
||||
- pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END);
|
||||
- }
|
||||
+ pwrap_writel(wrp, 0x4, PWRAP_CSHEXT);
|
||||
+ pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE);
|
||||
+ pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ);
|
||||
+ pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_START);
|
||||
+ pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_END);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int pwrap_mt8173_init_reg_clock(struct pmic_wrapper *wrp)
|
||||
+{
|
||||
+ pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE);
|
||||
+ pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ);
|
||||
+ pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START);
|
||||
+ pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -699,7 +691,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
|
||||
pwrap_writel(wrp, 1, PWRAP_WACS2_EN);
|
||||
|
||||
- ret = pwrap_init_reg_clock(wrp);
|
||||
+ ret = wrp->master->init_reg_clock(wrp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -814,6 +806,20 @@ static const struct regmap_config pwrap_regmap_config = {
|
||||
.max_register = 0xffff,
|
||||
};
|
||||
|
||||
+static struct pmic_wrapper_type pwrap_mt8135 = {
|
||||
+ .regs = mt8135_regs,
|
||||
+ .type = PWRAP_MT8135,
|
||||
+ .arb_en_all = 0x1ff,
|
||||
+ .init_reg_clock = pwrap_mt8135_init_reg_clock,
|
||||
+};
|
||||
+
|
||||
+static struct pmic_wrapper_type pwrap_mt8173 = {
|
||||
+ .regs = mt8173_regs,
|
||||
+ .type = PWRAP_MT8173,
|
||||
+ .arb_en_all = 0x3f,
|
||||
+ .init_reg_clock = pwrap_mt8173_init_reg_clock,
|
||||
+};
|
||||
+
|
||||
static struct of_device_id of_pwrap_match_tbl[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt8135-pwrap",
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,127 @@
|
||||
From b3cc9f4c4b1164ac6a0700920eca84dff81d13d7 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 20 Jan 2016 10:12:00 +0100
|
||||
Subject: [PATCH 34/53] soc: mediatek: PMIC wrap: split SoC specific init into
|
||||
callback
|
||||
|
||||
This patch moves the SoC specific wrapper init code into separate callback
|
||||
to avoid pwrap_init() getting too large. This is done by adding a new
|
||||
element called init_special to pmic_wrapper_type. Each currently supported
|
||||
SoC gets its own version of the callback and we copy the code that was
|
||||
previously inside pwrap_init() to these new callbacks. Finally we point the
|
||||
2 instances of pmic_wrapper_type at the 2 new functions.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/soc/mediatek/mtk-pmic-wrap.c | 67 +++++++++++++++++++++-------------
|
||||
1 file changed, 42 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
index b22b664..22c89e9 100644
|
||||
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
@@ -372,6 +372,7 @@ struct pmic_wrapper_type {
|
||||
enum pwrap_type type;
|
||||
u32 arb_en_all;
|
||||
int (*init_reg_clock)(struct pmic_wrapper *wrp);
|
||||
+ int (*init_soc_specific)(struct pmic_wrapper *wrp);
|
||||
};
|
||||
|
||||
static inline int pwrap_is_mt8135(struct pmic_wrapper *wrp)
|
||||
@@ -665,6 +666,41 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int pwrap_mt8135_init_soc_specific(struct pmic_wrapper *wrp)
|
||||
+{
|
||||
+ /* enable pwrap events and pwrap bridge in AP side */
|
||||
+ pwrap_writel(wrp, 0x1, PWRAP_EVENT_IN_EN);
|
||||
+ pwrap_writel(wrp, 0xffff, PWRAP_EVENT_DST_EN);
|
||||
+ writel(0x7f, wrp->bridge_base + PWRAP_MT8135_BRIDGE_IORD_ARB_EN);
|
||||
+ writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WACS3_EN);
|
||||
+ writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WACS4_EN);
|
||||
+ writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WDT_UNIT);
|
||||
+ writel(0xffff, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WDT_SRC_EN);
|
||||
+ writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_TIMER_EN);
|
||||
+ writel(0x7ff, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INT_EN);
|
||||
+
|
||||
+ /* enable PMIC event out and sources */
|
||||
+ if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
|
||||
+ pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
|
||||
+ dev_err(wrp->dev, "enable dewrap fail\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int pwrap_mt8173_init_soc_specific(struct pmic_wrapper *wrp)
|
||||
+{
|
||||
+ /* PMIC_DEWRAP enables */
|
||||
+ if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
|
||||
+ pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
|
||||
+ dev_err(wrp->dev, "enable dewrap fail\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
{
|
||||
int ret;
|
||||
@@ -743,31 +779,10 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
pwrap_writel(wrp, 0x5, PWRAP_STAUPD_PRD);
|
||||
pwrap_writel(wrp, 0xff, PWRAP_STAUPD_GRPEN);
|
||||
|
||||
- if (pwrap_is_mt8135(wrp)) {
|
||||
- /* enable pwrap events and pwrap bridge in AP side */
|
||||
- pwrap_writel(wrp, 0x1, PWRAP_EVENT_IN_EN);
|
||||
- pwrap_writel(wrp, 0xffff, PWRAP_EVENT_DST_EN);
|
||||
- writel(0x7f, wrp->bridge_base + PWRAP_MT8135_BRIDGE_IORD_ARB_EN);
|
||||
- writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WACS3_EN);
|
||||
- writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WACS4_EN);
|
||||
- writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WDT_UNIT);
|
||||
- writel(0xffff, wrp->bridge_base + PWRAP_MT8135_BRIDGE_WDT_SRC_EN);
|
||||
- writel(0x1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_TIMER_EN);
|
||||
- writel(0x7ff, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INT_EN);
|
||||
-
|
||||
- /* enable PMIC event out and sources */
|
||||
- if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
|
||||
- pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
|
||||
- dev_err(wrp->dev, "enable dewrap fail\n");
|
||||
- return -EFAULT;
|
||||
- }
|
||||
- } else {
|
||||
- /* PMIC_DEWRAP enables */
|
||||
- if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
|
||||
- pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
|
||||
- dev_err(wrp->dev, "enable dewrap fail\n");
|
||||
- return -EFAULT;
|
||||
- }
|
||||
+ if (wrp->master->init_soc_specific) {
|
||||
+ ret = wrp->master->init_soc_specific(wrp);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/* Setup the init done registers */
|
||||
@@ -811,6 +826,7 @@ static struct pmic_wrapper_type pwrap_mt8135 = {
|
||||
.type = PWRAP_MT8135,
|
||||
.arb_en_all = 0x1ff,
|
||||
.init_reg_clock = pwrap_mt8135_init_reg_clock,
|
||||
+ .init_soc_specific = pwrap_mt8135_init_soc_specific,
|
||||
};
|
||||
|
||||
static struct pmic_wrapper_type pwrap_mt8173 = {
|
||||
@@ -818,6 +834,7 @@ static struct pmic_wrapper_type pwrap_mt8173 = {
|
||||
.type = PWRAP_MT8173,
|
||||
.arb_en_all = 0x3f,
|
||||
.init_reg_clock = pwrap_mt8173_init_reg_clock,
|
||||
+ .init_soc_specific = pwrap_mt8173_init_soc_specific,
|
||||
};
|
||||
|
||||
static struct of_device_id of_pwrap_match_tbl[] = {
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,53 @@
|
||||
From 824563fe3d8b915714816255489fcfb2792c3a8a Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 20 Jan 2016 10:14:39 +0100
|
||||
Subject: [PATCH 35/53] soc: mediatek: PMIC wrap: WRAP_INT_EN needs a
|
||||
different bitmask for MT2701/7623
|
||||
|
||||
MT2701 and MT7623 use a different bitmask for PWRAP_INT_EN.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/soc/mediatek/mtk-pmic-wrap.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
index 22c89e9..9df1135 100644
|
||||
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
@@ -371,6 +371,7 @@ struct pmic_wrapper_type {
|
||||
int *regs;
|
||||
enum pwrap_type type;
|
||||
u32 arb_en_all;
|
||||
+ u32 int_en_all;
|
||||
int (*init_reg_clock)(struct pmic_wrapper *wrp);
|
||||
int (*init_soc_specific)(struct pmic_wrapper *wrp);
|
||||
};
|
||||
@@ -825,6 +826,7 @@ static struct pmic_wrapper_type pwrap_mt8135 = {
|
||||
.regs = mt8135_regs,
|
||||
.type = PWRAP_MT8135,
|
||||
.arb_en_all = 0x1ff,
|
||||
+ .int_en_all = ~(BIT(31) | BIT(1)),
|
||||
.init_reg_clock = pwrap_mt8135_init_reg_clock,
|
||||
.init_soc_specific = pwrap_mt8135_init_soc_specific,
|
||||
};
|
||||
@@ -833,6 +835,7 @@ static struct pmic_wrapper_type pwrap_mt8173 = {
|
||||
.regs = mt8173_regs,
|
||||
.type = PWRAP_MT8173,
|
||||
.arb_en_all = 0x3f,
|
||||
+ .int_en_all = ~(BIT(31) | BIT(1)),
|
||||
.init_reg_clock = pwrap_mt8173_init_reg_clock,
|
||||
.init_soc_specific = pwrap_mt8173_init_soc_specific,
|
||||
};
|
||||
@@ -946,7 +949,7 @@ static int pwrap_probe(struct platform_device *pdev)
|
||||
PWRAP_WDT_SRC_MASK_NO_STAUPD : PWRAP_WDT_SRC_MASK_ALL;
|
||||
pwrap_writel(wrp, wdt_src, PWRAP_WDT_SRC_EN);
|
||||
pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
|
||||
- pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN);
|
||||
+ pwrap_writel(wrp, wrp->master->int_en_all, PWRAP_INT_EN);
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt, IRQF_TRIGGER_HIGH,
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,66 @@
|
||||
From 2028a24d161da25b827b394bdcec4deba5d2efd9 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 20 Jan 2016 10:21:42 +0100
|
||||
Subject: [PATCH 36/53] soc: mediatek: PMIC wrap: SPI_WRITE needs a different
|
||||
bitmask for MT2701/7623
|
||||
|
||||
Different SoCs will use different bitmask for the SPI_WRITE command. This
|
||||
patch defines the bitmask in the pmic_wrapper_type struct. This allows us
|
||||
to support new SoCs with a different bitmask to the one currently used.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/soc/mediatek/mtk-pmic-wrap.c | 11 +++++++----
|
||||
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
index 9df1135..8ce1bad 100644
|
||||
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
@@ -372,6 +372,7 @@ struct pmic_wrapper_type {
|
||||
enum pwrap_type type;
|
||||
u32 arb_en_all;
|
||||
u32 int_en_all;
|
||||
+ u32 spi_w;
|
||||
int (*init_reg_clock)(struct pmic_wrapper *wrp);
|
||||
int (*init_soc_specific)(struct pmic_wrapper *wrp);
|
||||
};
|
||||
@@ -511,15 +512,15 @@ static int pwrap_reset_spislave(struct pmic_wrapper *wrp)
|
||||
pwrap_writel(wrp, 1, PWRAP_MAN_EN);
|
||||
pwrap_writel(wrp, 0, PWRAP_DIO_EN);
|
||||
|
||||
- pwrap_writel(wrp, PWRAP_MAN_CMD_SPI_WRITE | PWRAP_MAN_CMD_OP_CSL,
|
||||
+ pwrap_writel(wrp, wrp->master->spi_w | PWRAP_MAN_CMD_OP_CSL,
|
||||
PWRAP_MAN_CMD);
|
||||
- pwrap_writel(wrp, PWRAP_MAN_CMD_SPI_WRITE | PWRAP_MAN_CMD_OP_OUTS,
|
||||
+ pwrap_writel(wrp, wrp->master->spi_w | PWRAP_MAN_CMD_OP_OUTS,
|
||||
PWRAP_MAN_CMD);
|
||||
- pwrap_writel(wrp, PWRAP_MAN_CMD_SPI_WRITE | PWRAP_MAN_CMD_OP_CSH,
|
||||
+ pwrap_writel(wrp, wrp->master->spi_w | PWRAP_MAN_CMD_OP_CSH,
|
||||
PWRAP_MAN_CMD);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
- pwrap_writel(wrp, PWRAP_MAN_CMD_SPI_WRITE | PWRAP_MAN_CMD_OP_OUTS,
|
||||
+ pwrap_writel(wrp, wrp->master->spi_w | PWRAP_MAN_CMD_OP_OUTS,
|
||||
PWRAP_MAN_CMD);
|
||||
|
||||
ret = pwrap_wait_for_state(wrp, pwrap_is_sync_idle);
|
||||
@@ -827,6 +828,7 @@ static struct pmic_wrapper_type pwrap_mt8135 = {
|
||||
.type = PWRAP_MT8135,
|
||||
.arb_en_all = 0x1ff,
|
||||
.int_en_all = ~(BIT(31) | BIT(1)),
|
||||
+ .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
|
||||
.init_reg_clock = pwrap_mt8135_init_reg_clock,
|
||||
.init_soc_specific = pwrap_mt8135_init_soc_specific,
|
||||
};
|
||||
@@ -836,6 +838,7 @@ static struct pmic_wrapper_type pwrap_mt8173 = {
|
||||
.type = PWRAP_MT8173,
|
||||
.arb_en_all = 0x3f,
|
||||
.int_en_all = ~(BIT(31) | BIT(1)),
|
||||
+ .spi_w = PWRAP_MAN_CMD_SPI_WRITE,
|
||||
.init_reg_clock = pwrap_mt8173_init_reg_clock,
|
||||
.init_soc_specific = pwrap_mt8173_init_soc_specific,
|
||||
};
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,66 @@
|
||||
From 50bd0c152a0c33000ae88d0828f320eb603fd535 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 20 Jan 2016 10:48:35 +0100
|
||||
Subject: [PATCH 37/53] soc: mediatek: PMIC wrap: move wdt_src into the
|
||||
pmic_wrapper_type struct
|
||||
|
||||
Different SoCs will use different bitmask for the wdt_src. This patch
|
||||
defines the bitmask in the pmic_wrapper_type struct. This allows us to
|
||||
support new SoCs with a different bitmask to the one currently used.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/soc/mediatek/mtk-pmic-wrap.c | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
index 8ce1bad..aa54df3 100644
|
||||
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
@@ -373,6 +373,7 @@ struct pmic_wrapper_type {
|
||||
u32 arb_en_all;
|
||||
u32 int_en_all;
|
||||
u32 spi_w;
|
||||
+ u32 wdt_src;
|
||||
int (*init_reg_clock)(struct pmic_wrapper *wrp);
|
||||
int (*init_soc_specific)(struct pmic_wrapper *wrp);
|
||||
};
|
||||
@@ -829,6 +830,7 @@ static struct pmic_wrapper_type pwrap_mt8135 = {
|
||||
.arb_en_all = 0x1ff,
|
||||
.int_en_all = ~(BIT(31) | BIT(1)),
|
||||
.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
|
||||
+ .wdt_src = PWRAP_WDT_SRC_MASK_ALL,
|
||||
.init_reg_clock = pwrap_mt8135_init_reg_clock,
|
||||
.init_soc_specific = pwrap_mt8135_init_soc_specific,
|
||||
};
|
||||
@@ -839,6 +841,7 @@ static struct pmic_wrapper_type pwrap_mt8173 = {
|
||||
.arb_en_all = 0x3f,
|
||||
.int_en_all = ~(BIT(31) | BIT(1)),
|
||||
.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
|
||||
+ .wdt_src = PWRAP_WDT_SRC_MASK_NO_STAUPD,
|
||||
.init_reg_clock = pwrap_mt8173_init_reg_clock,
|
||||
.init_soc_specific = pwrap_mt8173_init_soc_specific,
|
||||
};
|
||||
@@ -858,7 +861,7 @@ MODULE_DEVICE_TABLE(of, of_pwrap_match_tbl);
|
||||
|
||||
static int pwrap_probe(struct platform_device *pdev)
|
||||
{
|
||||
- int ret, irq, wdt_src;
|
||||
+ int ret, irq;
|
||||
struct pmic_wrapper *wrp;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
const struct of_device_id *of_id =
|
||||
@@ -948,9 +951,7 @@ static int pwrap_probe(struct platform_device *pdev)
|
||||
* Since STAUPD was not used on mt8173 platform,
|
||||
* so STAUPD of WDT_SRC which should be turned off
|
||||
*/
|
||||
- wdt_src = pwrap_is_mt8173(wrp) ?
|
||||
- PWRAP_WDT_SRC_MASK_NO_STAUPD : PWRAP_WDT_SRC_MASK_ALL;
|
||||
- pwrap_writel(wrp, wdt_src, PWRAP_WDT_SRC_EN);
|
||||
+ pwrap_writel(wrp, wrp->master->wdt_src, PWRAP_WDT_SRC_EN);
|
||||
pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
|
||||
pwrap_writel(wrp, wrp->master->int_en_all, PWRAP_INT_EN);
|
||||
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,118 @@
|
||||
From f08ce6b84d2759fdff2e8ea2cf2b30b3220521ef Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 20 Jan 2016 10:54:18 +0100
|
||||
Subject: [PATCH 38/53] soc: mediatek: PMIC wrap: remove pwrap_is_mt8135() and
|
||||
pwrap_is_mt8173()
|
||||
|
||||
With more SoCs being added the list of helper functions like these would
|
||||
grow. To mitigate this problem we remove the existing helpers and change
|
||||
the code to test against the pmic type stored inside the pmic specific
|
||||
datastructure that our context structure points at. There is one usage of
|
||||
pwrap_is_mt8135() that is ambiguous as the test should not be dependent on
|
||||
mt8135, but rather on the existence of a bridge. Add a new element to
|
||||
pmic_wrapper_type to indicate if a bridge is present and use this where
|
||||
appropriate.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/soc/mediatek/mtk-pmic-wrap.c | 28 ++++++++++++----------------
|
||||
1 file changed, 12 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
index aa54df3..a2bacda 100644
|
||||
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
@@ -374,20 +374,11 @@ struct pmic_wrapper_type {
|
||||
u32 int_en_all;
|
||||
u32 spi_w;
|
||||
u32 wdt_src;
|
||||
+ int has_bridge:1;
|
||||
int (*init_reg_clock)(struct pmic_wrapper *wrp);
|
||||
int (*init_soc_specific)(struct pmic_wrapper *wrp);
|
||||
};
|
||||
|
||||
-static inline int pwrap_is_mt8135(struct pmic_wrapper *wrp)
|
||||
-{
|
||||
- return wrp->master->type == PWRAP_MT8135;
|
||||
-}
|
||||
-
|
||||
-static inline int pwrap_is_mt8173(struct pmic_wrapper *wrp)
|
||||
-{
|
||||
- return wrp->master->type == PWRAP_MT8173;
|
||||
-}
|
||||
-
|
||||
static u32 pwrap_readl(struct pmic_wrapper *wrp, enum pwrap_regs reg)
|
||||
{
|
||||
return readl(wrp->base + wrp->master->regs[reg]);
|
||||
@@ -619,11 +610,14 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
|
||||
pwrap_writel(wrp, 0x1, PWRAP_CIPHER_KEY_SEL);
|
||||
pwrap_writel(wrp, 0x2, PWRAP_CIPHER_IV_SEL);
|
||||
|
||||
- if (pwrap_is_mt8135(wrp)) {
|
||||
+ switch (wrp->master->type) {
|
||||
+ case PWRAP_MT8135:
|
||||
pwrap_writel(wrp, 1, PWRAP_CIPHER_LOAD);
|
||||
pwrap_writel(wrp, 1, PWRAP_CIPHER_START);
|
||||
- } else {
|
||||
+ break;
|
||||
+ case PWRAP_MT8173:
|
||||
pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);
|
||||
+ break;
|
||||
}
|
||||
|
||||
/* Config cipher mode @PMIC */
|
||||
@@ -713,7 +707,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
if (wrp->rstc_bridge)
|
||||
reset_control_reset(wrp->rstc_bridge);
|
||||
|
||||
- if (pwrap_is_mt8173(wrp)) {
|
||||
+ if (wrp->master->type == PWRAP_MT8173) {
|
||||
/* Enable DCM */
|
||||
pwrap_writel(wrp, 3, PWRAP_DCM_EN);
|
||||
pwrap_writel(wrp, 0, PWRAP_DCM_DBC_PRD);
|
||||
@@ -773,7 +767,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
pwrap_writel(wrp, PWRAP_DEW_CRC_VAL, PWRAP_SIG_ADR);
|
||||
pwrap_writel(wrp, wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN);
|
||||
|
||||
- if (pwrap_is_mt8135(wrp))
|
||||
+ if (wrp->master->type == PWRAP_MT8135)
|
||||
pwrap_writel(wrp, 0x7, PWRAP_RRARB_EN);
|
||||
|
||||
pwrap_writel(wrp, 0x1, PWRAP_WACS0_EN);
|
||||
@@ -793,7 +787,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
pwrap_writel(wrp, 1, PWRAP_INIT_DONE0);
|
||||
pwrap_writel(wrp, 1, PWRAP_INIT_DONE1);
|
||||
|
||||
- if (pwrap_is_mt8135(wrp)) {
|
||||
+ if (wrp->master->has_bridge) {
|
||||
writel(1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INIT_DONE3);
|
||||
writel(1, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INIT_DONE4);
|
||||
}
|
||||
@@ -831,6 +825,7 @@ static struct pmic_wrapper_type pwrap_mt8135 = {
|
||||
.int_en_all = ~(BIT(31) | BIT(1)),
|
||||
.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
|
||||
.wdt_src = PWRAP_WDT_SRC_MASK_ALL,
|
||||
+ .has_bridge = 1,
|
||||
.init_reg_clock = pwrap_mt8135_init_reg_clock,
|
||||
.init_soc_specific = pwrap_mt8135_init_soc_specific,
|
||||
};
|
||||
@@ -842,6 +837,7 @@ static struct pmic_wrapper_type pwrap_mt8173 = {
|
||||
.int_en_all = ~(BIT(31) | BIT(1)),
|
||||
.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
|
||||
.wdt_src = PWRAP_WDT_SRC_MASK_NO_STAUPD,
|
||||
+ .has_bridge = 0,
|
||||
.init_reg_clock = pwrap_mt8173_init_reg_clock,
|
||||
.init_soc_specific = pwrap_mt8173_init_soc_specific,
|
||||
};
|
||||
@@ -889,7 +885,7 @@ static int pwrap_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- if (pwrap_is_mt8135(wrp)) {
|
||||
+ if (wrp->master->has_bridge) {
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"pwrap-bridge");
|
||||
wrp->bridge_base = devm_ioremap_resource(wrp->dev, res);
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,301 @@
|
||||
From 7c6b5e5e36ccd9079a2425dc80507447784b9bb2 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 20 Jan 2016 09:55:08 +0100
|
||||
Subject: [PATCH 39/53] soc: mediatek: PMIC wrap: add a slave specific struct
|
||||
|
||||
This patch adds a new struct pwrap_slv_type that we use to store the slave
|
||||
specific data. The patch adds 2 new helper functions to access the dew
|
||||
registers. The slave type is looked up via the wrappers child node.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/soc/mediatek/mtk-pmic-wrap.c | 159 ++++++++++++++++++++++++----------
|
||||
1 file changed, 112 insertions(+), 47 deletions(-)
|
||||
|
||||
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
index a2bacda..bcc841e 100644
|
||||
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
@@ -69,33 +69,54 @@
|
||||
PWRAP_WDT_SRC_EN_HARB_STAUPD_DLE | \
|
||||
PWRAP_WDT_SRC_EN_HARB_STAUPD_ALE)
|
||||
|
||||
-/* macro for slave device wrapper registers */
|
||||
-#define PWRAP_DEW_BASE 0xbc00
|
||||
-#define PWRAP_DEW_EVENT_OUT_EN (PWRAP_DEW_BASE + 0x0)
|
||||
-#define PWRAP_DEW_DIO_EN (PWRAP_DEW_BASE + 0x2)
|
||||
-#define PWRAP_DEW_EVENT_SRC_EN (PWRAP_DEW_BASE + 0x4)
|
||||
-#define PWRAP_DEW_EVENT_SRC (PWRAP_DEW_BASE + 0x6)
|
||||
-#define PWRAP_DEW_EVENT_FLAG (PWRAP_DEW_BASE + 0x8)
|
||||
-#define PWRAP_DEW_READ_TEST (PWRAP_DEW_BASE + 0xa)
|
||||
-#define PWRAP_DEW_WRITE_TEST (PWRAP_DEW_BASE + 0xc)
|
||||
-#define PWRAP_DEW_CRC_EN (PWRAP_DEW_BASE + 0xe)
|
||||
-#define PWRAP_DEW_CRC_VAL (PWRAP_DEW_BASE + 0x10)
|
||||
-#define PWRAP_DEW_MON_GRP_SEL (PWRAP_DEW_BASE + 0x12)
|
||||
-#define PWRAP_DEW_MON_FLAG_SEL (PWRAP_DEW_BASE + 0x14)
|
||||
-#define PWRAP_DEW_EVENT_TEST (PWRAP_DEW_BASE + 0x16)
|
||||
-#define PWRAP_DEW_CIPHER_KEY_SEL (PWRAP_DEW_BASE + 0x18)
|
||||
-#define PWRAP_DEW_CIPHER_IV_SEL (PWRAP_DEW_BASE + 0x1a)
|
||||
-#define PWRAP_DEW_CIPHER_LOAD (PWRAP_DEW_BASE + 0x1c)
|
||||
-#define PWRAP_DEW_CIPHER_START (PWRAP_DEW_BASE + 0x1e)
|
||||
-#define PWRAP_DEW_CIPHER_RDY (PWRAP_DEW_BASE + 0x20)
|
||||
-#define PWRAP_DEW_CIPHER_MODE (PWRAP_DEW_BASE + 0x22)
|
||||
-#define PWRAP_DEW_CIPHER_SWRST (PWRAP_DEW_BASE + 0x24)
|
||||
-#define PWRAP_MT8173_DEW_CIPHER_IV0 (PWRAP_DEW_BASE + 0x26)
|
||||
-#define PWRAP_MT8173_DEW_CIPHER_IV1 (PWRAP_DEW_BASE + 0x28)
|
||||
-#define PWRAP_MT8173_DEW_CIPHER_IV2 (PWRAP_DEW_BASE + 0x2a)
|
||||
-#define PWRAP_MT8173_DEW_CIPHER_IV3 (PWRAP_DEW_BASE + 0x2c)
|
||||
-#define PWRAP_MT8173_DEW_CIPHER_IV4 (PWRAP_DEW_BASE + 0x2e)
|
||||
-#define PWRAP_MT8173_DEW_CIPHER_IV5 (PWRAP_DEW_BASE + 0x30)
|
||||
+/* defines for slave device wrapper registers */
|
||||
+enum dew_regs {
|
||||
+ PWRAP_DEW_BASE,
|
||||
+ PWRAP_DEW_DIO_EN,
|
||||
+ PWRAP_DEW_READ_TEST,
|
||||
+ PWRAP_DEW_WRITE_TEST,
|
||||
+ PWRAP_DEW_CRC_EN,
|
||||
+ PWRAP_DEW_CRC_VAL,
|
||||
+ PWRAP_DEW_MON_GRP_SEL,
|
||||
+ PWRAP_DEW_CIPHER_KEY_SEL,
|
||||
+ PWRAP_DEW_CIPHER_IV_SEL,
|
||||
+ PWRAP_DEW_CIPHER_RDY,
|
||||
+ PWRAP_DEW_CIPHER_MODE,
|
||||
+ PWRAP_DEW_CIPHER_SWRST,
|
||||
+
|
||||
+ /* MT6397 only regs */
|
||||
+ PWRAP_DEW_EVENT_OUT_EN,
|
||||
+ PWRAP_DEW_EVENT_SRC_EN,
|
||||
+ PWRAP_DEW_EVENT_SRC,
|
||||
+ PWRAP_DEW_EVENT_FLAG,
|
||||
+ PWRAP_DEW_MON_FLAG_SEL,
|
||||
+ PWRAP_DEW_EVENT_TEST,
|
||||
+ PWRAP_DEW_CIPHER_LOAD,
|
||||
+ PWRAP_DEW_CIPHER_START,
|
||||
+};
|
||||
+
|
||||
+static const u32 mt6397_regs[] = {
|
||||
+ [PWRAP_DEW_BASE] = 0xbc00,
|
||||
+ [PWRAP_DEW_EVENT_OUT_EN] = 0xbc00,
|
||||
+ [PWRAP_DEW_DIO_EN] = 0xbc02,
|
||||
+ [PWRAP_DEW_EVENT_SRC_EN] = 0xbc04,
|
||||
+ [PWRAP_DEW_EVENT_SRC] = 0xbc06,
|
||||
+ [PWRAP_DEW_EVENT_FLAG] = 0xbc08,
|
||||
+ [PWRAP_DEW_READ_TEST] = 0xbc0a,
|
||||
+ [PWRAP_DEW_WRITE_TEST] = 0xbc0c,
|
||||
+ [PWRAP_DEW_CRC_EN] = 0xbc0e,
|
||||
+ [PWRAP_DEW_CRC_VAL] = 0xbc10,
|
||||
+ [PWRAP_DEW_MON_GRP_SEL] = 0xbc12,
|
||||
+ [PWRAP_DEW_MON_FLAG_SEL] = 0xbc14,
|
||||
+ [PWRAP_DEW_EVENT_TEST] = 0xbc16,
|
||||
+ [PWRAP_DEW_CIPHER_KEY_SEL] = 0xbc18,
|
||||
+ [PWRAP_DEW_CIPHER_IV_SEL] = 0xbc1a,
|
||||
+ [PWRAP_DEW_CIPHER_LOAD] = 0xbc1c,
|
||||
+ [PWRAP_DEW_CIPHER_START] = 0xbc1e,
|
||||
+ [PWRAP_DEW_CIPHER_RDY] = 0xbc20,
|
||||
+ [PWRAP_DEW_CIPHER_MODE] = 0xbc22,
|
||||
+ [PWRAP_DEW_CIPHER_SWRST] = 0xbc24,
|
||||
+};
|
||||
|
||||
enum pwrap_regs {
|
||||
PWRAP_MUX_SEL,
|
||||
@@ -349,16 +370,26 @@ static int mt8135_regs[] = {
|
||||
[PWRAP_DCM_DBC_PRD] = 0x160,
|
||||
};
|
||||
|
||||
+enum pmic_type {
|
||||
+ PMIC_MT6397,
|
||||
+};
|
||||
+
|
||||
enum pwrap_type {
|
||||
PWRAP_MT8135,
|
||||
PWRAP_MT8173,
|
||||
};
|
||||
|
||||
+struct pwrap_slv_type {
|
||||
+ const u32 *dew_regs;
|
||||
+ enum pmic_type type;
|
||||
+};
|
||||
+
|
||||
struct pmic_wrapper {
|
||||
struct device *dev;
|
||||
void __iomem *base;
|
||||
struct regmap *regmap;
|
||||
const struct pmic_wrapper_type *master;
|
||||
+ const struct pwrap_slv_type *slave;
|
||||
struct clk *clk_spi;
|
||||
struct clk *clk_wrap;
|
||||
struct reset_control *rstc;
|
||||
@@ -544,7 +575,8 @@ static int pwrap_init_sidly(struct pmic_wrapper *wrp)
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
pwrap_writel(wrp, i, PWRAP_SIDLY);
|
||||
- pwrap_read(wrp, PWRAP_DEW_READ_TEST, &rdata);
|
||||
+ pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_READ_TEST],
|
||||
+ &rdata);
|
||||
if (rdata == PWRAP_DEW_READ_TEST_VAL) {
|
||||
dev_dbg(wrp->dev, "[Read Test] pass, SIDLY=%x\n", i);
|
||||
pass |= 1 << i;
|
||||
@@ -593,7 +625,8 @@ static bool pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp)
|
||||
u32 rdata;
|
||||
int ret;
|
||||
|
||||
- ret = pwrap_read(wrp, PWRAP_DEW_CIPHER_RDY, &rdata);
|
||||
+ ret = pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_RDY],
|
||||
+ &rdata);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
@@ -621,12 +654,12 @@ static int pwrap_init_cipher(struct pmic_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_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x1);
|
||||
+ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_SWRST], 0x0);
|
||||
+ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_KEY_SEL], 0x1);
|
||||
+ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_IV_SEL], 0x2);
|
||||
+ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_LOAD], 0x1);
|
||||
+ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_START], 0x1);
|
||||
|
||||
/* wait for cipher data ready@AP */
|
||||
ret = pwrap_wait_for_state(wrp, pwrap_is_cipher_ready);
|
||||
@@ -643,7 +676,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
|
||||
}
|
||||
|
||||
/* wait for cipher mode idle */
|
||||
- pwrap_write(wrp, PWRAP_DEW_CIPHER_MODE, 0x1);
|
||||
+ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_MODE], 0x1);
|
||||
ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle);
|
||||
if (ret) {
|
||||
dev_err(wrp->dev, "cipher mode idle fail, ret=%d\n", ret);
|
||||
@@ -653,9 +686,11 @@ static int pwrap_init_cipher(struct pmic_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) ||
|
||||
- (rdata != PWRAP_DEW_WRITE_TEST_VAL)) {
|
||||
+ if (pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_WRITE_TEST],
|
||||
+ PWRAP_DEW_WRITE_TEST_VAL) ||
|
||||
+ pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_WRITE_TEST],
|
||||
+ &rdata) ||
|
||||
+ (rdata != PWRAP_DEW_WRITE_TEST_VAL)) {
|
||||
dev_err(wrp->dev, "rdata=0x%04X\n", rdata);
|
||||
return -EFAULT;
|
||||
}
|
||||
@@ -677,8 +712,10 @@ static int pwrap_mt8135_init_soc_specific(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_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_EVENT_OUT_EN],
|
||||
+ 0x1) ||
|
||||
+ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_EVENT_SRC_EN],
|
||||
+ 0xffff)) {
|
||||
dev_err(wrp->dev, "enable dewrap fail\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
@@ -689,8 +726,10 @@ static int pwrap_mt8135_init_soc_specific(struct pmic_wrapper *wrp)
|
||||
static int pwrap_mt8173_init_soc_specific(struct pmic_wrapper *wrp)
|
||||
{
|
||||
/* PMIC_DEWRAP enables */
|
||||
- if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) ||
|
||||
- pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) {
|
||||
+ if (pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_EVENT_OUT_EN],
|
||||
+ 0x1) ||
|
||||
+ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_EVENT_SRC_EN],
|
||||
+ 0xffff)) {
|
||||
dev_err(wrp->dev, "enable dewrap fail\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
@@ -734,7 +773,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
return ret;
|
||||
|
||||
/* Enable dual IO mode */
|
||||
- pwrap_write(wrp, PWRAP_DEW_DIO_EN, 1);
|
||||
+ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_DIO_EN], 1);
|
||||
|
||||
/* Check IDLE & INIT_DONE in advance */
|
||||
ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle);
|
||||
@@ -746,7 +785,7 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
pwrap_writel(wrp, 1, PWRAP_DIO_EN);
|
||||
|
||||
/* Read Test */
|
||||
- pwrap_read(wrp, PWRAP_DEW_READ_TEST, &rdata);
|
||||
+ pwrap_read(wrp, wrp->slave->dew_regs[PWRAP_DEW_READ_TEST], &rdata);
|
||||
if (rdata != PWRAP_DEW_READ_TEST_VAL) {
|
||||
dev_err(wrp->dev, "Read test failed after switch to DIO mode: 0x%04x != 0x%04x\n",
|
||||
PWRAP_DEW_READ_TEST_VAL, rdata);
|
||||
@@ -759,12 +798,13 @@ static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
return ret;
|
||||
|
||||
/* Signature checking - using CRC */
|
||||
- if (pwrap_write(wrp, PWRAP_DEW_CRC_EN, 0x1))
|
||||
+ if (pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_EN], 0x1))
|
||||
return -EFAULT;
|
||||
|
||||
pwrap_writel(wrp, 0x1, PWRAP_CRC_EN);
|
||||
pwrap_writel(wrp, 0x0, PWRAP_SIG_MODE);
|
||||
- pwrap_writel(wrp, PWRAP_DEW_CRC_VAL, PWRAP_SIG_ADR);
|
||||
+ pwrap_writel(wrp, wrp->slave->dew_regs[PWRAP_DEW_CRC_VAL],
|
||||
+ PWRAP_SIG_ADR);
|
||||
pwrap_writel(wrp, wrp->master->arb_en_all, PWRAP_HIPRIO_ARB_EN);
|
||||
|
||||
if (wrp->master->type == PWRAP_MT8135)
|
||||
@@ -818,6 +858,21 @@ static const struct regmap_config pwrap_regmap_config = {
|
||||
.max_register = 0xffff,
|
||||
};
|
||||
|
||||
+static const struct pwrap_slv_type pmic_mt6397 = {
|
||||
+ .dew_regs = mt6397_regs,
|
||||
+ .type = PMIC_MT6397,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id of_slave_match_tbl[] = {
|
||||
+ {
|
||||
+ .compatible = "mediatek,mt6397",
|
||||
+ .data = &pmic_mt6397,
|
||||
+ }, {
|
||||
+ /* sentinel */
|
||||
+ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, of_slave_match_tbl);
|
||||
+
|
||||
static struct pmic_wrapper_type pwrap_mt8135 = {
|
||||
.regs = mt8135_regs,
|
||||
.type = PWRAP_MT8135,
|
||||
@@ -862,8 +917,17 @@ static int pwrap_probe(struct platform_device *pdev)
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
const struct of_device_id *of_id =
|
||||
of_match_device(of_pwrap_match_tbl, &pdev->dev);
|
||||
+ const struct of_device_id *of_slave_id = NULL;
|
||||
struct resource *res;
|
||||
|
||||
+ if (pdev->dev.of_node->child)
|
||||
+ of_slave_id = of_match_node(of_slave_match_tbl,
|
||||
+ pdev->dev.of_node->child);
|
||||
+ if (!of_slave_id) {
|
||||
+ dev_dbg(&pdev->dev, "slave pmic should be defined in dts\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
wrp = devm_kzalloc(&pdev->dev, sizeof(*wrp), GFP_KERNEL);
|
||||
if (!wrp)
|
||||
return -ENOMEM;
|
||||
@@ -871,6 +935,7 @@ static int pwrap_probe(struct platform_device *pdev)
|
||||
platform_set_drvdata(pdev, wrp);
|
||||
|
||||
wrp->master = of_id->data;
|
||||
+ wrp->slave = of_slave_id->data;
|
||||
wrp->dev = &pdev->dev;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwrap");
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,98 @@
|
||||
From b82474df3eb9fad739b2b74301b68f71011a9dc7 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 20 Jan 2016 11:40:43 +0100
|
||||
Subject: [PATCH 40/53] soc: mediatek: PMIC wrap: add mt6323 slave support
|
||||
|
||||
Add support for MT6323 slaves. This PMIC can be found on MT2701 and MT7623
|
||||
EVB. The only function that we need to touch is pwrap_init_cipher().
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/soc/mediatek/mtk-pmic-wrap.c | 43 ++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 43 insertions(+)
|
||||
|
||||
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
index bcc841e..0e4ebb8 100644
|
||||
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
@@ -93,6 +93,27 @@ enum dew_regs {
|
||||
PWRAP_DEW_EVENT_TEST,
|
||||
PWRAP_DEW_CIPHER_LOAD,
|
||||
PWRAP_DEW_CIPHER_START,
|
||||
+
|
||||
+ /* MT6323 only regs */
|
||||
+ PWRAP_DEW_CIPHER_EN,
|
||||
+ PWRAP_DEW_RDDMY_NO,
|
||||
+};
|
||||
+
|
||||
+static const u32 mt6323_regs[] = {
|
||||
+ [PWRAP_DEW_BASE] = 0x0000,
|
||||
+ [PWRAP_DEW_DIO_EN] = 0x018a,
|
||||
+ [PWRAP_DEW_READ_TEST] = 0x018c,
|
||||
+ [PWRAP_DEW_WRITE_TEST] = 0x018e,
|
||||
+ [PWRAP_DEW_CRC_EN] = 0x0192,
|
||||
+ [PWRAP_DEW_CRC_VAL] = 0x0194,
|
||||
+ [PWRAP_DEW_MON_GRP_SEL] = 0x0196,
|
||||
+ [PWRAP_DEW_CIPHER_KEY_SEL] = 0x0198,
|
||||
+ [PWRAP_DEW_CIPHER_IV_SEL] = 0x019a,
|
||||
+ [PWRAP_DEW_CIPHER_EN] = 0x019c,
|
||||
+ [PWRAP_DEW_CIPHER_RDY] = 0x019e,
|
||||
+ [PWRAP_DEW_CIPHER_MODE] = 0x01a0,
|
||||
+ [PWRAP_DEW_CIPHER_SWRST] = 0x01a2,
|
||||
+ [PWRAP_DEW_RDDMY_NO] = 0x01a4,
|
||||
};
|
||||
|
||||
static const u32 mt6397_regs[] = {
|
||||
@@ -371,6 +392,7 @@ static int mt8135_regs[] = {
|
||||
};
|
||||
|
||||
enum pmic_type {
|
||||
+ PMIC_MT6323,
|
||||
PMIC_MT6397,
|
||||
};
|
||||
|
||||
@@ -661,6 +683,19 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
|
||||
pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_LOAD], 0x1);
|
||||
pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_START], 0x1);
|
||||
|
||||
+ switch (wrp->slave->type) {
|
||||
+ case PMIC_MT6397:
|
||||
+ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_LOAD],
|
||||
+ 0x1);
|
||||
+ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_START],
|
||||
+ 0x1);
|
||||
+ break;
|
||||
+ case PMIC_MT6323:
|
||||
+ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_CIPHER_EN],
|
||||
+ 0x1);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
/* wait for cipher data ready@AP */
|
||||
ret = pwrap_wait_for_state(wrp, pwrap_is_cipher_ready);
|
||||
if (ret) {
|
||||
@@ -858,6 +893,11 @@ static const struct regmap_config pwrap_regmap_config = {
|
||||
.max_register = 0xffff,
|
||||
};
|
||||
|
||||
+static const struct pwrap_slv_type pmic_mt6323 = {
|
||||
+ .dew_regs = mt6323_regs,
|
||||
+ .type = PMIC_MT6323,
|
||||
+};
|
||||
+
|
||||
static const struct pwrap_slv_type pmic_mt6397 = {
|
||||
.dew_regs = mt6397_regs,
|
||||
.type = PMIC_MT6397,
|
||||
@@ -865,6 +905,9 @@ static const struct pwrap_slv_type pmic_mt6397 = {
|
||||
|
||||
static const struct of_device_id of_slave_match_tbl[] = {
|
||||
{
|
||||
+ .compatible = "mediatek,mt6323",
|
||||
+ .data = &pmic_mt6323,
|
||||
+ }, {
|
||||
.compatible = "mediatek,mt6397",
|
||||
.data = &pmic_mt6397,
|
||||
}, {
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,237 @@
|
||||
From 84e83af30688372723a3b5713e914b0867d9a745 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 20 Jan 2016 12:09:14 +0100
|
||||
Subject: [PATCH 41/53] soc: mediatek: PMIC wrap: add MT2701/7623 support
|
||||
|
||||
Add the registers, callbacks and data structures required to make the
|
||||
wrapper work on MT2701 and MT7623.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/soc/mediatek/mtk-pmic-wrap.c | 154 ++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 154 insertions(+)
|
||||
|
||||
diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
index 0e4ebb8..3c3e56d 100644
|
||||
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
|
||||
@@ -52,6 +52,7 @@
|
||||
#define PWRAP_DEW_WRITE_TEST_VAL 0xa55a
|
||||
|
||||
/* macro for manual command */
|
||||
+#define PWRAP_MAN_CMD_SPI_WRITE_NEW (1 << 14)
|
||||
#define PWRAP_MAN_CMD_SPI_WRITE (1 << 13)
|
||||
#define PWRAP_MAN_CMD_OP_CSH (0x0 << 8)
|
||||
#define PWRAP_MAN_CMD_OP_CSL (0x1 << 8)
|
||||
@@ -200,6 +201,13 @@ enum pwrap_regs {
|
||||
PWRAP_DCM_EN,
|
||||
PWRAP_DCM_DBC_PRD,
|
||||
|
||||
+ /* MT2701 only regs */
|
||||
+ PWRAP_ADC_CMD_ADDR,
|
||||
+ PWRAP_PWRAP_ADC_CMD,
|
||||
+ PWRAP_ADC_RDY_ADDR,
|
||||
+ PWRAP_ADC_RDATA_ADDR1,
|
||||
+ PWRAP_ADC_RDATA_ADDR2,
|
||||
+
|
||||
/* MT8135 only regs */
|
||||
PWRAP_CSHEXT,
|
||||
PWRAP_EVENT_IN_EN,
|
||||
@@ -236,6 +244,92 @@ enum pwrap_regs {
|
||||
PWRAP_CIPHER_EN,
|
||||
};
|
||||
|
||||
+static int mt2701_regs[] = {
|
||||
+ [PWRAP_MUX_SEL] = 0x0,
|
||||
+ [PWRAP_WRAP_EN] = 0x4,
|
||||
+ [PWRAP_DIO_EN] = 0x8,
|
||||
+ [PWRAP_SIDLY] = 0xc,
|
||||
+ [PWRAP_RDDMY] = 0x18,
|
||||
+ [PWRAP_SI_CK_CON] = 0x1c,
|
||||
+ [PWRAP_CSHEXT_WRITE] = 0x20,
|
||||
+ [PWRAP_CSHEXT_READ] = 0x24,
|
||||
+ [PWRAP_CSLEXT_START] = 0x28,
|
||||
+ [PWRAP_CSLEXT_END] = 0x2c,
|
||||
+ [PWRAP_STAUPD_PRD] = 0x30,
|
||||
+ [PWRAP_STAUPD_GRPEN] = 0x34,
|
||||
+ [PWRAP_STAUPD_MAN_TRIG] = 0x38,
|
||||
+ [PWRAP_STAUPD_STA] = 0x3c,
|
||||
+ [PWRAP_WRAP_STA] = 0x44,
|
||||
+ [PWRAP_HARB_INIT] = 0x48,
|
||||
+ [PWRAP_HARB_HPRIO] = 0x4c,
|
||||
+ [PWRAP_HIPRIO_ARB_EN] = 0x50,
|
||||
+ [PWRAP_HARB_STA0] = 0x54,
|
||||
+ [PWRAP_HARB_STA1] = 0x58,
|
||||
+ [PWRAP_MAN_EN] = 0x5c,
|
||||
+ [PWRAP_MAN_CMD] = 0x60,
|
||||
+ [PWRAP_MAN_RDATA] = 0x64,
|
||||
+ [PWRAP_MAN_VLDCLR] = 0x68,
|
||||
+ [PWRAP_WACS0_EN] = 0x6c,
|
||||
+ [PWRAP_INIT_DONE0] = 0x70,
|
||||
+ [PWRAP_WACS0_CMD] = 0x74,
|
||||
+ [PWRAP_WACS0_RDATA] = 0x78,
|
||||
+ [PWRAP_WACS0_VLDCLR] = 0x7c,
|
||||
+ [PWRAP_WACS1_EN] = 0x80,
|
||||
+ [PWRAP_INIT_DONE1] = 0x84,
|
||||
+ [PWRAP_WACS1_CMD] = 0x88,
|
||||
+ [PWRAP_WACS1_RDATA] = 0x8c,
|
||||
+ [PWRAP_WACS1_VLDCLR] = 0x90,
|
||||
+ [PWRAP_WACS2_EN] = 0x94,
|
||||
+ [PWRAP_INIT_DONE2] = 0x98,
|
||||
+ [PWRAP_WACS2_CMD] = 0x9c,
|
||||
+ [PWRAP_WACS2_RDATA] = 0xa0,
|
||||
+ [PWRAP_WACS2_VLDCLR] = 0xa4,
|
||||
+ [PWRAP_INT_EN] = 0xa8,
|
||||
+ [PWRAP_INT_FLG_RAW] = 0xac,
|
||||
+ [PWRAP_INT_FLG] = 0xb0,
|
||||
+ [PWRAP_INT_CLR] = 0xb4,
|
||||
+ [PWRAP_SIG_ADR] = 0xb8,
|
||||
+ [PWRAP_SIG_MODE] = 0xbc,
|
||||
+ [PWRAP_SIG_VALUE] = 0xc0,
|
||||
+ [PWRAP_SIG_ERRVAL] = 0xc4,
|
||||
+ [PWRAP_CRC_EN] = 0xc8,
|
||||
+ [PWRAP_TIMER_EN] = 0xcc,
|
||||
+ [PWRAP_TIMER_STA] = 0xd0,
|
||||
+ [PWRAP_WDT_UNIT] = 0xd4,
|
||||
+ [PWRAP_WDT_SRC_EN] = 0xd8,
|
||||
+ [PWRAP_WDT_FLG] = 0xdc,
|
||||
+ [PWRAP_DEBUG_INT_SEL] = 0xe0,
|
||||
+ [PWRAP_DVFS_ADR0] = 0xe4,
|
||||
+ [PWRAP_DVFS_WDATA0] = 0xe8,
|
||||
+ [PWRAP_DVFS_ADR1] = 0xec,
|
||||
+ [PWRAP_DVFS_WDATA1] = 0xf0,
|
||||
+ [PWRAP_DVFS_ADR2] = 0xf4,
|
||||
+ [PWRAP_DVFS_WDATA2] = 0xf8,
|
||||
+ [PWRAP_DVFS_ADR3] = 0xfc,
|
||||
+ [PWRAP_DVFS_WDATA3] = 0x100,
|
||||
+ [PWRAP_DVFS_ADR4] = 0x104,
|
||||
+ [PWRAP_DVFS_WDATA4] = 0x108,
|
||||
+ [PWRAP_DVFS_ADR5] = 0x10c,
|
||||
+ [PWRAP_DVFS_WDATA5] = 0x110,
|
||||
+ [PWRAP_DVFS_ADR6] = 0x114,
|
||||
+ [PWRAP_DVFS_WDATA6] = 0x118,
|
||||
+ [PWRAP_DVFS_ADR7] = 0x11c,
|
||||
+ [PWRAP_DVFS_WDATA7] = 0x120,
|
||||
+ [PWRAP_CIPHER_KEY_SEL] = 0x124,
|
||||
+ [PWRAP_CIPHER_IV_SEL] = 0x128,
|
||||
+ [PWRAP_CIPHER_EN] = 0x12c,
|
||||
+ [PWRAP_CIPHER_RDY] = 0x130,
|
||||
+ [PWRAP_CIPHER_MODE] = 0x134,
|
||||
+ [PWRAP_CIPHER_SWRST] = 0x138,
|
||||
+ [PWRAP_DCM_EN] = 0x13c,
|
||||
+ [PWRAP_DCM_DBC_PRD] = 0x140,
|
||||
+ [PWRAP_ADC_CMD_ADDR] = 0x144,
|
||||
+ [PWRAP_PWRAP_ADC_CMD] = 0x148,
|
||||
+ [PWRAP_ADC_RDY_ADDR] = 0x14c,
|
||||
+ [PWRAP_ADC_RDATA_ADDR1] = 0x150,
|
||||
+ [PWRAP_ADC_RDATA_ADDR2] = 0x154,
|
||||
+};
|
||||
+
|
||||
static int mt8173_regs[] = {
|
||||
[PWRAP_MUX_SEL] = 0x0,
|
||||
[PWRAP_WRAP_EN] = 0x4,
|
||||
@@ -397,6 +491,7 @@ enum pmic_type {
|
||||
};
|
||||
|
||||
enum pwrap_type {
|
||||
+ PWRAP_MT2701,
|
||||
PWRAP_MT8135,
|
||||
PWRAP_MT8173,
|
||||
};
|
||||
@@ -637,6 +732,31 @@ static int pwrap_mt8173_init_reg_clock(struct pmic_wrapper *wrp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int pwrap_mt2701_init_reg_clock(struct pmic_wrapper *wrp)
|
||||
+{
|
||||
+ switch (wrp->slave->type) {
|
||||
+ case PMIC_MT6397:
|
||||
+ pwrap_writel(wrp, 0xc, PWRAP_RDDMY);
|
||||
+ pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_WRITE);
|
||||
+ pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_READ);
|
||||
+ pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START);
|
||||
+ pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END);
|
||||
+ break;
|
||||
+
|
||||
+ case PMIC_MT6323:
|
||||
+ pwrap_writel(wrp, 0x8, PWRAP_RDDMY);
|
||||
+ pwrap_write(wrp, wrp->slave->dew_regs[PWRAP_DEW_RDDMY_NO],
|
||||
+ 0x8);
|
||||
+ pwrap_writel(wrp, 0x5, PWRAP_CSHEXT_WRITE);
|
||||
+ pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_READ);
|
||||
+ pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START);
|
||||
+ pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static bool pwrap_is_cipher_ready(struct pmic_wrapper *wrp)
|
||||
{
|
||||
return pwrap_readl(wrp, PWRAP_CIPHER_RDY) & 1;
|
||||
@@ -670,6 +790,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
|
||||
pwrap_writel(wrp, 1, PWRAP_CIPHER_LOAD);
|
||||
pwrap_writel(wrp, 1, PWRAP_CIPHER_START);
|
||||
break;
|
||||
+ case PWRAP_MT2701:
|
||||
case PWRAP_MT8173:
|
||||
pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);
|
||||
break;
|
||||
@@ -772,6 +893,24 @@ static int pwrap_mt8173_init_soc_specific(struct pmic_wrapper *wrp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int pwrap_mt2701_init_soc_specific(struct pmic_wrapper *wrp)
|
||||
+{
|
||||
+ /* GPS_INTF initialization */
|
||||
+ switch (wrp->slave->type) {
|
||||
+ case PMIC_MT6323:
|
||||
+ pwrap_writel(wrp, 0x076c, PWRAP_ADC_CMD_ADDR);
|
||||
+ pwrap_writel(wrp, 0x8000, PWRAP_PWRAP_ADC_CMD);
|
||||
+ pwrap_writel(wrp, 0x072c, PWRAP_ADC_RDY_ADDR);
|
||||
+ pwrap_writel(wrp, 0x072e, PWRAP_ADC_RDATA_ADDR1);
|
||||
+ pwrap_writel(wrp, 0x0730, PWRAP_ADC_RDATA_ADDR2);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int pwrap_init(struct pmic_wrapper *wrp)
|
||||
{
|
||||
int ret;
|
||||
@@ -916,6 +1055,18 @@ static const struct of_device_id of_slave_match_tbl[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_slave_match_tbl);
|
||||
|
||||
+static const struct pmic_wrapper_type pwrap_mt2701 = {
|
||||
+ .regs = mt2701_regs,
|
||||
+ .type = PWRAP_MT2701,
|
||||
+ .arb_en_all = 0x3f,
|
||||
+ .int_en_all = ~(BIT(31) | BIT(2)),
|
||||
+ .spi_w = PWRAP_MAN_CMD_SPI_WRITE_NEW,
|
||||
+ .wdt_src = PWRAP_WDT_SRC_MASK_ALL,
|
||||
+ .has_bridge = 0,
|
||||
+ .init_reg_clock = pwrap_mt2701_init_reg_clock,
|
||||
+ .init_soc_specific = pwrap_mt2701_init_soc_specific,
|
||||
+};
|
||||
+
|
||||
static struct pmic_wrapper_type pwrap_mt8135 = {
|
||||
.regs = mt8135_regs,
|
||||
.type = PWRAP_MT8135,
|
||||
@@ -942,6 +1093,9 @@ static struct pmic_wrapper_type pwrap_mt8173 = {
|
||||
|
||||
static struct of_device_id of_pwrap_match_tbl[] = {
|
||||
{
|
||||
+ .compatible = "mediatek,mt2701-pwrap",
|
||||
+ .data = &pwrap_mt2701,
|
||||
+ }, {
|
||||
.compatible = "mediatek,mt8135-pwrap",
|
||||
.data = &pwrap_mt8135,
|
||||
}, {
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,55 @@
|
||||
From 3af0e56f55d7676fab0ba39ef599c64dd6ab4b35 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 10 Jan 2016 17:12:37 +0100
|
||||
Subject: [PATCH 42/53] dt-bindings: mfd: Add bindings for the MediaTek MT6323
|
||||
PMIC
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Acked-by: Rob Herring <robh@kernel.org>
|
||||
Cc: devicetree@vger.kernel.org
|
||||
---
|
||||
Documentation/devicetree/bindings/mfd/mt6397.txt | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt
|
||||
index 15043e6..949c85f 100644
|
||||
--- a/Documentation/devicetree/bindings/mfd/mt6397.txt
|
||||
+++ b/Documentation/devicetree/bindings/mfd/mt6397.txt
|
||||
@@ -1,6 +1,6 @@
|
||||
-MediaTek MT6397 Multifunction Device Driver
|
||||
+MediaTek MT6397/MT6323 Multifunction Device Driver
|
||||
|
||||
-MT6397 is a multifunction device with the following sub modules:
|
||||
+MT6397/MT6323 is a multifunction device with the following sub modules:
|
||||
- Regulator
|
||||
- RTC
|
||||
- Audio codec
|
||||
@@ -8,14 +8,14 @@ MT6397 is a multifunction device with the following sub modules:
|
||||
- Clock
|
||||
|
||||
It is interfaced to host controller using SPI interface by a proprietary hardware
|
||||
-called PMIC wrapper or pwrap. MT6397 MFD is a child device of pwrap.
|
||||
+called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap.
|
||||
See the following for pwarp node definitions:
|
||||
Documentation/devicetree/bindings/soc/pwrap.txt
|
||||
|
||||
This document describes the binding for MFD device and its sub module.
|
||||
|
||||
Required properties:
|
||||
-compatible: "mediatek,mt6397"
|
||||
+compatible: "mediatek,mt6397" or "mediatek,mt6323"
|
||||
|
||||
Optional subnodes:
|
||||
|
||||
@@ -26,6 +26,8 @@ Optional subnodes:
|
||||
Required properties:
|
||||
- compatible: "mediatek,mt6397-regulator"
|
||||
see Documentation/devicetree/bindings/regulator/mt6397-regulator.txt
|
||||
+ - compatible: "mediatek,mt6323-regulator"
|
||||
+ see Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
|
||||
- codec
|
||||
Required properties:
|
||||
- compatible: "mediatek,mt6397-codec"
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,104 @@
|
||||
From f3d5ef8f5422de25f1c8a96b313baf60e4ce1081 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Fri, 8 Jan 2016 08:33:17 +0100
|
||||
Subject: [PATCH 43/53] mfd: mt6397: int_con and int_status may vary in
|
||||
location
|
||||
|
||||
MT6323 has the INT_CON and INT_STATUS located at a different position.
|
||||
Make the registers locations configurable.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/mfd/mt6397-core.c | 27 +++++++++++++++++----------
|
||||
include/linux/mfd/mt6397/core.h | 2 ++
|
||||
2 files changed, 19 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
|
||||
index 1749c1c..75ad0fe 100644
|
||||
--- a/drivers/mfd/mt6397-core.c
|
||||
+++ b/drivers/mfd/mt6397-core.c
|
||||
@@ -69,8 +69,10 @@ static void mt6397_irq_sync_unlock(struct irq_data *data)
|
||||
{
|
||||
struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
|
||||
|
||||
- regmap_write(mt6397->regmap, MT6397_INT_CON0, mt6397->irq_masks_cur[0]);
|
||||
- regmap_write(mt6397->regmap, MT6397_INT_CON1, mt6397->irq_masks_cur[1]);
|
||||
+ regmap_write(mt6397->regmap, mt6397->int_con[0],
|
||||
+ mt6397->irq_masks_cur[0]);
|
||||
+ regmap_write(mt6397->regmap, mt6397->int_con[1],
|
||||
+ mt6397->irq_masks_cur[1]);
|
||||
|
||||
mutex_unlock(&mt6397->irqlock);
|
||||
}
|
||||
@@ -147,8 +149,8 @@ static irqreturn_t mt6397_irq_thread(int irq, void *data)
|
||||
{
|
||||
struct mt6397_chip *mt6397 = data;
|
||||
|
||||
- mt6397_irq_handle_reg(mt6397, MT6397_INT_STATUS0, 0);
|
||||
- mt6397_irq_handle_reg(mt6397, MT6397_INT_STATUS1, 16);
|
||||
+ mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
|
||||
+ mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -177,8 +179,8 @@ static int mt6397_irq_init(struct mt6397_chip *mt6397)
|
||||
mutex_init(&mt6397->irqlock);
|
||||
|
||||
/* Mask all interrupt sources */
|
||||
- regmap_write(mt6397->regmap, MT6397_INT_CON0, 0x0);
|
||||
- regmap_write(mt6397->regmap, MT6397_INT_CON1, 0x0);
|
||||
+ regmap_write(mt6397->regmap, mt6397->int_con[0], 0x0);
|
||||
+ regmap_write(mt6397->regmap, mt6397->int_con[1], 0x0);
|
||||
|
||||
mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node,
|
||||
MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397);
|
||||
@@ -203,8 +205,8 @@ static int mt6397_irq_suspend(struct device *dev)
|
||||
{
|
||||
struct mt6397_chip *chip = dev_get_drvdata(dev);
|
||||
|
||||
- regmap_write(chip->regmap, MT6397_INT_CON0, chip->wake_mask[0]);
|
||||
- regmap_write(chip->regmap, MT6397_INT_CON1, chip->wake_mask[1]);
|
||||
+ regmap_write(chip->regmap, chip->int_con[0], chip->wake_mask[0]);
|
||||
+ regmap_write(chip->regmap, chip->int_con[1], chip->wake_mask[1]);
|
||||
|
||||
enable_irq_wake(chip->irq);
|
||||
|
||||
@@ -215,8 +217,8 @@ static int mt6397_irq_resume(struct device *dev)
|
||||
{
|
||||
struct mt6397_chip *chip = dev_get_drvdata(dev);
|
||||
|
||||
- regmap_write(chip->regmap, MT6397_INT_CON0, chip->irq_masks_cur[0]);
|
||||
- regmap_write(chip->regmap, MT6397_INT_CON1, chip->irq_masks_cur[1]);
|
||||
+ regmap_write(chip->regmap, chip->int_con[0], chip->irq_masks_cur[0]);
|
||||
+ regmap_write(chip->regmap, chip->int_con[1], chip->irq_masks_cur[1]);
|
||||
|
||||
disable_irq_wake(chip->irq);
|
||||
|
||||
@@ -237,6 +239,11 @@ static int mt6397_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
mt6397->dev = &pdev->dev;
|
||||
+ mt6397->int_con[0] = MT6397_INT_CON0;
|
||||
+ mt6397->int_con[1] = MT6397_INT_CON1;
|
||||
+ mt6397->int_status[0] = MT6397_INT_STATUS0;
|
||||
+ mt6397->int_status[1] = MT6397_INT_STATUS1;
|
||||
+
|
||||
/*
|
||||
* mt6397 MFD is child device of soc pmic wrapper.
|
||||
* Regmap is set from its parent.
|
||||
diff --git a/include/linux/mfd/mt6397/core.h b/include/linux/mfd/mt6397/core.h
|
||||
index 45b8e8a..d678f52 100644
|
||||
--- a/include/linux/mfd/mt6397/core.h
|
||||
+++ b/include/linux/mfd/mt6397/core.h
|
||||
@@ -60,6 +60,8 @@ struct mt6397_chip {
|
||||
u16 wake_mask[2];
|
||||
u16 irq_masks_cur[2];
|
||||
u16 irq_masks_cache[2];
|
||||
+ u16 int_con[2];
|
||||
+ u16 int_status[2];
|
||||
};
|
||||
|
||||
#endif /* __MFD_MT6397_CORE_H__ */
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,105 @@
|
||||
From d29ee5f0472ea3e964e698e3e9e87a83b4465e9c Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Fri, 8 Jan 2016 08:41:52 +0100
|
||||
Subject: [PATCH 44/53] mfd: mt6397: add support for different Slave types
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/mfd/mt6397-core.c | 58 ++++++++++++++++++++++++++++++++-------------
|
||||
1 file changed, 41 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
|
||||
index 75ad0fe..aa91606 100644
|
||||
--- a/drivers/mfd/mt6397-core.c
|
||||
+++ b/drivers/mfd/mt6397-core.c
|
||||
@@ -24,6 +24,9 @@
|
||||
#define MT6397_RTC_BASE 0xe000
|
||||
#define MT6397_RTC_SIZE 0x3e
|
||||
|
||||
+#define MT6391_CID_CODE 0x91
|
||||
+#define MT6397_CID_CODE 0x97
|
||||
+
|
||||
static const struct resource mt6397_rtc_resources[] = {
|
||||
{
|
||||
.start = MT6397_RTC_BASE,
|
||||
@@ -232,39 +235,60 @@ static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend,
|
||||
static int mt6397_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
- struct mt6397_chip *mt6397;
|
||||
+ unsigned int id;
|
||||
+ struct mt6397_chip *pmic;
|
||||
|
||||
- mt6397 = devm_kzalloc(&pdev->dev, sizeof(*mt6397), GFP_KERNEL);
|
||||
- if (!mt6397)
|
||||
+ pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
|
||||
+ if (!pmic)
|
||||
return -ENOMEM;
|
||||
|
||||
- mt6397->dev = &pdev->dev;
|
||||
- mt6397->int_con[0] = MT6397_INT_CON0;
|
||||
- mt6397->int_con[1] = MT6397_INT_CON1;
|
||||
- mt6397->int_status[0] = MT6397_INT_STATUS0;
|
||||
- mt6397->int_status[1] = MT6397_INT_STATUS1;
|
||||
+ pmic->dev = &pdev->dev;
|
||||
|
||||
/*
|
||||
* mt6397 MFD is child device of soc pmic wrapper.
|
||||
* Regmap is set from its parent.
|
||||
*/
|
||||
- mt6397->regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
||||
- if (!mt6397->regmap)
|
||||
+ pmic->regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
||||
+ if (!pmic->regmap)
|
||||
return -ENODEV;
|
||||
|
||||
- platform_set_drvdata(pdev, mt6397);
|
||||
+ platform_set_drvdata(pdev, pmic);
|
||||
+
|
||||
+ ret = regmap_read(pmic->regmap, MT6397_CID, &id);
|
||||
+ if (ret) {
|
||||
+ dev_err(pmic->dev, "Failed to read chip id: %d\n", ret);
|
||||
+ goto fail_irq;
|
||||
+ }
|
||||
+
|
||||
+ switch (id & 0xff) {
|
||||
+ case MT6397_CID_CODE:
|
||||
+ case MT6391_CID_CODE:
|
||||
+ pmic->int_con[0] = MT6397_INT_CON0;
|
||||
+ pmic->int_con[1] = MT6397_INT_CON1;
|
||||
+ pmic->int_status[0] = MT6397_INT_STATUS0;
|
||||
+ pmic->int_status[1] = MT6397_INT_STATUS1;
|
||||
+ ret = mfd_add_devices(&pdev->dev, -1, mt6397_devs,
|
||||
+ ARRAY_SIZE(mt6397_devs), NULL, 0, NULL);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ dev_err(&pdev->dev, "unsupported chip: %d\n", id);
|
||||
+ ret = -ENODEV;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- mt6397->irq = platform_get_irq(pdev, 0);
|
||||
- if (mt6397->irq > 0) {
|
||||
- ret = mt6397_irq_init(mt6397);
|
||||
+ pmic->irq = platform_get_irq(pdev, 0);
|
||||
+ if (pmic->irq > 0) {
|
||||
+ ret = mt6397_irq_init(pmic);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = mfd_add_devices(&pdev->dev, -1, mt6397_devs,
|
||||
- ARRAY_SIZE(mt6397_devs), NULL, 0, NULL);
|
||||
- if (ret)
|
||||
+fail_irq:
|
||||
+ if (ret) {
|
||||
+ irq_domain_remove(pmic->irq_domain);
|
||||
dev_err(&pdev->dev, "failed to add child devices: %d\n", ret);
|
||||
+ }
|
||||
|
||||
return ret;
|
||||
}
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,530 @@
|
||||
From 926910e33f5de67f229ac089ab5f3de1bfd117f9 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Fri, 8 Jan 2016 04:09:43 +0100
|
||||
Subject: [PATCH 45/53] mfd: mt6397: add MT6323 support to MT6397 driver
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/mfd/mt6397-core.c | 20 ++
|
||||
include/linux/mfd/mt6323/core.h | 36 +++
|
||||
include/linux/mfd/mt6323/registers.h | 408 ++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 464 insertions(+)
|
||||
create mode 100644 include/linux/mfd/mt6323/core.h
|
||||
create mode 100644 include/linux/mfd/mt6323/registers.h
|
||||
|
||||
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
|
||||
index aa91606..8234cd3 100644
|
||||
--- a/drivers/mfd/mt6397-core.c
|
||||
+++ b/drivers/mfd/mt6397-core.c
|
||||
@@ -19,11 +19,14 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/mt6397/core.h>
|
||||
+#include <linux/mfd/mt6323/core.h>
|
||||
#include <linux/mfd/mt6397/registers.h>
|
||||
+#include <linux/mfd/mt6323/registers.h>
|
||||
|
||||
#define MT6397_RTC_BASE 0xe000
|
||||
#define MT6397_RTC_SIZE 0x3e
|
||||
|
||||
+#define MT6323_CID_CODE 0x23
|
||||
#define MT6391_CID_CODE 0x91
|
||||
#define MT6397_CID_CODE 0x97
|
||||
|
||||
@@ -40,6 +43,13 @@ static const struct resource mt6397_rtc_resources[] = {
|
||||
},
|
||||
};
|
||||
|
||||
+static const struct mfd_cell mt6323_devs[] = {
|
||||
+ {
|
||||
+ .name = "mt6323-regulator",
|
||||
+ .of_compatible = "mediatek,mt6323-regulator"
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static const struct mfd_cell mt6397_devs[] = {
|
||||
{
|
||||
.name = "mt6397-rtc",
|
||||
@@ -261,6 +271,15 @@ static int mt6397_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
switch (id & 0xff) {
|
||||
+ case MT6323_CID_CODE:
|
||||
+ pmic->int_con[0] = MT6323_INT_CON0;
|
||||
+ pmic->int_con[1] = MT6323_INT_CON1;
|
||||
+ pmic->int_status[0] = MT6323_INT_STATUS0;
|
||||
+ pmic->int_status[1] = MT6323_INT_STATUS1;
|
||||
+ ret = mfd_add_devices(&pdev->dev, -1, mt6323_devs,
|
||||
+ ARRAY_SIZE(mt6323_devs), NULL, 0, NULL);
|
||||
+ break;
|
||||
+
|
||||
case MT6397_CID_CODE:
|
||||
case MT6391_CID_CODE:
|
||||
pmic->int_con[0] = MT6397_INT_CON0;
|
||||
@@ -302,6 +321,7 @@ static int mt6397_remove(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id mt6397_of_match[] = {
|
||||
{ .compatible = "mediatek,mt6397" },
|
||||
+ { .compatible = "mediatek,mt6323" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mt6397_of_match);
|
||||
diff --git a/include/linux/mfd/mt6323/core.h b/include/linux/mfd/mt6323/core.h
|
||||
new file mode 100644
|
||||
index 0000000..06d0ec3
|
||||
--- /dev/null
|
||||
+++ b/include/linux/mfd/mt6323/core.h
|
||||
@@ -0,0 +1,36 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2016 Chen Zhong <chen.zhong@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __MFD_MT6323_CORE_H__
|
||||
+#define __MFD_MT6323_CORE_H__
|
||||
+
|
||||
+enum MT6323_IRQ_STATUS_numbers {
|
||||
+ MT6323_IRQ_STATUS_SPKL_AB = 0,
|
||||
+ MT6323_IRQ_STATUS_SPKL,
|
||||
+ MT6323_IRQ_STATUS_BAT_L,
|
||||
+ MT6323_IRQ_STATUS_BAT_H,
|
||||
+ MT6323_IRQ_STATUS_WATCHDOG,
|
||||
+ MT6323_IRQ_STATUS_PWRKEY,
|
||||
+ MT6323_IRQ_STATUS_THR_L,
|
||||
+ MT6323_IRQ_STATUS_THR_H,
|
||||
+ MT6323_IRQ_STATUS_VBATON_UNDET,
|
||||
+ MT6323_IRQ_STATUS_BVALID_DET,
|
||||
+ MT6323_IRQ_STATUS_CHRDET,
|
||||
+ MT6323_IRQ_STATUS_OV,
|
||||
+ MT6323_IRQ_STATUS_LDO = 16,
|
||||
+ MT6323_IRQ_STATUS_FCHRKEY,
|
||||
+ MT6323_IRQ_STATUS_ACCDET,
|
||||
+ MT6323_IRQ_STATUS_AUDIO,
|
||||
+ MT6323_IRQ_STATUS_RTC,
|
||||
+ MT6323_IRQ_STATUS_VPROC,
|
||||
+ MT6323_IRQ_STATUS_VSYS,
|
||||
+ MT6323_IRQ_STATUS_VPA,
|
||||
+ MT6323_IRQ_STATUS_NR,
|
||||
+};
|
||||
+
|
||||
+#endif /* __MFD_MT6323_CORE_H__ */
|
||||
diff --git a/include/linux/mfd/mt6323/registers.h b/include/linux/mfd/mt6323/registers.h
|
||||
new file mode 100644
|
||||
index 0000000..160f3c0
|
||||
--- /dev/null
|
||||
+++ b/include/linux/mfd/mt6323/registers.h
|
||||
@@ -0,0 +1,408 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2016 Chen Zhong <chen.zhong@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __MFD_MT6323_REGISTERS_H__
|
||||
+#define __MFD_MT6323_REGISTERS_H__
|
||||
+
|
||||
+/* PMIC Registers */
|
||||
+#define MT6323_CHR_CON0 0x0000
|
||||
+#define MT6323_CHR_CON1 0x0002
|
||||
+#define MT6323_CHR_CON2 0x0004
|
||||
+#define MT6323_CHR_CON3 0x0006
|
||||
+#define MT6323_CHR_CON4 0x0008
|
||||
+#define MT6323_CHR_CON5 0x000A
|
||||
+#define MT6323_CHR_CON6 0x000C
|
||||
+#define MT6323_CHR_CON7 0x000E
|
||||
+#define MT6323_CHR_CON8 0x0010
|
||||
+#define MT6323_CHR_CON9 0x0012
|
||||
+#define MT6323_CHR_CON10 0x0014
|
||||
+#define MT6323_CHR_CON11 0x0016
|
||||
+#define MT6323_CHR_CON12 0x0018
|
||||
+#define MT6323_CHR_CON13 0x001A
|
||||
+#define MT6323_CHR_CON14 0x001C
|
||||
+#define MT6323_CHR_CON15 0x001E
|
||||
+#define MT6323_CHR_CON16 0x0020
|
||||
+#define MT6323_CHR_CON17 0x0022
|
||||
+#define MT6323_CHR_CON18 0x0024
|
||||
+#define MT6323_CHR_CON19 0x0026
|
||||
+#define MT6323_CHR_CON20 0x0028
|
||||
+#define MT6323_CHR_CON21 0x002A
|
||||
+#define MT6323_CHR_CON22 0x002C
|
||||
+#define MT6323_CHR_CON23 0x002E
|
||||
+#define MT6323_CHR_CON24 0x0030
|
||||
+#define MT6323_CHR_CON25 0x0032
|
||||
+#define MT6323_CHR_CON26 0x0034
|
||||
+#define MT6323_CHR_CON27 0x0036
|
||||
+#define MT6323_CHR_CON28 0x0038
|
||||
+#define MT6323_CHR_CON29 0x003A
|
||||
+#define MT6323_STRUP_CON0 0x003C
|
||||
+#define MT6323_STRUP_CON2 0x003E
|
||||
+#define MT6323_STRUP_CON3 0x0040
|
||||
+#define MT6323_STRUP_CON4 0x0042
|
||||
+#define MT6323_STRUP_CON5 0x0044
|
||||
+#define MT6323_STRUP_CON6 0x0046
|
||||
+#define MT6323_STRUP_CON7 0x0048
|
||||
+#define MT6323_STRUP_CON8 0x004A
|
||||
+#define MT6323_STRUP_CON9 0x004C
|
||||
+#define MT6323_STRUP_CON10 0x004E
|
||||
+#define MT6323_STRUP_CON11 0x0050
|
||||
+#define MT6323_SPK_CON0 0x0052
|
||||
+#define MT6323_SPK_CON1 0x0054
|
||||
+#define MT6323_SPK_CON2 0x0056
|
||||
+#define MT6323_SPK_CON6 0x005E
|
||||
+#define MT6323_SPK_CON7 0x0060
|
||||
+#define MT6323_SPK_CON8 0x0062
|
||||
+#define MT6323_SPK_CON9 0x0064
|
||||
+#define MT6323_SPK_CON10 0x0066
|
||||
+#define MT6323_SPK_CON11 0x0068
|
||||
+#define MT6323_SPK_CON12 0x006A
|
||||
+#define MT6323_CID 0x0100
|
||||
+#define MT6323_TOP_CKPDN0 0x0102
|
||||
+#define MT6323_TOP_CKPDN0_SET 0x0104
|
||||
+#define MT6323_TOP_CKPDN0_CLR 0x0106
|
||||
+#define MT6323_TOP_CKPDN1 0x0108
|
||||
+#define MT6323_TOP_CKPDN1_SET 0x010A
|
||||
+#define MT6323_TOP_CKPDN1_CLR 0x010C
|
||||
+#define MT6323_TOP_CKPDN2 0x010E
|
||||
+#define MT6323_TOP_CKPDN2_SET 0x0110
|
||||
+#define MT6323_TOP_CKPDN2_CLR 0x0112
|
||||
+#define MT6323_TOP_RST_CON 0x0114
|
||||
+#define MT6323_TOP_RST_CON_SET 0x0116
|
||||
+#define MT6323_TOP_RST_CON_CLR 0x0118
|
||||
+#define MT6323_TOP_RST_MISC 0x011A
|
||||
+#define MT6323_TOP_RST_MISC_SET 0x011C
|
||||
+#define MT6323_TOP_RST_MISC_CLR 0x011E
|
||||
+#define MT6323_TOP_CKCON0 0x0120
|
||||
+#define MT6323_TOP_CKCON0_SET 0x0122
|
||||
+#define MT6323_TOP_CKCON0_CLR 0x0124
|
||||
+#define MT6323_TOP_CKCON1 0x0126
|
||||
+#define MT6323_TOP_CKCON1_SET 0x0128
|
||||
+#define MT6323_TOP_CKCON1_CLR 0x012A
|
||||
+#define MT6323_TOP_CKTST0 0x012C
|
||||
+#define MT6323_TOP_CKTST1 0x012E
|
||||
+#define MT6323_TOP_CKTST2 0x0130
|
||||
+#define MT6323_TEST_OUT 0x0132
|
||||
+#define MT6323_TEST_CON0 0x0134
|
||||
+#define MT6323_TEST_CON1 0x0136
|
||||
+#define MT6323_EN_STATUS0 0x0138
|
||||
+#define MT6323_EN_STATUS1 0x013A
|
||||
+#define MT6323_OCSTATUS0 0x013C
|
||||
+#define MT6323_OCSTATUS1 0x013E
|
||||
+#define MT6323_PGSTATUS 0x0140
|
||||
+#define MT6323_CHRSTATUS 0x0142
|
||||
+#define MT6323_TDSEL_CON 0x0144
|
||||
+#define MT6323_RDSEL_CON 0x0146
|
||||
+#define MT6323_SMT_CON0 0x0148
|
||||
+#define MT6323_SMT_CON1 0x014A
|
||||
+#define MT6323_SMT_CON2 0x014C
|
||||
+#define MT6323_SMT_CON3 0x014E
|
||||
+#define MT6323_SMT_CON4 0x0150
|
||||
+#define MT6323_DRV_CON0 0x0152
|
||||
+#define MT6323_DRV_CON1 0x0154
|
||||
+#define MT6323_DRV_CON2 0x0156
|
||||
+#define MT6323_DRV_CON3 0x0158
|
||||
+#define MT6323_DRV_CON4 0x015A
|
||||
+#define MT6323_SIMLS1_CON 0x015C
|
||||
+#define MT6323_SIMLS2_CON 0x015E
|
||||
+#define MT6323_INT_CON0 0x0160
|
||||
+#define MT6323_INT_CON0_SET 0x0162
|
||||
+#define MT6323_INT_CON0_CLR 0x0164
|
||||
+#define MT6323_INT_CON1 0x0166
|
||||
+#define MT6323_INT_CON1_SET 0x0168
|
||||
+#define MT6323_INT_CON1_CLR 0x016A
|
||||
+#define MT6323_INT_MISC_CON 0x016C
|
||||
+#define MT6323_INT_MISC_CON_SET 0x016E
|
||||
+#define MT6323_INT_MISC_CON_CLR 0x0170
|
||||
+#define MT6323_INT_STATUS0 0x0172
|
||||
+#define MT6323_INT_STATUS1 0x0174
|
||||
+#define MT6323_OC_GEAR_0 0x0176
|
||||
+#define MT6323_OC_GEAR_1 0x0178
|
||||
+#define MT6323_OC_GEAR_2 0x017A
|
||||
+#define MT6323_OC_CTL_VPROC 0x017C
|
||||
+#define MT6323_OC_CTL_VSYS 0x017E
|
||||
+#define MT6323_OC_CTL_VPA 0x0180
|
||||
+#define MT6323_FQMTR_CON0 0x0182
|
||||
+#define MT6323_FQMTR_CON1 0x0184
|
||||
+#define MT6323_FQMTR_CON2 0x0186
|
||||
+#define MT6323_RG_SPI_CON 0x0188
|
||||
+#define MT6323_DEW_DIO_EN 0x018A
|
||||
+#define MT6323_DEW_READ_TEST 0x018C
|
||||
+#define MT6323_DEW_WRITE_TEST 0x018E
|
||||
+#define MT6323_DEW_CRC_SWRST 0x0190
|
||||
+#define MT6323_DEW_CRC_EN 0x0192
|
||||
+#define MT6323_DEW_CRC_VAL 0x0194
|
||||
+#define MT6323_DEW_DBG_MON_SEL 0x0196
|
||||
+#define MT6323_DEW_CIPHER_KEY_SEL 0x0198
|
||||
+#define MT6323_DEW_CIPHER_IV_SEL 0x019A
|
||||
+#define MT6323_DEW_CIPHER_EN 0x019C
|
||||
+#define MT6323_DEW_CIPHER_RDY 0x019E
|
||||
+#define MT6323_DEW_CIPHER_MODE 0x01A0
|
||||
+#define MT6323_DEW_CIPHER_SWRST 0x01A2
|
||||
+#define MT6323_DEW_RDDMY_NO 0x01A4
|
||||
+#define MT6323_DEW_RDATA_DLY_SEL 0x01A6
|
||||
+#define MT6323_BUCK_CON0 0x0200
|
||||
+#define MT6323_BUCK_CON1 0x0202
|
||||
+#define MT6323_BUCK_CON2 0x0204
|
||||
+#define MT6323_BUCK_CON3 0x0206
|
||||
+#define MT6323_BUCK_CON4 0x0208
|
||||
+#define MT6323_BUCK_CON5 0x020A
|
||||
+#define MT6323_VPROC_CON0 0x020C
|
||||
+#define MT6323_VPROC_CON1 0x020E
|
||||
+#define MT6323_VPROC_CON2 0x0210
|
||||
+#define MT6323_VPROC_CON3 0x0212
|
||||
+#define MT6323_VPROC_CON4 0x0214
|
||||
+#define MT6323_VPROC_CON5 0x0216
|
||||
+#define MT6323_VPROC_CON7 0x021A
|
||||
+#define MT6323_VPROC_CON8 0x021C
|
||||
+#define MT6323_VPROC_CON9 0x021E
|
||||
+#define MT6323_VPROC_CON10 0x0220
|
||||
+#define MT6323_VPROC_CON11 0x0222
|
||||
+#define MT6323_VPROC_CON12 0x0224
|
||||
+#define MT6323_VPROC_CON13 0x0226
|
||||
+#define MT6323_VPROC_CON14 0x0228
|
||||
+#define MT6323_VPROC_CON15 0x022A
|
||||
+#define MT6323_VPROC_CON18 0x0230
|
||||
+#define MT6323_VSYS_CON0 0x0232
|
||||
+#define MT6323_VSYS_CON1 0x0234
|
||||
+#define MT6323_VSYS_CON2 0x0236
|
||||
+#define MT6323_VSYS_CON3 0x0238
|
||||
+#define MT6323_VSYS_CON4 0x023A
|
||||
+#define MT6323_VSYS_CON5 0x023C
|
||||
+#define MT6323_VSYS_CON7 0x0240
|
||||
+#define MT6323_VSYS_CON8 0x0242
|
||||
+#define MT6323_VSYS_CON9 0x0244
|
||||
+#define MT6323_VSYS_CON10 0x0246
|
||||
+#define MT6323_VSYS_CON11 0x0248
|
||||
+#define MT6323_VSYS_CON12 0x024A
|
||||
+#define MT6323_VSYS_CON13 0x024C
|
||||
+#define MT6323_VSYS_CON14 0x024E
|
||||
+#define MT6323_VSYS_CON15 0x0250
|
||||
+#define MT6323_VSYS_CON18 0x0256
|
||||
+#define MT6323_VPA_CON0 0x0300
|
||||
+#define MT6323_VPA_CON1 0x0302
|
||||
+#define MT6323_VPA_CON2 0x0304
|
||||
+#define MT6323_VPA_CON3 0x0306
|
||||
+#define MT6323_VPA_CON4 0x0308
|
||||
+#define MT6323_VPA_CON5 0x030A
|
||||
+#define MT6323_VPA_CON7 0x030E
|
||||
+#define MT6323_VPA_CON8 0x0310
|
||||
+#define MT6323_VPA_CON9 0x0312
|
||||
+#define MT6323_VPA_CON10 0x0314
|
||||
+#define MT6323_VPA_CON11 0x0316
|
||||
+#define MT6323_VPA_CON12 0x0318
|
||||
+#define MT6323_VPA_CON14 0x031C
|
||||
+#define MT6323_VPA_CON16 0x0320
|
||||
+#define MT6323_VPA_CON17 0x0322
|
||||
+#define MT6323_VPA_CON18 0x0324
|
||||
+#define MT6323_VPA_CON19 0x0326
|
||||
+#define MT6323_VPA_CON20 0x0328
|
||||
+#define MT6323_BUCK_K_CON0 0x032A
|
||||
+#define MT6323_BUCK_K_CON1 0x032C
|
||||
+#define MT6323_BUCK_K_CON2 0x032E
|
||||
+#define MT6323_ISINK0_CON0 0x0330
|
||||
+#define MT6323_ISINK0_CON1 0x0332
|
||||
+#define MT6323_ISINK0_CON2 0x0334
|
||||
+#define MT6323_ISINK0_CON3 0x0336
|
||||
+#define MT6323_ISINK1_CON0 0x0338
|
||||
+#define MT6323_ISINK1_CON1 0x033A
|
||||
+#define MT6323_ISINK1_CON2 0x033C
|
||||
+#define MT6323_ISINK1_CON3 0x033E
|
||||
+#define MT6323_ISINK2_CON0 0x0340
|
||||
+#define MT6323_ISINK2_CON1 0x0342
|
||||
+#define MT6323_ISINK2_CON2 0x0344
|
||||
+#define MT6323_ISINK2_CON3 0x0346
|
||||
+#define MT6323_ISINK3_CON0 0x0348
|
||||
+#define MT6323_ISINK3_CON1 0x034A
|
||||
+#define MT6323_ISINK3_CON2 0x034C
|
||||
+#define MT6323_ISINK3_CON3 0x034E
|
||||
+#define MT6323_ISINK_ANA0 0x0350
|
||||
+#define MT6323_ISINK_ANA1 0x0352
|
||||
+#define MT6323_ISINK_PHASE_DLY 0x0354
|
||||
+#define MT6323_ISINK_EN_CTRL 0x0356
|
||||
+#define MT6323_ANALDO_CON0 0x0400
|
||||
+#define MT6323_ANALDO_CON1 0x0402
|
||||
+#define MT6323_ANALDO_CON2 0x0404
|
||||
+#define MT6323_ANALDO_CON3 0x0406
|
||||
+#define MT6323_ANALDO_CON4 0x0408
|
||||
+#define MT6323_ANALDO_CON5 0x040A
|
||||
+#define MT6323_ANALDO_CON6 0x040C
|
||||
+#define MT6323_ANALDO_CON7 0x040E
|
||||
+#define MT6323_ANALDO_CON8 0x0410
|
||||
+#define MT6323_ANALDO_CON10 0x0412
|
||||
+#define MT6323_ANALDO_CON15 0x0414
|
||||
+#define MT6323_ANALDO_CON16 0x0416
|
||||
+#define MT6323_ANALDO_CON17 0x0418
|
||||
+#define MT6323_ANALDO_CON18 0x041A
|
||||
+#define MT6323_ANALDO_CON19 0x041C
|
||||
+#define MT6323_ANALDO_CON20 0x041E
|
||||
+#define MT6323_ANALDO_CON21 0x0420
|
||||
+#define MT6323_DIGLDO_CON0 0x0500
|
||||
+#define MT6323_DIGLDO_CON2 0x0502
|
||||
+#define MT6323_DIGLDO_CON3 0x0504
|
||||
+#define MT6323_DIGLDO_CON5 0x0506
|
||||
+#define MT6323_DIGLDO_CON6 0x0508
|
||||
+#define MT6323_DIGLDO_CON7 0x050A
|
||||
+#define MT6323_DIGLDO_CON8 0x050C
|
||||
+#define MT6323_DIGLDO_CON9 0x050E
|
||||
+#define MT6323_DIGLDO_CON10 0x0510
|
||||
+#define MT6323_DIGLDO_CON11 0x0512
|
||||
+#define MT6323_DIGLDO_CON12 0x0514
|
||||
+#define MT6323_DIGLDO_CON13 0x0516
|
||||
+#define MT6323_DIGLDO_CON14 0x0518
|
||||
+#define MT6323_DIGLDO_CON15 0x051A
|
||||
+#define MT6323_DIGLDO_CON16 0x051C
|
||||
+#define MT6323_DIGLDO_CON17 0x051E
|
||||
+#define MT6323_DIGLDO_CON18 0x0520
|
||||
+#define MT6323_DIGLDO_CON19 0x0522
|
||||
+#define MT6323_DIGLDO_CON20 0x0524
|
||||
+#define MT6323_DIGLDO_CON21 0x0526
|
||||
+#define MT6323_DIGLDO_CON23 0x0528
|
||||
+#define MT6323_DIGLDO_CON24 0x052A
|
||||
+#define MT6323_DIGLDO_CON26 0x052C
|
||||
+#define MT6323_DIGLDO_CON27 0x052E
|
||||
+#define MT6323_DIGLDO_CON28 0x0530
|
||||
+#define MT6323_DIGLDO_CON29 0x0532
|
||||
+#define MT6323_DIGLDO_CON30 0x0534
|
||||
+#define MT6323_DIGLDO_CON31 0x0536
|
||||
+#define MT6323_DIGLDO_CON32 0x0538
|
||||
+#define MT6323_DIGLDO_CON33 0x053A
|
||||
+#define MT6323_DIGLDO_CON34 0x053C
|
||||
+#define MT6323_DIGLDO_CON35 0x053E
|
||||
+#define MT6323_DIGLDO_CON36 0x0540
|
||||
+#define MT6323_DIGLDO_CON39 0x0542
|
||||
+#define MT6323_DIGLDO_CON40 0x0544
|
||||
+#define MT6323_DIGLDO_CON41 0x0546
|
||||
+#define MT6323_DIGLDO_CON42 0x0548
|
||||
+#define MT6323_DIGLDO_CON43 0x054A
|
||||
+#define MT6323_DIGLDO_CON44 0x054C
|
||||
+#define MT6323_DIGLDO_CON45 0x054E
|
||||
+#define MT6323_DIGLDO_CON46 0x0550
|
||||
+#define MT6323_DIGLDO_CON47 0x0552
|
||||
+#define MT6323_DIGLDO_CON48 0x0554
|
||||
+#define MT6323_DIGLDO_CON49 0x0556
|
||||
+#define MT6323_DIGLDO_CON50 0x0558
|
||||
+#define MT6323_DIGLDO_CON51 0x055A
|
||||
+#define MT6323_DIGLDO_CON52 0x055C
|
||||
+#define MT6323_DIGLDO_CON53 0x055E
|
||||
+#define MT6323_DIGLDO_CON54 0x0560
|
||||
+#define MT6323_EFUSE_CON0 0x0600
|
||||
+#define MT6323_EFUSE_CON1 0x0602
|
||||
+#define MT6323_EFUSE_CON2 0x0604
|
||||
+#define MT6323_EFUSE_CON3 0x0606
|
||||
+#define MT6323_EFUSE_CON4 0x0608
|
||||
+#define MT6323_EFUSE_CON5 0x060A
|
||||
+#define MT6323_EFUSE_CON6 0x060C
|
||||
+#define MT6323_EFUSE_VAL_0_15 0x060E
|
||||
+#define MT6323_EFUSE_VAL_16_31 0x0610
|
||||
+#define MT6323_EFUSE_VAL_32_47 0x0612
|
||||
+#define MT6323_EFUSE_VAL_48_63 0x0614
|
||||
+#define MT6323_EFUSE_VAL_64_79 0x0616
|
||||
+#define MT6323_EFUSE_VAL_80_95 0x0618
|
||||
+#define MT6323_EFUSE_VAL_96_111 0x061A
|
||||
+#define MT6323_EFUSE_VAL_112_127 0x061C
|
||||
+#define MT6323_EFUSE_VAL_128_143 0x061E
|
||||
+#define MT6323_EFUSE_VAL_144_159 0x0620
|
||||
+#define MT6323_EFUSE_VAL_160_175 0x0622
|
||||
+#define MT6323_EFUSE_VAL_176_191 0x0624
|
||||
+#define MT6323_EFUSE_DOUT_0_15 0x0626
|
||||
+#define MT6323_EFUSE_DOUT_16_31 0x0628
|
||||
+#define MT6323_EFUSE_DOUT_32_47 0x062A
|
||||
+#define MT6323_EFUSE_DOUT_48_63 0x062C
|
||||
+#define MT6323_EFUSE_DOUT_64_79 0x062E
|
||||
+#define MT6323_EFUSE_DOUT_80_95 0x0630
|
||||
+#define MT6323_EFUSE_DOUT_96_111 0x0632
|
||||
+#define MT6323_EFUSE_DOUT_112_127 0x0634
|
||||
+#define MT6323_EFUSE_DOUT_128_143 0x0636
|
||||
+#define MT6323_EFUSE_DOUT_144_159 0x0638
|
||||
+#define MT6323_EFUSE_DOUT_160_175 0x063A
|
||||
+#define MT6323_EFUSE_DOUT_176_191 0x063C
|
||||
+#define MT6323_EFUSE_CON7 0x063E
|
||||
+#define MT6323_EFUSE_CON8 0x0640
|
||||
+#define MT6323_EFUSE_CON9 0x0642
|
||||
+#define MT6323_RTC_MIX_CON0 0x0644
|
||||
+#define MT6323_RTC_MIX_CON1 0x0646
|
||||
+#define MT6323_AUDTOP_CON0 0x0700
|
||||
+#define MT6323_AUDTOP_CON1 0x0702
|
||||
+#define MT6323_AUDTOP_CON2 0x0704
|
||||
+#define MT6323_AUDTOP_CON3 0x0706
|
||||
+#define MT6323_AUDTOP_CON4 0x0708
|
||||
+#define MT6323_AUDTOP_CON5 0x070A
|
||||
+#define MT6323_AUDTOP_CON6 0x070C
|
||||
+#define MT6323_AUDTOP_CON7 0x070E
|
||||
+#define MT6323_AUDTOP_CON8 0x0710
|
||||
+#define MT6323_AUDTOP_CON9 0x0712
|
||||
+#define MT6323_AUXADC_ADC0 0x0714
|
||||
+#define MT6323_AUXADC_ADC1 0x0716
|
||||
+#define MT6323_AUXADC_ADC2 0x0718
|
||||
+#define MT6323_AUXADC_ADC3 0x071A
|
||||
+#define MT6323_AUXADC_ADC4 0x071C
|
||||
+#define MT6323_AUXADC_ADC5 0x071E
|
||||
+#define MT6323_AUXADC_ADC6 0x0720
|
||||
+#define MT6323_AUXADC_ADC7 0x0722
|
||||
+#define MT6323_AUXADC_ADC8 0x0724
|
||||
+#define MT6323_AUXADC_ADC9 0x0726
|
||||
+#define MT6323_AUXADC_ADC10 0x0728
|
||||
+#define MT6323_AUXADC_ADC11 0x072A
|
||||
+#define MT6323_AUXADC_ADC12 0x072C
|
||||
+#define MT6323_AUXADC_ADC13 0x072E
|
||||
+#define MT6323_AUXADC_ADC14 0x0730
|
||||
+#define MT6323_AUXADC_ADC15 0x0732
|
||||
+#define MT6323_AUXADC_ADC16 0x0734
|
||||
+#define MT6323_AUXADC_ADC17 0x0736
|
||||
+#define MT6323_AUXADC_ADC18 0x0738
|
||||
+#define MT6323_AUXADC_ADC19 0x073A
|
||||
+#define MT6323_AUXADC_ADC20 0x073C
|
||||
+#define MT6323_AUXADC_RSV1 0x073E
|
||||
+#define MT6323_AUXADC_RSV2 0x0740
|
||||
+#define MT6323_AUXADC_CON0 0x0742
|
||||
+#define MT6323_AUXADC_CON1 0x0744
|
||||
+#define MT6323_AUXADC_CON2 0x0746
|
||||
+#define MT6323_AUXADC_CON3 0x0748
|
||||
+#define MT6323_AUXADC_CON4 0x074A
|
||||
+#define MT6323_AUXADC_CON5 0x074C
|
||||
+#define MT6323_AUXADC_CON6 0x074E
|
||||
+#define MT6323_AUXADC_CON7 0x0750
|
||||
+#define MT6323_AUXADC_CON8 0x0752
|
||||
+#define MT6323_AUXADC_CON9 0x0754
|
||||
+#define MT6323_AUXADC_CON10 0x0756
|
||||
+#define MT6323_AUXADC_CON11 0x0758
|
||||
+#define MT6323_AUXADC_CON12 0x075A
|
||||
+#define MT6323_AUXADC_CON13 0x075C
|
||||
+#define MT6323_AUXADC_CON14 0x075E
|
||||
+#define MT6323_AUXADC_CON15 0x0760
|
||||
+#define MT6323_AUXADC_CON16 0x0762
|
||||
+#define MT6323_AUXADC_CON17 0x0764
|
||||
+#define MT6323_AUXADC_CON18 0x0766
|
||||
+#define MT6323_AUXADC_CON19 0x0768
|
||||
+#define MT6323_AUXADC_CON20 0x076A
|
||||
+#define MT6323_AUXADC_CON21 0x076C
|
||||
+#define MT6323_AUXADC_CON22 0x076E
|
||||
+#define MT6323_AUXADC_CON23 0x0770
|
||||
+#define MT6323_AUXADC_CON24 0x0772
|
||||
+#define MT6323_AUXADC_CON25 0x0774
|
||||
+#define MT6323_AUXADC_CON26 0x0776
|
||||
+#define MT6323_AUXADC_CON27 0x0778
|
||||
+#define MT6323_ACCDET_CON0 0x077A
|
||||
+#define MT6323_ACCDET_CON1 0x077C
|
||||
+#define MT6323_ACCDET_CON2 0x077E
|
||||
+#define MT6323_ACCDET_CON3 0x0780
|
||||
+#define MT6323_ACCDET_CON4 0x0782
|
||||
+#define MT6323_ACCDET_CON5 0x0784
|
||||
+#define MT6323_ACCDET_CON6 0x0786
|
||||
+#define MT6323_ACCDET_CON7 0x0788
|
||||
+#define MT6323_ACCDET_CON8 0x078A
|
||||
+#define MT6323_ACCDET_CON9 0x078C
|
||||
+#define MT6323_ACCDET_CON10 0x078E
|
||||
+#define MT6323_ACCDET_CON11 0x0790
|
||||
+#define MT6323_ACCDET_CON12 0x0792
|
||||
+#define MT6323_ACCDET_CON13 0x0794
|
||||
+#define MT6323_ACCDET_CON14 0x0796
|
||||
+#define MT6323_ACCDET_CON15 0x0798
|
||||
+#define MT6323_ACCDET_CON16 0x079A
|
||||
+
|
||||
+#endif /* __MFD_MT6323_REGISTERS_H__ */
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,260 @@
|
||||
From 3900467f0f0470f889b9e6cdfd7dc4cf460e8d41 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Sun, 10 Jan 2016 17:31:46 +0100
|
||||
Subject: [PATCH 46/53] regulator: Add document for MT6323 regulator
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Cc: devicetree@vger.kernel.org
|
||||
---
|
||||
.../bindings/regulator/mt6323-regulator.txt | 239 ++++++++++++++++++++
|
||||
1 file changed, 239 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/regulator/mt6323-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
|
||||
new file mode 100644
|
||||
index 0000000..9fd95e7
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
|
||||
@@ -0,0 +1,239 @@
|
||||
+Mediatek MT6323 Regulator Driver
|
||||
+
|
||||
+All voltage regulators are defined as subnodes of the regulators node. A list
|
||||
+of regulators provided by this controller are defined as subnodes of the
|
||||
+PMIC's node. Each regulator is named according to its regulator type,
|
||||
+buck_<name> and ldo_<name>. The definition for each of these nodes is defined
|
||||
+using the standard binding for regulators at
|
||||
+Documentation/devicetree/bindings/regulator/regulator.txt.
|
||||
+
|
||||
+The valid names for regulators are::
|
||||
+BUCK:
|
||||
+ buck_vproc, buck_vsys, buck_vpa
|
||||
+LDO:
|
||||
+ ldo_vtcxo, ldo_vcn28, ldo_vcn33_bt, ldo_vcn33_wifi, ldo_va, ldo_vcama,
|
||||
+ ldo_vio28, ldo_vusb, ldo_vmc, ldo_vmch, ldo_vemc3v3, ldo_vgp1, ldo_vgp2,
|
||||
+ ldo_vgp3, ldo_vcn18, ldo_vsim1, ldo_vsim2, ldo_vrtc, ldo_vcamaf, ldo_vibr,
|
||||
+ ldo_vrf18, ldo_vm, ldo_vio18, ldo_vcamd, ldo_vcamio
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+ pmic: mt6323 {
|
||||
+ compatible = "mediatek,mt6323";
|
||||
+
|
||||
+ mt6323regulator: regulators {
|
||||
+ mt6323_vproc_reg: buck_vproc{
|
||||
+ regulator-name = "vproc";
|
||||
+ regulator-min-microvolt = < 700000>;
|
||||
+ regulator-max-microvolt = <1350000>;
|
||||
+ regulator-ramp-delay = <12500>;
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vsys_reg: buck_vsys{
|
||||
+ regulator-name = "vsys";
|
||||
+ regulator-min-microvolt = <1400000>;
|
||||
+ regulator-max-microvolt = <2987500>;
|
||||
+ regulator-ramp-delay = <25000>;
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vpa_reg: buck_vpa{
|
||||
+ regulator-name = "vpa";
|
||||
+ regulator-min-microvolt = < 500000>;
|
||||
+ regulator-max-microvolt = <3650000>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vtcxo_reg: ldo_vtcxo{
|
||||
+ regulator-name = "vtcxo";
|
||||
+ regulator-min-microvolt = <2800000>;
|
||||
+ regulator-max-microvolt = <2800000>;
|
||||
+ regulator-enable-ramp-delay = <90>;
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vcn28_reg: ldo_vcn28{
|
||||
+ regulator-name = "vcn28";
|
||||
+ regulator-min-microvolt = <2800000>;
|
||||
+ regulator-max-microvolt = <2800000>;
|
||||
+ regulator-enable-ramp-delay = <185>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vcn33_bt_reg: ldo_vcn33_bt{
|
||||
+ regulator-name = "vcn33_bt";
|
||||
+ regulator-min-microvolt = <3300000>;
|
||||
+ regulator-max-microvolt = <3600000>;
|
||||
+ regulator-enable-ramp-delay = <185>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vcn33_wifi_reg: ldo_vcn33_wifi{
|
||||
+ regulator-name = "vcn33_wifi";
|
||||
+ regulator-min-microvolt = <3300000>;
|
||||
+ regulator-max-microvolt = <3600000>;
|
||||
+ regulator-enable-ramp-delay = <185>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_va_reg: ldo_va{
|
||||
+ regulator-name = "va";
|
||||
+ regulator-min-microvolt = <2800000>;
|
||||
+ regulator-max-microvolt = <2800000>;
|
||||
+ regulator-enable-ramp-delay = <216>;
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vcama_reg: ldo_vcama{
|
||||
+ regulator-name = "vcama";
|
||||
+ regulator-min-microvolt = <1500000>;
|
||||
+ regulator-max-microvolt = <2800000>;
|
||||
+ regulator-enable-ramp-delay = <216>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vio28_reg: ldo_vio28{
|
||||
+ regulator-name = "vio28";
|
||||
+ regulator-min-microvolt = <2800000>;
|
||||
+ regulator-max-microvolt = <2800000>;
|
||||
+ regulator-enable-ramp-delay = <216>;
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vusb_reg: ldo_vusb{
|
||||
+ regulator-name = "vusb";
|
||||
+ regulator-min-microvolt = <3300000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-enable-ramp-delay = <216>;
|
||||
+ regulator-boot-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vmc_reg: ldo_vmc{
|
||||
+ regulator-name = "vmc";
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-enable-ramp-delay = <36>;
|
||||
+ regulator-boot-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vmch_reg: ldo_vmch{
|
||||
+ regulator-name = "vmch";
|
||||
+ regulator-min-microvolt = <3000000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-enable-ramp-delay = <36>;
|
||||
+ regulator-boot-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vemc3v3_reg: ldo_vemc3v3{
|
||||
+ regulator-name = "vemc3v3";
|
||||
+ regulator-min-microvolt = <3000000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-enable-ramp-delay = <36>;
|
||||
+ regulator-boot-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vgp1_reg: ldo_vgp1{
|
||||
+ regulator-name = "vgp1";
|
||||
+ regulator-min-microvolt = <1200000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-enable-ramp-delay = <216>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vgp2_reg: ldo_vgp2{
|
||||
+ regulator-name = "vgp2";
|
||||
+ regulator-min-microvolt = <1200000>;
|
||||
+ regulator-max-microvolt = <3000000>;
|
||||
+ regulator-enable-ramp-delay = <216>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vgp3_reg: ldo_vgp3{
|
||||
+ regulator-name = "vgp3";
|
||||
+ regulator-min-microvolt = <1200000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-enable-ramp-delay = <216>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vcn18_reg: ldo_vcn18{
|
||||
+ regulator-name = "vcn18";
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-enable-ramp-delay = <216>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vsim1_reg: ldo_vsim1{
|
||||
+ regulator-name = "vsim1";
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <3000000>;
|
||||
+ regulator-enable-ramp-delay = <216>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vsim2_reg: ldo_vsim2{
|
||||
+ regulator-name = "vsim2";
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <3000000>;
|
||||
+ regulator-enable-ramp-delay = <216>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vrtc_reg: ldo_vrtc{
|
||||
+ regulator-name = "vrtc";
|
||||
+ regulator-min-microvolt = <2800000>;
|
||||
+ regulator-max-microvolt = <2800000>;
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vcamaf_reg: ldo_vcamaf{
|
||||
+ regulator-name = "vcamaf";
|
||||
+ regulator-min-microvolt = <1200000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-enable-ramp-delay = <216>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vibr_reg: ldo_vibr{
|
||||
+ regulator-name = "vibr";
|
||||
+ regulator-min-microvolt = <1200000>;
|
||||
+ regulator-max-microvolt = <3300000>;
|
||||
+ regulator-enable-ramp-delay = <36>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vrf18_reg: ldo_vrf18{
|
||||
+ regulator-name = "vrf18";
|
||||
+ regulator-min-microvolt = <1825000>;
|
||||
+ regulator-max-microvolt = <1825000>;
|
||||
+ regulator-enable-ramp-delay = <187>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vm_reg: ldo_vm{
|
||||
+ regulator-name = "vm";
|
||||
+ regulator-min-microvolt = <1200000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-enable-ramp-delay = <216>;
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vio18_reg: ldo_vio18{
|
||||
+ regulator-name = "vio18";
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-enable-ramp-delay = <216>;
|
||||
+ regulator-always-on;
|
||||
+ regulator-boot-on;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vcamd_reg: ldo_vcamd{
|
||||
+ regulator-name = "vcamd";
|
||||
+ regulator-min-microvolt = <1200000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-enable-ramp-delay = <216>;
|
||||
+ };
|
||||
+
|
||||
+ mt6323_vcamio_reg: ldo_vcamio{
|
||||
+ regulator-name = "vcamio";
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
+ regulator-max-microvolt = <1800000>;
|
||||
+ regulator-enable-ramp-delay = <216>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,551 @@
|
||||
From eb0a8e236431bf233267299ba797e2269b6e19ea Mon Sep 17 00:00:00 2001
|
||||
From: Chen Zhong <chen.zhong@mediatek.com>
|
||||
Date: Fri, 8 Jan 2016 04:17:37 +0100
|
||||
Subject: [PATCH 47/53] regulator: mt6323: Add support for MT6323 regulator
|
||||
|
||||
The MT6323 is a regulator found on boards based on MediaTek MT7623 and
|
||||
probably other SoCs. It is a so called pmic and connects as a slave to
|
||||
SoC using SPI, wrapped inside the pmic-wrapper.
|
||||
|
||||
Signed-off-by: Chen Zhong <chen.zhong@mediatek.com>
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/regulator/Kconfig | 9 +
|
||||
drivers/regulator/Makefile | 1 +
|
||||
drivers/regulator/mt6323-regulator.c | 432 ++++++++++++++++++++++++++++
|
||||
include/linux/regulator/mt6323-regulator.h | 52 ++++
|
||||
4 files changed, 494 insertions(+)
|
||||
create mode 100644 drivers/regulator/mt6323-regulator.c
|
||||
create mode 100644 include/linux/regulator/mt6323-regulator.h
|
||||
|
||||
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
|
||||
index 8df0b0e..4aec931 100644
|
||||
--- a/drivers/regulator/Kconfig
|
||||
+++ b/drivers/regulator/Kconfig
|
||||
@@ -452,6 +452,15 @@ config REGULATOR_MT6311
|
||||
This driver supports the control of different power rails of device
|
||||
through regulator interface.
|
||||
|
||||
+config REGULATOR_MT6323
|
||||
+ tristate "MediaTek MT6323 PMIC"
|
||||
+ depends on MFD_MT6397
|
||||
+ help
|
||||
+ Say y here to select this option to enable the power regulator of
|
||||
+ MediaTek MT6323 PMIC.
|
||||
+ This driver supports the control of different power rails of device
|
||||
+ through regulator interface.
|
||||
+
|
||||
config REGULATOR_MT6397
|
||||
tristate "MediaTek MT6397 PMIC"
|
||||
depends on MFD_MT6397
|
||||
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
|
||||
index 0f81749..b42a84e 100644
|
||||
--- a/drivers/regulator/Makefile
|
||||
+++ b/drivers/regulator/Makefile
|
||||
@@ -60,6 +60,7 @@ obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
|
||||
obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
|
||||
+obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
|
||||
diff --git a/drivers/regulator/mt6323-regulator.c b/drivers/regulator/mt6323-regulator.c
|
||||
new file mode 100644
|
||||
index 0000000..28ebbda
|
||||
--- /dev/null
|
||||
+++ b/drivers/regulator/mt6323-regulator.c
|
||||
@@ -0,0 +1,432 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2016 MediaTek Inc.
|
||||
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/mfd/mt6397/core.h>
|
||||
+#include <linux/mfd/mt6323/registers.h>
|
||||
+#include <linux/regulator/driver.h>
|
||||
+#include <linux/regulator/machine.h>
|
||||
+#include <linux/regulator/mt6323-regulator.h>
|
||||
+#include <linux/regulator/of_regulator.h>
|
||||
+
|
||||
+#define MT6323_LDO_MODE_NORMAL 0
|
||||
+#define MT6323_LDO_MODE_LP 1
|
||||
+
|
||||
+/*
|
||||
+ * MT6323 regulators' information
|
||||
+ *
|
||||
+ * @desc: standard fields of regulator description.
|
||||
+ * @qi: Mask for query enable signal status of regulators
|
||||
+ * @vselon_reg: Register sections for hardware control mode of bucks
|
||||
+ * @vselctrl_reg: Register for controlling the buck control mode.
|
||||
+ * @vselctrl_mask: Mask for query buck's voltage control mode.
|
||||
+ */
|
||||
+struct mt6323_regulator_info {
|
||||
+ struct regulator_desc desc;
|
||||
+ u32 qi;
|
||||
+ u32 vselon_reg;
|
||||
+ u32 vselctrl_reg;
|
||||
+ u32 vselctrl_mask;
|
||||
+ u32 modeset_reg;
|
||||
+ u32 modeset_mask;
|
||||
+};
|
||||
+
|
||||
+#define MT6323_BUCK(match, vreg, min, max, step, volt_ranges, enreg, \
|
||||
+ vosel, vosel_mask, voselon, vosel_ctrl) \
|
||||
+[MT6323_ID_##vreg] = { \
|
||||
+ .desc = { \
|
||||
+ .name = #vreg, \
|
||||
+ .of_match = of_match_ptr(match), \
|
||||
+ .ops = &mt6323_volt_range_ops, \
|
||||
+ .type = REGULATOR_VOLTAGE, \
|
||||
+ .id = MT6323_ID_##vreg, \
|
||||
+ .owner = THIS_MODULE, \
|
||||
+ .n_voltages = (max - min)/step + 1, \
|
||||
+ .linear_ranges = volt_ranges, \
|
||||
+ .n_linear_ranges = ARRAY_SIZE(volt_ranges), \
|
||||
+ .vsel_reg = vosel, \
|
||||
+ .vsel_mask = vosel_mask, \
|
||||
+ .enable_reg = enreg, \
|
||||
+ .enable_mask = BIT(0), \
|
||||
+ }, \
|
||||
+ .qi = BIT(13), \
|
||||
+ .vselon_reg = voselon, \
|
||||
+ .vselctrl_reg = vosel_ctrl, \
|
||||
+ .vselctrl_mask = BIT(1), \
|
||||
+}
|
||||
+
|
||||
+#define MT6323_LDO(match, vreg, ldo_volt_table, enreg, enbit, vosel, \
|
||||
+ vosel_mask, _modeset_reg, _modeset_mask) \
|
||||
+[MT6323_ID_##vreg] = { \
|
||||
+ .desc = { \
|
||||
+ .name = #vreg, \
|
||||
+ .of_match = of_match_ptr(match), \
|
||||
+ .ops = &mt6323_volt_table_ops, \
|
||||
+ .type = REGULATOR_VOLTAGE, \
|
||||
+ .id = MT6323_ID_##vreg, \
|
||||
+ .owner = THIS_MODULE, \
|
||||
+ .n_voltages = ARRAY_SIZE(ldo_volt_table), \
|
||||
+ .volt_table = ldo_volt_table, \
|
||||
+ .vsel_reg = vosel, \
|
||||
+ .vsel_mask = vosel_mask, \
|
||||
+ .enable_reg = enreg, \
|
||||
+ .enable_mask = BIT(enbit), \
|
||||
+ }, \
|
||||
+ .qi = BIT(15), \
|
||||
+ .modeset_reg = _modeset_reg, \
|
||||
+ .modeset_mask = _modeset_mask, \
|
||||
+}
|
||||
+
|
||||
+#define MT6323_REG_FIXED(match, vreg, enreg, enbit, volt, \
|
||||
+ _modeset_reg, _modeset_mask) \
|
||||
+[MT6323_ID_##vreg] = { \
|
||||
+ .desc = { \
|
||||
+ .name = #vreg, \
|
||||
+ .of_match = of_match_ptr(match), \
|
||||
+ .ops = &mt6323_volt_fixed_ops, \
|
||||
+ .type = REGULATOR_VOLTAGE, \
|
||||
+ .id = MT6323_ID_##vreg, \
|
||||
+ .owner = THIS_MODULE, \
|
||||
+ .n_voltages = 1, \
|
||||
+ .enable_reg = enreg, \
|
||||
+ .enable_mask = BIT(enbit), \
|
||||
+ .min_uV = volt, \
|
||||
+ }, \
|
||||
+ .qi = BIT(15), \
|
||||
+ .modeset_reg = _modeset_reg, \
|
||||
+ .modeset_mask = _modeset_mask, \
|
||||
+}
|
||||
+
|
||||
+static const struct regulator_linear_range buck_volt_range1[] = {
|
||||
+ REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250),
|
||||
+};
|
||||
+
|
||||
+static const struct regulator_linear_range buck_volt_range2[] = {
|
||||
+ REGULATOR_LINEAR_RANGE(1400000, 0, 0x7f, 12500),
|
||||
+};
|
||||
+
|
||||
+static const struct regulator_linear_range buck_volt_range3[] = {
|
||||
+ REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000),
|
||||
+};
|
||||
+
|
||||
+static const u32 ldo_volt_table1[] = {
|
||||
+ 3300000, 3400000, 3500000, 3600000,
|
||||
+};
|
||||
+
|
||||
+static const u32 ldo_volt_table2[] = {
|
||||
+ 1500000, 1800000, 2500000, 2800000,
|
||||
+};
|
||||
+
|
||||
+static const u32 ldo_volt_table3[] = {
|
||||
+ 1800000, 3300000,
|
||||
+};
|
||||
+
|
||||
+static const u32 ldo_volt_table4[] = {
|
||||
+ 3000000, 3300000,
|
||||
+};
|
||||
+
|
||||
+static const u32 ldo_volt_table5[] = {
|
||||
+ 1200000, 1300000, 1500000, 1800000, 2000000, 2800000, 3000000, 3300000,
|
||||
+};
|
||||
+
|
||||
+static const u32 ldo_volt_table6[] = {
|
||||
+ 1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 2000000,
|
||||
+};
|
||||
+
|
||||
+static const u32 ldo_volt_table7[] = {
|
||||
+ 1200000, 1300000, 1500000, 1800000,
|
||||
+};
|
||||
+
|
||||
+static const u32 ldo_volt_table8[] = {
|
||||
+ 1800000, 3000000,
|
||||
+};
|
||||
+
|
||||
+static const u32 ldo_volt_table9[] = {
|
||||
+ 1200000, 1350000, 1500000, 1800000,
|
||||
+};
|
||||
+
|
||||
+static const u32 ldo_volt_table10[] = {
|
||||
+ 1200000, 1300000, 1500000, 1800000,
|
||||
+};
|
||||
+
|
||||
+static int mt6323_get_status(struct regulator_dev *rdev)
|
||||
+{
|
||||
+ int ret;
|
||||
+ u32 regval;
|
||||
+ struct mt6323_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
+
|
||||
+ ret = regmap_read(rdev->regmap, info->desc.enable_reg, ®val);
|
||||
+ if (ret != 0) {
|
||||
+ dev_err(&rdev->dev, "Failed to get enable reg: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
|
||||
+}
|
||||
+
|
||||
+static int mt6323_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||
+{
|
||||
+ int ret, val = 0;
|
||||
+ struct mt6323_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
+
|
||||
+ if (!info->modeset_mask) {
|
||||
+ dev_err(&rdev->dev, "regulator %s doesn't support set_mode\n",
|
||||
+ info->desc.name);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ switch (mode) {
|
||||
+ case REGULATOR_MODE_STANDBY:
|
||||
+ val = MT6323_LDO_MODE_LP;
|
||||
+ break;
|
||||
+ case REGULATOR_MODE_NORMAL:
|
||||
+ val = MT6323_LDO_MODE_NORMAL;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ val <<= ffs(info->modeset_mask) - 1;
|
||||
+
|
||||
+ ret = regmap_update_bits(rdev->regmap, info->modeset_reg,
|
||||
+ info->modeset_mask, val);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static unsigned int mt6323_ldo_get_mode(struct regulator_dev *rdev)
|
||||
+{
|
||||
+ unsigned int val;
|
||||
+ unsigned int mode;
|
||||
+ int ret;
|
||||
+ struct mt6323_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
+
|
||||
+ if (!info->modeset_mask) {
|
||||
+ dev_err(&rdev->dev, "regulator %s doesn't support get_mode\n",
|
||||
+ info->desc.name);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ret = regmap_read(rdev->regmap, info->modeset_reg, &val);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ val &= info->modeset_mask;
|
||||
+ val >>= ffs(info->modeset_mask) - 1;
|
||||
+
|
||||
+ if (val & 0x1)
|
||||
+ mode = REGULATOR_MODE_STANDBY;
|
||||
+ else
|
||||
+ mode = REGULATOR_MODE_NORMAL;
|
||||
+
|
||||
+ return mode;
|
||||
+}
|
||||
+
|
||||
+static struct regulator_ops mt6323_volt_range_ops = {
|
||||
+ .list_voltage = regulator_list_voltage_linear_range,
|
||||
+ .map_voltage = regulator_map_voltage_linear_range,
|
||||
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
+ .enable = regulator_enable_regmap,
|
||||
+ .disable = regulator_disable_regmap,
|
||||
+ .is_enabled = regulator_is_enabled_regmap,
|
||||
+ .get_status = mt6323_get_status,
|
||||
+};
|
||||
+
|
||||
+static struct regulator_ops mt6323_volt_table_ops = {
|
||||
+ .list_voltage = regulator_list_voltage_table,
|
||||
+ .map_voltage = regulator_map_voltage_iterate,
|
||||
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
+ .enable = regulator_enable_regmap,
|
||||
+ .disable = regulator_disable_regmap,
|
||||
+ .is_enabled = regulator_is_enabled_regmap,
|
||||
+ .get_status = mt6323_get_status,
|
||||
+ .set_mode = mt6323_ldo_set_mode,
|
||||
+ .get_mode = mt6323_ldo_get_mode,
|
||||
+};
|
||||
+
|
||||
+static struct regulator_ops mt6323_volt_fixed_ops = {
|
||||
+ .list_voltage = regulator_list_voltage_linear,
|
||||
+ .enable = regulator_enable_regmap,
|
||||
+ .disable = regulator_disable_regmap,
|
||||
+ .is_enabled = regulator_is_enabled_regmap,
|
||||
+ .get_status = mt6323_get_status,
|
||||
+ .set_mode = mt6323_ldo_set_mode,
|
||||
+ .get_mode = mt6323_ldo_get_mode,
|
||||
+};
|
||||
+
|
||||
+/* The array is indexed by id(MT6323_ID_XXX) */
|
||||
+static struct mt6323_regulator_info mt6323_regulators[] = {
|
||||
+ MT6323_BUCK("buck_vproc", VPROC, 700000, 1493750, 6250,
|
||||
+ buck_volt_range1, MT6323_VPROC_CON7, MT6323_VPROC_CON9, 0x7f,
|
||||
+ MT6323_VPROC_CON10, MT6323_VPROC_CON5),
|
||||
+ MT6323_BUCK("buck_vsys", VSYS, 1400000, 2987500, 12500,
|
||||
+ buck_volt_range2, MT6323_VSYS_CON7, MT6323_VSYS_CON9, 0x7f,
|
||||
+ MT6323_VSYS_CON10, MT6323_VSYS_CON5),
|
||||
+ MT6323_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
|
||||
+ buck_volt_range3, MT6323_VPA_CON7, MT6323_VPA_CON9,
|
||||
+ 0x3f, MT6323_VPA_CON10, MT6323_VPA_CON5),
|
||||
+ MT6323_REG_FIXED("ldo_vtcxo", VTCXO, MT6323_ANALDO_CON1, 10, 2800000,
|
||||
+ MT6323_ANALDO_CON1, 0x2),
|
||||
+ MT6323_REG_FIXED("ldo_vcn28", VCN28, MT6323_ANALDO_CON19, 12, 2800000,
|
||||
+ MT6323_ANALDO_CON20, 0x2),
|
||||
+ MT6323_LDO("ldo_vcn33_bt", VCN33_BT, ldo_volt_table1,
|
||||
+ MT6323_ANALDO_CON16, 7, MT6323_ANALDO_CON16, 0xC,
|
||||
+ MT6323_ANALDO_CON21, 0x2),
|
||||
+ MT6323_LDO("ldo_vcn33_wifi", VCN33_WIFI, ldo_volt_table1,
|
||||
+ MT6323_ANALDO_CON17, 12, MT6323_ANALDO_CON16, 0xC,
|
||||
+ MT6323_ANALDO_CON21, 0x2),
|
||||
+ MT6323_REG_FIXED("ldo_va", VA, MT6323_ANALDO_CON2, 14, 2800000,
|
||||
+ MT6323_ANALDO_CON2, 0x2),
|
||||
+ MT6323_LDO("ldo_vcama", VCAMA, ldo_volt_table2,
|
||||
+ MT6323_ANALDO_CON4, 15, MT6323_ANALDO_CON10, 0x60, -1, 0),
|
||||
+ MT6323_REG_FIXED("ldo_vio28", VIO28, MT6323_DIGLDO_CON0, 14, 2800000,
|
||||
+ MT6323_DIGLDO_CON0, 0x2),
|
||||
+ MT6323_REG_FIXED("ldo_vusb", VUSB, MT6323_DIGLDO_CON2, 14, 3300000,
|
||||
+ MT6323_DIGLDO_CON2, 0x2),
|
||||
+ MT6323_LDO("ldo_vmc", VMC, ldo_volt_table3,
|
||||
+ MT6323_DIGLDO_CON3, 12, MT6323_DIGLDO_CON24, 0x10,
|
||||
+ MT6323_DIGLDO_CON3, 0x2),
|
||||
+ MT6323_LDO("ldo_vmch", VMCH, ldo_volt_table4,
|
||||
+ MT6323_DIGLDO_CON5, 14, MT6323_DIGLDO_CON26, 0x80,
|
||||
+ MT6323_DIGLDO_CON5, 0x2),
|
||||
+ MT6323_LDO("ldo_vemc3v3", VEMC3V3, ldo_volt_table4,
|
||||
+ MT6323_DIGLDO_CON6, 14, MT6323_DIGLDO_CON27, 0x80,
|
||||
+ MT6323_DIGLDO_CON6, 0x2),
|
||||
+ MT6323_LDO("ldo_vgp1", VGP1, ldo_volt_table5,
|
||||
+ MT6323_DIGLDO_CON7, 15, MT6323_DIGLDO_CON28, 0xE0,
|
||||
+ MT6323_DIGLDO_CON7, 0x2),
|
||||
+ MT6323_LDO("ldo_vgp2", VGP2, ldo_volt_table6,
|
||||
+ MT6323_DIGLDO_CON8, 15, MT6323_DIGLDO_CON29, 0xE0,
|
||||
+ MT6323_DIGLDO_CON8, 0x2),
|
||||
+ MT6323_LDO("ldo_vgp3", VGP3, ldo_volt_table7,
|
||||
+ MT6323_DIGLDO_CON9, 15, MT6323_DIGLDO_CON30, 0x60,
|
||||
+ MT6323_DIGLDO_CON9, 0x2),
|
||||
+ MT6323_REG_FIXED("ldo_vcn18", VCN18, MT6323_DIGLDO_CON11, 14, 1800000,
|
||||
+ MT6323_DIGLDO_CON11, 0x2),
|
||||
+ MT6323_LDO("ldo_vsim1", VSIM1, ldo_volt_table8,
|
||||
+ MT6323_DIGLDO_CON13, 15, MT6323_DIGLDO_CON34, 0x20,
|
||||
+ MT6323_DIGLDO_CON13, 0x2),
|
||||
+ MT6323_LDO("ldo_vsim2", VSIM2, ldo_volt_table8,
|
||||
+ MT6323_DIGLDO_CON14, 15, MT6323_DIGLDO_CON35, 0x20,
|
||||
+ MT6323_DIGLDO_CON14, 0x2),
|
||||
+ MT6323_REG_FIXED("ldo_vrtc", VRTC, MT6323_DIGLDO_CON15, 8, 2800000,
|
||||
+ -1, 0),
|
||||
+ MT6323_LDO("ldo_vcamaf", VCAMAF, ldo_volt_table5,
|
||||
+ MT6323_DIGLDO_CON31, 15, MT6323_DIGLDO_CON32, 0xE0,
|
||||
+ MT6323_DIGLDO_CON31, 0x2),
|
||||
+ MT6323_LDO("ldo_vibr", VIBR, ldo_volt_table5,
|
||||
+ MT6323_DIGLDO_CON39, 15, MT6323_DIGLDO_CON40, 0xE0,
|
||||
+ MT6323_DIGLDO_CON39, 0x2),
|
||||
+ MT6323_REG_FIXED("ldo_vrf18", VRF18, MT6323_DIGLDO_CON45, 15, 1825000,
|
||||
+ MT6323_DIGLDO_CON45, 0x2),
|
||||
+ MT6323_LDO("ldo_vm", VM, ldo_volt_table9,
|
||||
+ MT6323_DIGLDO_CON47, 14, MT6323_DIGLDO_CON48, 0x30,
|
||||
+ MT6323_DIGLDO_CON47, 0x2),
|
||||
+ MT6323_REG_FIXED("ldo_vio18", VIO18, MT6323_DIGLDO_CON49, 14, 1800000,
|
||||
+ MT6323_DIGLDO_CON49, 0x2),
|
||||
+ MT6323_LDO("ldo_vcamd", VCAMD, ldo_volt_table10,
|
||||
+ MT6323_DIGLDO_CON51, 14, MT6323_DIGLDO_CON52, 0x60,
|
||||
+ MT6323_DIGLDO_CON51, 0x2),
|
||||
+ MT6323_REG_FIXED("ldo_vcamio", VCAMIO, MT6323_DIGLDO_CON53, 14, 1800000,
|
||||
+ MT6323_DIGLDO_CON53, 0x2),
|
||||
+};
|
||||
+
|
||||
+static int mt6323_set_buck_vosel_reg(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mt6397_chip *mt6323 = dev_get_drvdata(pdev->dev.parent);
|
||||
+ int i;
|
||||
+ u32 regval;
|
||||
+
|
||||
+ for (i = 0; i < MT6323_MAX_REGULATOR; i++) {
|
||||
+ if (mt6323_regulators[i].vselctrl_reg) {
|
||||
+ if (regmap_read(mt6323->regmap,
|
||||
+ mt6323_regulators[i].vselctrl_reg,
|
||||
+ ®val) < 0) {
|
||||
+ dev_err(&pdev->dev,
|
||||
+ "Failed to read buck ctrl\n");
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ if (regval & mt6323_regulators[i].vselctrl_mask) {
|
||||
+ mt6323_regulators[i].desc.vsel_reg =
|
||||
+ mt6323_regulators[i].vselon_reg;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mt6323_regulator_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mt6397_chip *mt6323 = dev_get_drvdata(pdev->dev.parent);
|
||||
+ struct regulator_config config = {};
|
||||
+ struct regulator_dev *rdev;
|
||||
+ int i;
|
||||
+ u32 reg_value;
|
||||
+
|
||||
+ /* Query buck controller to select activated voltage register part */
|
||||
+ if (mt6323_set_buck_vosel_reg(pdev))
|
||||
+ return -EIO;
|
||||
+
|
||||
+ /* Read PMIC chip revision to update constraints and voltage table */
|
||||
+ if (regmap_read(mt6323->regmap, MT6323_CID, ®_value) < 0) {
|
||||
+ dev_err(&pdev->dev, "Failed to read Chip ID\n");
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+ dev_info(&pdev->dev, "Chip ID = 0x%x\n", reg_value);
|
||||
+
|
||||
+ for (i = 0; i < MT6323_MAX_REGULATOR; i++) {
|
||||
+ config.dev = &pdev->dev;
|
||||
+ config.driver_data = &mt6323_regulators[i];
|
||||
+ config.regmap = mt6323->regmap;
|
||||
+ rdev = devm_regulator_register(&pdev->dev,
|
||||
+ &mt6323_regulators[i].desc, &config);
|
||||
+ if (IS_ERR(rdev)) {
|
||||
+ dev_err(&pdev->dev, "failed to register %s\n",
|
||||
+ mt6323_regulators[i].desc.name);
|
||||
+ return PTR_ERR(rdev);
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct platform_device_id mt6323_platform_ids[] = {
|
||||
+ {"mt6323-regulator", 0},
|
||||
+ { /* sentinel */ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(platform, mt6323_platform_ids);
|
||||
+
|
||||
+static const struct of_device_id mt6323_of_match[] = {
|
||||
+ { .compatible = "mediatek,mt6323-regulator", },
|
||||
+ { /* sentinel */ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mt6323_of_match);
|
||||
+
|
||||
+static struct platform_driver mt6323_regulator_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "mt6323-regulator",
|
||||
+ .of_match_table = of_match_ptr(mt6323_of_match),
|
||||
+ },
|
||||
+ .probe = mt6323_regulator_probe,
|
||||
+ .id_table = mt6323_platform_ids,
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(mt6323_regulator_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Chen Zhong <chen.zhong@mediatek.com>");
|
||||
+MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6397 PMIC");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
diff --git a/include/linux/regulator/mt6323-regulator.h b/include/linux/regulator/mt6323-regulator.h
|
||||
new file mode 100644
|
||||
index 0000000..67011cd
|
||||
--- /dev/null
|
||||
+++ b/include/linux/regulator/mt6323-regulator.h
|
||||
@@ -0,0 +1,52 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2016 MediaTek Inc.
|
||||
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __LINUX_REGULATOR_MT6323_H
|
||||
+#define __LINUX_REGULATOR_MT6323_H
|
||||
+
|
||||
+enum {
|
||||
+ MT6323_ID_VPROC = 0,
|
||||
+ MT6323_ID_VSYS,
|
||||
+ MT6323_ID_VPA,
|
||||
+ MT6323_ID_VTCXO,
|
||||
+ MT6323_ID_VCN28,
|
||||
+ MT6323_ID_VCN33_BT,
|
||||
+ MT6323_ID_VCN33_WIFI,
|
||||
+ MT6323_ID_VA,
|
||||
+ MT6323_ID_VCAMA,
|
||||
+ MT6323_ID_VIO28 = 9,
|
||||
+ MT6323_ID_VUSB,
|
||||
+ MT6323_ID_VMC,
|
||||
+ MT6323_ID_VMCH,
|
||||
+ MT6323_ID_VEMC3V3,
|
||||
+ MT6323_ID_VGP1,
|
||||
+ MT6323_ID_VGP2,
|
||||
+ MT6323_ID_VGP3,
|
||||
+ MT6323_ID_VCN18,
|
||||
+ MT6323_ID_VSIM1,
|
||||
+ MT6323_ID_VSIM2,
|
||||
+ MT6323_ID_VRTC,
|
||||
+ MT6323_ID_VCAMAF,
|
||||
+ MT6323_ID_VIBR,
|
||||
+ MT6323_ID_VRF18,
|
||||
+ MT6323_ID_VM,
|
||||
+ MT6323_ID_VIO18,
|
||||
+ MT6323_ID_VCAMD,
|
||||
+ MT6323_ID_VCAMIO,
|
||||
+ MT6323_ID_RG_MAX,
|
||||
+};
|
||||
+
|
||||
+#define MT6323_MAX_REGULATOR MT6323_ID_RG_MAX
|
||||
+
|
||||
+#endif /* __LINUX_REGULATOR_MT6323_H */
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,103 @@
|
||||
From 32f95a0bc03886b38a53569466d5bee4a6d66875 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 2 Mar 2016 07:18:52 +0100
|
||||
Subject: [PATCH 48/53] net-next: mediatek: document MediaTek SoC ethernet
|
||||
binding
|
||||
|
||||
This adds the binding documentation for the MediaTek Ethernet
|
||||
controller.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
Acked-by: Rob Herring <robh@kernel.org>
|
||||
Cc: devicetree@vger.kernel.org
|
||||
---
|
||||
.../devicetree/bindings/net/mediatek-net.txt | 77 ++++++++++++++++++++
|
||||
1 file changed, 77 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/net/mediatek-net.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/net/mediatek-net.txt b/Documentation/devicetree/bindings/net/mediatek-net.txt
|
||||
new file mode 100644
|
||||
index 0000000..5ca7929
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/net/mediatek-net.txt
|
||||
@@ -0,0 +1,77 @@
|
||||
+MediaTek Frame Engine Ethernet controller
|
||||
+=========================================
|
||||
+
|
||||
+The frame engine ethernet controller can be found on MediaTek SoCs. These SoCs
|
||||
+have dual GMAC each represented by a child node..
|
||||
+
|
||||
+* Ethernet controller node
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible: Should be "mediatek,mt7623-eth"
|
||||
+- reg: Address and length of the register set for the device
|
||||
+- interrupts: Should contain the frame engines interrupt
|
||||
+- clocks: the clock used by the core
|
||||
+- clock-names: the names of the clock listed in the clocks property. These are
|
||||
+ "ethif", "esw", "gp2", "gp1"
|
||||
+- power-domains: phandle to the power domain that the ethernet is part of
|
||||
+- resets: Should contain a phandle to the ethsys reset signal
|
||||
+- reset-names: Should contain the reset signal name "eth"
|
||||
+- mediatek,ethsys: phandle to the syscon node that handles the port setup
|
||||
+- mediatek,pctl: phandle to the syscon node that handles the ports slew rate
|
||||
+ and driver current
|
||||
+
|
||||
+Optional properties:
|
||||
+- interrupt-parent: Should be the phandle for the interrupt controller
|
||||
+ that services interrupts for this device
|
||||
+
|
||||
+
|
||||
+* Ethernet MAC node
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible: Should be "mediatek,eth-mac"
|
||||
+- reg: The number of the MAC
|
||||
+- phy-handle: see ethernet.txt file in the same directory.
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+eth: ethernet@1b100000 {
|
||||
+ compatible = "mediatek,mt7623-eth";
|
||||
+ reg = <0 0x1b100000 0 0x20000>;
|
||||
+ clocks = <&topckgen CLK_TOP_ETHIF_SEL>,
|
||||
+ <ðsys CLK_ETHSYS_ESW>,
|
||||
+ <ðsys CLK_ETHSYS_GP2>,
|
||||
+ <ðsys CLK_ETHSYS_GP1>;
|
||||
+ clock-names = "ethif", "esw", "gp2", "gp1";
|
||||
+ interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
|
||||
+ resets = <ðsys MT2701_ETHSYS_ETH_RST>;
|
||||
+ reset-names = "eth";
|
||||
+ mediatek,ethsys = <ðsys>;
|
||||
+ mediatek,pctl = <&syscfg_pctl_a>;
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ gmac1: mac@0 {
|
||||
+ compatible = "mediatek,eth-mac";
|
||||
+ reg = <0>;
|
||||
+ phy-handle = <&phy0>;
|
||||
+ };
|
||||
+
|
||||
+ gmac2: mac@1 {
|
||||
+ compatible = "mediatek,eth-mac";
|
||||
+ reg = <1>;
|
||||
+ phy-handle = <&phy1>;
|
||||
+ };
|
||||
+
|
||||
+ mdio-bus {
|
||||
+ phy0: ethernet-phy@0 {
|
||||
+ reg = <0>;
|
||||
+ phy-mode = "rgmii";
|
||||
+ };
|
||||
+
|
||||
+ phy1: ethernet-phy@1 {
|
||||
+ reg = <1>;
|
||||
+ phy-mode = "rgmii";
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
--
|
||||
1.7.10.4
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,78 @@
|
||||
From 093d38375d35e6fa0f54c2c30b517a73d8448710 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 2 Mar 2016 04:32:43 +0100
|
||||
Subject: [PATCH 50/53] net-next: mediatek: add Kconfig and Makefile
|
||||
|
||||
This patch adds the Makefile and Kconfig required to make the driver build.
|
||||
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
drivers/net/ethernet/Kconfig | 1 +
|
||||
drivers/net/ethernet/Makefile | 1 +
|
||||
drivers/net/ethernet/mediatek/Kconfig | 17 +++++++++++++++++
|
||||
drivers/net/ethernet/mediatek/Makefile | 5 +++++
|
||||
4 files changed, 24 insertions(+)
|
||||
create mode 100644 drivers/net/ethernet/mediatek/Kconfig
|
||||
create mode 100644 drivers/net/ethernet/mediatek/Makefile
|
||||
|
||||
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
|
||||
index 31c5e47..cd28b95 100644
|
||||
--- a/drivers/net/ethernet/Kconfig
|
||||
+++ b/drivers/net/ethernet/Kconfig
|
||||
@@ -106,6 +106,7 @@ config LANTIQ_ETOP
|
||||
Support for the MII0 inside the Lantiq SoC
|
||||
|
||||
source "drivers/net/ethernet/marvell/Kconfig"
|
||||
+source "drivers/net/ethernet/mediatek/Kconfig"
|
||||
source "drivers/net/ethernet/mellanox/Kconfig"
|
||||
source "drivers/net/ethernet/micrel/Kconfig"
|
||||
source "drivers/net/ethernet/microchip/Kconfig"
|
||||
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
|
||||
index 071f84e..c62191f 100644
|
||||
--- a/drivers/net/ethernet/Makefile
|
||||
+++ b/drivers/net/ethernet/Makefile
|
||||
@@ -46,6 +46,7 @@ obj-$(CONFIG_JME) += jme.o
|
||||
obj-$(CONFIG_KORINA) += korina.o
|
||||
obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o
|
||||
obj-$(CONFIG_NET_VENDOR_MARVELL) += marvell/
|
||||
+obj-$(CONFIG_NET_VENDOR_MEDIATEK) += mediatek/
|
||||
obj-$(CONFIG_NET_VENDOR_MELLANOX) += mellanox/
|
||||
obj-$(CONFIG_NET_VENDOR_MICREL) += micrel/
|
||||
obj-$(CONFIG_NET_VENDOR_MICROCHIP) += microchip/
|
||||
diff --git a/drivers/net/ethernet/mediatek/Kconfig b/drivers/net/ethernet/mediatek/Kconfig
|
||||
new file mode 100644
|
||||
index 0000000..b0229f4
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/mediatek/Kconfig
|
||||
@@ -0,0 +1,17 @@
|
||||
+config NET_VENDOR_MEDIATEK
|
||||
+ bool "MediaTek ethernet driver"
|
||||
+ depends on ARCH_MEDIATEK
|
||||
+ ---help---
|
||||
+ If you have a Mediatek SoC with ethernet, say Y.
|
||||
+
|
||||
+if NET_VENDOR_MEDIATEK
|
||||
+
|
||||
+config NET_MEDIATEK_SOC
|
||||
+ tristate "MediaTek MT7623 Gigabit ethernet support"
|
||||
+ depends on NET_VENDOR_MEDIATEK #&& (MACH_MT7623 || MACH_MT2701)
|
||||
+ select PHYLIB
|
||||
+ ---help---
|
||||
+ This driver supports the gigabit ethernet MACs in the
|
||||
+ MediaTek MT2701/MT7623 chipset family.
|
||||
+
|
||||
+endif #NET_VENDOR_MEDIATEK
|
||||
diff --git a/drivers/net/ethernet/mediatek/Makefile b/drivers/net/ethernet/mediatek/Makefile
|
||||
new file mode 100644
|
||||
index 0000000..aa3f1c8
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/ethernet/mediatek/Makefile
|
||||
@@ -0,0 +1,5 @@
|
||||
+#
|
||||
+# Makefile for the Mediatek SoCs built-in ethernet macs
|
||||
+#
|
||||
+
|
||||
+obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth_soc.o
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -0,0 +1,34 @@
|
||||
From 3180cf4f325411f796468e12d524fe6354ded274 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <blogic@openwrt.org>
|
||||
Date: Wed, 2 Mar 2016 04:34:04 +0100
|
||||
Subject: [PATCH 51/53] net-next: mediatek: add an entry to MAINTAINERS
|
||||
|
||||
Add myself and Felix as the Maintainers for the MediaTek ethernet driver.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
Signed-off-by: John Crispin <blogic@openwrt.org>
|
||||
---
|
||||
MAINTAINERS | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 156e1d3..7737042 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -6908,6 +6908,13 @@ F: include/uapi/linux/meye.h
|
||||
F: include/uapi/linux/ivtv*
|
||||
F: include/uapi/linux/uvcvideo.h
|
||||
|
||||
+MEDIATEK ETHERNET DRIVER
|
||||
+M: Felix Fietkau <nbd@openwrt.org>
|
||||
+M: John Crispin <blogic@openwrt.org>
|
||||
+L: netdev@vger.kernel.org
|
||||
+S: Maintained
|
||||
+F: drivers/net/ethernet/mediatek/
|
||||
+
|
||||
MEDIATEK MT7601U WIRELESS LAN DRIVER
|
||||
M: Jakub Kicinski <kubakici@wp.pl>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
--
|
||||
1.7.10.4
|
||||
|
2409
target/linux/mediatek/patches-4.4/0052-net-out-of-tree-fixes.patch
Normal file
2409
target/linux/mediatek/patches-4.4/0052-net-out-of-tree-fixes.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,15 +1,17 @@
|
||||
From b1c69201563ae3ff878abf4ba192e73031de8653 Mon Sep 17 00:00:00 2001
|
||||
From 308cdd2b743a5e01b26d79c8fb89e513dea09856 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
|
||||
Subject: [PATCH 53/53] 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 f13c3f4..5e9ddae 100644
|
||||
--- a/drivers/clk/clk.c
|
||||
+++ b/drivers/clk/clk.c
|
||||
@@ -542,7 +542,7 @@ unlock_out:
|
||||
@@ -233,7 +233,7 @@ unlock_out:
|
||||
clk_enable_unlock(flags);
|
||||
}
|
||||
|
||||
@ -18,3 +20,6 @@ Subject: [PATCH 58/76] dont disable clocks
|
||||
static int __init clk_ignore_unused_setup(char *__unused)
|
||||
{
|
||||
clk_ignore_unused = true;
|
||||
--
|
||||
1.7.10.4
|
||||
|
@ -1,91 +0,0 @@
|
||||
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(-)
|
||||
|
||||
--- a/drivers/clk/clk-composite.c
|
||||
+++ b/drivers/clk/clk-composite.c
|
||||
@@ -188,7 +188,7 @@ static void clk_composite_disable(struct
|
||||
}
|
||||
|
||||
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,
|
||||
--- 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(struc
|
||||
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)
|
||||
{
|
||||
--- 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,954 +0,0 @@
|
||||
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
|
||||
|
||||
--- 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
|
||||
--- /dev/null
|
||||
+++ b/drivers/clk/mediatek/Makefile
|
||||
@@ -0,0 +1 @@
|
||||
+obj-y += clk-mtk.o clk-pll.o clk-gate.o
|
||||
--- /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;
|
||||
+}
|
||||
--- /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 */
|
||||
--- /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;
|
||||
+ }
|
||||
+}
|
||||
--- /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 */
|
||||
--- /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,145 +0,0 @@
|
||||
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
|
||||
|
||||
--- 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
|
||||
--- 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
|
||||
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 */
|
||||
--- /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,938 +0,0 @@
|
||||
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
|
||||
|
||||
--- 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
|
||||
--- /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);
|
||||
--- /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 */
|
||||
--- /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 */
|
File diff suppressed because it is too large
Load Diff
@ -1,166 +0,0 @@
|
||||
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
|
||||
|
||||
--- 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
|
||||
--- 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
|
||||
--- /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;
|
||||
+}
|
||||
--- /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,51 +0,0 @@
|
||||
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
|
||||
|
||||
--- /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,560 +0,0 @@
|
||||
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
|
||||
|
||||
--- 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.
|
||||
--- 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
|
||||
--- /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);
|
||||
--- /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,139 +0,0 @@
|
||||
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
|
||||
|
||||
--- /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>;
|
||||
+};
|
||||
--- /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>;
|
||||
+};
|
||||
--- /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>;
|
||||
+};
|
||||
--- /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>;
|
||||
+};
|
File diff suppressed because it is too large
Load Diff
@ -1,22 +0,0 @@
|
||||
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(-)
|
||||
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -405,7 +405,7 @@ static void handle_thermal_trip(struct t
|
||||
}
|
||||
|
||||
/**
|
||||
- * 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,29 +0,0 @@
|
||||
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(-)
|
||||
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -1601,9 +1601,6 @@ struct thermal_zone_device *thermal_zone
|
||||
|
||||
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_reset(tz);
|
||||
/* Update the new thermal zone and mark it as already updated. */
|
||||
if (atomic_cmpxchg(&tz->need_update, 1, 0))
|
@ -1,101 +0,0 @@
|
||||
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(-)
|
||||
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -417,11 +417,9 @@ static void handle_thermal_trip(struct t
|
||||
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;
|
||||
@@ -429,25 +427,21 @@ int thermal_zone_get_temp(struct thermal
|
||||
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;
|
||||
@@ -800,7 +794,6 @@ policy_show(struct device *dev, struct d
|
||||
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)
|
||||
@@ -826,7 +819,6 @@ emul_temp_store(struct device *dev, stru
|
||||
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);
|
||||
@@ -1566,11 +1558,12 @@ struct thermal_zone_device *thermal_zone
|
||||
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,29 +0,0 @@
|
||||
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(+)
|
||||
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -438,6 +438,11 @@ int thermal_zone_get_temp(struct thermal
|
||||
}
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * 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,70 +0,0 @@
|
||||
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(-)
|
||||
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -453,9 +453,15 @@ 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 (atomic_read(&in_suspend))
|
||||
+ return;
|
||||
+
|
||||
+ if (!tz->ops->get_temp)
|
||||
+ return;
|
||||
|
||||
ret = thermal_zone_get_temp(tz, &temp);
|
||||
if (ret) {
|
||||
@@ -478,7 +484,11 @@ static void update_temperature(struct th
|
||||
else
|
||||
dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n",
|
||||
tz->last_temperature, tz->temperature);
|
||||
+
|
||||
+ for (count = 0; count < tz->trips; count++)
|
||||
+ handle_thermal_trip(tz, count);
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(thermal_zone_device_update);
|
||||
|
||||
static void thermal_zone_device_reset(struct thermal_zone_device *tz)
|
||||
{
|
||||
@@ -490,23 +500,6 @@ static void thermal_zone_device_reset(st
|
||||
pos->initialized = false;
|
||||
}
|
||||
|
||||
-void thermal_zone_device_update(struct thermal_zone_device *tz)
|
||||
-{
|
||||
- int count;
|
||||
-
|
||||
- if (atomic_read(&in_suspend))
|
||||
- return;
|
||||
-
|
||||
- if (!tz->ops->get_temp)
|
||||
- return;
|
||||
-
|
||||
- update_temperature(tz);
|
||||
-
|
||||
- for (count = 0; count < tz->trips; count++)
|
||||
- handle_thermal_trip(tz, count);
|
||||
-}
|
||||
-EXPORT_SYMBOL_GPL(thermal_zone_device_update);
|
||||
-
|
||||
static void thermal_zone_device_check(struct work_struct *work)
|
||||
{
|
||||
struct thermal_zone_device *tz = container_of(work, struct
|
@ -1,114 +0,0 @@
|
||||
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(-)
|
||||
|
||||
--- a/drivers/thermal/of-thermal.c
|
||||
+++ b/drivers/thermal/of-thermal.c
|
||||
@@ -187,24 +187,15 @@ static int of_thermal_get_trend(struct t
|
||||
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;
|
||||
}
|
||||
|
||||
--- 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(stru
|
||||
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 *
|
||||
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 t
|
||||
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)
|
||||
--- a/include/linux/thermal.h
|
||||
+++ b/include/linux/thermal.h
|
||||
@@ -274,7 +274,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,85 +0,0 @@
|
||||
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(-)
|
||||
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -416,13 +416,16 @@ static void handle_thermal_trip(struct t
|
||||
*/
|
||||
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);
|
||||
|
||||
@@ -448,7 +451,7 @@ int thermal_zone_get_temp(struct thermal
|
||||
}
|
||||
|
||||
mutex_unlock(&tz->lock);
|
||||
-exit:
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
|
||||
@@ -460,10 +463,11 @@ void thermal_zone_device_update(struct t
|
||||
if (atomic_read(&in_suspend))
|
||||
return;
|
||||
|
||||
- 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,
|
||||
@@ -803,10 +807,16 @@ emul_temp_store(struct device *dev, stru
|
||||
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,124 +0,0 @@
|
||||
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(-)
|
||||
|
||||
--- a/drivers/thermal/of-thermal.c
|
||||
+++ b/drivers/thermal/of-thermal.c
|
||||
@@ -91,7 +91,7 @@ static int of_thermal_get_temp(struct th
|
||||
{
|
||||
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(stru
|
||||
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 t
|
||||
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(stru
|
||||
}
|
||||
|
||||
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
|
||||
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(s
|
||||
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,282 +0,0 @@
|
||||
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(-)
|
||||
|
||||
--- a/Documentation/thermal/sysfs-api.txt
|
||||
+++ b/Documentation/thermal/sysfs-api.txt
|
||||
@@ -33,7 +33,7 @@ temperature) and throttle appropriate de
|
||||
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))
|
||||
|
||||
--- a/drivers/acpi/thermal.c
|
||||
+++ b/drivers/acpi/thermal.c
|
||||
@@ -869,7 +869,7 @@ acpi_thermal_unbind_cooling_device(struc
|
||||
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,
|
||||
--- a/drivers/platform/x86/acerhdf.c
|
||||
+++ b/drivers/platform/x86/acerhdf.c
|
||||
@@ -482,7 +482,7 @@ static int acerhdf_get_crit_temp(struct
|
||||
}
|
||||
|
||||
/* 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,
|
||||
--- 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
|
||||
}
|
||||
|
||||
/* 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,
|
||||
};
|
||||
|
||||
--- a/drivers/power/power_supply_core.c
|
||||
+++ b/drivers/power/power_supply_core.c
|
||||
@@ -535,7 +535,7 @@ static int power_supply_read_temp(struct
|
||||
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,
|
||||
};
|
||||
|
||||
--- a/drivers/thermal/armada_thermal.c
|
||||
+++ b/drivers/thermal/armada_thermal.c
|
||||
@@ -183,7 +183,7 @@ static int armada_get_temp(struct therma
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops ops = {
|
||||
+static const struct thermal_zone_device_ops ops = {
|
||||
.get_temp = armada_get_temp,
|
||||
};
|
||||
|
||||
--- a/drivers/thermal/db8500_thermal.c
|
||||
+++ b/drivers/thermal/db8500_thermal.c
|
||||
@@ -210,7 +210,7 @@ static int db8500_sys_get_crit_temp(stru
|
||||
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,
|
||||
--- a/drivers/thermal/dove_thermal.c
|
||||
+++ b/drivers/thermal/dove_thermal.c
|
||||
@@ -118,7 +118,7 @@ static int dove_get_temp(struct thermal_
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops ops = {
|
||||
+static const struct thermal_zone_device_ops ops = {
|
||||
.get_temp = dove_get_temp,
|
||||
};
|
||||
|
||||
--- a/drivers/thermal/imx_thermal.c
|
||||
+++ b/drivers/thermal/imx_thermal.c
|
||||
@@ -332,7 +332,7 @@ static int imx_unbind(struct thermal_zon
|
||||
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,
|
||||
--- 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(stru
|
||||
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,
|
||||
};
|
||||
|
||||
--- 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
|
||||
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,
|
||||
--- 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 ther
|
||||
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,
|
||||
--- a/drivers/thermal/kirkwood_thermal.c
|
||||
+++ b/drivers/thermal/kirkwood_thermal.c
|
||||
@@ -60,7 +60,7 @@ static int kirkwood_get_temp(struct ther
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops ops = {
|
||||
+static const struct thermal_zone_device_ops ops = {
|
||||
.get_temp = kirkwood_get_temp,
|
||||
};
|
||||
|
||||
--- a/drivers/thermal/of-thermal.c
|
||||
+++ b/drivers/thermal/of-thermal.c
|
||||
@@ -365,7 +365,7 @@ static int of_thermal_get_crit_temp(stru
|
||||
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,
|
||||
--- a/drivers/thermal/rcar_thermal.c
|
||||
+++ b/drivers/thermal/rcar_thermal.c
|
||||
@@ -270,7 +270,7 @@ static int rcar_thermal_notify(struct th
|
||||
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,
|
||||
--- a/drivers/thermal/spear_thermal.c
|
||||
+++ b/drivers/thermal/spear_thermal.c
|
||||
@@ -50,7 +50,7 @@ static inline int thermal_get_temp(struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct thermal_zone_device_ops ops = {
|
||||
+static const struct thermal_zone_device_ops ops = {
|
||||
.get_temp = thermal_get_temp,
|
||||
};
|
||||
|
||||
--- 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(stru
|
||||
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,
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -1479,7 +1479,7 @@ static void remove_trip_attrs(struct the
|
||||
*/
|
||||
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)
|
||||
{
|
||||
--- 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_devi
|
||||
.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,
|
||||
--- 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 ther
|
||||
}
|
||||
|
||||
/* 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,
|
||||
--- a/include/linux/thermal.h
|
||||
+++ b/include/linux/thermal.h
|
||||
@@ -186,7 +186,7 @@ struct thermal_zone_device {
|
||||
int passive;
|
||||
unsigned int forced_passive;
|
||||
atomic_t need_update;
|
||||
- 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;
|
||||
@@ -318,7 +318,7 @@ void thermal_zone_of_sensor_unregister(s
|
||||
|
||||
#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 *);
|
||||
|
||||
@@ -346,7 +346,7 @@ void thermal_notify_framework(struct the
|
||||
#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,117 +0,0 @@
|
||||
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(+)
|
||||
|
||||
--- a/drivers/thermal/thermal_core.c
|
||||
+++ b/drivers/thermal/thermal_core.c
|
||||
@@ -456,6 +456,45 @@ int thermal_zone_get_temp(struct thermal
|
||||
}
|
||||
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;
|
||||
@@ -489,6 +528,8 @@ void thermal_zone_device_update(struct t
|
||||
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);
|
||||
}
|
||||
@@ -1522,6 +1563,8 @@ struct thermal_zone_device *thermal_zone
|
||||
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;
|
||||
/* A new thermal zone needs to be updated anyway. */
|
||||
atomic_set(&tz->need_update, 1);
|
||||
|
||||
--- a/include/linux/thermal.h
|
||||
+++ b/include/linux/thermal.h
|
||||
@@ -90,6 +90,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 *,
|
||||
@@ -184,6 +185,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;
|
||||
atomic_t need_update;
|
||||
const struct thermal_zone_device_ops *ops;
|
@ -1,58 +0,0 @@
|
||||
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(+)
|
||||
|
||||
--- a/drivers/thermal/of-thermal.c
|
||||
+++ b/drivers/thermal/of-thermal.c
|
||||
@@ -97,6 +97,17 @@ static int of_thermal_get_temp(struct th
|
||||
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(stru
|
||||
|
||||
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,
|
||||
|
||||
--- a/include/linux/thermal.h
|
||||
+++ b/include/linux/thermal.h
|
||||
@@ -272,12 +272,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,51 +0,0 @@
|
||||
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
|
||||
|
||||
--- /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,775 +0,0 @@
|
||||
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
|
||||
|
||||
--- 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
|
||||
--- a/drivers/thermal/Makefile
|
||||
+++ b/drivers/thermal/Makefile
|
||||
@@ -39,3 +39,4 @@ obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-t
|
||||
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
|
||||
--- /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,44 +0,0 @@
|
||||
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(+)
|
||||
|
||||
--- 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,47 +0,0 @@
|
||||
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
|
||||
|
||||
--- /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,669 +0,0 @@
|
||||
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
|
||||
|
||||
--- a/drivers/spi/Kconfig
|
||||
+++ b/drivers/spi/Kconfig
|
||||
@@ -334,6 +334,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
|
||||
--- a/drivers/spi/Makefile
|
||||
+++ b/drivers/spi/Makefile
|
||||
@@ -49,6 +49,7 @@ obj-$(CONFIG_SPI_MESON_SPIFC) += spi-me
|
||||
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
|
||||
--- /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,41 +0,0 @@
|
||||
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
|
||||
|
||||
--- /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,271 +0,0 @@
|
||||
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
|
||||
|
||||
--- 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
|
||||
--- a/drivers/pwm/Makefile
|
||||
+++ b/drivers/pwm/Makefile
|
||||
@@ -8,6 +8,7 @@ obj-$(CONFIG_PWM_BCM_KONA) += pwm-bcm-ko
|
||||
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
|
||||
--- /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,58 +0,0 @@
|
||||
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
|
||||
|
||||
--- /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,750 +0,0 @@
|
||||
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
|
||||
|
||||
--- 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
|
||||
--- 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
|
||||
--- /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,239 +0,0 @@
|
||||
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(-)
|
||||
|
||||
--- 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 m
|
||||
.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_
|
||||
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 mt
|
||||
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 mt
|
||||
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 mt
|
||||
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 mt
|
||||
/* 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 mt
|
||||
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_a
|
||||
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
|
||||
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,144 +0,0 @@
|
||||
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
|
||||
|
||||
--- /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,594 +0,0 @@
|
||||
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
|
||||
|
||||
--- 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
|
||||
--- a/drivers/cpufreq/Makefile
|
||||
+++ b/drivers/cpufreq/Makefile
|
||||
@@ -63,6 +63,7 @@ obj-$(CONFIG_ARM_HISI_ACPU_CPUFREQ) += h
|
||||
obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
|
||||
obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o
|
||||
obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
|
||||
+obj-$(CONFIG_ARM_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
|
||||
--- /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,48 +0,0 @@
|
||||
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
|
||||
|
||||
--- /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>;
|
||||
+};
|
File diff suppressed because it is too large
Load Diff
@ -1,204 +0,0 @@
|
||||
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(-)
|
||||
|
||||
--- 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 msd
|
||||
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_
|
||||
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_
|
||||
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_
|
||||
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_
|
||||
|
||||
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 platfor
|
||||
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 platfo
|
||||
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 platfo
|
||||
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_dr
|
||||
.driver = {
|
||||
.name = "mtk-msdc",
|
||||
.of_match_table = msdc_of_ids,
|
||||
+ .pm = &msdc_dev_pm_ops,
|
||||
},
|
||||
};
|
||||
|
@ -1,23 +0,0 @@
|
||||
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(+)
|
||||
|
||||
--- 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,24 +0,0 @@
|
||||
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(+)
|
||||
|
||||
--- 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,27 +0,0 @@
|
||||
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(-)
|
||||
|
||||
--- a/drivers/clocksource/mtk_timer.c
|
||||
+++ b/drivers/clocksource/mtk_timer.c
|
||||
@@ -143,7 +143,8 @@ static irqreturn_t mtk_timer_interrupt(i
|
||||
|
||||
/* 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,46 +0,0 @@
|
||||
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(+)
|
||||
|
||||
--- 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
|
||||
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,58 +0,0 @@
|
||||
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(+)
|
||||
|
||||
--- 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_MACHINE_START(MEDIATEK_DT, "Mediatek Cortex-A7 (Device Tree)")
|
||||
.dt_compat = mediatek_board_dt_compat,
|
||||
+ .init_time = mediatek_timer_init,
|
||||
MACHINE_END
|
@ -1,170 +0,0 @@
|
||||
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
|
||||
|
||||
--- 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
|
||||
--- /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);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user