Import Pro1-X kernel source code
This commit is contained in:
parent
96060693a5
commit
1d86f7ae7b
559 changed files with 90104 additions and 7564 deletions
26
Makefile
26
Makefile
|
@ -319,7 +319,7 @@ include scripts/subarch.include
|
|||
# Alternatively CROSS_COMPILE can be set in the environment.
|
||||
# Default value for CROSS_COMPILE is not to prefix executables
|
||||
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
|
||||
ARCH := arm64
|
||||
ARCH ?= $(SUBARCH)
|
||||
|
||||
# Architecture as present in compile.h
|
||||
UTS_MACHINE := $(ARCH)
|
||||
|
@ -366,7 +366,7 @@ HOSTCC = gcc
|
|||
HOSTCXX = g++
|
||||
endif
|
||||
KBUILD_HOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 \
|
||||
-fomit-frame-pointer -std=gnu89 -pipe $(HOST_LFS_CFLAGS) \
|
||||
-fomit-frame-pointer -std=gnu89 $(HOST_LFS_CFLAGS) \
|
||||
$(HOSTCFLAGS)
|
||||
KBUILD_HOSTCXXFLAGS := -O2 $(HOST_LFS_CFLAGS) $(HOSTCXXFLAGS)
|
||||
KBUILD_HOSTLDFLAGS := $(HOST_LFS_LDFLAGS) $(HOSTLDFLAGS)
|
||||
|
@ -385,7 +385,7 @@ READELF = llvm-readelf
|
|||
OBJSIZE = llvm-size
|
||||
STRIP = llvm-strip
|
||||
else
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
REAL_CC = $(CROSS_COMPILE)gcc
|
||||
LD = $(CROSS_COMPILE)ld
|
||||
AR = $(CROSS_COMPILE)ar
|
||||
NM = $(CROSS_COMPILE)nm
|
||||
|
@ -409,7 +409,7 @@ CHECK = sparse
|
|||
|
||||
# Use the wrapper for the compiler. This wrapper scans for new
|
||||
# warnings and causes the build to stop upon encountering them
|
||||
# CC = $(PYTHON2) $(srctree)/scripts/gcc-wrapper.py $(REAL_CC)
|
||||
CC = $(PYTHON) $(srctree)/scripts/gcc-wrapper.py $(REAL_CC)
|
||||
|
||||
CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
|
||||
-Wbitwise -Wno-return-void -Wno-unknown-attribute $(CF)
|
||||
|
@ -439,7 +439,7 @@ LINUXINCLUDE := \
|
|||
$(USERINCLUDE)
|
||||
|
||||
KBUILD_AFLAGS := -D__ASSEMBLY__
|
||||
KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -pipe \
|
||||
KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
|
||||
-fno-strict-aliasing -fno-common -fshort-wchar \
|
||||
-Werror-implicit-function-declaration \
|
||||
-Wno-format-security \
|
||||
|
@ -688,18 +688,11 @@ KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation)
|
|||
KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, int-in-bool-context)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, attribute-alias)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, packed-not-aligned)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, psabi)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, restrict)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, stringop-overflow)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, zero-length-bounds)
|
||||
|
||||
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
|
||||
KBUILD_CFLAGS += -Os
|
||||
else
|
||||
KBUILD_CFLAGS += -O3
|
||||
KBUILD_CFLAGS += -O2
|
||||
endif
|
||||
|
||||
# Tell gcc to never replace conditional load with a non-conditional one
|
||||
|
@ -961,6 +954,9 @@ KBUILD_CFLAGS += $(call cc-option,-fmerge-constants)
|
|||
# Make sure -fstack-check isn't enabled (like gentoo apparently did)
|
||||
KBUILD_CFLAGS += $(call cc-option,-fno-stack-check,)
|
||||
|
||||
# conserve stack if available
|
||||
KBUILD_CFLAGS += $(call cc-option,-fconserve-stack)
|
||||
|
||||
# disallow errors like 'EXPORT_GPL(foo);' with missing header
|
||||
KBUILD_CFLAGS += $(call cc-option,-Werror=implicit-int)
|
||||
|
||||
|
@ -1349,7 +1345,7 @@ headers_install: __headers
|
|||
$(error Headers not exportable for the $(SRCARCH) architecture))
|
||||
$(Q)$(MAKE) $(hdr-inst)=include/uapi dst=include
|
||||
$(Q)$(MAKE) $(hdr-inst)=arch/$(SRCARCH)/include/uapi $(hdr-dst)
|
||||
$(Q)$(MAKE) $(hdr-inst)=techpack/audio/include/uapi dst=techpack/audio/include
|
||||
$(Q)$(MAKE) $(hdr-inst)=techpack
|
||||
|
||||
PHONY += headers_check_all
|
||||
headers_check_all: headers_install_all
|
||||
|
@ -1359,7 +1355,7 @@ PHONY += headers_check
|
|||
headers_check: headers_install
|
||||
$(Q)$(MAKE) $(hdr-inst)=include/uapi dst=include HDRCHECK=1
|
||||
$(Q)$(MAKE) $(hdr-inst)=arch/$(SRCARCH)/include/uapi $(hdr-dst) HDRCHECK=1
|
||||
$(Q)$(MAKE) $(hdr-inst)=techpack/audio/include/uapi dst=techpack/audio/include HDRCHECK=1
|
||||
$(Q)$(MAKE) $(hdr-inst)=techpack HDRCHECK=1
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Kernel selftest
|
||||
|
|
13
arch/Kconfig
13
arch/Kconfig
|
@ -563,7 +563,6 @@ config CFI_CLANG_SHADOW
|
|||
|
||||
config ARCH_SUPPORTS_SHADOW_CALL_STACK
|
||||
bool
|
||||
default y
|
||||
help
|
||||
An architecture should select this if it supports Clang's Shadow
|
||||
Call Stack, has asm/scs.h, and implements runtime support for shadow
|
||||
|
@ -944,16 +943,6 @@ config STRICT_MODULE_RWX
|
|||
config ARCH_HAS_PHYS_TO_DMA
|
||||
bool
|
||||
|
||||
config ARCH_HAS_REFCOUNT_FULL
|
||||
bool
|
||||
select ARCH_HAS_REFCOUNT
|
||||
help
|
||||
An architecture selects this when the optimized refcount_t
|
||||
implementation it provides covers all the cases that
|
||||
CONFIG_REFCOUNT_FULL covers as well, in which case it makes no
|
||||
sense to even offer CONFIG_REFCOUNT_FULL as a user selectable
|
||||
option.
|
||||
|
||||
config ARCH_HAS_REFCOUNT
|
||||
bool
|
||||
help
|
||||
|
@ -967,7 +956,7 @@ config ARCH_HAS_REFCOUNT
|
|||
against bugs in reference counts.
|
||||
|
||||
config REFCOUNT_FULL
|
||||
bool "Perform full reference count validation at the expense of speed" if !ARCH_HAS_REFCOUNT_FULL
|
||||
bool "Perform full reference count validation at the expense of speed"
|
||||
help
|
||||
Enabling this switches the refcounting infrastructure from a fast
|
||||
unchecked atomic_t implementation to a fully state checked
|
||||
|
|
655
arch/arm/configs/vendor/msm8937_32go-perf_defconfig
vendored
Normal file
655
arch/arm/configs/vendor/msm8937_32go-perf_defconfig
vendored
Normal file
|
@ -0,0 +1,655 @@
|
|||
CONFIG_LOCALVERSION="-perf"
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_AUDIT=y
|
||||
# CONFIG_AUDITSYSCALL is not set
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_IRQ_TIME_ACCOUNTING=y
|
||||
CONFIG_SCHED_WALT=y
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_PSI=y
|
||||
CONFIG_RCU_EXPERT=y
|
||||
CONFIG_RCU_FAST_NO_HZ=y
|
||||
CONFIG_RCU_NOCB_CPU=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_LOG_CPU_MAX_BUF_SHIFT=17
|
||||
CONFIG_MEMCG=y
|
||||
CONFIG_MEMCG_SWAP=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_RT_GROUP_SCHED=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_CGROUP_BPF=y
|
||||
CONFIG_SCHED_CORE_CTL=y
|
||||
CONFIG_NAMESPACES=y
|
||||
# CONFIG_UTS_NS is not set
|
||||
# CONFIG_PID_NS is not set
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_SCHED_TUNE=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_RD_BZIP2 is not set
|
||||
# CONFIG_RD_LZMA is not set
|
||||
# CONFIG_RD_XZ is not set
|
||||
# CONFIG_RD_LZO is not set
|
||||
# CONFIG_RD_LZ4 is not set
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
# CONFIG_FHANDLE is not set
|
||||
# CONFIG_BASE_FULL is not set
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_BPF_SYSCALL=y
|
||||
CONFIG_EMBEDDED=y
|
||||
# CONFIG_SLUB_DEBUG is not set
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_ARCH_QCOM=y
|
||||
CONFIG_ARCH_QM215=y
|
||||
CONFIG_ARCH_MSM8917=y
|
||||
# CONFIG_VDSO is not set
|
||||
CONFIG_SMP=y
|
||||
CONFIG_SCHED_MC=y
|
||||
CONFIG_NR_CPUS=8
|
||||
CONFIG_ARM_PSCI=y
|
||||
CONFIG_HIGHMEM=y
|
||||
CONFIG_SECCOMP=y
|
||||
CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_TIMES=y
|
||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
|
||||
CONFIG_CPU_BOOST=y
|
||||
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
|
||||
CONFIG_CPU_FREQ_MSM=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_VFP=y
|
||||
CONFIG_NEON=y
|
||||
CONFIG_KERNEL_MODE_NEON=y
|
||||
CONFIG_PM_WAKELOCKS=y
|
||||
CONFIG_PM_WAKELOCKS_LIMIT=0
|
||||
# CONFIG_PM_WAKELOCKS_GC is not set
|
||||
CONFIG_ENERGY_MODEL=y
|
||||
CONFIG_MSM_TZ_LOG=y
|
||||
CONFIG_ARM_CRYPTO=y
|
||||
CONFIG_CRYPTO_SHA1_ARM_NEON=y
|
||||
CONFIG_CRYPTO_SHA2_ARM_CE=y
|
||||
CONFIG_CRYPTO_AES_ARM_BS=y
|
||||
CONFIG_CRYPTO_AES_ARM_CE=y
|
||||
CONFIG_CRYPTO_GHASH_ARM_CE=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS=16
|
||||
CONFIG_PANIC_ON_REFCOUNT_ERROR=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_SIG=y
|
||||
CONFIG_MODULE_SIG_FORCE=y
|
||||
CONFIG_MODULE_SIG_SHA512=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
CONFIG_BLK_DEV_ZONED=y
|
||||
CONFIG_BLK_INLINE_ENCRYPTION=y
|
||||
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
CONFIG_CFQ_GROUP_IOSCHED=y
|
||||
CONFIG_IOSCHED_BFQ=y
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_CLEANCACHE=y
|
||||
CONFIG_CMA=y
|
||||
CONFIG_CMA_DEBUGFS=y
|
||||
CONFIG_ZSMALLOC=y
|
||||
CONFIG_BALANCE_ANON_FILE_RECLAIM=y
|
||||
CONFIG_HAVE_USERSPACE_LOW_MEMORY_KILLER=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=y
|
||||
CONFIG_XFRM_INTERFACE=y
|
||||
CONFIG_XFRM_STATISTICS=y
|
||||
CONFIG_NET_KEY=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_MULTIPLE_TABLES=y
|
||||
CONFIG_IP_ROUTE_VERBOSE=y
|
||||
CONFIG_IP_PNP=y
|
||||
CONFIG_IP_PNP_DHCP=y
|
||||
CONFIG_NET_IPGRE_DEMUX=y
|
||||
CONFIG_NET_IPVTI=y
|
||||
CONFIG_INET_AH=y
|
||||
CONFIG_INET_ESP=y
|
||||
CONFIG_INET_IPCOMP=y
|
||||
CONFIG_INET_UDP_DIAG=y
|
||||
CONFIG_INET_DIAG_DESTROY=y
|
||||
CONFIG_IPV6_ROUTER_PREF=y
|
||||
CONFIG_IPV6_ROUTE_INFO=y
|
||||
CONFIG_IPV6_OPTIMISTIC_DAD=y
|
||||
CONFIG_INET6_AH=y
|
||||
CONFIG_INET6_ESP=y
|
||||
CONFIG_INET6_IPCOMP=y
|
||||
CONFIG_IPV6_MIP6=y
|
||||
CONFIG_IPV6_VTI=y
|
||||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
CONFIG_IPV6_SUBTREES=y
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=y
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=y
|
||||
CONFIG_NF_CONNTRACK_FTP=y
|
||||
CONFIG_NF_CONNTRACK_H323=y
|
||||
CONFIG_NF_CONNTRACK_IRC=y
|
||||
CONFIG_NF_CONNTRACK_NETBIOS_NS=y
|
||||
CONFIG_NF_CONNTRACK_PPTP=y
|
||||
CONFIG_NF_CONNTRACK_SANE=y
|
||||
CONFIG_NF_CONNTRACK_TFTP=y
|
||||
CONFIG_NF_CT_NETLINK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
|
||||
CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y
|
||||
CONFIG_NETFILTER_XT_TARGET_LOG=y
|
||||
CONFIG_NETFILTER_XT_TARGET_MARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=y
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TEE=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=y
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
|
||||
CONFIG_NETFILTER_XT_MATCH_BPF=y
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_DSCP=y
|
||||
CONFIG_NETFILTER_XT_MATCH_ESP=y
|
||||
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_HELPER=y
|
||||
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
|
||||
# CONFIG_NETFILTER_XT_MATCH_L2TP is not set
|
||||
CONFIG_NETFILTER_XT_MATCH_LENGTH=y
|
||||
CONFIG_NETFILTER_XT_MATCH_LIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MAC=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_OWNER=y
|
||||
CONFIG_NETFILTER_XT_MATCH_POLICY=y
|
||||
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
|
||||
CONFIG_NETFILTER_XT_MATCH_SOCKET=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STATE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STRING=y
|
||||
CONFIG_NETFILTER_XT_MATCH_TIME=y
|
||||
CONFIG_NETFILTER_XT_MATCH_U32=y
|
||||
CONFIG_IP_NF_IPTABLES=y
|
||||
CONFIG_IP_NF_MATCH_AH=y
|
||||
CONFIG_IP_NF_MATCH_ECN=y
|
||||
CONFIG_IP_NF_MATCH_RPFILTER=y
|
||||
CONFIG_IP_NF_MATCH_TTL=y
|
||||
CONFIG_IP_NF_FILTER=y
|
||||
CONFIG_IP_NF_TARGET_REJECT=y
|
||||
CONFIG_IP_NF_NAT=y
|
||||
CONFIG_IP_NF_TARGET_MASQUERADE=y
|
||||
CONFIG_IP_NF_TARGET_NETMAP=y
|
||||
CONFIG_IP_NF_TARGET_REDIRECT=y
|
||||
CONFIG_IP_NF_MANGLE=y
|
||||
CONFIG_IP_NF_RAW=y
|
||||
CONFIG_IP_NF_SECURITY=y
|
||||
CONFIG_IP_NF_ARPTABLES=y
|
||||
CONFIG_IP_NF_ARPFILTER=y
|
||||
CONFIG_IP_NF_ARP_MANGLE=y
|
||||
CONFIG_IP6_NF_IPTABLES=y
|
||||
CONFIG_IP6_NF_MATCH_RPFILTER=y
|
||||
CONFIG_IP6_NF_FILTER=y
|
||||
CONFIG_IP6_NF_TARGET_REJECT=y
|
||||
CONFIG_IP6_NF_MANGLE=y
|
||||
CONFIG_IP6_NF_RAW=y
|
||||
CONFIG_BRIDGE_NF_EBTABLES=y
|
||||
CONFIG_BRIDGE_EBT_BROUTE=y
|
||||
CONFIG_L2TP=y
|
||||
CONFIG_L2TP_DEBUGFS=y
|
||||
CONFIG_L2TP_V3=y
|
||||
CONFIG_L2TP_IP=y
|
||||
CONFIG_L2TP_ETH=y
|
||||
CONFIG_BRIDGE=y
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_HTB=y
|
||||
CONFIG_NET_SCH_PRIO=y
|
||||
CONFIG_NET_SCH_INGRESS=y
|
||||
CONFIG_NET_CLS_FW=y
|
||||
CONFIG_NET_CLS_U32=y
|
||||
CONFIG_CLS_U32_MARK=y
|
||||
CONFIG_NET_CLS_FLOW=y
|
||||
CONFIG_NET_CLS_BPF=y
|
||||
CONFIG_NET_EMATCH=y
|
||||
CONFIG_NET_EMATCH_CMP=y
|
||||
CONFIG_NET_EMATCH_NBYTE=y
|
||||
CONFIG_NET_EMATCH_U32=y
|
||||
CONFIG_NET_EMATCH_META=y
|
||||
CONFIG_NET_EMATCH_TEXT=y
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_DNS_RESOLVER=y
|
||||
CONFIG_QRTR=y
|
||||
CONFIG_QRTR_SMD=y
|
||||
CONFIG_BT=y
|
||||
# CONFIG_BT_BREDR is not set
|
||||
# CONFIG_BT_LE is not set
|
||||
CONFIG_MSM_BT_POWER=y
|
||||
CONFIG_BTFM_SLIM_WCN3990=y
|
||||
CONFIG_CFG80211=y
|
||||
CONFIG_CFG80211_INTERNAL_REGDB=y
|
||||
# CONFIG_CFG80211_CRDA_SUPPORT is not set
|
||||
CONFIG_RFKILL=y
|
||||
CONFIG_NFC_NQ=y
|
||||
CONFIG_FW_LOADER_USER_HELPER=y
|
||||
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
|
||||
# CONFIG_FW_CACHE is not set
|
||||
CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y
|
||||
CONFIG_DMA_CMA=y
|
||||
CONFIG_ZRAM=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_LOOP_MIN_COUNT=16
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_SIZE=8192
|
||||
CONFIG_HDCP_QSEECOM=y
|
||||
CONFIG_QSEECOM=y
|
||||
CONFIG_UID_SYS_STATS=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_CHR_DEV_SG=y
|
||||
CONFIG_CHR_DEV_SCH=y
|
||||
CONFIG_SCSI_CONSTANTS=y
|
||||
CONFIG_SCSI_LOGGING=y
|
||||
CONFIG_SCSI_SCAN_ASYNC=y
|
||||
CONFIG_SCSI_UFSHCD=y
|
||||
CONFIG_SCSI_UFSHCD_PLATFORM=y
|
||||
CONFIG_SCSI_UFS_QCOM=y
|
||||
CONFIG_SCSI_UFS_CRYPTO=y
|
||||
CONFIG_SCSI_UFS_CRYPTO_QTI=y
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_DM=y
|
||||
CONFIG_DM_CRYPT=y
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_VERITY=y
|
||||
CONFIG_DM_VERITY_FEC=y
|
||||
CONFIG_DM_ANDROID_VERITY=y
|
||||
CONFIG_DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED=y
|
||||
CONFIG_DM_BOW=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_DUMMY=y
|
||||
CONFIG_TUN=y
|
||||
# CONFIG_NET_VENDOR_AMAZON is not set
|
||||
# CONFIG_NET_VENDOR_EZCHIP is not set
|
||||
# CONFIG_NET_VENDOR_HISILICON is not set
|
||||
# CONFIG_NET_VENDOR_MARVELL is not set
|
||||
# CONFIG_NET_VENDOR_NETRONOME is not set
|
||||
# CONFIG_NET_VENDOR_ROCKER is not set
|
||||
# CONFIG_NET_VENDOR_SYNOPSYS is not set
|
||||
CONFIG_PPP=y
|
||||
CONFIG_PPP_BSDCOMP=y
|
||||
CONFIG_PPP_DEFLATE=y
|
||||
CONFIG_PPP_FILTER=y
|
||||
CONFIG_PPP_MPPE=y
|
||||
CONFIG_PPP_MULTILINK=y
|
||||
CONFIG_PPPOE=y
|
||||
CONFIG_PPTP=y
|
||||
CONFIG_PPPOL2TP=y
|
||||
CONFIG_PPP_ASYNC=y
|
||||
CONFIG_PPP_SYNC_TTY=y
|
||||
CONFIG_USB_RTL8152=y
|
||||
CONFIG_USB_USBNET=y
|
||||
# CONFIG_WLAN_VENDOR_ADMTEK is not set
|
||||
# CONFIG_WLAN_VENDOR_ATH is not set
|
||||
# CONFIG_WLAN_VENDOR_ATMEL is not set
|
||||
# CONFIG_WLAN_VENDOR_BROADCOM is not set
|
||||
# CONFIG_WLAN_VENDOR_CISCO is not set
|
||||
# CONFIG_WLAN_VENDOR_INTEL is not set
|
||||
# CONFIG_WLAN_VENDOR_INTERSIL is not set
|
||||
# CONFIG_WLAN_VENDOR_MARVELL is not set
|
||||
# CONFIG_WLAN_VENDOR_MEDIATEK is not set
|
||||
# CONFIG_WLAN_VENDOR_RALINK is not set
|
||||
# CONFIG_WLAN_VENDOR_REALTEK is not set
|
||||
# CONFIG_WLAN_VENDOR_RSI is not set
|
||||
# CONFIG_WLAN_VENDOR_ST is not set
|
||||
# CONFIG_WLAN_VENDOR_TI is not set
|
||||
# CONFIG_WLAN_VENDOR_ZYDAS is not set
|
||||
CONFIG_WCNSS_MEM_PRE_ALLOC=y
|
||||
CONFIG_CLD_LL_CORE=y
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_KEYBOARD_GPIO=y
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
CONFIG_INPUT_JOYSTICK=y
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_HBTP_INPUT=y
|
||||
CONFIG_INPUT_QPNP_POWER_ON=y
|
||||
CONFIG_INPUT_UINPUT=y
|
||||
# CONFIG_SERIO_SERPORT is not set
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_DEVMEM is not set
|
||||
CONFIG_SERIAL_MSM_HS=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HW_RANDOM_MSM_LEGACY=y
|
||||
CONFIG_MSM_SMD_PKT=y
|
||||
CONFIG_DIAG_CHAR=y
|
||||
CONFIG_MSM_ADSPRPC=y
|
||||
CONFIG_MSM_RDBG=m
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_MSM_V2=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_QUP=y
|
||||
CONFIG_SPI_SPIDEV=y
|
||||
CONFIG_SPMI=y
|
||||
CONFIG_PINCTRL_MSM8937=y
|
||||
CONFIG_PINCTRL_MSM8917=y
|
||||
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_POWER_RESET=y
|
||||
CONFIG_POWER_RESET_QCOM=y
|
||||
CONFIG_POWER_RESET_SYSCON=y
|
||||
CONFIG_QPNP_SMB5=y
|
||||
CONFIG_SMB1351_USB_CHARGER=y
|
||||
CONFIG_SMB1355_SLAVE_CHARGER=y
|
||||
CONFIG_QPNP_QG=y
|
||||
CONFIG_THERMAL=y
|
||||
CONFIG_THERMAL_WRITABLE_TRIPS=y
|
||||
CONFIG_THERMAL_GOV_USER_SPACE=y
|
||||
CONFIG_THERMAL_GOV_LOW_LIMITS=y
|
||||
CONFIG_CPU_THERMAL=y
|
||||
CONFIG_DEVFREQ_THERMAL=y
|
||||
CONFIG_THERMAL_TSENS=y
|
||||
CONFIG_QTI_VIRTUAL_SENSOR=y
|
||||
CONFIG_QTI_BCL_PMIC5=y
|
||||
CONFIG_QTI_BCL_SOC_DRIVER=y
|
||||
CONFIG_QTI_QMI_COOLING_DEVICE=y
|
||||
CONFIG_REGULATOR_COOLING_DEVICE=y
|
||||
CONFIG_MFD_I2C_PMIC=y
|
||||
CONFIG_MFD_SPMI_PMIC=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
CONFIG_REGULATOR_PROXY_CONSUMER=y
|
||||
CONFIG_REGULATOR_QPNP_LABIBB=y
|
||||
CONFIG_REGULATOR_QPNP_LCDB=y
|
||||
CONFIG_REGULATOR_MEM_ACC=y
|
||||
CONFIG_REGULATOR_CPR=y
|
||||
CONFIG_REGULATOR_RPM_SMD=y
|
||||
CONFIG_REGULATOR_SPM=y
|
||||
CONFIG_REGULATOR_STUB=y
|
||||
CONFIG_MEDIA_SUPPORT=y
|
||||
CONFIG_MEDIA_CAMERA_SUPPORT=y
|
||||
CONFIG_MEDIA_CONTROLLER=y
|
||||
CONFIG_VIDEO_V4L2_SUBDEV_API=y
|
||||
CONFIG_MEDIA_USB_SUPPORT=y
|
||||
CONFIG_USB_VIDEO_CLASS=y
|
||||
CONFIG_V4L_PLATFORM_DRIVERS=y
|
||||
CONFIG_MSM_VIDC_3X_GOVERNORS=y
|
||||
CONFIG_MSM_VIDC_3X_V4L2=y
|
||||
CONFIG_MSM_CAMERA=y
|
||||
CONFIG_MSMB_CAMERA=y
|
||||
CONFIG_MSM_CAMERA_SENSOR=y
|
||||
CONFIG_MSM_CPP=y
|
||||
CONFIG_MSM_CCI=y
|
||||
CONFIG_MSM_CSI20_HEADER=y
|
||||
CONFIG_MSM_CSI22_HEADER=y
|
||||
CONFIG_MSM_CSI30_HEADER=y
|
||||
CONFIG_MSM_CSI31_HEADER=y
|
||||
CONFIG_MSM_CSIPHY=y
|
||||
CONFIG_MSM_CSID=y
|
||||
CONFIG_MSM_EEPROM=y
|
||||
CONFIG_MSM_ISPIF_V2=y
|
||||
CONFIG_IMX134=y
|
||||
CONFIG_IMX132=y
|
||||
CONFIG_OV9724=y
|
||||
CONFIG_OV5648=y
|
||||
CONFIG_GC0339=y
|
||||
CONFIG_OV8825=y
|
||||
CONFIG_OV8865=y
|
||||
CONFIG_s5k4e1=y
|
||||
CONFIG_OV12830=y
|
||||
CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE=y
|
||||
CONFIG_MSMB_JPEG=y
|
||||
CONFIG_MSM_FD=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_MSM=y
|
||||
CONFIG_FB_MSM_MDSS=y
|
||||
CONFIG_FB_MSM_MDSS_WRITEBACK=y
|
||||
CONFIG_FB_MSM_MDSS_SPI_PANEL=y
|
||||
CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS=y
|
||||
CONFIG_FB_MSM_MDSS_XLOG_DEBUG=y
|
||||
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
||||
# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
CONFIG_SND_DYNAMIC_MINORS=y
|
||||
CONFIG_SND_USB_AUDIO=y
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_UHID=y
|
||||
CONFIG_HID_APPLE=y
|
||||
CONFIG_HID_ELECOM=y
|
||||
CONFIG_HID_MAGICMOUSE=y
|
||||
CONFIG_HID_MICROSOFT=y
|
||||
CONFIG_HID_MULTITOUCH=y
|
||||
CONFIG_HID_SONY=y
|
||||
CONFIG_USB_HIDDEV=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
CONFIG_USB_MON=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||
CONFIG_USB_EHCI_MSM=y
|
||||
CONFIG_USB_ACM=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_STORAGE_DATAFAB=y
|
||||
CONFIG_USB_STORAGE_FREECOM=y
|
||||
CONFIG_USB_STORAGE_ISD200=y
|
||||
CONFIG_USB_STORAGE_USBAT=y
|
||||
CONFIG_USB_STORAGE_SDDR09=y
|
||||
CONFIG_USB_STORAGE_SDDR55=y
|
||||
CONFIG_USB_STORAGE_JUMPSHOT=y
|
||||
CONFIG_USB_STORAGE_ALAUDA=y
|
||||
CONFIG_USB_STORAGE_ONETOUCH=y
|
||||
CONFIG_USB_STORAGE_KARMA=y
|
||||
CONFIG_USB_STORAGE_CYPRESS_ATACB=y
|
||||
CONFIG_USB_SERIAL=y
|
||||
CONFIG_USB_EHSET_TEST_FIXTURE=y
|
||||
CONFIG_NOP_USB_XCEIV=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_GADGET_DEBUG_FILES=y
|
||||
CONFIG_USB_GADGET_DEBUG_FS=y
|
||||
CONFIG_USB_GADGET_VBUS_DRAW=500
|
||||
CONFIG_USB_CI13XXX_MSM=y
|
||||
CONFIG_USB_CONFIGFS=y
|
||||
CONFIG_USB_CONFIGFS_UEVENT=y
|
||||
CONFIG_USB_CONFIGFS_SERIAL=y
|
||||
CONFIG_USB_CONFIGFS_NCM=y
|
||||
CONFIG_USB_CONFIGFS_RNDIS=y
|
||||
CONFIG_USB_CONFIGFS_RMNET_BAM=y
|
||||
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
|
||||
CONFIG_USB_CONFIGFS_F_FS=y
|
||||
CONFIG_USB_CONFIGFS_F_ACC=y
|
||||
CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y
|
||||
CONFIG_USB_CONFIGFS_F_MIDI=y
|
||||
CONFIG_USB_CONFIGFS_F_HID=y
|
||||
CONFIG_USB_CONFIGFS_F_DIAG=y
|
||||
CONFIG_USB_CONFIGFS_F_CDEV=y
|
||||
CONFIG_USB_CONFIGFS_F_CCID=y
|
||||
CONFIG_USB_CONFIGFS_F_QDSS=y
|
||||
CONFIG_USB_CONFIGFS_F_MTP=y
|
||||
CONFIG_USB_CONFIGFS_F_PTP=y
|
||||
CONFIG_TYPEC=y
|
||||
CONFIG_MMC=y
|
||||
# CONFIG_PWRSEQ_EMMC is not set
|
||||
# CONFIG_PWRSEQ_SIMPLE is not set
|
||||
CONFIG_MMC_BLOCK_MINORS=32
|
||||
CONFIG_MMC_BLOCK_DEFERRED_RESUME=y
|
||||
CONFIG_MMC_IPC_LOGGING=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_SDHCI_MSM=y
|
||||
CONFIG_MMC_CQHCI_CRYPTO=y
|
||||
CONFIG_MMC_CQHCI_CRYPTO_QTI=y
|
||||
CONFIG_LEDS_QTI_TRI_LED=y
|
||||
CONFIG_LEDS_QPNP_FLASH_V2=y
|
||||
CONFIG_LEDS_QPNP_VIBRATOR_LDO=y
|
||||
CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
CONFIG_EDAC=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_QCOM_SPS_DMA=y
|
||||
CONFIG_UIO=y
|
||||
CONFIG_UIO_MSM_SHAREDMEM=y
|
||||
CONFIG_STAGING=y
|
||||
CONFIG_ASHMEM=y
|
||||
CONFIG_ION=y
|
||||
CONFIG_ION_POOL_AUTO_REFILL=y
|
||||
CONFIG_QPNP_REVID=y
|
||||
CONFIG_SPS=y
|
||||
CONFIG_SPS_SUPPORT_NDP_BAM=y
|
||||
CONFIG_IPA=y
|
||||
CONFIG_RMNET_IPA=y
|
||||
CONFIG_RNDIS_IPA=y
|
||||
CONFIG_MDSS_PLL=y
|
||||
CONFIG_QCOM_CLK_SMD_RPM=y
|
||||
CONFIG_SDM_GCC_429W=y
|
||||
CONFIG_SDM_DEBUGCC_429W=y
|
||||
CONFIG_CLOCK_CPU_SDM=y
|
||||
CONFIG_HWSPINLOCK=y
|
||||
CONFIG_HWSPINLOCK_QCOM=y
|
||||
CONFIG_MAILBOX=y
|
||||
CONFIG_ARM_SMMU=y
|
||||
CONFIG_QCOM_LAZY_MAPPING=y
|
||||
CONFIG_RPMSG_CHAR=y
|
||||
CONFIG_RPMSG_QCOM_GLINK_RPM=y
|
||||
CONFIG_RPMSG_QCOM_GLINK_SMEM=y
|
||||
CONFIG_RPMSG_QCOM_SMD=y
|
||||
CONFIG_MSM_RPM_SMD=y
|
||||
CONFIG_QCOM_CPUSS_DUMP=y
|
||||
CONFIG_QCOM_RUN_QUEUE_STATS=y
|
||||
CONFIG_QCOM_QMI_HELPERS=y
|
||||
CONFIG_QCOM_SMEM=y
|
||||
CONFIG_QCOM_SMD_RPM=y
|
||||
CONFIG_MSM_SPM=y
|
||||
CONFIG_MSM_L2_SPM=y
|
||||
CONFIG_QCOM_EARLY_RANDOM=y
|
||||
CONFIG_QCOM_MEMORY_DUMP_V2=y
|
||||
CONFIG_QCOM_SMP2P=y
|
||||
CONFIG_QCOM_SMSM=y
|
||||
CONFIG_MSM_PIL_MSS_QDSP6V5=y
|
||||
CONFIG_QCOM_SECURE_BUFFER=y
|
||||
CONFIG_MSM_SUBSYSTEM_RESTART=y
|
||||
CONFIG_MSM_PIL=y
|
||||
CONFIG_MSM_PIL_SSR_GENERIC=y
|
||||
CONFIG_MSM_BOOT_STATS=y
|
||||
CONFIG_QCOM_DCC_V2=y
|
||||
CONFIG_MSM_CORE_HANG_DETECT=y
|
||||
CONFIG_QCOM_WATCHDOG_V2=y
|
||||
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
|
||||
CONFIG_QCOM_BUS_SCALING=y
|
||||
CONFIG_QCOM_GLINK=y
|
||||
CONFIG_MSM_EVENT_TIMER=y
|
||||
CONFIG_MSM_PM=y
|
||||
CONFIG_QTI_RPM_STATS_LOG=y
|
||||
CONFIG_QTEE_SHM_BRIDGE=y
|
||||
CONFIG_MEM_SHARE_QMI_SERVICE=y
|
||||
CONFIG_MSM_PERFORMANCE=y
|
||||
CONFIG_QTI_CRYPTO_COMMON=y
|
||||
CONFIG_QTI_CRYPTO_TZ=y
|
||||
CONFIG_WCNSS_CORE=y
|
||||
CONFIG_WCNSS_CORE_PRONTO=y
|
||||
CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y
|
||||
CONFIG_DEVFREQ_GOV_PASSIVE=y
|
||||
CONFIG_QCOM_BIMC_BWMON=y
|
||||
CONFIG_ARM_MEMLAT_MON=y
|
||||
CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
|
||||
CONFIG_DEVFREQ_GOV_MEMLAT=y
|
||||
CONFIG_DEVFREQ_SIMPLE_DEV=y
|
||||
CONFIG_QCOM_DEVFREQ_DEVBW=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PWM_QTI_LPG=y
|
||||
CONFIG_QCOM_SHOW_RESUME_IRQ=y
|
||||
CONFIG_QCOM_MPM=y
|
||||
CONFIG_RAS=y
|
||||
CONFIG_ANDROID=y
|
||||
CONFIG_ANDROID_BINDER_IPC=y
|
||||
CONFIG_ANDROID_BINDERFS=y
|
||||
CONFIG_QCOM_QFPROM=y
|
||||
CONFIG_SLIMBUS_MSM_NGD=y
|
||||
CONFIG_SENSORS_SSC=y
|
||||
CONFIG_QCOM_KGSL=y
|
||||
CONFIG_LEGACY_ENERGY_MODEL_DT=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_EXT4_ENCRYPTION=y
|
||||
CONFIG_F2FS_FS=y
|
||||
CONFIG_F2FS_FS_SECURITY=y
|
||||
CONFIG_F2FS_FS_ENCRYPTION=y
|
||||
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
|
||||
CONFIG_FS_VERITY=y
|
||||
CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y
|
||||
CONFIG_QUOTA=y
|
||||
CONFIG_QUOTA_NETLINK_INTERFACE=y
|
||||
CONFIG_QFMT_V2=y
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_OVERLAY_FS=y
|
||||
CONFIG_INCREMENTAL_FS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_SDCARD_FS=y
|
||||
CONFIG_SQUASHFS=y
|
||||
CONFIG_SQUASHFS_XATTR=y
|
||||
CONFIG_SQUASHFS_LZ4=y
|
||||
# CONFIG_NETWORK_FILESYSTEMS is not set
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
|
||||
CONFIG_SECURITY=y
|
||||
CONFIG_LSM_MMAP_MIN_ADDR=4096
|
||||
CONFIG_HARDENED_USERCOPY=y
|
||||
CONFIG_HARDENED_USERCOPY_PAGESPAN=y
|
||||
CONFIG_FORTIFY_SOURCE=y
|
||||
CONFIG_STATIC_USERMODEHELPER=y
|
||||
CONFIG_STATIC_USERMODEHELPER_PATH=""
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
CONFIG_SECURITY_SMACK=y
|
||||
CONFIG_CRYPTO_GCM=y
|
||||
CONFIG_CRYPTO_XCBC=y
|
||||
CONFIG_CRYPTO_MD4=y
|
||||
CONFIG_CRYPTO_TWOFISH=y
|
||||
CONFIG_CRYPTO_LZ4=y
|
||||
CONFIG_CRYPTO_ANSI_CPRNG=y
|
||||
CONFIG_CRYPTO_DEV_QCE=y
|
||||
CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
|
||||
CONFIG_CRYPTO_DEV_QCRYPTO=y
|
||||
CONFIG_CRYPTO_DEV_QCEDEV=y
|
||||
CONFIG_CRYPTO_DEV_QCOM_ICE=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_FRAME_WARN=2048
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_WQ_WATCHDOG=y
|
||||
CONFIG_PANIC_ON_OOPS=y
|
||||
CONFIG_PANIC_TIMEOUT=5
|
||||
CONFIG_SCHED_STACK_END_CHECK=y
|
||||
# CONFIG_DEBUG_PREEMPT is not set
|
||||
CONFIG_FAULT_INJECTION=y
|
||||
CONFIG_FAIL_PAGE_ALLOC=y
|
||||
CONFIG_IPC_LOGGING=y
|
||||
# CONFIG_FTRACE is not set
|
||||
CONFIG_LKDTM=m
|
||||
CONFIG_BUG_ON_DATA_CORRUPTION=y
|
711
arch/arm/configs/vendor/msm8937_32go_defconfig
vendored
Normal file
711
arch/arm/configs/vendor/msm8937_32go_defconfig
vendored
Normal file
|
@ -0,0 +1,711 @@
|
|||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_AUDIT=y
|
||||
# CONFIG_AUDITSYSCALL is not set
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_IRQ_TIME_ACCOUNTING=y
|
||||
CONFIG_SCHED_WALT=y
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_PSI=y
|
||||
CONFIG_RCU_EXPERT=y
|
||||
CONFIG_RCU_FAST_NO_HZ=y
|
||||
CONFIG_RCU_NOCB_CPU=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_LOG_CPU_MAX_BUF_SHIFT=17
|
||||
CONFIG_MEMCG=y
|
||||
CONFIG_MEMCG_SWAP=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_DEBUG_BLK_CGROUP=y
|
||||
CONFIG_RT_GROUP_SCHED=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_CGROUP_BPF=y
|
||||
CONFIG_CGROUP_DEBUG=y
|
||||
CONFIG_SCHED_CORE_CTL=y
|
||||
CONFIG_NAMESPACES=y
|
||||
# CONFIG_UTS_NS is not set
|
||||
# CONFIG_PID_NS is not set
|
||||
CONFIG_SCHED_AUTOGROUP=y
|
||||
CONFIG_SCHED_TUNE=y
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_RD_BZIP2 is not set
|
||||
# CONFIG_RD_LZMA is not set
|
||||
# CONFIG_RD_XZ is not set
|
||||
# CONFIG_RD_LZO is not set
|
||||
# CONFIG_RD_LZ4 is not set
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
# CONFIG_FHANDLE is not set
|
||||
# CONFIG_BASE_FULL is not set
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_BPF_SYSCALL=y
|
||||
CONFIG_EMBEDDED=y
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_PROFILING=y
|
||||
CONFIG_ARCH_QCOM=y
|
||||
CONFIG_ARCH_QM215=y
|
||||
CONFIG_ARCH_MSM8917=y
|
||||
# CONFIG_VDSO is not set
|
||||
CONFIG_SMP=y
|
||||
CONFIG_SCHED_MC=y
|
||||
CONFIG_NR_CPUS=8
|
||||
CONFIG_ARM_PSCI=y
|
||||
CONFIG_HIGHMEM=y
|
||||
CONFIG_SECCOMP=y
|
||||
CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_TIMES=y
|
||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
|
||||
CONFIG_CPU_BOOST=y
|
||||
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
|
||||
CONFIG_CPU_FREQ_MSM=y
|
||||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_VFP=y
|
||||
CONFIG_NEON=y
|
||||
CONFIG_KERNEL_MODE_NEON=y
|
||||
CONFIG_PM_WAKELOCKS=y
|
||||
CONFIG_PM_WAKELOCKS_LIMIT=0
|
||||
# CONFIG_PM_WAKELOCKS_GC is not set
|
||||
CONFIG_PM_DEBUG=y
|
||||
CONFIG_ENERGY_MODEL=y
|
||||
CONFIG_MSM_TZ_LOG=y
|
||||
CONFIG_ARM_CRYPTO=y
|
||||
CONFIG_CRYPTO_SHA1_ARM_NEON=y
|
||||
CONFIG_CRYPTO_SHA2_ARM_CE=y
|
||||
CONFIG_CRYPTO_AES_ARM_BS=y
|
||||
CONFIG_CRYPTO_AES_ARM_CE=y
|
||||
CONFIG_CRYPTO_GHASH_ARM_CE=y
|
||||
CONFIG_OPROFILE=m
|
||||
CONFIG_KPROBES=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS=16
|
||||
CONFIG_PANIC_ON_REFCOUNT_ERROR=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_SIG=y
|
||||
CONFIG_MODULE_SIG_FORCE=y
|
||||
CONFIG_MODULE_SIG_SHA512=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
CONFIG_BLK_DEV_ZONED=y
|
||||
CONFIG_BLK_INLINE_ENCRYPTION=y
|
||||
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
# CONFIG_IOSCHED_DEADLINE is not set
|
||||
CONFIG_CFQ_GROUP_IOSCHED=y
|
||||
CONFIG_IOSCHED_BFQ=y
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
CONFIG_CLEANCACHE=y
|
||||
CONFIG_CMA=y
|
||||
CONFIG_CMA_DEBUGFS=y
|
||||
CONFIG_ZSMALLOC=y
|
||||
CONFIG_BALANCE_ANON_FILE_RECLAIM=y
|
||||
CONFIG_HAVE_USERSPACE_LOW_MEMORY_KILLER=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_XFRM_USER=y
|
||||
CONFIG_XFRM_INTERFACE=y
|
||||
CONFIG_XFRM_STATISTICS=y
|
||||
CONFIG_NET_KEY=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_MULTIPLE_TABLES=y
|
||||
CONFIG_IP_ROUTE_VERBOSE=y
|
||||
CONFIG_IP_PNP=y
|
||||
CONFIG_IP_PNP_DHCP=y
|
||||
CONFIG_NET_IPGRE_DEMUX=y
|
||||
CONFIG_NET_IPVTI=y
|
||||
CONFIG_INET_AH=y
|
||||
CONFIG_INET_ESP=y
|
||||
CONFIG_INET_IPCOMP=y
|
||||
CONFIG_INET_UDP_DIAG=y
|
||||
CONFIG_INET_DIAG_DESTROY=y
|
||||
CONFIG_IPV6_ROUTER_PREF=y
|
||||
CONFIG_IPV6_ROUTE_INFO=y
|
||||
CONFIG_IPV6_OPTIMISTIC_DAD=y
|
||||
CONFIG_INET6_AH=y
|
||||
CONFIG_INET6_ESP=y
|
||||
CONFIG_INET6_IPCOMP=y
|
||||
CONFIG_IPV6_MIP6=y
|
||||
CONFIG_IPV6_VTI=y
|
||||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
CONFIG_IPV6_SUBTREES=y
|
||||
CONFIG_NETFILTER=y
|
||||
CONFIG_NF_CONNTRACK=y
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CONNTRACK_AMANDA=y
|
||||
CONFIG_NF_CONNTRACK_FTP=y
|
||||
CONFIG_NF_CONNTRACK_H323=y
|
||||
CONFIG_NF_CONNTRACK_IRC=y
|
||||
CONFIG_NF_CONNTRACK_NETBIOS_NS=y
|
||||
CONFIG_NF_CONNTRACK_PPTP=y
|
||||
CONFIG_NF_CONNTRACK_SANE=y
|
||||
CONFIG_NF_CONNTRACK_TFTP=y
|
||||
CONFIG_NF_CT_NETLINK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
|
||||
CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y
|
||||
CONFIG_NETFILTER_XT_TARGET_LOG=y
|
||||
CONFIG_NETFILTER_XT_TARGET_MARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=y
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
|
||||
CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TEE=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=y
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=y
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
|
||||
CONFIG_NETFILTER_XT_MATCH_BPF=y
|
||||
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_DSCP=y
|
||||
CONFIG_NETFILTER_XT_MATCH_ESP=y
|
||||
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_HELPER=y
|
||||
CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
|
||||
# CONFIG_NETFILTER_XT_MATCH_L2TP is not set
|
||||
CONFIG_NETFILTER_XT_MATCH_LENGTH=y
|
||||
CONFIG_NETFILTER_XT_MATCH_LIMIT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MAC=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MARK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_OWNER=y
|
||||
CONFIG_NETFILTER_XT_MATCH_POLICY=y
|
||||
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
|
||||
CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
|
||||
CONFIG_NETFILTER_XT_MATCH_SOCKET=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STATE=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
|
||||
CONFIG_NETFILTER_XT_MATCH_STRING=y
|
||||
CONFIG_NETFILTER_XT_MATCH_TIME=y
|
||||
CONFIG_NETFILTER_XT_MATCH_U32=y
|
||||
CONFIG_IP_NF_IPTABLES=y
|
||||
CONFIG_IP_NF_MATCH_AH=y
|
||||
CONFIG_IP_NF_MATCH_ECN=y
|
||||
CONFIG_IP_NF_MATCH_RPFILTER=y
|
||||
CONFIG_IP_NF_MATCH_TTL=y
|
||||
CONFIG_IP_NF_FILTER=y
|
||||
CONFIG_IP_NF_TARGET_REJECT=y
|
||||
CONFIG_IP_NF_NAT=y
|
||||
CONFIG_IP_NF_TARGET_MASQUERADE=y
|
||||
CONFIG_IP_NF_TARGET_NETMAP=y
|
||||
CONFIG_IP_NF_TARGET_REDIRECT=y
|
||||
CONFIG_IP_NF_MANGLE=y
|
||||
CONFIG_IP_NF_RAW=y
|
||||
CONFIG_IP_NF_SECURITY=y
|
||||
CONFIG_IP_NF_ARPTABLES=y
|
||||
CONFIG_IP_NF_ARPFILTER=y
|
||||
CONFIG_IP_NF_ARP_MANGLE=y
|
||||
CONFIG_IP6_NF_IPTABLES=y
|
||||
CONFIG_IP6_NF_MATCH_RPFILTER=y
|
||||
CONFIG_IP6_NF_FILTER=y
|
||||
CONFIG_IP6_NF_TARGET_REJECT=y
|
||||
CONFIG_IP6_NF_MANGLE=y
|
||||
CONFIG_IP6_NF_RAW=y
|
||||
CONFIG_BRIDGE_NF_EBTABLES=y
|
||||
CONFIG_BRIDGE_EBT_BROUTE=y
|
||||
CONFIG_L2TP=y
|
||||
CONFIG_L2TP_DEBUGFS=y
|
||||
CONFIG_L2TP_V3=y
|
||||
CONFIG_L2TP_IP=y
|
||||
CONFIG_L2TP_ETH=y
|
||||
CONFIG_BRIDGE=y
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_HTB=y
|
||||
CONFIG_NET_SCH_PRIO=y
|
||||
CONFIG_NET_SCH_INGRESS=y
|
||||
CONFIG_NET_CLS_FW=y
|
||||
CONFIG_NET_CLS_U32=y
|
||||
CONFIG_CLS_U32_MARK=y
|
||||
CONFIG_NET_CLS_FLOW=y
|
||||
CONFIG_NET_CLS_BPF=y
|
||||
CONFIG_NET_EMATCH=y
|
||||
CONFIG_NET_EMATCH_CMP=y
|
||||
CONFIG_NET_EMATCH_NBYTE=y
|
||||
CONFIG_NET_EMATCH_U32=y
|
||||
CONFIG_NET_EMATCH_META=y
|
||||
CONFIG_NET_EMATCH_TEXT=y
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_DNS_RESOLVER=y
|
||||
CONFIG_QRTR=y
|
||||
CONFIG_QRTR_SMD=y
|
||||
CONFIG_BT=y
|
||||
# CONFIG_BT_BREDR is not set
|
||||
# CONFIG_BT_LE is not set
|
||||
CONFIG_MSM_BT_POWER=y
|
||||
CONFIG_BTFM_SLIM_WCN3990=y
|
||||
CONFIG_CFG80211=y
|
||||
CONFIG_CFG80211_INTERNAL_REGDB=y
|
||||
# CONFIG_CFG80211_CRDA_SUPPORT is not set
|
||||
CONFIG_RFKILL=y
|
||||
CONFIG_NFC_NQ=y
|
||||
CONFIG_FW_LOADER_USER_HELPER=y
|
||||
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
|
||||
# CONFIG_FW_CACHE is not set
|
||||
CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y
|
||||
CONFIG_DMA_CMA=y
|
||||
CONFIG_ZRAM=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_LOOP_MIN_COUNT=16
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_SIZE=8192
|
||||
CONFIG_HDCP_QSEECOM=y
|
||||
CONFIG_QSEECOM=y
|
||||
CONFIG_UID_SYS_STATS=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_CHR_DEV_SG=y
|
||||
CONFIG_CHR_DEV_SCH=y
|
||||
CONFIG_SCSI_CONSTANTS=y
|
||||
CONFIG_SCSI_LOGGING=y
|
||||
CONFIG_SCSI_SCAN_ASYNC=y
|
||||
CONFIG_SCSI_UFSHCD=y
|
||||
CONFIG_SCSI_UFSHCD_PLATFORM=y
|
||||
CONFIG_SCSI_UFS_QCOM=y
|
||||
CONFIG_SCSI_UFSHCD_CMD_LOGGING=y
|
||||
CONFIG_SCSI_UFS_CRYPTO=y
|
||||
CONFIG_SCSI_UFS_CRYPTO_QTI=y
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_DM=y
|
||||
CONFIG_DM_CRYPT=y
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_VERITY=y
|
||||
CONFIG_DM_VERITY_FEC=y
|
||||
CONFIG_DM_ANDROID_VERITY=y
|
||||
CONFIG_DM_ANDROID_VERITY_AT_MOST_ONCE_DEFAULT_ENABLED=y
|
||||
CONFIG_DM_BOW=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_DUMMY=y
|
||||
CONFIG_TUN=y
|
||||
# CONFIG_NET_VENDOR_AMAZON is not set
|
||||
# CONFIG_NET_VENDOR_EZCHIP is not set
|
||||
# CONFIG_NET_VENDOR_HISILICON is not set
|
||||
# CONFIG_NET_VENDOR_MARVELL is not set
|
||||
# CONFIG_NET_VENDOR_NETRONOME is not set
|
||||
# CONFIG_NET_VENDOR_ROCKER is not set
|
||||
# CONFIG_NET_VENDOR_SYNOPSYS is not set
|
||||
CONFIG_PPP=y
|
||||
CONFIG_PPP_BSDCOMP=y
|
||||
CONFIG_PPP_DEFLATE=y
|
||||
CONFIG_PPP_FILTER=y
|
||||
CONFIG_PPP_MPPE=y
|
||||
CONFIG_PPP_MULTILINK=y
|
||||
CONFIG_PPPOE=y
|
||||
CONFIG_PPTP=y
|
||||
CONFIG_PPPOL2TP=y
|
||||
CONFIG_PPP_ASYNC=y
|
||||
CONFIG_PPP_SYNC_TTY=y
|
||||
CONFIG_USB_RTL8152=y
|
||||
CONFIG_USB_USBNET=y
|
||||
# CONFIG_WLAN_VENDOR_ADMTEK is not set
|
||||
# CONFIG_WLAN_VENDOR_ATH is not set
|
||||
# CONFIG_WLAN_VENDOR_ATMEL is not set
|
||||
# CONFIG_WLAN_VENDOR_BROADCOM is not set
|
||||
# CONFIG_WLAN_VENDOR_CISCO is not set
|
||||
# CONFIG_WLAN_VENDOR_INTEL is not set
|
||||
# CONFIG_WLAN_VENDOR_INTERSIL is not set
|
||||
# CONFIG_WLAN_VENDOR_MARVELL is not set
|
||||
# CONFIG_WLAN_VENDOR_MEDIATEK is not set
|
||||
# CONFIG_WLAN_VENDOR_RALINK is not set
|
||||
# CONFIG_WLAN_VENDOR_REALTEK is not set
|
||||
# CONFIG_WLAN_VENDOR_RSI is not set
|
||||
# CONFIG_WLAN_VENDOR_ST is not set
|
||||
# CONFIG_WLAN_VENDOR_TI is not set
|
||||
# CONFIG_WLAN_VENDOR_ZYDAS is not set
|
||||
CONFIG_WCNSS_MEM_PRE_ALLOC=y
|
||||
CONFIG_CLD_LL_CORE=y
|
||||
CONFIG_INPUT_EVDEV=y
|
||||
CONFIG_KEYBOARD_GPIO=y
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
CONFIG_INPUT_JOYSTICK=y
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_HBTP_INPUT=y
|
||||
CONFIG_INPUT_QPNP_POWER_ON=y
|
||||
CONFIG_INPUT_UINPUT=y
|
||||
# CONFIG_SERIO_SERPORT is not set
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_DEVMEM is not set
|
||||
CONFIG_SERIAL_MSM=y
|
||||
CONFIG_SERIAL_MSM_CONSOLE=y
|
||||
CONFIG_SERIAL_MSM_HS=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HW_RANDOM_MSM_LEGACY=y
|
||||
CONFIG_MSM_SMD_PKT=y
|
||||
CONFIG_DIAG_CHAR=y
|
||||
CONFIG_MSM_ADSPRPC=y
|
||||
CONFIG_MSM_RDBG=m
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_MSM_V2=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_QUP=y
|
||||
CONFIG_SPI_SPIDEV=y
|
||||
CONFIG_SPMI=y
|
||||
CONFIG_PINCTRL_MSM8937=y
|
||||
CONFIG_PINCTRL_MSM8917=y
|
||||
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_POWER_RESET=y
|
||||
CONFIG_POWER_RESET_QCOM=y
|
||||
CONFIG_QPNP_SMB5=y
|
||||
CONFIG_SMB1351_USB_CHARGER=y
|
||||
CONFIG_SMB1355_SLAVE_CHARGER=y
|
||||
CONFIG_QPNP_QG=y
|
||||
CONFIG_THERMAL=y
|
||||
CONFIG_THERMAL_WRITABLE_TRIPS=y
|
||||
CONFIG_THERMAL_GOV_USER_SPACE=y
|
||||
CONFIG_THERMAL_GOV_LOW_LIMITS=y
|
||||
CONFIG_CPU_THERMAL=y
|
||||
CONFIG_DEVFREQ_THERMAL=y
|
||||
CONFIG_THERMAL_TSENS=y
|
||||
CONFIG_QTI_VIRTUAL_SENSOR=y
|
||||
CONFIG_QTI_BCL_PMIC5=y
|
||||
CONFIG_QTI_BCL_SOC_DRIVER=y
|
||||
CONFIG_QTI_QMI_COOLING_DEVICE=y
|
||||
CONFIG_REGULATOR_COOLING_DEVICE=y
|
||||
CONFIG_MFD_I2C_PMIC=y
|
||||
CONFIG_MFD_SPMI_PMIC=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
CONFIG_REGULATOR_PROXY_CONSUMER=y
|
||||
CONFIG_REGULATOR_QPNP_LABIBB=y
|
||||
CONFIG_REGULATOR_QPNP_LCDB=y
|
||||
CONFIG_REGULATOR_MEM_ACC=y
|
||||
CONFIG_REGULATOR_CPR=y
|
||||
CONFIG_REGULATOR_RPM_SMD=y
|
||||
CONFIG_REGULATOR_SPM=y
|
||||
CONFIG_REGULATOR_STUB=y
|
||||
CONFIG_MEDIA_SUPPORT=y
|
||||
CONFIG_MEDIA_CAMERA_SUPPORT=y
|
||||
CONFIG_MEDIA_CONTROLLER=y
|
||||
CONFIG_VIDEO_V4L2_SUBDEV_API=y
|
||||
CONFIG_V4L_PLATFORM_DRIVERS=y
|
||||
CONFIG_MSM_VIDC_3X_GOVERNORS=y
|
||||
CONFIG_MSM_VIDC_3X_V4L2=y
|
||||
CONFIG_MSM_CAMERA=y
|
||||
CONFIG_MSM_CAMERA_DEBUG=y
|
||||
CONFIG_MSMB_CAMERA=y
|
||||
CONFIG_MSMB_CAMERA_DEBUG=y
|
||||
CONFIG_MSM_CAMERA_SENSOR=y
|
||||
CONFIG_MSM_CPP=y
|
||||
CONFIG_MSM_CCI=y
|
||||
CONFIG_MSM_CSI20_HEADER=y
|
||||
CONFIG_MSM_CSI22_HEADER=y
|
||||
CONFIG_MSM_CSI30_HEADER=y
|
||||
CONFIG_MSM_CSI31_HEADER=y
|
||||
CONFIG_MSM_CSIPHY=y
|
||||
CONFIG_MSM_CSID=y
|
||||
CONFIG_MSM_EEPROM=y
|
||||
CONFIG_MSM_ISPIF_V2=y
|
||||
CONFIG_IMX134=y
|
||||
CONFIG_IMX132=y
|
||||
CONFIG_OV9724=y
|
||||
CONFIG_OV5648=y
|
||||
CONFIG_GC0339=y
|
||||
CONFIG_OV8825=y
|
||||
CONFIG_OV8865=y
|
||||
CONFIG_s5k4e1=y
|
||||
CONFIG_OV12830=y
|
||||
CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE=y
|
||||
CONFIG_MSMB_JPEG=y
|
||||
CONFIG_MSM_FD=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_VIRTUAL=y
|
||||
CONFIG_FB_MSM=y
|
||||
CONFIG_FB_MSM_MDSS=y
|
||||
CONFIG_FB_MSM_MDSS_WRITEBACK=y
|
||||
CONFIG_FB_MSM_MDSS_SPI_PANEL=y
|
||||
CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS=y
|
||||
CONFIG_FB_MSM_MDSS_XLOG_DEBUG=y
|
||||
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
||||
# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
CONFIG_SND_DYNAMIC_MINORS=y
|
||||
CONFIG_SND_USB_AUDIO=y
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_UHID=y
|
||||
CONFIG_HID_APPLE=y
|
||||
CONFIG_HID_ELECOM=y
|
||||
CONFIG_HID_MAGICMOUSE=y
|
||||
CONFIG_HID_MICROSOFT=y
|
||||
CONFIG_HID_MULTITOUCH=y
|
||||
CONFIG_HID_SONY=y
|
||||
CONFIG_USB_HIDDEV=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
|
||||
CONFIG_USB_MON=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||
CONFIG_USB_EHCI_MSM=y
|
||||
CONFIG_USB_ACM=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_USB_STORAGE_DATAFAB=y
|
||||
CONFIG_USB_STORAGE_FREECOM=y
|
||||
CONFIG_USB_STORAGE_ISD200=y
|
||||
CONFIG_USB_STORAGE_USBAT=y
|
||||
CONFIG_USB_STORAGE_SDDR09=y
|
||||
CONFIG_USB_STORAGE_SDDR55=y
|
||||
CONFIG_USB_STORAGE_JUMPSHOT=y
|
||||
CONFIG_USB_STORAGE_ALAUDA=y
|
||||
CONFIG_USB_STORAGE_ONETOUCH=y
|
||||
CONFIG_USB_STORAGE_KARMA=y
|
||||
CONFIG_USB_STORAGE_CYPRESS_ATACB=y
|
||||
CONFIG_USB_SERIAL=y
|
||||
CONFIG_USB_EHSET_TEST_FIXTURE=y
|
||||
CONFIG_NOP_USB_XCEIV=y
|
||||
CONFIG_USB_GADGET=y
|
||||
CONFIG_USB_GADGET_DEBUG_FILES=y
|
||||
CONFIG_USB_GADGET_DEBUG_FS=y
|
||||
CONFIG_USB_GADGET_VBUS_DRAW=500
|
||||
CONFIG_USB_CI13XXX_MSM=y
|
||||
CONFIG_USB_CONFIGFS=y
|
||||
CONFIG_USB_CONFIGFS_UEVENT=y
|
||||
CONFIG_USB_CONFIGFS_SERIAL=y
|
||||
CONFIG_USB_CONFIGFS_NCM=y
|
||||
CONFIG_USB_CONFIGFS_RNDIS=y
|
||||
CONFIG_USB_CONFIGFS_RMNET_BAM=y
|
||||
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
|
||||
CONFIG_USB_CONFIGFS_F_FS=y
|
||||
CONFIG_USB_CONFIGFS_F_ACC=y
|
||||
CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y
|
||||
CONFIG_USB_CONFIGFS_F_MIDI=y
|
||||
CONFIG_USB_CONFIGFS_F_HID=y
|
||||
CONFIG_USB_CONFIGFS_F_DIAG=y
|
||||
CONFIG_USB_CONFIGFS_F_CDEV=y
|
||||
CONFIG_USB_CONFIGFS_F_CCID=y
|
||||
CONFIG_USB_CONFIGFS_F_QDSS=y
|
||||
CONFIG_USB_CONFIGFS_F_MTP=y
|
||||
CONFIG_USB_CONFIGFS_F_PTP=y
|
||||
CONFIG_TYPEC=y
|
||||
CONFIG_MMC=y
|
||||
# CONFIG_PWRSEQ_EMMC is not set
|
||||
# CONFIG_PWRSEQ_SIMPLE is not set
|
||||
CONFIG_MMC_BLOCK_MINORS=32
|
||||
CONFIG_MMC_BLOCK_DEFERRED_RESUME=y
|
||||
CONFIG_MMC_IPC_LOGGING=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_SDHCI_MSM=y
|
||||
CONFIG_MMC_CQHCI_CRYPTO=y
|
||||
CONFIG_MMC_CQHCI_CRYPTO_QTI=y
|
||||
CONFIG_LEDS_QTI_TRI_LED=y
|
||||
CONFIG_LEDS_QPNP_FLASH_V2=y
|
||||
CONFIG_LEDS_QPNP_VIBRATOR_LDO=y
|
||||
CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
CONFIG_EDAC=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_QCOM_SPS_DMA=y
|
||||
CONFIG_UIO=y
|
||||
CONFIG_UIO_MSM_SHAREDMEM=y
|
||||
CONFIG_STAGING=y
|
||||
CONFIG_ASHMEM=y
|
||||
CONFIG_ION=y
|
||||
CONFIG_ION_POOL_AUTO_REFILL=y
|
||||
CONFIG_MSM_EXT_DISPLAY=y
|
||||
CONFIG_QPNP_REVID=y
|
||||
CONFIG_SPS=y
|
||||
CONFIG_SPS_SUPPORT_NDP_BAM=y
|
||||
CONFIG_IPA=y
|
||||
CONFIG_RMNET_IPA=y
|
||||
CONFIG_RNDIS_IPA=y
|
||||
CONFIG_MDSS_PLL=y
|
||||
CONFIG_QCOM_CLK_SMD_RPM=y
|
||||
CONFIG_SDM_GCC_429W=y
|
||||
CONFIG_SDM_DEBUGCC_429W=y
|
||||
CONFIG_CLOCK_CPU_SDM=y
|
||||
CONFIG_HWSPINLOCK=y
|
||||
CONFIG_HWSPINLOCK_QCOM=y
|
||||
CONFIG_MAILBOX=y
|
||||
CONFIG_ARM_SMMU=y
|
||||
CONFIG_QCOM_LAZY_MAPPING=y
|
||||
CONFIG_IOMMU_DEBUG=y
|
||||
CONFIG_IOMMU_TESTS=y
|
||||
CONFIG_RPMSG_CHAR=y
|
||||
CONFIG_RPMSG_QCOM_GLINK_RPM=y
|
||||
CONFIG_RPMSG_QCOM_GLINK_SMEM=y
|
||||
CONFIG_RPMSG_QCOM_SMD=y
|
||||
CONFIG_MSM_RPM_SMD=y
|
||||
CONFIG_QCOM_CPUSS_DUMP=y
|
||||
CONFIG_QCOM_RUN_QUEUE_STATS=y
|
||||
CONFIG_QCOM_QMI_HELPERS=y
|
||||
CONFIG_QCOM_SMEM=y
|
||||
CONFIG_QCOM_SMD_RPM=y
|
||||
CONFIG_MSM_SPM=y
|
||||
CONFIG_MSM_L2_SPM=y
|
||||
CONFIG_QCOM_EARLY_RANDOM=y
|
||||
CONFIG_QCOM_MEMORY_DUMP_V2=y
|
||||
CONFIG_QCOM_SMP2P=y
|
||||
CONFIG_QCOM_SMSM=y
|
||||
CONFIG_MSM_PIL_MSS_QDSP6V5=y
|
||||
CONFIG_QCOM_SECURE_BUFFER=y
|
||||
CONFIG_MSM_SUBSYSTEM_RESTART=y
|
||||
CONFIG_MSM_PIL=y
|
||||
CONFIG_MSM_PIL_SSR_GENERIC=y
|
||||
CONFIG_MSM_BOOT_STATS=y
|
||||
CONFIG_QCOM_DCC_V2=y
|
||||
CONFIG_MSM_CORE_HANG_DETECT=y
|
||||
CONFIG_QCOM_WATCHDOG_V2=y
|
||||
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
|
||||
CONFIG_QCOM_BUS_SCALING=y
|
||||
CONFIG_QCOM_GLINK=y
|
||||
CONFIG_MSM_EVENT_TIMER=y
|
||||
CONFIG_MSM_PM=y
|
||||
CONFIG_QTI_RPM_STATS_LOG=y
|
||||
CONFIG_QTEE_SHM_BRIDGE=y
|
||||
CONFIG_MEM_SHARE_QMI_SERVICE=y
|
||||
CONFIG_MSM_PERFORMANCE=y
|
||||
CONFIG_QTI_CRYPTO_COMMON=y
|
||||
CONFIG_QTI_CRYPTO_TZ=y
|
||||
CONFIG_WCNSS_CORE=y
|
||||
CONFIG_WCNSS_CORE_PRONTO=y
|
||||
CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y
|
||||
CONFIG_DEVFREQ_GOV_PASSIVE=y
|
||||
CONFIG_QCOM_BIMC_BWMON=y
|
||||
CONFIG_ARM_MEMLAT_MON=y
|
||||
CONFIG_DEVFREQ_GOV_QCOM_BW_HWMON=y
|
||||
CONFIG_DEVFREQ_GOV_MEMLAT=y
|
||||
CONFIG_DEVFREQ_SIMPLE_DEV=y
|
||||
CONFIG_QCOM_DEVFREQ_DEVBW=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PWM_QTI_LPG=y
|
||||
CONFIG_QCOM_SHOW_RESUME_IRQ=y
|
||||
CONFIG_QCOM_MPM=y
|
||||
CONFIG_RAS=y
|
||||
CONFIG_ANDROID=y
|
||||
CONFIG_ANDROID_BINDER_IPC=y
|
||||
CONFIG_ANDROID_BINDERFS=y
|
||||
CONFIG_QCOM_QFPROM=y
|
||||
CONFIG_STM=y
|
||||
CONFIG_SLIMBUS_MSM_NGD=y
|
||||
CONFIG_SENSORS_SSC=y
|
||||
CONFIG_QCOM_KGSL=y
|
||||
CONFIG_LEGACY_ENERGY_MODEL_DT=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_EXT4_ENCRYPTION=y
|
||||
CONFIG_F2FS_FS=y
|
||||
CONFIG_F2FS_FS_SECURITY=y
|
||||
CONFIG_F2FS_CHECK_FS=y
|
||||
CONFIG_F2FS_FS_ENCRYPTION=y
|
||||
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
|
||||
CONFIG_FS_VERITY=y
|
||||
CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y
|
||||
CONFIG_QUOTA=y
|
||||
CONFIG_QUOTA_NETLINK_INTERFACE=y
|
||||
CONFIG_QFMT_V2=y
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_OVERLAY_FS=y
|
||||
CONFIG_INCREMENTAL_FS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_SDCARD_FS=y
|
||||
CONFIG_SQUASHFS=y
|
||||
CONFIG_SQUASHFS_XATTR=y
|
||||
CONFIG_SQUASHFS_LZ4=y
|
||||
# CONFIG_NETWORK_FILESYSTEMS is not set
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
|
||||
CONFIG_SECURITY=y
|
||||
CONFIG_LSM_MMAP_MIN_ADDR=4096
|
||||
CONFIG_HARDENED_USERCOPY=y
|
||||
CONFIG_HARDENED_USERCOPY_PAGESPAN=y
|
||||
CONFIG_FORTIFY_SOURCE=y
|
||||
CONFIG_STATIC_USERMODEHELPER=y
|
||||
CONFIG_STATIC_USERMODEHELPER_PATH=""
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
CONFIG_SECURITY_SMACK=y
|
||||
CONFIG_CRYPTO_GCM=y
|
||||
CONFIG_CRYPTO_XCBC=y
|
||||
CONFIG_CRYPTO_MD4=y
|
||||
CONFIG_CRYPTO_TWOFISH=y
|
||||
CONFIG_CRYPTO_LZ4=y
|
||||
CONFIG_CRYPTO_ANSI_CPRNG=y
|
||||
CONFIG_CRYPTO_DEV_QCE=y
|
||||
CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
|
||||
CONFIG_CRYPTO_DEV_QCRYPTO=y
|
||||
CONFIG_CRYPTO_DEV_QCEDEV=y
|
||||
CONFIG_CRYPTO_DEV_QCOM_ICE=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DYNAMIC_DEBUG=y
|
||||
CONFIG_DEBUG_CONSOLE_UNHASHED_POINTERS=y
|
||||
CONFIG_DEBUG_MODULE_LOAD_INFO=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_FRAME_WARN=2048
|
||||
CONFIG_PAGE_OWNER=y
|
||||
CONFIG_PAGE_OWNER_ENABLE_DEFAULT=y
|
||||
CONFIG_DEBUG_SECTION_MISMATCH=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_PAGEALLOC=y
|
||||
CONFIG_SLUB_DEBUG_PANIC_ON=y
|
||||
CONFIG_DEBUG_PANIC_ON_OOM=y
|
||||
CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y
|
||||
CONFIG_PAGE_POISONING=y
|
||||
CONFIG_PAGE_POISONING_ENABLE_DEFAULT=y
|
||||
CONFIG_DEBUG_OBJECTS=y
|
||||
CONFIG_DEBUG_OBJECTS_FREE=y
|
||||
CONFIG_DEBUG_OBJECTS_TIMERS=y
|
||||
CONFIG_DEBUG_OBJECTS_WORK=y
|
||||
CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
|
||||
CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y
|
||||
CONFIG_DEBUG_KMEMLEAK=y
|
||||
CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=4000
|
||||
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
|
||||
CONFIG_DEBUG_STACK_USAGE=y
|
||||
CONFIG_DEBUG_MEMORY_INIT=y
|
||||
CONFIG_WQ_WATCHDOG=y
|
||||
CONFIG_PANIC_ON_OOPS=y
|
||||
CONFIG_PANIC_TIMEOUT=5
|
||||
CONFIG_PANIC_ON_SCHED_BUG=y
|
||||
CONFIG_PANIC_ON_RT_THROTTLING=y
|
||||
CONFIG_SCHED_STACK_END_CHECK=y
|
||||
# CONFIG_DEBUG_PREEMPT is not set
|
||||
CONFIG_DEBUG_SPINLOCK=y
|
||||
CONFIG_DEBUG_MUTEXES=y
|
||||
CONFIG_DEBUG_ATOMIC_SLEEP=y
|
||||
CONFIG_LOCK_TORTURE_TEST=m
|
||||
CONFIG_DEBUG_SG=y
|
||||
CONFIG_DEBUG_NOTIFIERS=y
|
||||
CONFIG_DEBUG_CREDENTIALS=y
|
||||
CONFIG_FAULT_INJECTION=y
|
||||
CONFIG_FAIL_PAGE_ALLOC=y
|
||||
CONFIG_FAULT_INJECTION_DEBUG_FS=y
|
||||
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
|
||||
CONFIG_IPC_LOGGING=y
|
||||
CONFIG_QCOM_RTB=y
|
||||
CONFIG_QCOM_RTB_SEPARATE_CPUS=y
|
||||
CONFIG_PREEMPTIRQ_EVENTS=y
|
||||
CONFIG_IRQSOFF_TRACER=y
|
||||
CONFIG_PREEMPT_TRACER=y
|
||||
CONFIG_BLK_DEV_IO_TRACE=y
|
||||
CONFIG_LKDTM=y
|
||||
CONFIG_ATOMIC64_SELFTEST=m
|
||||
CONFIG_MEMTEST=y
|
||||
CONFIG_BUG_ON_DATA_CORRUPTION=y
|
||||
CONFIG_PANIC_ON_DATA_CORRUPTION=y
|
||||
CONFIG_DEBUG_USER=y
|
||||
CONFIG_FORCE_PAGES=y
|
||||
CONFIG_PID_IN_CONTEXTIDR=y
|
|
@ -130,6 +130,42 @@ config ARCH_MSM8917
|
|||
select COMMON_CLK
|
||||
select COMMON_CLK_QCOM
|
||||
|
||||
config ARCH_MSM8937
|
||||
bool "Enable support for MSM8937"
|
||||
select CPU_V7
|
||||
select HAVE_ARM_ARCH_TIMER
|
||||
select PINCTRL
|
||||
select QCOM_SCM if SMP
|
||||
select PM_DEVFREQ
|
||||
select CLKDEV_LOOKUP
|
||||
select HAVE_CLK
|
||||
select HAVE_CLK_PREPARE
|
||||
select COMMON_CLK_QCOM
|
||||
|
||||
config ARCH_SDM439
|
||||
bool "Enable support for SDM439"
|
||||
select CPU_V7
|
||||
select HAVE_ARM_ARCH_TIMER
|
||||
select PINCTRL
|
||||
select QCOM_SCM if SMP
|
||||
select PM_DEVFREQ
|
||||
select CLKDEV_LOOKUP
|
||||
select HAVE_CLK
|
||||
select HAVE_CLK_PREPARE
|
||||
select COMMON_CLK_QCOM
|
||||
|
||||
config ARCH_SDM429
|
||||
bool "Enable support for SDM429"
|
||||
select CPU_V7
|
||||
select HAVE_ARM_ARCH_TIMER
|
||||
select PINCTRL
|
||||
select QCOM_SCM if SMP
|
||||
select PM_DEVFREQ
|
||||
select CLKDEV_LOOKUP
|
||||
select HAVE_CLK
|
||||
select HAVE_CLK_PREPARE
|
||||
select COMMON_CLK_QCOM
|
||||
|
||||
config ARCH_SCUBA
|
||||
bool "Enable Support for Qualcomm Technologies, Inc. SCUBA"
|
||||
select COMMON_CLK_QCOM
|
||||
|
@ -153,5 +189,27 @@ config ARCH_SCUBA
|
|||
This enables support for the SCUBA chipset. If you do not
|
||||
wish to build a kernel that runs on this chipset, say 'N' here.
|
||||
|
||||
config ARCH_MSM8953
|
||||
bool "Enable support for MSM8953"
|
||||
select CPU_V7
|
||||
select HAVE_ARM_ARCH_TIMER
|
||||
select PINCTRL
|
||||
select QCOM_SCM if SMP
|
||||
select PM_DEVFREQ
|
||||
select COMMON_CLK
|
||||
select COMMON_CLK_QCOM
|
||||
select QCOM_GDSC
|
||||
|
||||
config ARCH_SDM450
|
||||
bool "Enable support for SDM450"
|
||||
select CPU_V7
|
||||
select HAVE_ARM_ARCH_TIMER
|
||||
select PINCTRL
|
||||
select QCOM_SCM if SMP
|
||||
select PM_DEVFREQ
|
||||
select COMMON_CLK
|
||||
select COMMON_CLK_QCOM
|
||||
select QCOM_GDSC
|
||||
|
||||
endmenu
|
||||
endif
|
||||
|
|
|
@ -4,3 +4,9 @@ obj-$(CONFIG_ARCH_BENGAL) += board-bengal.o
|
|||
obj-$(CONFIG_ARCH_SCUBA) += board-scuba.o
|
||||
obj-$(CONFIG_ARCH_SDM660) += board-660.o
|
||||
obj-$(CONFIG_ARCH_MSM8917) += board-msm8917.o
|
||||
obj-$(CONFIG_ARCH_QM215) += board-qm215.o
|
||||
obj-$(CONFIG_ARCH_MSM8953) += board-msm8953.o
|
||||
obj-$(CONFIG_ARCH_SDM450) += board-sdm450.o
|
||||
obj-$(CONFIG_ARCH_MSM8937) += board-msm8937.o
|
||||
obj-$(CONFIG_ARCH_SDM429) += board-sdm429.o
|
||||
obj-$(CONFIG_ARCH_SDM439) += board-sdm439.o
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (C) 2020 XiaoMi, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -12,6 +11,7 @@
|
|||
static const char *trinket_dt_match[] __initconst = {
|
||||
"qcom,bengal",
|
||||
"qcom,bengal-iot",
|
||||
"qcom,bengalp-iot",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
25
arch/arm/mach-qcom/board-msm8937.c
Normal file
25
arch/arm/mach-qcom/board-msm8937.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include "board-dt.h"
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
static const char *msm8937_dt_match[] __initconst = {
|
||||
"qcom,msm8937",
|
||||
NULL
|
||||
};
|
||||
|
||||
static void __init msm8937_init(void)
|
||||
{
|
||||
board_dt_populate(NULL);
|
||||
}
|
||||
|
||||
DT_MACHINE_START(MSM8937_DT,
|
||||
"Qualcomm Technologies, Inc. MSM8937 (Flattened Device Tree)")
|
||||
.init_machine = msm8937_init,
|
||||
.dt_compat = msm8937_dt_match,
|
||||
MACHINE_END
|
25
arch/arm/mach-qcom/board-msm8953.c
Normal file
25
arch/arm/mach-qcom/board-msm8953.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017,2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include "board-dt.h"
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
static const char *msm8953_dt_match[] __initconst = {
|
||||
"qcom,msm8953",
|
||||
NULL
|
||||
};
|
||||
|
||||
static void __init msm8953_init(void)
|
||||
{
|
||||
board_dt_populate(NULL);
|
||||
}
|
||||
|
||||
DT_MACHINE_START(MSM8953_DT,
|
||||
"Qualcomm Technologies, Inc. MSM8953 (Flattened Device Tree)")
|
||||
.init_machine = msm8953_init,
|
||||
.dt_compat = msm8953_dt_match,
|
||||
MACHINE_END
|
25
arch/arm/mach-qcom/board-qm215.c
Normal file
25
arch/arm/mach-qcom/board-qm215.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include "board-dt.h"
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
static const char *qm215_dt_match[] __initconst = {
|
||||
"qcom,qm215",
|
||||
NULL
|
||||
};
|
||||
|
||||
static void __init qm215_init(void)
|
||||
{
|
||||
board_dt_populate(NULL);
|
||||
}
|
||||
|
||||
DT_MACHINE_START(QM215_DT,
|
||||
"Qualcomm Technologies, Inc. QM215")
|
||||
.init_machine = qm215_init,
|
||||
.dt_compat = qm215_dt_match,
|
||||
MACHINE_END
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (C) 2020 XiaoMi, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
|
25
arch/arm/mach-qcom/board-sdm429.c
Normal file
25
arch/arm/mach-qcom/board-sdm429.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include "board-dt.h"
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
static const char *sdm429_dt_match[] __initconst = {
|
||||
"qcom,sdm429",
|
||||
NULL
|
||||
};
|
||||
|
||||
static void __init sdm429_init(void)
|
||||
{
|
||||
board_dt_populate(NULL);
|
||||
}
|
||||
|
||||
DT_MACHINE_START(SDM429_DT,
|
||||
"Qualcomm Technologies, Inc. SDM429 (Flattened Device Tree)")
|
||||
.init_machine = sdm429_init,
|
||||
.dt_compat = sdm429_dt_match,
|
||||
MACHINE_END
|
25
arch/arm/mach-qcom/board-sdm439.c
Normal file
25
arch/arm/mach-qcom/board-sdm439.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include "board-dt.h"
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
static const char *sdm439_dt_match[] __initconst = {
|
||||
"qcom,sdm439",
|
||||
NULL
|
||||
};
|
||||
|
||||
static void __init sdm439_init(void)
|
||||
{
|
||||
board_dt_populate(NULL);
|
||||
}
|
||||
|
||||
DT_MACHINE_START(SDM439_DT,
|
||||
"Qualcomm Technologies, Inc. SDM439 (Flattened Device Tree)")
|
||||
.init_machine = sdm439_init,
|
||||
.dt_compat = sdm439_dt_match,
|
||||
MACHINE_END
|
25
arch/arm/mach-qcom/board-sdm450.c
Normal file
25
arch/arm/mach-qcom/board-sdm450.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017,2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include "board-dt.h"
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
||||
static const char *sdm450_dt_match[] __initconst = {
|
||||
"qcom,sdm450",
|
||||
NULL
|
||||
};
|
||||
|
||||
static void __init sdm450_init(void)
|
||||
{
|
||||
board_dt_populate(NULL);
|
||||
}
|
||||
|
||||
DT_MACHINE_START(SDM450_DT,
|
||||
"Qualcomm Technologies, Inc. SDM450 (Flattened Device Tree)")
|
||||
.init_machine = sdm450_init,
|
||||
.dt_compat = sdm450_dt_match,
|
||||
MACHINE_END
|
|
@ -20,7 +20,6 @@ config ARM64
|
|||
select ARCH_HAS_KCOV
|
||||
select ARCH_HAS_MEMBARRIER_SYNC_CORE
|
||||
select ARCH_HAS_PTE_SPECIAL
|
||||
select ARCH_HAS_REFCOUNT_FULL
|
||||
select ARCH_HAS_SET_MEMORY
|
||||
select ARCH_HAS_SG_CHAIN
|
||||
select ARCH_HAS_STRICT_KERNEL_RWX
|
||||
|
@ -505,8 +504,6 @@ config ARM64_ERRATUM_1024718
|
|||
config ARM64_ERRATUM_1188873
|
||||
bool "Cortex-A76: MRC read following MRRC read of specific Generic Timer in AArch32 might give incorrect result"
|
||||
default y
|
||||
select ARM_ARCH_TIMER_OOL_WORKAROUND
|
||||
depends on ARM_ARCH_TIMER
|
||||
help
|
||||
This option adds work arounds for ARM Cortex-A76 erratum 1188873
|
||||
|
||||
|
@ -1579,13 +1576,6 @@ config KRYO_PMU_WORKAROUND
|
|||
|
||||
Enable this flag for effect SoCs.
|
||||
|
||||
config BOOT_INFO
|
||||
bool "Boot information from bootloader"
|
||||
default y
|
||||
help
|
||||
On embedded linux device, we try to collect more information from
|
||||
bootloader to kernel. eg. powerup reason.
|
||||
|
||||
config BUILD_ARM64_DT_OVERLAY
|
||||
bool "enable DT overlay compilation support"
|
||||
depends on OF
|
||||
|
|
|
@ -248,6 +248,26 @@ config ARCH_SDM439
|
|||
This enables support for the sdm439 chipset. If you do not
|
||||
wish to build a kernel that runs on this chipset, say 'N' here.
|
||||
|
||||
config ARCH_MSM8953
|
||||
bool "Enable Support for Qualcomm Technologies Inc. MSM8953"
|
||||
depends on ARCH_QCOM
|
||||
select COMMON_CLK_QCOM
|
||||
select QCOM_GDSC
|
||||
select CPU_FREQ_QCOM
|
||||
help
|
||||
This enables support for the MSM8953 chipset. If you do not
|
||||
wish to build a kernel that runs on this chipset, say 'N' here.
|
||||
|
||||
config ARCH_SDM450
|
||||
bool "Enable Support for Qualcomm Technologies Inc. SDM450"
|
||||
depends on ARCH_QCOM
|
||||
select COMMON_CLK_QCOM
|
||||
select QCOM_GDSC
|
||||
select CPU_FREQ_QCOM
|
||||
help
|
||||
This enables support for the sdm450 chipset. If you do not
|
||||
wish to build a kernel that runs on this chipset, say 'N' here.
|
||||
|
||||
config ARCH_ROCKCHIP
|
||||
bool "Rockchip Platforms"
|
||||
select ARCH_HAS_RESET_CONTROLLER
|
||||
|
|
|
@ -148,10 +148,6 @@ endif
|
|||
|
||||
KBUILD_DTBS := dtbs
|
||||
|
||||
KBUILD_DTBO_IMG := dtbo.img
|
||||
|
||||
KBUILD_DTB_IMG := dtb.img
|
||||
|
||||
ifeq ($(CONFIG_BUILD_ARM64_DT_OVERLAY),y)
|
||||
export DTC_FLAGS := -@
|
||||
endif
|
||||
|
@ -184,17 +180,6 @@ Image-dtb: vmlinux scripts dtbs
|
|||
Image.gz-dtb: vmlinux scripts dtbs Image.gz
|
||||
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
|
||||
|
||||
ifeq ($(CONFIG_BUILD_ARM64_DT_OVERLAY),y)
|
||||
$(KBUILD_DTBO_IMG): dtbs
|
||||
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
|
||||
|
||||
all: $(KBUILD_DTBO_IMG)
|
||||
$(KBUILD_DTB_IMG): dtbs
|
||||
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
|
||||
|
||||
all: $(KBUILD_DTB_IMG)
|
||||
endif
|
||||
|
||||
PHONY += vdso_install
|
||||
vdso_install:
|
||||
$(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso $@
|
||||
|
|
|
@ -18,7 +18,7 @@ include $(srctree)/arch/arm64/boot/dts/Makefile
|
|||
|
||||
OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
|
||||
|
||||
targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo dtbo.img dtb.img
|
||||
targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo
|
||||
|
||||
DTB_NAMES := $(subst $\",,$(CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES))
|
||||
ifneq ($(DTB_NAMES),)
|
||||
|
@ -28,8 +28,6 @@ DTB_LIST := $(dtb-y)
|
|||
endif
|
||||
DTB_OBJS := $(shell find $(obj)/dts/ -name \*.dtb)
|
||||
|
||||
DTBO_OBJS := $(shell find $(obj)/dts/ -name \*.dtbo)
|
||||
|
||||
# Add RTIC DTB to the DTB list if RTIC MPGen is enabled
|
||||
# Note, we keep this for compatibility with
|
||||
# BUILD_ARM64_APPENDED_DTB_IMAGE targets.
|
||||
|
@ -70,12 +68,6 @@ $(obj)/Image.lzo: $(obj)/Image FORCE
|
|||
$(obj)/Image.gz-dtb: $(obj)/Image.gz $(DTB_OBJS) FORCE
|
||||
$(call if_changed,cat)
|
||||
|
||||
$(obj)/dtbo.img: $(DTBO_OBJS) FORCE
|
||||
$(call if_changed,mkdtimg)
|
||||
|
||||
$(obj)/dtb.img: $(DTB_OBJS) FORCE
|
||||
$(call if_changed,cat)
|
||||
|
||||
install:
|
||||
$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
|
||||
$(obj)/Image System.map "$(INSTALL_PATH)"
|
||||
|
|
|
@ -16,6 +16,7 @@ subdir-y += lg
|
|||
subdir-y += marvell
|
||||
subdir-y += mediatek
|
||||
subdir-y += nvidia
|
||||
subdir-y += qcom
|
||||
subdir-y += realtek
|
||||
subdir-y += renesas
|
||||
subdir-y += rockchip
|
||||
|
|
130
arch/arm64/configs/vendor/bengal-perf_defconfig
vendored
130
arch/arm64/configs/vendor/bengal-perf_defconfig
vendored
|
@ -1,15 +1,13 @@
|
|||
CONFIG_LOCALVERSION="-CartelProject"
|
||||
CONFIG_LOCALVERSION="-perf"
|
||||
# CONFIG_LOCALVERSION_AUTO is not set
|
||||
CONFIG_AUDIT=y
|
||||
# CONFIG_AUDITSYSCALL is not set
|
||||
CONFIG_BOEFFLA_WL_BLOCKER=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_IRQ_TIME_ACCOUNTING=y
|
||||
CONFIG_SCHED_WALT=y
|
||||
CONFIG_TASKSTATS=y
|
||||
CONFIG_TASK_DELAY_ACCT=y
|
||||
CONFIG_TASK_XACCT=y
|
||||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_PSI=y
|
||||
|
@ -19,7 +17,7 @@ CONFIG_RCU_FAST_NO_HZ=y
|
|||
CONFIG_RCU_NOCB_CPU=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_LOG_BUF_SHIFT=21
|
||||
CONFIG_IKHEADERS=y
|
||||
CONFIG_LOG_CPU_MAX_BUF_SHIFT=17
|
||||
CONFIG_MEMCG=y
|
||||
CONFIG_MEMCG_SWAP=y
|
||||
|
@ -37,11 +35,13 @@ CONFIG_BLK_DEV_INITRD=y
|
|||
# CONFIG_RD_BZIP2 is not set
|
||||
# CONFIG_RD_LZMA is not set
|
||||
# CONFIG_RD_XZ is not set
|
||||
# CONFIG_RD_LZO is not set
|
||||
# CONFIG_RD_LZ4 is not set
|
||||
# CONFIG_FHANDLE is not set
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_BPF_SYSCALL=y
|
||||
CONFIG_BPF_JIT_ALWAYS_ON=y
|
||||
CONFIG_EMBEDDED=y
|
||||
# CONFIG_SLUB_DEBUG is not set
|
||||
# CONFIG_COMPAT_BRK is not set
|
||||
CONFIG_SLAB_FREELIST_RANDOM=y
|
||||
CONFIG_SLAB_FREELIST_HARDENED=y
|
||||
|
@ -50,9 +50,9 @@ CONFIG_PROFILING=y
|
|||
CONFIG_HOTPLUG_SIZE_BITS=29
|
||||
CONFIG_ARCH_QCOM=y
|
||||
CONFIG_ARCH_BENGAL=y
|
||||
CONFIG_ARCH_SCUBA=y
|
||||
CONFIG_SCHED_MC=y
|
||||
CONFIG_NR_CPUS=8
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_SECCOMP=y
|
||||
# CONFIG_UNMAP_KERNEL_AT_EL0 is not set
|
||||
CONFIG_HARDEN_BRANCH_PREDICTOR=y
|
||||
|
@ -63,9 +63,6 @@ CONFIG_SETEND_EMULATION=y
|
|||
CONFIG_ARM64_SW_TTBR0_PAN=y
|
||||
# CONFIG_ARM64_VHE is not set
|
||||
CONFIG_RANDOMIZE_BASE=y
|
||||
CONFIG_CMDLINE="ramoops_memreserve=4M mitigations=off"
|
||||
CONFIG_BUILD_ARM64_UNCOMPRESSED_KERNEL=y
|
||||
CONFIG_BUILD_ARM64_DT_OVERLAY=y
|
||||
CONFIG_COMPAT=y
|
||||
CONFIG_PM_WAKELOCKS=y
|
||||
CONFIG_PM_WAKELOCKS_LIMIT=0
|
||||
|
@ -74,7 +71,6 @@ CONFIG_ENERGY_MODEL=y
|
|||
CONFIG_CPU_IDLE=y
|
||||
CONFIG_ARM_CPUIDLE=y
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_STAT=y
|
||||
CONFIG_CPU_FREQ_TIMES=y
|
||||
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
|
@ -83,6 +79,7 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
|
|||
CONFIG_CPU_BOOST=y
|
||||
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
|
||||
CONFIG_ARM_QCOM_CPUFREQ_HW=y
|
||||
CONFIG_MSM_TZ_LOG=y
|
||||
CONFIG_ARM64_CRYPTO=y
|
||||
CONFIG_CRYPTO_SHA1_ARM64_CE=y
|
||||
CONFIG_CRYPTO_SHA2_ARM64_CE=y
|
||||
|
@ -90,8 +87,7 @@ CONFIG_CRYPTO_GHASH_ARM64_CE=y
|
|||
CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
|
||||
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
|
||||
CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
|
||||
# CONFIG_STACKPROTECTOR is not set
|
||||
# CONFIG_VMAP_STACK is not set
|
||||
CONFIG_PANIC_ON_REFCOUNT_ERROR=y
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
|
@ -99,7 +95,6 @@ CONFIG_MODULE_SIG=y
|
|||
CONFIG_MODULE_SIG_FORCE=y
|
||||
CONFIG_MODULE_SIG_SHA512=y
|
||||
# CONFIG_BLK_DEV_BSG is not set
|
||||
CONFIG_BLK_WBT=y
|
||||
CONFIG_BLK_INLINE_ENCRYPTION=y
|
||||
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
|
@ -237,7 +232,6 @@ CONFIG_L2TP_V3=y
|
|||
CONFIG_L2TP_IP=y
|
||||
CONFIG_L2TP_ETH=y
|
||||
CONFIG_BRIDGE=y
|
||||
# CONFIG_BRIDGE_IGMP_SNOOPING is not set
|
||||
CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_HTB=y
|
||||
CONFIG_NET_SCH_PRIO=y
|
||||
|
@ -275,6 +269,7 @@ CONFIG_FW_LOADER_USER_HELPER=y
|
|||
CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
|
||||
# CONFIG_FW_CACHE is not set
|
||||
CONFIG_REGMAP_WCD_IRQ=y
|
||||
CONFIG_REGMAP_ALLOW_WRITE_DEBUGFS=y
|
||||
CONFIG_DMA_CMA=y
|
||||
CONFIG_ZRAM=y
|
||||
CONFIG_ZRAM_DEDUP=y
|
||||
|
@ -284,11 +279,7 @@ CONFIG_BLK_DEV_RAM=y
|
|||
CONFIG_BLK_DEV_RAM_SIZE=8192
|
||||
CONFIG_QSEECOM=y
|
||||
CONFIG_UID_SYS_STATS=y
|
||||
CONFIG_SIMTRAY_STATUS=y
|
||||
CONFIG_DPDT_STATUS=y
|
||||
CONFIG_FPR_FPC=y
|
||||
CONFIG_MI_FS=y
|
||||
CONFIG_HQ_SYSFS_SUPPORT=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_CHR_DEV_SG=y
|
||||
|
@ -346,10 +337,10 @@ CONFIG_INPUT_JOYSTICK=y
|
|||
CONFIG_JOYSTICK_XPAD=y
|
||||
CONFIG_JOYSTICK_XPAD_LEDS=y
|
||||
CONFIG_INPUT_TOUCHSCREEN=y
|
||||
CONFIG_TOUCHSCREEN_NT36672A=y
|
||||
CONFIG_VITURALSAR=y
|
||||
CONFIG_TOUCHSCREEN_FT8719=y
|
||||
CONFIG_TOUCHSCREEN_XIAOMI_TOUCHFEATURE=y
|
||||
# CONFIG_TOUCHSCREEN_SYNAPTICS_TCM_REFLASH is not set
|
||||
# CONFIG_TOUCHSCREEN_SYNAPTICS_TCM_RECOVERY is not set
|
||||
# CONFIG_TOUCHSCREEN_FTS is not set
|
||||
# CONFIG_TOUCHSCREEN_NT36XXX is not set
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_QPNP_POWER_ON=y
|
||||
CONFIG_INPUT_UINPUT=y
|
||||
|
@ -363,7 +354,7 @@ CONFIG_HW_RANDOM=y
|
|||
CONFIG_HW_RANDOM_MSM_LEGACY=y
|
||||
CONFIG_DIAG_CHAR=y
|
||||
CONFIG_MSM_ADSPRPC=y
|
||||
CONFIG_MSM_RDBG=y
|
||||
CONFIG_MSM_RDBG=m
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_QCOM_GENI=y
|
||||
CONFIG_SPI=y
|
||||
|
@ -372,6 +363,7 @@ CONFIG_SPI_SPIDEV=y
|
|||
CONFIG_SPMI=y
|
||||
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
|
||||
CONFIG_PINCTRL_BENGAL=y
|
||||
CONFIG_PINCTRL_SCUBA=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_POWER_RESET_QCOM=y
|
||||
CONFIG_POWER_RESET_XGENE=y
|
||||
|
@ -410,11 +402,6 @@ CONFIG_REGULATOR_QPNP_LCDB=y
|
|||
CONFIG_REGULATOR_RPM_SMD=y
|
||||
CONFIG_REGULATOR_STUB=y
|
||||
CONFIG_REGULATOR_PM8008=y
|
||||
CONFIG_RC_CORE=y
|
||||
CONFIG_LIRC=y
|
||||
CONFIG_RC_DECODERS=y
|
||||
CONFIG_IR_SPI=y
|
||||
CONFIG_RC_DEVICES=y
|
||||
CONFIG_MEDIA_SUPPORT=y
|
||||
CONFIG_MEDIA_CAMERA_SUPPORT=y
|
||||
CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
|
||||
|
@ -422,13 +409,12 @@ CONFIG_MEDIA_CONTROLLER=y
|
|||
CONFIG_VIDEO_V4L2_SUBDEV_API=y
|
||||
CONFIG_VIDEO_FIXED_MINOR_RANGES=y
|
||||
CONFIG_V4L_PLATFORM_DRIVERS=y
|
||||
CONFIG_DVB_MPQ=y
|
||||
CONFIG_DVB_MPQ_DEMUX=y
|
||||
CONFIG_DVB_MPQ=m
|
||||
CONFIG_DVB_MPQ_DEMUX=m
|
||||
CONFIG_DVB_MPQ_SW=y
|
||||
CONFIG_VIDEO_V4L2_VIDEOBUF2_CORE=y
|
||||
CONFIG_DRM=y
|
||||
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
||||
CONFIG_LCD_CLASS_DEVICE=y
|
||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||
CONFIG_LOGO=y
|
||||
# CONFIG_LOGO_LINUX_MONO is not set
|
||||
|
@ -495,7 +481,7 @@ CONFIG_LEDS_QTI_FLASH=y
|
|||
CONFIG_LEDS_PWM=y
|
||||
CONFIG_LEDS_QTI_TRI_LED=y
|
||||
CONFIG_LEDS_QPNP_FLASH_V2=y
|
||||
CONFIG_LEDS_QPNP_VIBRATOR_LDO=y
|
||||
# CONFIG_LEDS_QPNP_VIBRATOR_LDO is not set
|
||||
CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_PM8XXX=y
|
||||
|
@ -507,7 +493,6 @@ CONFIG_STAGING=y
|
|||
CONFIG_ASHMEM=y
|
||||
CONFIG_ION=y
|
||||
CONFIG_ION_POOL_AUTO_REFILL=y
|
||||
CONFIG_QCA_CLD_WLAN=y
|
||||
CONFIG_QPNP_REVID=y
|
||||
CONFIG_SPS=y
|
||||
CONFIG_SPS_SUPPORT_NDP_BAM=y
|
||||
|
@ -515,14 +500,17 @@ CONFIG_IPA3=y
|
|||
CONFIG_IPA_WDI_UNIFIED_API=y
|
||||
CONFIG_RMNET_IPA3=y
|
||||
CONFIG_RNDIS_IPA=y
|
||||
CONFIG_IPA_UT=y
|
||||
CONFIG_USB_BAM=y
|
||||
CONFIG_QCOM_GENI_SE=y
|
||||
CONFIG_MACH_XIAOMI_LIME=y
|
||||
CONFIG_QCOM_CLK_SMD_RPM=y
|
||||
CONFIG_SPMI_PMIC_CLKDIV=y
|
||||
CONFIG_SM_GPUCC_BENGAL=y
|
||||
CONFIG_SM_DISPCC_BENGAL=y
|
||||
CONFIG_SM_DEBUGCC_BENGAL=y
|
||||
CONFIG_QM_DISPCC_SCUBA=y
|
||||
CONFIG_QM_GPUCC_SCUBA=y
|
||||
CONFIG_QM_DEBUGCC_SCUBA=y
|
||||
CONFIG_HWSPINLOCK=y
|
||||
CONFIG_HWSPINLOCK_QCOM=y
|
||||
CONFIG_MAILBOX=y
|
||||
|
@ -530,6 +518,8 @@ CONFIG_QCOM_APCS_IPC=y
|
|||
CONFIG_IOMMU_IO_PGTABLE_FAST=y
|
||||
CONFIG_ARM_SMMU=y
|
||||
CONFIG_QCOM_LAZY_MAPPING=y
|
||||
CONFIG_IOMMU_DEBUG=y
|
||||
CONFIG_IOMMU_TESTS=y
|
||||
CONFIG_RPMSG_CHAR=y
|
||||
CONFIG_RPMSG_QCOM_GLINK_RPM=y
|
||||
CONFIG_RPMSG_QCOM_GLINK_SMEM=y
|
||||
|
@ -571,16 +561,15 @@ CONFIG_QCOM_GLINK_PKT=y
|
|||
CONFIG_QCOM_SMP2P_SLEEPSTATE=y
|
||||
CONFIG_MSM_CDSP_LOADER=y
|
||||
CONFIG_QCOM_SMCINVOKE=y
|
||||
CONFIG_SERIAL_NUM=y
|
||||
CONFIG_MSM_EVENT_TIMER=y
|
||||
CONFIG_MSM_PM=y
|
||||
CONFIG_QTI_L2_REUSE=y
|
||||
CONFIG_QTI_RPM_STATS_LOG=y
|
||||
CONFIG_QTEE_SHM_BRIDGE=y
|
||||
CONFIG_MEM_SHARE_QMI_SERVICE=y
|
||||
# CONFIG_MSM_PERFORMANCE is not set
|
||||
CONFIG_MSM_PERFORMANCE=y
|
||||
CONFIG_QCOM_CDSP_RM=y
|
||||
# CONFIG_QCOM_QHEE_ENABLE_MEM_PROTECTION is not set
|
||||
CONFIG_QCOM_QHEE_ENABLE_MEM_PROTECTION=y
|
||||
CONFIG_QCOM_CX_IPEAK=y
|
||||
CONFIG_QTI_CRYPTO_COMMON=y
|
||||
CONFIG_QTI_CRYPTO_TZ=y
|
||||
|
@ -610,9 +599,7 @@ CONFIG_ANDROID_BINDERFS=y
|
|||
# CONFIG_NVMEM_SYSFS is not set
|
||||
CONFIG_QCOM_QFPROM=y
|
||||
CONFIG_NVMEM_SPMI_SDAM=y
|
||||
CONFIG_STM=y
|
||||
CONFIG_SLIMBUS_MSM_NGD=y
|
||||
CONFIG_SWITCH=y
|
||||
CONFIG_QCOM_KGSL=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
|
@ -631,19 +618,10 @@ CONFIG_OVERLAY_FS=y
|
|||
CONFIG_INCREMENTAL_FS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_EXFAT_FS=y
|
||||
CONFIG_EXFAT_DEFAULT_CODEPAGE=437
|
||||
CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8"
|
||||
CONFIG_NTFS_FS=y
|
||||
CONFIG_NTFS_RW=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_EFIVAR_FS=y
|
||||
CONFIG_SDCARD_FS=y
|
||||
CONFIG_PSTORE=y
|
||||
CONFIG_PSTORE_CONSOLE=y
|
||||
CONFIG_PSTORE_PMSG=y
|
||||
CONFIG_PSTORE_RAM=y
|
||||
# CONFIG_NETWORK_FILESYSTEMS is not set
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
|
@ -658,37 +636,39 @@ CONFIG_SECURITY_SELINUX=y
|
|||
CONFIG_SECURITY_SMACK=y
|
||||
CONFIG_CRYPTO_GCM=y
|
||||
CONFIG_CRYPTO_XCBC=y
|
||||
CONFIG_CRYPTO_MD4=y
|
||||
CONFIG_CRYPTO_TWOFISH=y
|
||||
CONFIG_CRYPTO_ANSI_CPRNG=y
|
||||
CONFIG_CRYPTO_DEV_QCE=y
|
||||
CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
|
||||
CONFIG_CRYPTO_DEV_QCRYPTO=y
|
||||
CONFIG_CRYPTO_DEV_QCEDEV=y
|
||||
CONFIG_STRIP_ASM_SYMS=y
|
||||
CONFIG_STACK_HASH_ORDER_SHIFT=12
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_PAGE_OWNER=y
|
||||
# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_PANIC_TIMEOUT=5
|
||||
CONFIG_STACKTRACE=y
|
||||
# CONFIG_RUNTIME_TESTING_MENU is not set
|
||||
# CONFIG_ARM64_ERRATUM_826319 is not set
|
||||
# CONFIG_ARM64_ERRATUM_827319 is not set
|
||||
# CONFIG_ARM64_ERRATUM_824069 is not set
|
||||
# CONFIG_ARM64_ERRATUM_819472 is not set
|
||||
# CONFIG_ARM64_ERRATUM_832075 is not set
|
||||
# CONFIG_ARM64_ERRATUM_845719 is not set
|
||||
# CONFIG_ARM64_ERRATUM_843419 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1024718 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1463225 is not set
|
||||
# CONFIG_ARM64_ERRATUM_1542418 is not set
|
||||
# CONFIG_CAVIUM_ERRATUM_22375 is not set
|
||||
# CONFIG_CAVIUM_ERRATUM_23154 is not set
|
||||
# CONFIG_CAVIUM_ERRATUM_27456 is not set
|
||||
# CONFIG_CAVIUM_ERRATUM_30115 is not set
|
||||
# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set
|
||||
# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set
|
||||
# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set
|
||||
# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set
|
||||
# CONFIG_HISILICON_ERRATUM_161600802 is not set
|
||||
# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set
|
||||
# CONFIG_FSL_ERRATUM_A008585 is not set
|
||||
# CONFIG_HISILICON_ERRATUM_161010101 is not set
|
||||
# CONFIG_ARM64_ERRATUM_858921 is not set
|
||||
CONFIG_SCHEDSTATS=y
|
||||
# CONFIG_DEBUG_PREEMPT is not set
|
||||
CONFIG_DEBUG_LIST=y
|
||||
CONFIG_IPC_LOGGING=y
|
||||
CONFIG_CORESIGHT=y
|
||||
CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
|
||||
CONFIG_CORESIGHT_DYNAMIC_REPLICATOR=y
|
||||
CONFIG_CORESIGHT_STM=y
|
||||
CONFIG_CORESIGHT_CTI=y
|
||||
CONFIG_CORESIGHT_CTI_SAVE_DISABLE=y
|
||||
CONFIG_CORESIGHT_TPDA=y
|
||||
CONFIG_CORESIGHT_TPDM=y
|
||||
CONFIG_CORESIGHT_HWEVENT=y
|
||||
CONFIG_CORESIGHT_DUMMY=y
|
||||
CONFIG_CORESIGHT_REMOTE_ETM=y
|
||||
CONFIG_CORESIGHT_TGU=y
|
||||
CONFIG_TOUCHSCREEN_GOODIX_GT1X=y
|
||||
CONFIG_KEYBOARD_AW9523B=y
|
||||
CONFIG_GPIO_PCA953X=y
|
||||
CONFIG_LEDS_GPIO=y
|
||||
# CONFIG_TOUCHSCREEN_ST is not set
|
||||
CONFIG_AW862XX_HAPTIC=y
|
||||
CONFIG_MICROARRAY_FINGERPRINT=y
|
||||
|
|
19
arch/arm64/configs/vendor/bengal_defconfig
vendored
19
arch/arm64/configs/vendor/bengal_defconfig
vendored
|
@ -54,7 +54,6 @@ CONFIG_ARCH_BENGAL=y
|
|||
CONFIG_ARCH_SCUBA=y
|
||||
CONFIG_SCHED_MC=y
|
||||
CONFIG_NR_CPUS=8
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_SECCOMP=y
|
||||
# CONFIG_UNMAP_KERNEL_AT_EL0 is not set
|
||||
CONFIG_HARDEN_BRANCH_PREDICTOR=y
|
||||
|
@ -349,10 +348,10 @@ CONFIG_INPUT_JOYSTICK=y
|
|||
CONFIG_JOYSTICK_XPAD=y
|
||||
CONFIG_JOYSTICK_XPAD_LEDS=y
|
||||
CONFIG_INPUT_TOUCHSCREEN=y
|
||||
CONFIG_TOUCHSCREEN_SYNAPTICS_TCM_REFLASH=y
|
||||
CONFIG_TOUCHSCREEN_SYNAPTICS_TCM_RECOVERY=y
|
||||
CONFIG_TOUCHSCREEN_FTS=y
|
||||
CONFIG_TOUCHSCREEN_NT36XXX=y
|
||||
# CONFIG_TOUCHSCREEN_SYNAPTICS_TCM_REFLASH is not set
|
||||
# CONFIG_TOUCHSCREEN_SYNAPTICS_TCM_RECOVERY is not set
|
||||
# CONFIG_TOUCHSCREEN_FTS is not set
|
||||
# CONFIG_TOUCHSCREEN_NT36XXX is not set
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_QPNP_POWER_ON=y
|
||||
CONFIG_INPUT_UINPUT=y
|
||||
|
@ -497,7 +496,7 @@ CONFIG_LEDS_QTI_FLASH=y
|
|||
CONFIG_LEDS_PWM=y
|
||||
CONFIG_LEDS_QTI_TRI_LED=y
|
||||
CONFIG_LEDS_QPNP_FLASH_V2=y
|
||||
CONFIG_LEDS_QPNP_VIBRATOR_LDO=y
|
||||
# CONFIG_LEDS_QPNP_VIBRATOR_LDO is not set
|
||||
CONFIG_LEDS_TRIGGER_TIMER=y
|
||||
CONFIG_EDAC=y
|
||||
CONFIG_EDAC_CORTEX_ARM64=y
|
||||
|
@ -740,3 +739,11 @@ CONFIG_CORESIGHT_HWEVENT=y
|
|||
CONFIG_CORESIGHT_DUMMY=y
|
||||
CONFIG_CORESIGHT_REMOTE_ETM=y
|
||||
CONFIG_CORESIGHT_TGU=y
|
||||
CONFIG_TOUCHSCREEN_GOODIX_GT1X=y
|
||||
CONFIG_KEYBOARD_AW9523B=y
|
||||
CONFIG_GPIO_PCA953X=y
|
||||
CONFIG_LEDS_GPIO=y
|
||||
# CONFIG_TOUCHSCREEN_ST is not set
|
||||
CONFIG_AW862XX_HAPTIC=y
|
||||
CONFIG_MICROARRAY_FINGERPRINT=y
|
||||
CONFIG_AW862xx_HAPTIC=y
|
||||
|
|
|
@ -306,6 +306,7 @@ CONFIG_SCSI_UFS_CRYPTO_QTI=y
|
|||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_DM=y
|
||||
CONFIG_DM_CRYPT=y
|
||||
CONFIG_DM_DEFAULT_KEY=y
|
||||
CONFIG_DM_SNAPSHOT=y
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_VERITY=y
|
||||
|
@ -377,6 +378,7 @@ CONFIG_SPI_QCOM_GENI=y
|
|||
CONFIG_SPI_SPIDEV=y
|
||||
CONFIG_SPMI=y
|
||||
CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y
|
||||
CONFIG_PINCTRL_SX150X=y
|
||||
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
|
||||
CONFIG_PINCTRL_KONA=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
|
@ -448,6 +450,7 @@ CONFIG_SND_DYNAMIC_MINORS=y
|
|||
CONFIG_SND_USB_AUDIO=y
|
||||
CONFIG_SND_USB_AUDIO_QMI=y
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_HIDRAW=y
|
||||
CONFIG_UHID=y
|
||||
CONFIG_HID_APPLE=y
|
||||
CONFIG_HID_ELECOM=y
|
||||
|
@ -530,8 +533,6 @@ CONFIG_STAGING=y
|
|||
CONFIG_ASHMEM=y
|
||||
CONFIG_ION=y
|
||||
CONFIG_ION_POOL_AUTO_REFILL=y
|
||||
CONFIG_QCA_CLD_WLAN=y
|
||||
CONFIG_QCA_CLD_WLAN_PROFILE="qca6390"
|
||||
CONFIG_QPNP_REVID=y
|
||||
CONFIG_SPS=y
|
||||
CONFIG_SPS_SUPPORT_NDP_BAM=y
|
||||
|
@ -645,6 +646,8 @@ CONFIG_DEVFREQ_GOV_STATICMAP=y
|
|||
CONFIG_EXTCON_USB_GPIO=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_QCOM_SPMI_ADC5=y
|
||||
CONFIG_CH101_I2C=y
|
||||
CONFIG_ADS7052_TDK_THERMISTOR=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PWM_QTI_LPG=y
|
||||
CONFIG_QCOM_PDC=y
|
||||
|
|
5
arch/arm64/configs/vendor/kona_defconfig
vendored
5
arch/arm64/configs/vendor/kona_defconfig
vendored
|
@ -321,6 +321,7 @@ CONFIG_SCSI_UFS_CRYPTO_QTI=y
|
|||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_DM=y
|
||||
CONFIG_DM_CRYPT=y
|
||||
CONFIG_DM_DEFAULT_KEY=y
|
||||
CONFIG_DM_SNAPSHOT=y
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_VERITY=y
|
||||
|
@ -395,6 +396,7 @@ CONFIG_SPI_QCOM_GENI=y
|
|||
CONFIG_SPI_SPIDEV=y
|
||||
CONFIG_SPMI=y
|
||||
CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y
|
||||
CONFIG_PINCTRL_SX150X=y
|
||||
CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
|
||||
CONFIG_PINCTRL_KONA=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
|
@ -467,6 +469,7 @@ CONFIG_SND_DYNAMIC_MINORS=y
|
|||
CONFIG_SND_USB_AUDIO=y
|
||||
CONFIG_SND_USB_AUDIO_QMI=y
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_HIDRAW=y
|
||||
CONFIG_UHID=y
|
||||
CONFIG_HID_APPLE=y
|
||||
CONFIG_HID_ELECOM=y
|
||||
|
@ -675,6 +678,8 @@ CONFIG_DEVFREQ_GOV_STATICMAP=y
|
|||
CONFIG_EXTCON_USB_GPIO=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_QCOM_SPMI_ADC5=y
|
||||
CONFIG_CH101_I2C=y
|
||||
CONFIG_ADS7052_TDK_THERMISTOR=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PWM_QTI_LPG=y
|
||||
CONFIG_QCOM_PDC=y
|
||||
|
|
|
@ -21,37 +21,13 @@
|
|||
#define __ASM_ATOMIC_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/stringify.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/brk-imm.h>
|
||||
#include <asm/lse.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/*
|
||||
* To avoid having to allocate registers that pass the counter address and
|
||||
* address of the call site to the overflow handler, encode the register and
|
||||
* call site offset in a dummy cbz instruction that we can decode later.
|
||||
*/
|
||||
#define REFCOUNT_CHECK_TAIL \
|
||||
" .subsection 1\n" \
|
||||
"33: brk " __stringify(REFCOUNT_BRK_IMM) "\n" \
|
||||
" cbz %[counter], 22b\n" /* never reached */ \
|
||||
" .previous\n"
|
||||
|
||||
#define REFCOUNT_POST_CHECK_NEG \
|
||||
"22: b.mi 33f\n" \
|
||||
REFCOUNT_CHECK_TAIL
|
||||
|
||||
#define REFCOUNT_POST_CHECK_NEG_OR_ZERO \
|
||||
" b.eq 33f\n" \
|
||||
REFCOUNT_POST_CHECK_NEG
|
||||
|
||||
#define REFCOUNT_PRE_CHECK_ZERO(reg) "ccmp " #reg ", wzr, #8, pl\n"
|
||||
#define REFCOUNT_PRE_CHECK_NONE(reg)
|
||||
|
||||
#define __ARM64_IN_ATOMIC_IMPL
|
||||
|
||||
#if defined(CONFIG_ARM64_LSE_ATOMICS) && defined(CONFIG_AS_LSE)
|
||||
|
|
|
@ -327,54 +327,4 @@ __CMPXCHG_DBL(_mb, dmb ish, l, "memory")
|
|||
|
||||
#undef __CMPXCHG_DBL
|
||||
|
||||
#define REFCOUNT_OP(op, asm_op, pre, post, l) \
|
||||
__LL_SC_INLINE int \
|
||||
__LL_SC_PREFIX(__refcount_##op(int i, atomic_t *r)) \
|
||||
{ \
|
||||
unsigned int tmp; \
|
||||
int result; \
|
||||
\
|
||||
asm volatile("// refcount_" #op "\n" \
|
||||
" prfm pstl1strm, %[cval]\n" \
|
||||
"1: ldxr %w1, %[cval]\n" \
|
||||
" " #asm_op " %w[val], %w1, %w[i]\n" \
|
||||
REFCOUNT_PRE_CHECK_ ## pre (%w1) \
|
||||
" st" #l "xr %w1, %w[val], %[cval]\n" \
|
||||
" cbnz %w1, 1b\n" \
|
||||
REFCOUNT_POST_CHECK_ ## post \
|
||||
: [val] "=&r"(result), "=&r"(tmp), [cval] "+Q"(r->counter) \
|
||||
: [counter] "r"(&r->counter), [i] "Ir" (i) \
|
||||
: "cc"); \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
__LL_SC_EXPORT(__refcount_##op);
|
||||
|
||||
REFCOUNT_OP(add_lt, adds, ZERO, NEG_OR_ZERO, );
|
||||
REFCOUNT_OP(sub_lt, subs, NONE, NEG, l);
|
||||
REFCOUNT_OP(sub_le, subs, NONE, NEG_OR_ZERO, l);
|
||||
|
||||
__LL_SC_INLINE int
|
||||
__LL_SC_PREFIX(__refcount_add_not_zero(int i, atomic_t *r))
|
||||
{
|
||||
unsigned int tmp;
|
||||
int result;
|
||||
|
||||
asm volatile("// refcount_add_not_zero\n"
|
||||
" prfm pstl1strm, %[cval]\n"
|
||||
"1: ldxr %w[val], %[cval]\n"
|
||||
" cbz %w[val], 2f\n"
|
||||
" adds %w[val], %w[val], %w[i]\n"
|
||||
" stxr %w1, %w[val], %[cval]\n"
|
||||
" cbnz %w1, 1b\n"
|
||||
REFCOUNT_POST_CHECK_NEG
|
||||
"2:"
|
||||
: [val] "=&r" (result), "=&r" (tmp), [cval] "+Q" (r->counter)
|
||||
: [counter] "r"(&r->counter), [i] "Ir" (i)
|
||||
: "cc");
|
||||
|
||||
return result;
|
||||
}
|
||||
__LL_SC_EXPORT(__refcount_add_not_zero);
|
||||
|
||||
#endif /* __ASM_ATOMIC_LL_SC_H */
|
||||
|
|
|
@ -32,12 +32,7 @@ static inline void atomic_##op(int i, atomic_t *v) \
|
|||
register int w0 asm ("w0") = i; \
|
||||
register atomic_t *x1 asm ("x1") = v; \
|
||||
\
|
||||
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
||||
/* LL/SC */ \
|
||||
__LL_SC_ATOMIC(op) \
|
||||
__nops(1), \
|
||||
/* LSE atomics */ \
|
||||
" prfm pstl1strm, %[v]\n" \
|
||||
asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(op), \
|
||||
" " #asm_op " %w[i], %[v]\n") \
|
||||
: [i] "+r" (w0), [v] "+Q" (v->counter) \
|
||||
: "r" (x1) \
|
||||
|
@ -59,10 +54,8 @@ static inline int atomic_fetch_##op##name(int i, atomic_t *v) \
|
|||
\
|
||||
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
||||
/* LL/SC */ \
|
||||
__LL_SC_ATOMIC(fetch_##op##name) \
|
||||
__nops(1), \
|
||||
__LL_SC_ATOMIC(fetch_##op##name), \
|
||||
/* LSE atomics */ \
|
||||
" prfm pstl1strm, %[v]\n" \
|
||||
" " #asm_op #mb " %w[i], %w[i], %[v]") \
|
||||
: [i] "+r" (w0), [v] "+Q" (v->counter) \
|
||||
: "r" (x1) \
|
||||
|
@ -94,9 +87,8 @@ static inline int atomic_add_return##name(int i, atomic_t *v) \
|
|||
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
||||
/* LL/SC */ \
|
||||
__LL_SC_ATOMIC(add_return##name) \
|
||||
__nops(2), \
|
||||
__nops(1), \
|
||||
/* LSE atomics */ \
|
||||
" prfm pstl1strm, %[v]\n" \
|
||||
" ldadd" #mb " %w[i], w30, %[v]\n" \
|
||||
" add %w[i], %w[i], w30") \
|
||||
: [i] "+r" (w0), [v] "+Q" (v->counter) \
|
||||
|
@ -121,9 +113,8 @@ static inline void atomic_and(int i, atomic_t *v)
|
|||
asm volatile(ARM64_LSE_ATOMIC_INSN(
|
||||
/* LL/SC */
|
||||
__LL_SC_ATOMIC(and)
|
||||
__nops(2),
|
||||
__nops(1),
|
||||
/* LSE atomics */
|
||||
" prfm pstl1strm, %[v]\n"
|
||||
" mvn %w[i], %w[i]\n"
|
||||
" stclr %w[i], %[v]")
|
||||
: [i] "+&r" (w0), [v] "+Q" (v->counter)
|
||||
|
@ -140,9 +131,8 @@ static inline int atomic_fetch_and##name(int i, atomic_t *v) \
|
|||
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
||||
/* LL/SC */ \
|
||||
__LL_SC_ATOMIC(fetch_and##name) \
|
||||
__nops(2), \
|
||||
__nops(1), \
|
||||
/* LSE atomics */ \
|
||||
" prfm pstl1strm, %[v]\n" \
|
||||
" mvn %w[i], %w[i]\n" \
|
||||
" ldclr" #mb " %w[i], %w[i], %[v]") \
|
||||
: [i] "+&r" (w0), [v] "+Q" (v->counter) \
|
||||
|
@ -167,9 +157,8 @@ static inline void atomic_sub(int i, atomic_t *v)
|
|||
asm volatile(ARM64_LSE_ATOMIC_INSN(
|
||||
/* LL/SC */
|
||||
__LL_SC_ATOMIC(sub)
|
||||
__nops(2),
|
||||
__nops(1),
|
||||
/* LSE atomics */
|
||||
" prfm pstl1strm, %[v]\n"
|
||||
" neg %w[i], %w[i]\n"
|
||||
" stadd %w[i], %[v]")
|
||||
: [i] "+&r" (w0), [v] "+Q" (v->counter)
|
||||
|
@ -186,9 +175,8 @@ static inline int atomic_sub_return##name(int i, atomic_t *v) \
|
|||
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
||||
/* LL/SC */ \
|
||||
__LL_SC_ATOMIC(sub_return##name) \
|
||||
__nops(3), \
|
||||
__nops(2), \
|
||||
/* LSE atomics */ \
|
||||
" prfm pstl1strm, %[v]\n" \
|
||||
" neg %w[i], %w[i]\n" \
|
||||
" ldadd" #mb " %w[i], w30, %[v]\n" \
|
||||
" add %w[i], %w[i], w30") \
|
||||
|
@ -215,9 +203,8 @@ static inline int atomic_fetch_sub##name(int i, atomic_t *v) \
|
|||
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
||||
/* LL/SC */ \
|
||||
__LL_SC_ATOMIC(fetch_sub##name) \
|
||||
__nops(2), \
|
||||
__nops(1), \
|
||||
/* LSE atomics */ \
|
||||
" prfm pstl1strm, %[v]\n" \
|
||||
" neg %w[i], %w[i]\n" \
|
||||
" ldadd" #mb " %w[i], %w[i], %[v]") \
|
||||
: [i] "+&r" (w0), [v] "+Q" (v->counter) \
|
||||
|
@ -242,12 +229,7 @@ static inline void atomic64_##op(long i, atomic64_t *v) \
|
|||
register long x0 asm ("x0") = i; \
|
||||
register atomic64_t *x1 asm ("x1") = v; \
|
||||
\
|
||||
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
||||
/* LL/SC */ \
|
||||
__LL_SC_ATOMIC64(op) \
|
||||
__nops(1), \
|
||||
/* LSE atomics */ \
|
||||
" prfm pstl1strm, %[v]\n" \
|
||||
asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC64(op), \
|
||||
" " #asm_op " %[i], %[v]\n") \
|
||||
: [i] "+r" (x0), [v] "+Q" (v->counter) \
|
||||
: "r" (x1) \
|
||||
|
@ -269,10 +251,8 @@ static inline long atomic64_fetch_##op##name(long i, atomic64_t *v) \
|
|||
\
|
||||
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
||||
/* LL/SC */ \
|
||||
__LL_SC_ATOMIC64(fetch_##op##name) \
|
||||
__nops(1), \
|
||||
__LL_SC_ATOMIC64(fetch_##op##name), \
|
||||
/* LSE atomics */ \
|
||||
" prfm pstl1strm, %[v]\n" \
|
||||
" " #asm_op #mb " %[i], %[i], %[v]") \
|
||||
: [i] "+r" (x0), [v] "+Q" (v->counter) \
|
||||
: "r" (x1) \
|
||||
|
@ -304,9 +284,8 @@ static inline long atomic64_add_return##name(long i, atomic64_t *v) \
|
|||
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
||||
/* LL/SC */ \
|
||||
__LL_SC_ATOMIC64(add_return##name) \
|
||||
__nops(2), \
|
||||
__nops(1), \
|
||||
/* LSE atomics */ \
|
||||
" prfm pstl1strm, %[v]\n" \
|
||||
" ldadd" #mb " %[i], x30, %[v]\n" \
|
||||
" add %[i], %[i], x30") \
|
||||
: [i] "+r" (x0), [v] "+Q" (v->counter) \
|
||||
|
@ -331,9 +310,8 @@ static inline void atomic64_and(long i, atomic64_t *v)
|
|||
asm volatile(ARM64_LSE_ATOMIC_INSN(
|
||||
/* LL/SC */
|
||||
__LL_SC_ATOMIC64(and)
|
||||
__nops(2),
|
||||
__nops(1),
|
||||
/* LSE atomics */
|
||||
" prfm pstl1strm, %[v]\n"
|
||||
" mvn %[i], %[i]\n"
|
||||
" stclr %[i], %[v]")
|
||||
: [i] "+&r" (x0), [v] "+Q" (v->counter)
|
||||
|
@ -350,9 +328,8 @@ static inline long atomic64_fetch_and##name(long i, atomic64_t *v) \
|
|||
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
||||
/* LL/SC */ \
|
||||
__LL_SC_ATOMIC64(fetch_and##name) \
|
||||
__nops(2), \
|
||||
__nops(1), \
|
||||
/* LSE atomics */ \
|
||||
" prfm pstl1strm, %[v]\n" \
|
||||
" mvn %[i], %[i]\n" \
|
||||
" ldclr" #mb " %[i], %[i], %[v]") \
|
||||
: [i] "+&r" (x0), [v] "+Q" (v->counter) \
|
||||
|
@ -377,9 +354,8 @@ static inline void atomic64_sub(long i, atomic64_t *v)
|
|||
asm volatile(ARM64_LSE_ATOMIC_INSN(
|
||||
/* LL/SC */
|
||||
__LL_SC_ATOMIC64(sub)
|
||||
__nops(2),
|
||||
__nops(1),
|
||||
/* LSE atomics */
|
||||
" prfm pstl1strm, %[v]\n"
|
||||
" neg %[i], %[i]\n"
|
||||
" stadd %[i], %[v]")
|
||||
: [i] "+&r" (x0), [v] "+Q" (v->counter)
|
||||
|
@ -396,9 +372,8 @@ static inline long atomic64_sub_return##name(long i, atomic64_t *v) \
|
|||
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
||||
/* LL/SC */ \
|
||||
__LL_SC_ATOMIC64(sub_return##name) \
|
||||
__nops(3), \
|
||||
__nops(2), \
|
||||
/* LSE atomics */ \
|
||||
" prfm pstl1strm, %[v]\n" \
|
||||
" neg %[i], %[i]\n" \
|
||||
" ldadd" #mb " %[i], x30, %[v]\n" \
|
||||
" add %[i], %[i], x30") \
|
||||
|
@ -425,9 +400,8 @@ static inline long atomic64_fetch_sub##name(long i, atomic64_t *v) \
|
|||
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
||||
/* LL/SC */ \
|
||||
__LL_SC_ATOMIC64(fetch_sub##name) \
|
||||
__nops(2), \
|
||||
__nops(1), \
|
||||
/* LSE atomics */ \
|
||||
" prfm pstl1strm, %[v]\n" \
|
||||
" neg %[i], %[i]\n" \
|
||||
" ldadd" #mb " %[i], %[i], %[v]") \
|
||||
: [i] "+&r" (x0), [v] "+Q" (v->counter) \
|
||||
|
@ -451,9 +425,8 @@ static inline long atomic64_dec_if_positive(atomic64_t *v)
|
|||
asm volatile(ARM64_LSE_ATOMIC_INSN(
|
||||
/* LL/SC */
|
||||
__LL_SC_ATOMIC64(dec_if_positive)
|
||||
__nops(7),
|
||||
__nops(6),
|
||||
/* LSE atomics */
|
||||
" prfm pstl1strm, %[v]\n"
|
||||
"1: ldr x30, %[v]\n"
|
||||
" subs %[ret], x30, #1\n"
|
||||
" b.lt 2f\n"
|
||||
|
@ -485,9 +458,8 @@ static inline unsigned long __cmpxchg_case_##name(volatile void *ptr, \
|
|||
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
||||
/* LL/SC */ \
|
||||
__LL_SC_CMPXCHG(name) \
|
||||
__nops(3), \
|
||||
__nops(2), \
|
||||
/* LSE atomics */ \
|
||||
" prfm pstl1strm, %[v]\n" \
|
||||
" mov " #w "30, %" #w "[old]\n" \
|
||||
" cas" #mb #sz "\t" #w "30, %" #w "[new], %[v]\n" \
|
||||
" mov %" #w "[ret], " #w "30") \
|
||||
|
@ -538,9 +510,8 @@ static inline long __cmpxchg_double##name(unsigned long old1, \
|
|||
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
||||
/* LL/SC */ \
|
||||
__LL_SC_CMPXCHG_DBL(name) \
|
||||
__nops(4), \
|
||||
__nops(3), \
|
||||
/* LSE atomics */ \
|
||||
" prfm pstl1strm, %[v]\n" \
|
||||
" casp" #mb "\t%[old1], %[old2], %[new1], %[new2], %[v]\n"\
|
||||
" eor %[old1], %[old1], %[oldval1]\n" \
|
||||
" eor %[old2], %[old2], %[oldval2]\n" \
|
||||
|
@ -560,88 +531,4 @@ __CMPXCHG_DBL(_mb, al, "memory")
|
|||
#undef __LL_SC_CMPXCHG_DBL
|
||||
#undef __CMPXCHG_DBL
|
||||
|
||||
#define REFCOUNT_ADD_OP(op, pre, post) \
|
||||
static inline int __refcount_##op(int i, atomic_t *r) \
|
||||
{ \
|
||||
register int w0 asm ("w0") = i; \
|
||||
register atomic_t *x1 asm ("x1") = r; \
|
||||
\
|
||||
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
||||
/* LL/SC */ \
|
||||
__LL_SC_CALL(__refcount_##op) \
|
||||
" cmp %w0, wzr\n" \
|
||||
__nops(2), \
|
||||
/* LSE atomics */ \
|
||||
" prfm pstl1strm, %[cval]\n" \
|
||||
" ldadd %w[i], w30, %[cval]\n" \
|
||||
" adds %w[i], %w[i], w30\n" \
|
||||
REFCOUNT_PRE_CHECK_ ## pre (w30)) \
|
||||
REFCOUNT_POST_CHECK_ ## post \
|
||||
: [i] "+r" (w0), [cval] "+Q" (r->counter) \
|
||||
: [counter] "r"(&r->counter), "r" (x1) \
|
||||
: __LL_SC_CLOBBERS, "cc"); \
|
||||
\
|
||||
return w0; \
|
||||
}
|
||||
|
||||
REFCOUNT_ADD_OP(add_lt, ZERO, NEG_OR_ZERO);
|
||||
|
||||
#define REFCOUNT_SUB_OP(op, post) \
|
||||
static inline int __refcount_##op(int i, atomic_t *r) \
|
||||
{ \
|
||||
register int w0 asm ("w0") = i; \
|
||||
register atomic_t *x1 asm ("x1") = r; \
|
||||
\
|
||||
asm volatile(ARM64_LSE_ATOMIC_INSN( \
|
||||
/* LL/SC */ \
|
||||
__LL_SC_CALL(__refcount_##op) \
|
||||
" cmp %w0, wzr\n" \
|
||||
__nops(2), \
|
||||
/* LSE atomics */ \
|
||||
" prfm pstl1strm, %[cval]\n" \
|
||||
" neg %w[i], %w[i]\n" \
|
||||
" ldaddl %w[i], w30, %[cval]\n" \
|
||||
" adds %w[i], %w[i], w30\n") \
|
||||
REFCOUNT_POST_CHECK_ ## post \
|
||||
: [i] "+r" (w0), [cval] "+Q" (r->counter) \
|
||||
: [counter] "r" (&r->counter), "r" (x1) \
|
||||
: __LL_SC_CLOBBERS, "cc"); \
|
||||
\
|
||||
return w0; \
|
||||
}
|
||||
|
||||
REFCOUNT_SUB_OP(sub_lt, NEG);
|
||||
REFCOUNT_SUB_OP(sub_le, NEG_OR_ZERO);
|
||||
|
||||
static inline int __refcount_add_not_zero(int i, atomic_t *r)
|
||||
{
|
||||
register int result asm ("w0");
|
||||
register atomic_t *x1 asm ("x1") = r;
|
||||
|
||||
asm volatile(ARM64_LSE_ATOMIC_INSN(
|
||||
/* LL/SC */
|
||||
" mov %w0, %w[i]\n"
|
||||
__LL_SC_CALL(__refcount_add_not_zero)
|
||||
" cmp %w0, wzr\n"
|
||||
__nops(7),
|
||||
/* LSE atomics */
|
||||
" prfm pstl1strm, %[cval]\n"
|
||||
" ldr %w0, %[cval]\n"
|
||||
"1: cmp %w0, wzr\n"
|
||||
" b.eq 2f\n"
|
||||
" add w30, %w0, %w[i]\n"
|
||||
" cas %w0, w30, %[cval]\n"
|
||||
" sub w30, w30, %w[i]\n"
|
||||
" cmp %w0, w30\n"
|
||||
" b.ne 1b\n"
|
||||
" adds %w0, w30, %w[i]\n"
|
||||
"2:\n")
|
||||
REFCOUNT_POST_CHECK_NEG
|
||||
: "=&r" (result), [cval] "+Q" (r->counter)
|
||||
: [counter] "r" (&r->counter), [i] "Ir" (i), "r" (x1)
|
||||
: __LL_SC_CLOBBERS, "cc");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* __ASM_ATOMIC_LSE_H */
|
||||
|
|
|
@ -19,11 +19,9 @@
|
|||
* 0x9xx: tag-based KASAN trap (allowed values 0x900 - 0x9ff)
|
||||
*/
|
||||
#define FAULT_BRK_IMM 0x100
|
||||
#define REFCOUNT_BRK_IMM 0x101
|
||||
#define KGDB_DYN_DBG_BRK_IMM 0x400
|
||||
#define KGDB_COMPILED_DBG_BRK_IMM 0x401
|
||||
#define BUG_BRK_IMM 0x800
|
||||
#define KASAN_BRK_IMM 0x900
|
||||
#define KASAN_BRK_MASK 0x0ff
|
||||
|
||||
#endif
|
||||
|
|
|
@ -95,24 +95,18 @@ struct step_hook {
|
|||
int (*fn)(struct pt_regs *regs, unsigned int esr);
|
||||
};
|
||||
|
||||
void register_user_step_hook(struct step_hook *hook);
|
||||
void unregister_user_step_hook(struct step_hook *hook);
|
||||
|
||||
void register_kernel_step_hook(struct step_hook *hook);
|
||||
void unregister_kernel_step_hook(struct step_hook *hook);
|
||||
void register_step_hook(struct step_hook *hook);
|
||||
void unregister_step_hook(struct step_hook *hook);
|
||||
|
||||
struct break_hook {
|
||||
struct list_head node;
|
||||
u32 esr_val;
|
||||
u32 esr_mask;
|
||||
int (*fn)(struct pt_regs *regs, unsigned int esr);
|
||||
u16 imm;
|
||||
u16 mask; /* These bits are ignored when comparing with imm */
|
||||
};
|
||||
|
||||
void register_user_break_hook(struct break_hook *hook);
|
||||
void unregister_user_break_hook(struct break_hook *hook);
|
||||
|
||||
void register_kernel_break_hook(struct break_hook *hook);
|
||||
void unregister_kernel_break_hook(struct break_hook *hook);
|
||||
void register_break_hook(struct break_hook *hook);
|
||||
void unregister_break_hook(struct break_hook *hook);
|
||||
|
||||
u8 debug_monitors_arch(void);
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@ arm64-obj-$(CONFIG_CPU_PM) += sleep.o suspend.o
|
|||
arm64-obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||
arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o
|
||||
arm64-obj-$(CONFIG_KGDB) += kgdb.o
|
||||
arm64-obj-$(CONFIG_BOOT_INFO) += bootinfo.o
|
||||
arm64-obj-$(CONFIG_EFI) += efi.o efi-entry.stub.o \
|
||||
efi-rt-wrapper.o
|
||||
arm64-obj-$(CONFIG_PCI) += pci.o
|
||||
|
|
|
@ -167,46 +167,25 @@ NOKPROBE_SYMBOL(clear_user_regs_spsr_ss);
|
|||
#define set_regs_spsr_ss(r) set_user_regs_spsr_ss(&(r)->user_regs)
|
||||
#define clear_regs_spsr_ss(r) clear_user_regs_spsr_ss(&(r)->user_regs)
|
||||
|
||||
static DEFINE_SPINLOCK(debug_hook_lock);
|
||||
static LIST_HEAD(user_step_hook);
|
||||
static LIST_HEAD(kernel_step_hook);
|
||||
/* EL1 Single Step Handler hooks */
|
||||
static LIST_HEAD(step_hook);
|
||||
static DEFINE_SPINLOCK(step_hook_lock);
|
||||
|
||||
static void register_debug_hook(struct list_head *node, struct list_head *list)
|
||||
void register_step_hook(struct step_hook *hook)
|
||||
{
|
||||
spin_lock(&debug_hook_lock);
|
||||
list_add_rcu(node, list);
|
||||
spin_unlock(&debug_hook_lock);
|
||||
|
||||
spin_lock(&step_hook_lock);
|
||||
list_add_rcu(&hook->node, &step_hook);
|
||||
spin_unlock(&step_hook_lock);
|
||||
}
|
||||
|
||||
static void unregister_debug_hook(struct list_head *node)
|
||||
void unregister_step_hook(struct step_hook *hook)
|
||||
{
|
||||
spin_lock(&debug_hook_lock);
|
||||
list_del_rcu(node);
|
||||
spin_unlock(&debug_hook_lock);
|
||||
spin_lock(&step_hook_lock);
|
||||
list_del_rcu(&hook->node);
|
||||
spin_unlock(&step_hook_lock);
|
||||
synchronize_rcu();
|
||||
}
|
||||
|
||||
void register_user_step_hook(struct step_hook *hook)
|
||||
{
|
||||
register_debug_hook(&hook->node, &user_step_hook);
|
||||
}
|
||||
|
||||
void unregister_user_step_hook(struct step_hook *hook)
|
||||
{
|
||||
unregister_debug_hook(&hook->node);
|
||||
}
|
||||
|
||||
void register_kernel_step_hook(struct step_hook *hook)
|
||||
{
|
||||
register_debug_hook(&hook->node, &kernel_step_hook);
|
||||
}
|
||||
|
||||
void unregister_kernel_step_hook(struct step_hook *hook)
|
||||
{
|
||||
unregister_debug_hook(&hook->node);
|
||||
}
|
||||
|
||||
/*
|
||||
* Call registered single step handlers
|
||||
* There is no Syndrome info to check for determining the handler.
|
||||
|
@ -216,14 +195,11 @@ void unregister_kernel_step_hook(struct step_hook *hook)
|
|||
static int call_step_hook(struct pt_regs *regs, unsigned int esr)
|
||||
{
|
||||
struct step_hook *hook;
|
||||
struct list_head *list;
|
||||
int retval = DBG_HOOK_ERROR;
|
||||
|
||||
list = user_mode(regs) ? &user_step_hook : &kernel_step_hook;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
list_for_each_entry_rcu(hook, list, node) {
|
||||
list_for_each_entry_rcu(hook, &step_hook, node) {
|
||||
retval = hook->fn(regs, esr);
|
||||
if (retval == DBG_HOOK_HANDLED)
|
||||
break;
|
||||
|
@ -302,44 +278,33 @@ NOKPROBE_SYMBOL(single_step_handler);
|
|||
* hit within breakpoint handler, especically in kprobes.
|
||||
* Use reader/writer locks instead of plain spinlock.
|
||||
*/
|
||||
static LIST_HEAD(user_break_hook);
|
||||
static LIST_HEAD(kernel_break_hook);
|
||||
static LIST_HEAD(break_hook);
|
||||
static DEFINE_SPINLOCK(break_hook_lock);
|
||||
|
||||
void register_user_break_hook(struct break_hook *hook)
|
||||
void register_break_hook(struct break_hook *hook)
|
||||
{
|
||||
register_debug_hook(&hook->node, &user_break_hook);
|
||||
spin_lock(&break_hook_lock);
|
||||
list_add_rcu(&hook->node, &break_hook);
|
||||
spin_unlock(&break_hook_lock);
|
||||
}
|
||||
|
||||
void unregister_user_break_hook(struct break_hook *hook)
|
||||
void unregister_break_hook(struct break_hook *hook)
|
||||
{
|
||||
unregister_debug_hook(&hook->node);
|
||||
}
|
||||
|
||||
void register_kernel_break_hook(struct break_hook *hook)
|
||||
{
|
||||
register_debug_hook(&hook->node, &kernel_break_hook);
|
||||
}
|
||||
|
||||
void unregister_kernel_break_hook(struct break_hook *hook)
|
||||
{
|
||||
unregister_debug_hook(&hook->node);
|
||||
spin_lock(&break_hook_lock);
|
||||
list_del_rcu(&hook->node);
|
||||
spin_unlock(&break_hook_lock);
|
||||
synchronize_rcu();
|
||||
}
|
||||
|
||||
static int call_break_hook(struct pt_regs *regs, unsigned int esr)
|
||||
{
|
||||
struct break_hook *hook;
|
||||
struct list_head *list;
|
||||
int (*fn)(struct pt_regs *regs, unsigned int esr) = NULL;
|
||||
|
||||
list = user_mode(regs) ? &user_break_hook : &kernel_break_hook;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(hook, list, node) {
|
||||
unsigned int comment = esr & BRK64_ESR_MASK;
|
||||
|
||||
if ((comment & ~hook->mask) == hook->imm)
|
||||
list_for_each_entry_rcu(hook, &break_hook, node)
|
||||
if ((esr & hook->esr_mask) == hook->esr_val)
|
||||
fn = hook->fn;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
return fn ? fn(regs, esr) : DBG_HOOK_ERROR;
|
||||
|
|
|
@ -275,13 +275,15 @@ static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr)
|
|||
NOKPROBE_SYMBOL(kgdb_step_brk_fn);
|
||||
|
||||
static struct break_hook kgdb_brkpt_hook = {
|
||||
.fn = kgdb_brk_fn,
|
||||
.imm = KGDB_DYN_DBG_BRK_IMM,
|
||||
.esr_mask = 0xffffffff,
|
||||
.esr_val = (u32)ESR_ELx_VAL_BRK64(KGDB_DYN_DBG_BRK_IMM),
|
||||
.fn = kgdb_brk_fn
|
||||
};
|
||||
|
||||
static struct break_hook kgdb_compiled_brkpt_hook = {
|
||||
.fn = kgdb_compiled_brk_fn,
|
||||
.imm = KGDB_COMPILED_DBG_BRK_IMM,
|
||||
.esr_mask = 0xffffffff,
|
||||
.esr_val = (u32)ESR_ELx_VAL_BRK64(KGDB_COMPILED_DBG_BRK_IMM),
|
||||
.fn = kgdb_compiled_brk_fn
|
||||
};
|
||||
|
||||
static struct step_hook kgdb_step_hook = {
|
||||
|
@ -342,9 +344,9 @@ int kgdb_arch_init(void)
|
|||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
register_kernel_break_hook(&kgdb_brkpt_hook);
|
||||
register_kernel_break_hook(&kgdb_compiled_brkpt_hook);
|
||||
register_kernel_step_hook(&kgdb_step_hook);
|
||||
register_break_hook(&kgdb_brkpt_hook);
|
||||
register_break_hook(&kgdb_compiled_brkpt_hook);
|
||||
register_step_hook(&kgdb_step_hook);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -355,9 +357,9 @@ int kgdb_arch_init(void)
|
|||
*/
|
||||
void kgdb_arch_exit(void)
|
||||
{
|
||||
unregister_kernel_break_hook(&kgdb_brkpt_hook);
|
||||
unregister_kernel_break_hook(&kgdb_compiled_brkpt_hook);
|
||||
unregister_kernel_step_hook(&kgdb_step_hook);
|
||||
unregister_break_hook(&kgdb_brkpt_hook);
|
||||
unregister_break_hook(&kgdb_compiled_brkpt_hook);
|
||||
unregister_step_hook(&kgdb_step_hook);
|
||||
unregister_die_notifier(&kgdb_notifier);
|
||||
}
|
||||
|
||||
|
|
|
@ -195,7 +195,8 @@ static int uprobe_single_step_handler(struct pt_regs *regs,
|
|||
|
||||
/* uprobe breakpoint handler hook */
|
||||
static struct break_hook uprobes_break_hook = {
|
||||
.imm = BRK64_ESR_UPROBES,
|
||||
.esr_mask = BRK64_ESR_MASK,
|
||||
.esr_val = BRK64_ESR_UPROBES,
|
||||
.fn = uprobe_breakpoint_handler,
|
||||
};
|
||||
|
||||
|
@ -206,8 +207,8 @@ static struct step_hook uprobes_step_hook = {
|
|||
|
||||
static int __init arch_init_uprobes(void)
|
||||
{
|
||||
register_user_break_hook(&uprobes_break_hook);
|
||||
register_user_step_hook(&uprobes_step_hook);
|
||||
register_break_hook(&uprobes_break_hook);
|
||||
register_step_hook(&uprobes_step_hook);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -975,8 +975,9 @@ static int bug_handler(struct pt_regs *regs, unsigned int esr)
|
|||
}
|
||||
|
||||
static struct break_hook bug_break_hook = {
|
||||
.esr_val = 0xf2000000 | BUG_BRK_IMM,
|
||||
.esr_mask = 0xffffffff,
|
||||
.fn = bug_handler,
|
||||
.imm = BUG_BRK_IMM,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_KASAN_SW_TAGS
|
||||
|
@ -1025,9 +1026,9 @@ static int kasan_handler(struct pt_regs *regs, unsigned int esr)
|
|||
#define KASAN_ESR_MASK 0xffffff00
|
||||
|
||||
static struct break_hook kasan_break_hook = {
|
||||
.esr_val = KASAN_ESR_VAL,
|
||||
.esr_mask = KASAN_ESR_MASK,
|
||||
.fn = kasan_handler,
|
||||
.imm = KASAN_BRK_IMM,
|
||||
.mask = KASAN_BRK_MASK,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -1045,48 +1046,11 @@ int __init early_brk64(unsigned long addr, unsigned int esr,
|
|||
return bug_handler(regs, esr) != DBG_HOOK_HANDLED;
|
||||
}
|
||||
|
||||
static int refcount_overflow_handler(struct pt_regs *regs, unsigned int esr)
|
||||
{
|
||||
u32 dummy_cbz = le32_to_cpup((__le32 *)(regs->pc + 4));
|
||||
bool zero = regs->pstate & PSR_Z_BIT;
|
||||
u32 rt;
|
||||
|
||||
/*
|
||||
* Find the register that holds the counter address from the
|
||||
* dummy 'cbz' instruction that follows the 'brk' instruction
|
||||
* that sent us here.
|
||||
*/
|
||||
rt = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RT, dummy_cbz);
|
||||
|
||||
/* First unconditionally saturate the refcount. */
|
||||
*(int *)regs->regs[rt] = INT_MIN / 2;
|
||||
|
||||
/*
|
||||
* This function has been called because either a negative refcount
|
||||
* value was seen by any of the refcount functions, or a zero
|
||||
* refcount value was seen by refcount_{add,dec}().
|
||||
*/
|
||||
|
||||
/* point pc to the branch instruction that detected the overflow */
|
||||
regs->pc += 4 + aarch64_get_branch_offset(dummy_cbz);
|
||||
refcount_error_report(regs, zero ? "hit zero" : "overflow");
|
||||
|
||||
/* advance pc and proceed */
|
||||
regs->pc += 4;
|
||||
return DBG_HOOK_HANDLED;
|
||||
}
|
||||
|
||||
static struct break_hook refcount_break_hook = {
|
||||
.fn = refcount_overflow_handler,
|
||||
.imm = REFCOUNT_BRK_IMM,
|
||||
};
|
||||
|
||||
/* This registration must happen early, before debug_traps_init(). */
|
||||
void __init trap_init(void)
|
||||
{
|
||||
register_kernel_break_hook(&bug_break_hook);
|
||||
register_break_hook(&bug_break_hook);
|
||||
#ifdef CONFIG_KASAN_SW_TAGS
|
||||
register_kernel_break_hook(&kasan_break_hook);
|
||||
register_break_hook(&kasan_break_hook);
|
||||
#endif
|
||||
register_kernel_break_hook(&refcount_break_hook);
|
||||
}
|
||||
|
|
|
@ -76,6 +76,10 @@ jiffies = jiffies_64;
|
|||
#define TRAMP_TEXT
|
||||
#endif
|
||||
|
||||
#define RTIC_BSS \
|
||||
. = ALIGN(PAGE_SIZE); \
|
||||
KEEP(*(.bss.rtic)); \
|
||||
. = ALIGN(PAGE_SIZE); \
|
||||
/*
|
||||
* The size of the PE/COFF section that covers the kernel image, which
|
||||
* runs from stext to _edata, must be a round multiple of the PE/COFF
|
||||
|
@ -256,6 +260,10 @@ SECTIONS
|
|||
STABS_DEBUG
|
||||
|
||||
HEAD_SYMBOLS
|
||||
|
||||
.bss : { /* bss segment */
|
||||
RTIC_BSS
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,15 +1,3 @@
|
|||
#include <asm/atomic.h>
|
||||
#define __ARM64_IN_ATOMIC_IMPL
|
||||
|
||||
/*
|
||||
* Disarm the refcount checks in the out-of-line LL/SC routines. These are
|
||||
* redundant, given that the LSE callers already perform the same checks.
|
||||
* We do have to make sure that we exit with a zero value if the pre-check
|
||||
* detected a zero value.
|
||||
*/
|
||||
#undef REFCOUNT_POST_CHECK_NEG
|
||||
#undef REFCOUNT_POST_CHECK_NEG_OR_ZERO
|
||||
#define REFCOUNT_POST_CHECK_NEG
|
||||
#define REFCOUNT_POST_CHECK_NEG_OR_ZERO "csel %w[val], wzr, %w[val], eq\n"
|
||||
|
||||
#include <asm/atomic_ll_sc.h>
|
||||
|
|
|
@ -51,7 +51,6 @@ C_h .req x12
|
|||
D_l .req x13
|
||||
D_h .req x14
|
||||
|
||||
prfm pldl1strm, [src, #(1*L1_CACHE_BYTES)]
|
||||
mov dst, dstin
|
||||
cmp count, #16
|
||||
/*When memory length is less than 16, the accessed are not aligned.*/
|
||||
|
@ -182,7 +181,6 @@ D_h .req x14
|
|||
ldp1 C_l, C_h, src, #16
|
||||
stp1 D_l, D_h, dst, #16
|
||||
ldp1 D_l, D_h, src, #16
|
||||
prfm pldl1strm, [src, #(4*L1_CACHE_BYTES)]
|
||||
subs count, count, #64
|
||||
b.ge 1b
|
||||
stp1 A_l, A_h, dst, #16
|
||||
|
|
|
@ -1,131 +1,258 @@
|
|||
/*
|
||||
* Copyright (c) 2017 ARM Ltd
|
||||
* All rights reserved.
|
||||
* Copyright (C) 2013 ARM Ltd.
|
||||
* Copyright (C) 2013 Linaro.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the company may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
* This code is based on glibc cortex strings work originally authored by Linaro
|
||||
* and re-licensed under GPLv2 for the Linux kernel. The original code can
|
||||
* be found @
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/
|
||||
* files/head:/src/aarch64/
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Assumptions:
|
||||
*
|
||||
* ARMv8-a, AArch64, unaligned accesses.
|
||||
*/
|
||||
|
||||
/* includes here */
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
/*
|
||||
* compare memory areas(when two memory areas' offset are different,
|
||||
* alignment handled by the hardware)
|
||||
*
|
||||
* Parameters:
|
||||
* x0 - const memory area 1 pointer
|
||||
* x1 - const memory area 2 pointer
|
||||
* x2 - the maximal compare byte length
|
||||
* Returns:
|
||||
* x0 - a compare result, maybe less than, equal to, or greater than ZERO
|
||||
*/
|
||||
|
||||
/* Parameters and result. */
|
||||
#define src1 x0
|
||||
#define src2 x1
|
||||
#define limit x2
|
||||
#define result w0
|
||||
src1 .req x0
|
||||
src2 .req x1
|
||||
limit .req x2
|
||||
result .req x0
|
||||
|
||||
/* Internal variables. */
|
||||
#define data1 x3
|
||||
#define data1w w3
|
||||
#define data2 x4
|
||||
#define data2w w4
|
||||
#define tmp1 x5
|
||||
data1 .req x3
|
||||
data1w .req w3
|
||||
data2 .req x4
|
||||
data2w .req w4
|
||||
has_nul .req x5
|
||||
diff .req x6
|
||||
endloop .req x7
|
||||
tmp1 .req x8
|
||||
tmp2 .req x9
|
||||
tmp3 .req x10
|
||||
pos .req x11
|
||||
limit_wd .req x12
|
||||
mask .req x13
|
||||
|
||||
/* Small inputs of less than 8 bytes are handled separately. This allows the
|
||||
main code to be sped up using unaligned loads since there are now at least
|
||||
8 bytes to be compared. If the first 8 bytes are equal, align src1.
|
||||
This ensures each iteration does at most one unaligned access even if both
|
||||
src1 and src2 are unaligned, and mutually aligned inputs behave as if
|
||||
aligned. After the main loop, process the last 8 bytes using unaligned
|
||||
accesses. */
|
||||
|
||||
.p2align 6
|
||||
WEAK(memcmp)
|
||||
subs limit, limit, 8
|
||||
b.lo .Lless8
|
||||
cbz limit, .Lret0
|
||||
eor tmp1, src1, src2
|
||||
tst tmp1, #7
|
||||
b.ne .Lmisaligned8
|
||||
ands tmp1, src1, #7
|
||||
b.ne .Lmutual_align
|
||||
sub limit_wd, limit, #1 /* limit != 0, so no underflow. */
|
||||
lsr limit_wd, limit_wd, #3 /* Convert to Dwords. */
|
||||
/*
|
||||
* The input source addresses are at alignment boundary.
|
||||
* Directly compare eight bytes each time.
|
||||
*/
|
||||
.Lloop_aligned:
|
||||
ldr data1, [src1], #8
|
||||
ldr data2, [src2], #8
|
||||
.Lstart_realigned:
|
||||
subs limit_wd, limit_wd, #1
|
||||
eor diff, data1, data2 /* Non-zero if differences found. */
|
||||
csinv endloop, diff, xzr, cs /* Last Dword or differences. */
|
||||
cbz endloop, .Lloop_aligned
|
||||
|
||||
/* Limit >= 8, so check first 8 bytes using unaligned loads. */
|
||||
ldr data1, [src1], 8
|
||||
ldr data2, [src2], 8
|
||||
and tmp1, src1, 7
|
||||
add limit, limit, tmp1
|
||||
cmp data1, data2
|
||||
bne .Lreturn
|
||||
/* Not reached the limit, must have found a diff. */
|
||||
tbz limit_wd, #63, .Lnot_limit
|
||||
|
||||
/* Align src1 and adjust src2 with bytes not yet done. */
|
||||
sub src1, src1, tmp1
|
||||
sub src2, src2, tmp1
|
||||
/* Limit % 8 == 0 => the diff is in the last 8 bytes. */
|
||||
ands limit, limit, #7
|
||||
b.eq .Lnot_limit
|
||||
/*
|
||||
* The remained bytes less than 8. It is needed to extract valid data
|
||||
* from last eight bytes of the intended memory range.
|
||||
*/
|
||||
lsl limit, limit, #3 /* bytes-> bits. */
|
||||
mov mask, #~0
|
||||
CPU_BE( lsr mask, mask, limit )
|
||||
CPU_LE( lsl mask, mask, limit )
|
||||
bic data1, data1, mask
|
||||
bic data2, data2, mask
|
||||
|
||||
subs limit, limit, 8
|
||||
b.ls .Llast_bytes
|
||||
orr diff, diff, mask
|
||||
b .Lnot_limit
|
||||
|
||||
/* Loop performing 8 bytes per iteration using aligned src1.
|
||||
Limit is pre-decremented by 8 and must be larger than zero.
|
||||
Exit if <= 8 bytes left to do or if the data is not equal. */
|
||||
.p2align 4
|
||||
.Lloop8:
|
||||
ldr data1, [src1], 8
|
||||
ldr data2, [src2], 8
|
||||
subs limit, limit, 8
|
||||
ccmp data1, data2, 0, hi /* NZCV = 0b0000. */
|
||||
b.eq .Lloop8
|
||||
.Lmutual_align:
|
||||
/*
|
||||
* Sources are mutually aligned, but are not currently at an
|
||||
* alignment boundary. Round down the addresses and then mask off
|
||||
* the bytes that precede the start point.
|
||||
*/
|
||||
bic src1, src1, #7
|
||||
bic src2, src2, #7
|
||||
ldr data1, [src1], #8
|
||||
ldr data2, [src2], #8
|
||||
/*
|
||||
* We can not add limit with alignment offset(tmp1) here. Since the
|
||||
* addition probably make the limit overflown.
|
||||
*/
|
||||
sub limit_wd, limit, #1/*limit != 0, so no underflow.*/
|
||||
and tmp3, limit_wd, #7
|
||||
lsr limit_wd, limit_wd, #3
|
||||
add tmp3, tmp3, tmp1
|
||||
add limit_wd, limit_wd, tmp3, lsr #3
|
||||
add limit, limit, tmp1/* Adjust the limit for the extra. */
|
||||
|
||||
cmp data1, data2
|
||||
bne .Lreturn
|
||||
lsl tmp1, tmp1, #3/* Bytes beyond alignment -> bits.*/
|
||||
neg tmp1, tmp1/* Bits to alignment -64. */
|
||||
mov tmp2, #~0
|
||||
/*mask off the non-intended bytes before the start address.*/
|
||||
CPU_BE( lsl tmp2, tmp2, tmp1 )/*Big-endian.Early bytes are at MSB*/
|
||||
/* Little-endian. Early bytes are at LSB. */
|
||||
CPU_LE( lsr tmp2, tmp2, tmp1 )
|
||||
|
||||
/* Compare last 1-8 bytes using unaligned access. */
|
||||
.Llast_bytes:
|
||||
ldr data1, [src1, limit]
|
||||
ldr data2, [src2, limit]
|
||||
orr data1, data1, tmp2
|
||||
orr data2, data2, tmp2
|
||||
b .Lstart_realigned
|
||||
|
||||
/* Compare data bytes and set return value to 0, -1 or 1. */
|
||||
.Lreturn:
|
||||
#ifndef __AARCH64EB__
|
||||
rev data1, data1
|
||||
rev data2, data2
|
||||
#endif
|
||||
cmp data1, data2
|
||||
.Lret_eq:
|
||||
cset result, ne
|
||||
cneg result, result, lo
|
||||
ret
|
||||
/*src1 and src2 have different alignment offset.*/
|
||||
.Lmisaligned8:
|
||||
cmp limit, #8
|
||||
b.lo .Ltiny8proc /*limit < 8: compare byte by byte*/
|
||||
|
||||
.p2align 4
|
||||
/* Compare up to 8 bytes. Limit is [-8..-1]. */
|
||||
.Lless8:
|
||||
adds limit, limit, 4
|
||||
b.lo .Lless4
|
||||
ldr data1w, [src1], 4
|
||||
ldr data2w, [src2], 4
|
||||
and tmp1, src1, #7
|
||||
neg tmp1, tmp1
|
||||
add tmp1, tmp1, #8/*valid length in the first 8 bytes of src1*/
|
||||
and tmp2, src2, #7
|
||||
neg tmp2, tmp2
|
||||
add tmp2, tmp2, #8/*valid length in the first 8 bytes of src2*/
|
||||
subs tmp3, tmp1, tmp2
|
||||
csel pos, tmp1, tmp2, hi /*Choose the maximum.*/
|
||||
|
||||
sub limit, limit, pos
|
||||
/*compare the proceeding bytes in the first 8 byte segment.*/
|
||||
.Ltinycmp:
|
||||
ldrb data1w, [src1], #1
|
||||
ldrb data2w, [src2], #1
|
||||
subs pos, pos, #1
|
||||
ccmp data1w, data2w, #0, ne /* NZCV = 0b0000. */
|
||||
b.eq .Ltinycmp
|
||||
cbnz pos, 1f /*diff occurred before the last byte.*/
|
||||
cmp data1w, data2w
|
||||
b.ne .Lreturn
|
||||
sub limit, limit, 4
|
||||
.Lless4:
|
||||
adds limit, limit, 4
|
||||
beq .Lret_eq
|
||||
.Lbyte_loop:
|
||||
ldrb data1w, [src1], 1
|
||||
ldrb data2w, [src2], 1
|
||||
subs limit, limit, 1
|
||||
ccmp data1w, data2w, 0, ne /* NZCV = 0b0000. */
|
||||
b.eq .Lbyte_loop
|
||||
sub result, data1w, data2w
|
||||
b.eq .Lstart_align
|
||||
1:
|
||||
sub result, data1, data2
|
||||
ret
|
||||
|
||||
.Lstart_align:
|
||||
lsr limit_wd, limit, #3
|
||||
cbz limit_wd, .Lremain8
|
||||
|
||||
ands xzr, src1, #7
|
||||
b.eq .Lrecal_offset
|
||||
/*process more leading bytes to make src1 aligned...*/
|
||||
add src1, src1, tmp3 /*backwards src1 to alignment boundary*/
|
||||
add src2, src2, tmp3
|
||||
sub limit, limit, tmp3
|
||||
lsr limit_wd, limit, #3
|
||||
cbz limit_wd, .Lremain8
|
||||
/*load 8 bytes from aligned SRC1..*/
|
||||
ldr data1, [src1], #8
|
||||
ldr data2, [src2], #8
|
||||
|
||||
subs limit_wd, limit_wd, #1
|
||||
eor diff, data1, data2 /*Non-zero if differences found.*/
|
||||
csinv endloop, diff, xzr, ne
|
||||
cbnz endloop, .Lunequal_proc
|
||||
/*How far is the current SRC2 from the alignment boundary...*/
|
||||
and tmp3, tmp3, #7
|
||||
|
||||
.Lrecal_offset:/*src1 is aligned now..*/
|
||||
neg pos, tmp3
|
||||
.Lloopcmp_proc:
|
||||
/*
|
||||
* Divide the eight bytes into two parts. First,backwards the src2
|
||||
* to an alignment boundary,load eight bytes and compare from
|
||||
* the SRC2 alignment boundary. If all 8 bytes are equal,then start
|
||||
* the second part's comparison. Otherwise finish the comparison.
|
||||
* This special handle can garantee all the accesses are in the
|
||||
* thread/task space in avoid to overrange access.
|
||||
*/
|
||||
ldr data1, [src1,pos]
|
||||
ldr data2, [src2,pos]
|
||||
eor diff, data1, data2 /* Non-zero if differences found. */
|
||||
cbnz diff, .Lnot_limit
|
||||
|
||||
/*The second part process*/
|
||||
ldr data1, [src1], #8
|
||||
ldr data2, [src2], #8
|
||||
eor diff, data1, data2 /* Non-zero if differences found. */
|
||||
subs limit_wd, limit_wd, #1
|
||||
csinv endloop, diff, xzr, ne/*if limit_wd is 0,will finish the cmp*/
|
||||
cbz endloop, .Lloopcmp_proc
|
||||
.Lunequal_proc:
|
||||
cbz diff, .Lremain8
|
||||
|
||||
/* There is difference occurred in the latest comparison. */
|
||||
.Lnot_limit:
|
||||
/*
|
||||
* For little endian,reverse the low significant equal bits into MSB,then
|
||||
* following CLZ can find how many equal bits exist.
|
||||
*/
|
||||
CPU_LE( rev diff, diff )
|
||||
CPU_LE( rev data1, data1 )
|
||||
CPU_LE( rev data2, data2 )
|
||||
|
||||
/*
|
||||
* The MS-non-zero bit of DIFF marks either the first bit
|
||||
* that is different, or the end of the significant data.
|
||||
* Shifting left now will bring the critical information into the
|
||||
* top bits.
|
||||
*/
|
||||
clz pos, diff
|
||||
lsl data1, data1, pos
|
||||
lsl data2, data2, pos
|
||||
/*
|
||||
* We need to zero-extend (char is unsigned) the value and then
|
||||
* perform a signed subtraction.
|
||||
*/
|
||||
lsr data1, data1, #56
|
||||
sub result, data1, data2, lsr #56
|
||||
ret
|
||||
|
||||
.Lremain8:
|
||||
/* Limit % 8 == 0 =>. all data are equal.*/
|
||||
ands limit, limit, #7
|
||||
b.eq .Lret0
|
||||
|
||||
.Ltiny8proc:
|
||||
ldrb data1w, [src1], #1
|
||||
ldrb data2w, [src2], #1
|
||||
subs limit, limit, #1
|
||||
|
||||
ccmp data1w, data2w, #0, ne /* NZCV = 0b0000. */
|
||||
b.eq .Ltiny8proc
|
||||
sub result, data1, data2
|
||||
ret
|
||||
.Lret0:
|
||||
mov result, #0
|
||||
ret
|
||||
ENDPIPROC(memcmp)
|
||||
|
|
|
@ -60,7 +60,6 @@ D_h .req x14
|
|||
.weak memmove
|
||||
ENTRY(__memmove)
|
||||
ENTRY(memmove)
|
||||
prfm pldl1strm, [src, #L1_CACHE_BYTES]
|
||||
cmp dstin, src
|
||||
b.lo __memcpy
|
||||
add tmp1, src, count
|
||||
|
@ -187,7 +186,6 @@ ENTRY(memmove)
|
|||
ldp C_l, C_h, [src, #-48]
|
||||
stp D_l, D_h, [dst, #-64]!
|
||||
ldp D_l, D_h, [src, #-64]!
|
||||
prfm pldl1strm, [src, #(4*L1_CACHE_BYTES)]
|
||||
subs count, count, #64
|
||||
b.ge 1b
|
||||
stp A_l, A_h, [dst, #-16]
|
||||
|
|
|
@ -508,10 +508,9 @@ void __init arm64_memblock_init(void)
|
|||
* Save bootloader imposed memory limit before we overwirte
|
||||
* memblock.
|
||||
*/
|
||||
if (memory_limit == PHYS_ADDR_MAX)
|
||||
bootloader_memory_limit = memblock_max_addr(memory_limit);
|
||||
if (bootloader_memory_limit > memblock_end_of_DRAM())
|
||||
bootloader_memory_limit = memblock_end_of_DRAM();
|
||||
else
|
||||
bootloader_memory_limit = memblock_max_addr(memory_limit);
|
||||
|
||||
update_memory_limit();
|
||||
|
||||
|
|
|
@ -11,8 +11,6 @@ obj-$(CONFIG_BLOCK) := bio.o elevator.o blk-core.o blk-tag.o blk-sysfs.o \
|
|||
genhd.o partition-generic.o ioprio.o \
|
||||
badblocks.o partitions/ blk-rq-qos.o
|
||||
|
||||
CFLAGS_blk-mq.o := $(call cc-disable-warning, align-mismatch)
|
||||
|
||||
obj-$(CONFIG_BOUNCE) += bounce.o
|
||||
obj-$(CONFIG_BLK_SCSI_REQUEST) += scsi_ioctl.o
|
||||
obj-$(CONFIG_BLK_DEV_BSG) += bsg.o
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* main.c - Multi purpose firmware loading support
|
||||
*
|
||||
* Copyright (c) 2003 Manuel Estrada Sainz
|
||||
* Copyright (C) 2020 XiaoMi, Inc.
|
||||
*
|
||||
* Please see Documentation/firmware_class/ for more information.
|
||||
*
|
||||
|
@ -284,12 +283,12 @@ static void free_fw_priv(struct fw_priv *fw_priv)
|
|||
static char fw_path_para[256];
|
||||
static const char * const fw_path[] = {
|
||||
fw_path_para,
|
||||
"/system/vendor/firmware",
|
||||
"/system/etc/firmware",
|
||||
"/lib/firmware/updates/" UTS_RELEASE,
|
||||
"/lib/firmware/updates",
|
||||
"/lib/firmware/" UTS_RELEASE,
|
||||
"/lib/firmware",
|
||||
"/system/vendor/firmware",
|
||||
"/vendor/firmware"
|
||||
"/lib/firmware"
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <linux/suspend.h>
|
||||
#include <trace/events/power.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/wakeup_reason.h>
|
||||
|
||||
|
@ -797,6 +798,7 @@ void dpm_noirq_end(void)
|
|||
{
|
||||
resume_device_irqs();
|
||||
device_wakeup_disarm_wake_irqs();
|
||||
cpuidle_resume();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1418,6 +1420,7 @@ static int device_suspend_noirq(struct device *dev)
|
|||
|
||||
void dpm_noirq_begin(void)
|
||||
{
|
||||
cpuidle_pause();
|
||||
device_wakeup_arm_wake_irqs();
|
||||
suspend_device_irqs();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -388,6 +388,7 @@ static int bt_configure_gpios(int on)
|
|||
if (rc) {
|
||||
BT_PWR_ERR("%s:bt_enable_bt_reset_gpios_safely failed",
|
||||
__func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
msleep(50);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef BTFM_SLIM_SLAVE_H
|
||||
|
@ -97,6 +97,9 @@ enum {
|
|||
QCA_COMANCHE_SOC_ID_0101 = 0x40070101,
|
||||
QCA_COMANCHE_SOC_ID_0110 = 0x40070110,
|
||||
QCA_COMANCHE_SOC_ID_0120 = 0x40070120,
|
||||
QCA_COMANCHE_SOC_ID_0130 = 0x40070130,
|
||||
QCA_COMANCHE_SOC_ID_5120 = 0x40075120,
|
||||
QCA_COMANCHE_SOC_ID_5130 = 0x40075130,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
|
@ -1511,6 +1511,15 @@ int mhi_pm_fast_resume(struct mhi_controller *mhi_cntrl, bool notify_client)
|
|||
}
|
||||
|
||||
if (mhi_cntrl->rddm_supported) {
|
||||
|
||||
/* check EP is in proper state */
|
||||
if (mhi_cntrl->link_status(mhi_cntrl, mhi_cntrl->priv_data)) {
|
||||
MHI_ERR("Unable to access EP Config space\n");
|
||||
write_unlock_irq(&mhi_cntrl->pm_lock);
|
||||
tasklet_enable(&mhi_cntrl->mhi_event->task);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
if (mhi_get_exec_env(mhi_cntrl) == MHI_EE_RDDM &&
|
||||
!mhi_cntrl->power_down) {
|
||||
mhi_cntrl->ee = MHI_EE_RDDM;
|
||||
|
|
|
@ -538,6 +538,27 @@ config DEVPORT
|
|||
|
||||
source "drivers/s390/char/Kconfig"
|
||||
|
||||
config MSM_SMD_PKT
|
||||
bool "Enable device interface for some SMD packet ports"
|
||||
default n
|
||||
depends on RPMSG_QCOM_SMD
|
||||
help
|
||||
smd_pkt driver provides the interface for the userspace clients
|
||||
to communicate over smd via device nodes. This enable the
|
||||
usersapce clients to read and write to some smd packets channel
|
||||
for MSM chipset.
|
||||
|
||||
config TILE_SROM
|
||||
tristate "Character-device access via hypervisor to the Tilera SPI ROM"
|
||||
depends on TILE
|
||||
default y
|
||||
help
|
||||
This device provides character-level read-write access
|
||||
to the SROM, typically via the "0", "1", and "2" devices
|
||||
in /dev/srom/. The Tilera hypervisor makes the flash
|
||||
device appear much like a simple EEPROM, and knows
|
||||
how to partition a single ROM for multiple purposes.
|
||||
|
||||
source "drivers/char/xillybus/Kconfig"
|
||||
source "drivers/char/diag/Kconfig"
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ obj-$(CONFIG_MSPEC) += mspec.o
|
|||
obj-$(CONFIG_UV_MMTIMER) += uv_mmtimer.o
|
||||
obj-$(CONFIG_IBM_BSR) += bsr.o
|
||||
obj-$(CONFIG_SGI_MBCS) += mbcs.o
|
||||
obj-$(CONFIG_BFIN_OTP) += bfin-otp.o
|
||||
obj-$(CONFIG_MSM_SMD_PKT) += msm_smd_pkt.o
|
||||
|
||||
obj-$(CONFIG_PRINTER) += lp.o
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <linux/completion.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/cdev.h>
|
||||
|
@ -23,7 +22,6 @@
|
|||
#include <soc/qcom/service-notifier.h>
|
||||
#include <soc/qcom/service-locator.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/of.h>
|
||||
|
@ -1698,7 +1696,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
|
|||
uintptr_t args;
|
||||
size_t rlen = 0, copylen = 0, metalen = 0, lrpralen = 0;
|
||||
int i, oix;
|
||||
int err = 0;
|
||||
int err = 0, j = 0;
|
||||
int mflags = 0;
|
||||
uint64_t *fdlist;
|
||||
uint32_t *crclist;
|
||||
|
@ -1743,6 +1741,8 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
|
|||
FASTRPC_ATTR_NOVA, 0, 0, dmaflags,
|
||||
&ctx->maps[i]);
|
||||
if (err) {
|
||||
for (j = bufs; j < i; j++)
|
||||
fastrpc_mmap_free(ctx->maps[j], 0);
|
||||
mutex_unlock(&ctx->fl->map_mutex);
|
||||
goto bail;
|
||||
}
|
||||
|
@ -2780,19 +2780,6 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
|
|||
return err;
|
||||
}
|
||||
|
||||
static int fastrpc_kstat(const char *filename, struct kstat *stat)
|
||||
{
|
||||
int result;
|
||||
mm_segment_t fs_old;
|
||||
|
||||
fs_old = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
result = vfs_stat((const char __user *)filename, stat);
|
||||
set_fs(fs_old);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int fastrpc_send_cpuinfo_to_dsp(struct fastrpc_file *fl)
|
||||
{
|
||||
int err = 0;
|
||||
|
@ -2835,33 +2822,29 @@ static int fastrpc_get_info_from_dsp(struct fastrpc_file *fl,
|
|||
int err = 0, dsp_support = 0;
|
||||
struct fastrpc_ioctl_invoke_crc ioctl;
|
||||
remote_arg_t ra[2];
|
||||
struct kstat sb;
|
||||
struct fastrpc_apps *me = &gfa;
|
||||
|
||||
// Querying device about DSP support
|
||||
switch (domain) {
|
||||
case ADSP_DOMAIN_ID:
|
||||
if (!fastrpc_kstat("/dev/subsys_adsp", &sb))
|
||||
case SDSP_DOMAIN_ID:
|
||||
case CDSP_DOMAIN_ID:
|
||||
if (me->channel[domain].issubsystemup)
|
||||
dsp_support = 1;
|
||||
break;
|
||||
case MDSP_DOMAIN_ID:
|
||||
//Modem not supported for fastRPC
|
||||
break;
|
||||
case SDSP_DOMAIN_ID:
|
||||
if (!fastrpc_kstat("/dev/subsys_slpi", &sb))
|
||||
dsp_support = 1;
|
||||
break;
|
||||
case CDSP_DOMAIN_ID:
|
||||
if (!fastrpc_kstat("/dev/subsys_cdsp", &sb))
|
||||
dsp_support = 1;
|
||||
break;
|
||||
default:
|
||||
dsp_support = 0;
|
||||
break;
|
||||
}
|
||||
dsp_attr_buf[0] = dsp_support;
|
||||
|
||||
if (dsp_support == 0)
|
||||
if (dsp_support == 0) {
|
||||
err = -ENOTCONN;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
err = fastrpc_channel_open(fl);
|
||||
if (err)
|
||||
|
@ -3315,8 +3298,13 @@ static int fastrpc_internal_munmap(struct fastrpc_file *fl,
|
|||
mutex_unlock(&fl->map_mutex);
|
||||
if (err)
|
||||
goto bail;
|
||||
VERIFY(err, map != NULL);
|
||||
if (err) {
|
||||
err = -EINVAL;
|
||||
goto bail;
|
||||
}
|
||||
VERIFY(err, !fastrpc_munmap_on_dsp(fl, map->raddr,
|
||||
map->phys, map->size, map->flags));
|
||||
map->phys, map->size, map->flags));
|
||||
if (err)
|
||||
goto bail;
|
||||
mutex_lock(&fl->map_mutex);
|
||||
|
@ -4737,6 +4725,8 @@ static const struct of_device_id fastrpc_match_table[] = {
|
|||
{ .compatible = "qcom,msm-fastrpc-adsp", },
|
||||
{ .compatible = "qcom,msm-fastrpc-compute", },
|
||||
{ .compatible = "qcom,msm-fastrpc-compute-cb", },
|
||||
{ .compatible = "qcom,msm-fastrpc-legacy-compute", },
|
||||
{ .compatible = "qcom,msm-fastrpc-legacy-compute-cb", },
|
||||
{ .compatible = "qcom,msm-adsprpc-mem-region", },
|
||||
{}
|
||||
};
|
||||
|
@ -4834,6 +4824,85 @@ static int fastrpc_cb_probe(struct device *dev)
|
|||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int fastrpc_cb_legacy_probe(struct device *dev)
|
||||
{
|
||||
struct fastrpc_channel_ctx *chan;
|
||||
struct fastrpc_session_ctx *first_sess = NULL, *sess = NULL;
|
||||
struct fastrpc_apps *me = &gfa;
|
||||
const char *name;
|
||||
unsigned int *sids = NULL, sids_size = 0;
|
||||
int err = 0, ret = 0, i;
|
||||
uint32_t dma_addr_pool[2] = {0, 0};
|
||||
|
||||
|
||||
VERIFY(err, NULL != (name = of_get_property(dev->of_node,
|
||||
"label", NULL)));
|
||||
if (err)
|
||||
goto bail;
|
||||
|
||||
for (i = 0; i < NUM_CHANNELS; i++) {
|
||||
if (!gcinfo[i].name)
|
||||
continue;
|
||||
if (!strcmp(name, gcinfo[i].name))
|
||||
break;
|
||||
}
|
||||
VERIFY(err, i < NUM_CHANNELS);
|
||||
if (err)
|
||||
goto bail;
|
||||
|
||||
chan = &gcinfo[i];
|
||||
VERIFY(err, chan->sesscount < NUM_SESSIONS);
|
||||
if (err)
|
||||
goto bail;
|
||||
|
||||
first_sess = &chan->session[chan->sesscount];
|
||||
|
||||
VERIFY(err, NULL != of_get_property(dev->of_node,
|
||||
"sids", &sids_size));
|
||||
if (err)
|
||||
goto bail;
|
||||
|
||||
VERIFY(err, NULL != (sids = kzalloc(sids_size, GFP_KERNEL)));
|
||||
if (err)
|
||||
goto bail;
|
||||
ret = of_property_read_u32_array(dev->of_node, "sids", sids,
|
||||
sids_size/sizeof(unsigned int));
|
||||
if (ret)
|
||||
goto bail;
|
||||
|
||||
if (err)
|
||||
goto bail;
|
||||
|
||||
for (i = 0; i < sids_size/sizeof(unsigned int); i++) {
|
||||
VERIFY(err, chan->sesscount < NUM_SESSIONS);
|
||||
if (err)
|
||||
goto bail;
|
||||
sess = &chan->session[chan->sesscount];
|
||||
sess->smmu.cb = sids[i];
|
||||
sess->smmu.dev = dev;
|
||||
sess->smmu.dev_name = dev_name(dev);
|
||||
sess->smmu.enabled = 1;
|
||||
sess->used = 0;
|
||||
sess->smmu.coherent = false;
|
||||
sess->smmu.secure = false;
|
||||
chan->sesscount++;
|
||||
if (!sess->smmu.dev->dma_parms)
|
||||
sess->smmu.dev->dma_parms = devm_kzalloc(sess->smmu.dev,
|
||||
sizeof(*sess->smmu.dev->dma_parms), GFP_KERNEL);
|
||||
dma_set_max_seg_size(sess->smmu.dev, DMA_BIT_MASK(32));
|
||||
dma_set_seg_boundary(sess->smmu.dev,
|
||||
(unsigned long)DMA_BIT_MASK(64));
|
||||
}
|
||||
of_property_read_u32_array(dev->of_node, "qcom,iommu-dma-addr-pool",
|
||||
dma_addr_pool, 2);
|
||||
me->max_size_limit = (dma_addr_pool[1] == 0 ? 0x78000000 :
|
||||
dma_addr_pool[1]);
|
||||
bail:
|
||||
kfree(sids);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void init_secure_vmid_list(struct device *dev, char *prop_name,
|
||||
struct secure_vm *destvm)
|
||||
{
|
||||
|
@ -4964,6 +5033,9 @@ static int fastrpc_probe(struct platform_device *pdev)
|
|||
if (of_device_is_compatible(dev->of_node,
|
||||
"qcom,msm-fastrpc-compute-cb"))
|
||||
return fastrpc_cb_probe(dev);
|
||||
if (of_device_is_compatible(dev->of_node,
|
||||
"qcom,msm-fastrpc-legacy-compute-cb"))
|
||||
return fastrpc_cb_legacy_probe(dev);
|
||||
|
||||
if (of_device_is_compatible(dev->of_node,
|
||||
"qcom,msm-adsprpc-mem-region")) {
|
||||
|
@ -5112,7 +5184,7 @@ static struct platform_driver fastrpc_driver = {
|
|||
|
||||
static const struct rpmsg_device_id fastrpc_rpmsg_match[] = {
|
||||
{ FASTRPC_GLINK_GUID },
|
||||
{ },
|
||||
{ FASTRPC_SMD_GUID },
|
||||
};
|
||||
|
||||
static const struct of_device_id fastrpc_rpmsg_of_match[] = {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2008-2020, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2008-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
@ -3120,8 +3120,13 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = copy_to_user(buf, mask_info->update_buf_client,
|
||||
if ((count - (sizeof(int))) >=
|
||||
mask_info->update_buf_client_len) {
|
||||
err = copy_to_user(buf, mask_info->update_buf_client,
|
||||
mask_info->update_buf_client_len);
|
||||
} else {
|
||||
err = -EINVAL;
|
||||
}
|
||||
if (err) {
|
||||
pr_err("diag: In %s Unable to send msg masks to user space clients, err: %d\n",
|
||||
__func__, err);
|
||||
|
@ -3147,8 +3152,13 @@ int diag_copy_to_user_log_mask(char __user *buf, size_t count,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = copy_to_user(buf, mask_info->update_buf_client,
|
||||
if ((count - (sizeof(int))) >=
|
||||
mask_info->update_buf_client_len) {
|
||||
err = copy_to_user(buf, mask_info->update_buf_client,
|
||||
mask_info->update_buf_client_len);
|
||||
} else {
|
||||
err = -EINVAL;
|
||||
}
|
||||
if (err) {
|
||||
pr_err("diag: In %s Unable to send msg masks to user space clients, err: %d\n",
|
||||
__func__, err);
|
||||
|
|
|
@ -312,7 +312,9 @@ static void usb_read_work_fn(struct work_struct *work)
|
|||
atomic_set(&ch->read_pending, 1);
|
||||
req->buf = ch->read_buf;
|
||||
req->length = USB_MAX_OUT_BUF;
|
||||
spin_unlock_irqrestore(&ch->lock, flags);
|
||||
err = usb_diag_read(ch->hdl, req);
|
||||
spin_lock_irqsave(&ch->lock, flags);
|
||||
if (err) {
|
||||
pr_debug("diag: In %s, error in reading from USB %s, err: %d\n",
|
||||
__func__, ch->name, err);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
|
@ -1345,11 +1345,26 @@ int diagfwd_channel_open(struct diagfwd_info *fwd_info)
|
|||
|
||||
int diagfwd_channel_close(struct diagfwd_info *fwd_info)
|
||||
{
|
||||
struct diag_rpmsg_info *rpmsg_info = NULL;
|
||||
struct diag_socket_info *socket_info = NULL;
|
||||
|
||||
if (!fwd_info)
|
||||
return -EIO;
|
||||
|
||||
mutex_lock(&driver->diagfwd_channel_mutex[fwd_info->peripheral]);
|
||||
fwd_info->ch_open = 0;
|
||||
rpmsg_info = diag_get_rpmsg_info_ptr(fwd_info->type,
|
||||
fwd_info->peripheral);
|
||||
socket_info = diag_get_socket_info_ptr(fwd_info->type,
|
||||
fwd_info->peripheral);
|
||||
|
||||
if (rpmsg_info && socket_info && rpmsg_info->probed
|
||||
&& socket_info->reset_flag) {
|
||||
mutex_unlock(
|
||||
&driver->diagfwd_channel_mutex[fwd_info->peripheral]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fwd_info && fwd_info->c_ops && fwd_info->c_ops->close)
|
||||
fwd_info->c_ops->close(fwd_info);
|
||||
|
||||
|
@ -1440,6 +1455,7 @@ void diagfwd_write_done(uint8_t peripheral, uint8_t type, int buf_num)
|
|||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
|
||||
"Buffer 1 for core PD is marked free, p: %d, t: %d, buf_num: %d\n",
|
||||
fwd_info->peripheral, fwd_info->type, buf_num);
|
||||
rpmsg_mark_buffers_free(peripheral, type, buf_num);
|
||||
}
|
||||
} else if (buf_num == 2 && fwd_info->buf_2) {
|
||||
/*
|
||||
|
@ -1466,6 +1482,7 @@ void diagfwd_write_done(uint8_t peripheral, uint8_t type, int buf_num)
|
|||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
|
||||
"Buffer 2 for core PD is marked free, p: %d, t: %d, buf_num: %d\n",
|
||||
fwd_info->peripheral, fwd_info->type, buf_num);
|
||||
rpmsg_mark_buffers_free(peripheral, type, buf_num);
|
||||
}
|
||||
} else if (buf_num >= 3 && (buf_num % 2)) {
|
||||
/*
|
||||
|
@ -1501,6 +1518,7 @@ void diagfwd_write_done(uint8_t peripheral, uint8_t type, int buf_num)
|
|||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
|
||||
"Buffer 1 for core PD is marked free, p: %d, t: %d, buf_num: %d\n",
|
||||
fwd_info->peripheral, fwd_info->type, buf_num);
|
||||
rpmsg_mark_buffers_free(peripheral, type, 1);
|
||||
}
|
||||
} else if (buf_num >= 4 && !(buf_num % 2)) {
|
||||
/*
|
||||
|
@ -1536,7 +1554,8 @@ void diagfwd_write_done(uint8_t peripheral, uint8_t type, int buf_num)
|
|||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
|
||||
"Buffer 2 for core PD is marked free, p: %d, t: %d, buf_num: %d\n",
|
||||
fwd_info->peripheral, fwd_info->type, buf_num);
|
||||
}
|
||||
rpmsg_mark_buffers_free(peripheral, type, 2);
|
||||
}
|
||||
} else
|
||||
pr_err("diag: In %s, invalid buf_num %d\n", __func__, buf_num);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
@ -24,11 +24,22 @@
|
|||
#define PERI_RPMSG rpmsg_info->peripheral
|
||||
|
||||
struct diag_rpmsg_read_work {
|
||||
struct diag_rpmsg_info *rpmsg_info;
|
||||
const void *ptr_read_done;
|
||||
const void *ptr_rx_done;
|
||||
size_t ptr_read_size;
|
||||
struct work_struct work;
|
||||
struct list_head rx_list_head;
|
||||
spinlock_t rx_lock;
|
||||
};
|
||||
|
||||
static struct diag_rpmsg_read_work *read_work_struct;
|
||||
|
||||
/**
|
||||
** struct rx_buff_list - holds rx rpmsg data, before it will be consumed
|
||||
** by diagfwd_channel_read_done worker, item per rx packet
|
||||
**/
|
||||
struct rx_buff_list {
|
||||
struct list_head list;
|
||||
void *rpmsg_rx_buf;
|
||||
int rx_buf_size;
|
||||
struct diag_rpmsg_info *rpmsg_info;
|
||||
};
|
||||
|
||||
struct diag_rpmsg_info rpmsg_data[NUM_PERIPHERALS] = {
|
||||
|
@ -36,7 +47,7 @@ struct diag_rpmsg_info rpmsg_data[NUM_PERIPHERALS] = {
|
|||
.peripheral = PERIPHERAL_MODEM,
|
||||
.type = TYPE_DATA,
|
||||
.edge = "mpss",
|
||||
.name = "DIAG_DATA",
|
||||
.name = "DIAG",
|
||||
.buf1 = NULL,
|
||||
.buf2 = NULL,
|
||||
.hdl = NULL
|
||||
|
@ -45,7 +56,7 @@ struct diag_rpmsg_info rpmsg_data[NUM_PERIPHERALS] = {
|
|||
.peripheral = PERIPHERAL_LPASS,
|
||||
.type = TYPE_DATA,
|
||||
.edge = "lpass",
|
||||
.name = "DIAG_DATA",
|
||||
.name = "DIAG",
|
||||
.buf1 = NULL,
|
||||
.buf2 = NULL,
|
||||
.hdl = NULL
|
||||
|
@ -54,7 +65,7 @@ struct diag_rpmsg_info rpmsg_data[NUM_PERIPHERALS] = {
|
|||
.peripheral = PERIPHERAL_WCNSS,
|
||||
.type = TYPE_DATA,
|
||||
.edge = "wcnss",
|
||||
.name = "DIAG_DATA",
|
||||
.name = "APPS_RIVA_DATA",
|
||||
.buf1 = NULL,
|
||||
.buf2 = NULL,
|
||||
.hdl = NULL
|
||||
|
@ -102,7 +113,7 @@ struct diag_rpmsg_info rpmsg_cntl[NUM_PERIPHERALS] = {
|
|||
.peripheral = PERIPHERAL_MODEM,
|
||||
.type = TYPE_CNTL,
|
||||
.edge = "mpss",
|
||||
.name = "DIAG_CTRL",
|
||||
.name = "DIAG_CNTL",
|
||||
.buf1 = NULL,
|
||||
.buf2 = NULL,
|
||||
.hdl = NULL
|
||||
|
@ -111,7 +122,7 @@ struct diag_rpmsg_info rpmsg_cntl[NUM_PERIPHERALS] = {
|
|||
.peripheral = PERIPHERAL_LPASS,
|
||||
.type = TYPE_CNTL,
|
||||
.edge = "lpass",
|
||||
.name = "DIAG_CTRL",
|
||||
.name = "DIAG_CNTL",
|
||||
.buf1 = NULL,
|
||||
.buf2 = NULL,
|
||||
.hdl = NULL
|
||||
|
@ -120,7 +131,7 @@ struct diag_rpmsg_info rpmsg_cntl[NUM_PERIPHERALS] = {
|
|||
.peripheral = PERIPHERAL_WCNSS,
|
||||
.type = TYPE_CNTL,
|
||||
.edge = "wcnss",
|
||||
.name = "DIAG_CTRL",
|
||||
.name = "APPS_RIVA_CTRL",
|
||||
.buf1 = NULL,
|
||||
.buf2 = NULL,
|
||||
.hdl = NULL
|
||||
|
@ -168,7 +179,7 @@ struct diag_rpmsg_info rpmsg_dci[NUM_PERIPHERALS] = {
|
|||
.peripheral = PERIPHERAL_MODEM,
|
||||
.type = TYPE_DCI,
|
||||
.edge = "mpss",
|
||||
.name = "DIAG_DCI_DATA",
|
||||
.name = "DIAG_2",
|
||||
.buf1 = NULL,
|
||||
.buf2 = NULL,
|
||||
.hdl = NULL
|
||||
|
@ -300,7 +311,7 @@ struct diag_rpmsg_info rpmsg_dci_cmd[NUM_PERIPHERALS] = {
|
|||
.peripheral = PERIPHERAL_MODEM,
|
||||
.type = TYPE_DCI_CMD,
|
||||
.edge = "mpss",
|
||||
.name = "DIAG_DCI_CMD",
|
||||
.name = "DIAG_2_CMD",
|
||||
.buf1 = NULL,
|
||||
.buf2 = NULL,
|
||||
.hdl = NULL
|
||||
|
@ -463,7 +474,7 @@ static int diag_rpmsg_read(void *ctxt, unsigned char *buf, int buf_len)
|
|||
rpmsg_info->buf2 = buf;
|
||||
}
|
||||
mutex_unlock(&driver->diagfwd_channel_mutex[rpmsg_info->peripheral]);
|
||||
|
||||
queue_work(rpmsg_info->wq, &read_work_struct->work);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
@ -488,14 +499,13 @@ static void diag_rpmsg_read_work_fn(struct work_struct *work)
|
|||
return;
|
||||
}
|
||||
mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
|
||||
|
||||
diagfwd_channel_read(rpmsg_info->fwd_ctxt);
|
||||
}
|
||||
|
||||
static int diag_rpmsg_write(void *ctxt, unsigned char *buf, int len)
|
||||
{
|
||||
struct diag_rpmsg_info *rpmsg_info = NULL;
|
||||
int err = 0;
|
||||
struct diag_rpmsg_info *rpmsg_info = NULL;
|
||||
struct rpmsg_device *rpdev = NULL;
|
||||
|
||||
if (!ctxt || !buf)
|
||||
|
@ -518,6 +528,7 @@ static int diag_rpmsg_write(void *ctxt, unsigned char *buf, int len)
|
|||
}
|
||||
|
||||
rpdev = (struct rpmsg_device *)rpmsg_info->hdl;
|
||||
|
||||
err = rpmsg_send(rpdev->ept, buf, len);
|
||||
if (!err) {
|
||||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "%s wrote to rpmsg, len: %d\n",
|
||||
|
@ -599,85 +610,178 @@ static int diag_rpmsg_notify_cb(struct rpmsg_device *rpdev, void *data, int len,
|
|||
void *priv, u32 src)
|
||||
{
|
||||
struct diag_rpmsg_info *rpmsg_info = NULL;
|
||||
struct diagfwd_info *fwd_info = NULL;
|
||||
struct diag_rpmsg_read_work *read_work = NULL;
|
||||
void *buf = NULL;
|
||||
struct rx_buff_list *rx_item;
|
||||
unsigned long flags;
|
||||
|
||||
if (!rpdev || !data)
|
||||
return -EINVAL;
|
||||
|
||||
rpmsg_info = dev_get_drvdata(&rpdev->dev);
|
||||
|
||||
if (!rpmsg_info || !rpmsg_info->fwd_ctxt) {
|
||||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "diag: Invalid rpmsg info\n");
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!rpmsg_info->buf1 && !rpmsg_info->buf2) {
|
||||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
|
||||
"dropping data for %s len %d\n",
|
||||
rpmsg_info->name, len);
|
||||
return 0;
|
||||
rx_item = kzalloc(sizeof(*rx_item), GFP_ATOMIC);
|
||||
if (!rx_item)
|
||||
return -ENOMEM;
|
||||
|
||||
rx_item->rpmsg_rx_buf = kmemdup(data, len, GFP_ATOMIC);
|
||||
if (!rx_item->rpmsg_rx_buf) {
|
||||
kfree(rx_item);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
fwd_info = rpmsg_info->fwd_ctxt;
|
||||
rx_item->rx_buf_size = len;
|
||||
rx_item->rpmsg_info = rpmsg_info;
|
||||
|
||||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
|
||||
"diag: received data of length: %d for p:%d, t:%d\n",
|
||||
len, rpmsg_info->peripheral, rpmsg_info->type);
|
||||
spin_lock_irqsave(&read_work_struct->rx_lock, flags);
|
||||
list_add(&rx_item->list, &read_work_struct->rx_list_head);
|
||||
spin_unlock_irqrestore(&read_work_struct->rx_lock, flags);
|
||||
|
||||
if (rpmsg_info->buf1 && !fwd_info->buffer_status[BUF_1_INDEX] &&
|
||||
atomic_read(&fwd_info->buf_1->in_busy)) {
|
||||
buf = rpmsg_info->buf1;
|
||||
fwd_info->buffer_status[BUF_1_INDEX] = 1;
|
||||
} else if (rpmsg_info->buf2 && !fwd_info->buffer_status[BUF_2_INDEX] &&
|
||||
atomic_read(&fwd_info->buf_2->in_busy) &&
|
||||
(fwd_info->type == TYPE_DATA)) {
|
||||
buf = rpmsg_info->buf2;
|
||||
fwd_info->buffer_status[BUF_2_INDEX] = 1;
|
||||
} else {
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
if (!buf)
|
||||
return 0;
|
||||
|
||||
memcpy(buf, data, len);
|
||||
|
||||
read_work = kmalloc(sizeof(*read_work), GFP_ATOMIC);
|
||||
if (!read_work) {
|
||||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
|
||||
"diag: Could not allocate read_work\n");
|
||||
return 0;
|
||||
}
|
||||
read_work->rpmsg_info = rpmsg_info;
|
||||
read_work->ptr_read_done = buf;
|
||||
read_work->ptr_read_size = len;
|
||||
INIT_WORK(&read_work->work, diag_rpmsg_notify_rx_work_fn);
|
||||
queue_work(rpmsg_info->wq, &read_work->work);
|
||||
queue_work(rpmsg_info->wq, &read_work_struct->work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void diag_rpmsg_notify_rx_work_fn(struct work_struct *work)
|
||||
{
|
||||
struct diag_rpmsg_read_work *read_work = container_of(work,
|
||||
struct diag_rpmsg_read_work, work);
|
||||
struct diag_rpmsg_info *rpmsg_info = read_work->rpmsg_info;
|
||||
struct diag_rpmsg_info *rpmsg_info;
|
||||
struct rx_buff_list *rx_item;
|
||||
struct diagfwd_info *fwd_info;
|
||||
void *buf = NULL;
|
||||
unsigned long flags;
|
||||
int err_flag = 0;
|
||||
|
||||
if (!rpmsg_info || !rpmsg_info->hdl) {
|
||||
kfree(read_work);
|
||||
read_work = NULL;
|
||||
spin_lock_irqsave(&read_work_struct->rx_lock, flags);
|
||||
if (!list_empty(&read_work_struct->rx_list_head)) {
|
||||
/* detach last entry */
|
||||
rx_item = list_last_entry(&read_work_struct->rx_list_head,
|
||||
struct rx_buff_list, list);
|
||||
|
||||
if (!rx_item) {
|
||||
err_flag = 1;
|
||||
goto err_handling;
|
||||
}
|
||||
|
||||
rpmsg_info = rx_item->rpmsg_info;
|
||||
if (!rpmsg_info) {
|
||||
err_flag = 1;
|
||||
goto err_handling;
|
||||
}
|
||||
|
||||
fwd_info = rpmsg_info->fwd_ctxt;
|
||||
if (!fwd_info) {
|
||||
err_flag = 1;
|
||||
goto err_handling;
|
||||
}
|
||||
|
||||
if (!rpmsg_info->buf1 && !rpmsg_info->buf2) {
|
||||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
|
||||
"retry data send for %s len %d\n",
|
||||
rpmsg_info->name, rx_item->rx_buf_size);
|
||||
err_flag = 1;
|
||||
goto err_handling;
|
||||
}
|
||||
|
||||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
|
||||
"diag: received data of length: %d, p: %d, t: %d\n",
|
||||
rx_item->rx_buf_size, rpmsg_info->peripheral,
|
||||
rpmsg_info->type);
|
||||
|
||||
if (rpmsg_info->buf1 && !fwd_info->buffer_status[BUF_1_INDEX] &&
|
||||
atomic_read(&(fwd_info->buf_1->in_busy))) {
|
||||
buf = rpmsg_info->buf1;
|
||||
fwd_info->buffer_status[BUF_1_INDEX] = 1;
|
||||
} else if (rpmsg_info->buf2 &&
|
||||
!fwd_info->buffer_status[BUF_2_INDEX] &&
|
||||
atomic_read(&fwd_info->buf_2->in_busy) &&
|
||||
(fwd_info->type == TYPE_DATA)) {
|
||||
buf = rpmsg_info->buf2;
|
||||
fwd_info->buffer_status[BUF_2_INDEX] = 1;
|
||||
} else {
|
||||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
|
||||
"Both the rpmsg buffers are busy\n");
|
||||
buf = NULL;
|
||||
}
|
||||
if (!buf) {
|
||||
err_flag = 1;
|
||||
goto err_handling;
|
||||
}
|
||||
|
||||
err_handling:
|
||||
if (!err_flag) {
|
||||
memcpy(buf, rx_item->rpmsg_rx_buf,
|
||||
rx_item->rx_buf_size);
|
||||
list_del(&rx_item->list);
|
||||
spin_unlock_irqrestore(&read_work_struct->rx_lock,
|
||||
flags);
|
||||
} else {
|
||||
spin_unlock_irqrestore(&read_work_struct->rx_lock,
|
||||
flags);
|
||||
goto end;
|
||||
}
|
||||
|
||||
mutex_lock(&driver->diagfwd_channel_mutex[PERI_RPMSG]);
|
||||
|
||||
diagfwd_channel_read_done(rpmsg_info->fwd_ctxt,
|
||||
(unsigned char *)(buf), rx_item->rx_buf_size);
|
||||
|
||||
mutex_unlock(&driver->diagfwd_channel_mutex[PERI_RPMSG]);
|
||||
kfree(rx_item->rpmsg_rx_buf);
|
||||
kfree(rx_item);
|
||||
|
||||
} else {
|
||||
spin_unlock_irqrestore(&read_work_struct->rx_lock, flags);
|
||||
}
|
||||
end:
|
||||
return;
|
||||
}
|
||||
|
||||
struct diag_rpmsg_info *diag_get_rpmsg_info_ptr(int type, int peripheral)
|
||||
{
|
||||
if (type == TYPE_CMD)
|
||||
return &rpmsg_cmd[peripheral];
|
||||
else if (type == TYPE_CNTL)
|
||||
return &rpmsg_cntl[peripheral];
|
||||
else if (type == TYPE_DATA)
|
||||
return &rpmsg_data[peripheral];
|
||||
else if (type == TYPE_DCI_CMD)
|
||||
return &rpmsg_dci_cmd[peripheral];
|
||||
else if (type == TYPE_DCI)
|
||||
return &rpmsg_dci[peripheral];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rpmsg_mark_buffers_free(uint8_t peripheral, uint8_t type, int buf_num)
|
||||
{
|
||||
struct diag_rpmsg_info *rpmsg_info;
|
||||
|
||||
switch (peripheral) {
|
||||
case PERIPHERAL_WDSP:
|
||||
break;
|
||||
case PERIPHERAL_WCNSS:
|
||||
break;
|
||||
case PERIPHERAL_MODEM:
|
||||
break;
|
||||
case PERIPHERAL_LPASS:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&driver->diagfwd_channel_mutex[rpmsg_info->peripheral]);
|
||||
diagfwd_channel_read_done(rpmsg_info->fwd_ctxt,
|
||||
(unsigned char *)(read_work->ptr_read_done),
|
||||
read_work->ptr_read_size);
|
||||
rpmsg_info = diag_get_rpmsg_info_ptr(type, peripheral);
|
||||
if (!rpmsg_info)
|
||||
return;
|
||||
|
||||
if (read_work->ptr_read_done == rpmsg_info->buf1)
|
||||
if (buf_num == 1) {
|
||||
rpmsg_info->buf1 = NULL;
|
||||
else if (read_work->ptr_read_done == rpmsg_info->buf2)
|
||||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "marked buf1 NULL");
|
||||
} else if (buf_num == 2) {
|
||||
rpmsg_info->buf2 = NULL;
|
||||
kfree(read_work);
|
||||
read_work = NULL;
|
||||
mutex_unlock(&driver->diagfwd_channel_mutex[rpmsg_info->peripheral]);
|
||||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "marked buf2 NULL");
|
||||
}
|
||||
}
|
||||
|
||||
static void rpmsg_late_init(struct diag_rpmsg_info *rpmsg_info)
|
||||
|
@ -745,6 +849,7 @@ static void __diag_rpmsg_init(struct diag_rpmsg_info *rpmsg_info)
|
|||
mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
|
||||
rpmsg_info->hdl = NULL;
|
||||
rpmsg_info->fwd_ctxt = NULL;
|
||||
rpmsg_info->probed = 0;
|
||||
atomic_set(&rpmsg_info->opened, 0);
|
||||
atomic_set(&rpmsg_info->diag_state, 0);
|
||||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
|
||||
|
@ -771,8 +876,19 @@ int diag_rpmsg_init(void)
|
|||
struct diag_rpmsg_info *rpmsg_info = NULL;
|
||||
|
||||
for (peripheral = 0; peripheral < NUM_PERIPHERALS; peripheral++) {
|
||||
if (peripheral != PERIPHERAL_WDSP)
|
||||
switch (peripheral) {
|
||||
case PERIPHERAL_WDSP:
|
||||
break;
|
||||
case PERIPHERAL_WCNSS:
|
||||
break;
|
||||
case PERIPHERAL_MODEM:
|
||||
break;
|
||||
case PERIPHERAL_LPASS:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
rpmsg_info = &rpmsg_cntl[peripheral];
|
||||
__diag_rpmsg_init(rpmsg_info);
|
||||
diagfwd_cntl_register(TRANSPORT_RPMSG, rpmsg_info->peripheral,
|
||||
|
@ -788,6 +904,18 @@ int diag_rpmsg_init(void)
|
|||
__diag_rpmsg_init(&rpmsg_dci[peripheral]);
|
||||
__diag_rpmsg_init(&rpmsg_dci_cmd[peripheral]);
|
||||
}
|
||||
read_work_struct = kmalloc(sizeof(*read_work_struct), GFP_ATOMIC);
|
||||
if (!read_work_struct) {
|
||||
DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
|
||||
"diag: Could not allocate read_work\n");
|
||||
return 0;
|
||||
}
|
||||
kmemleak_not_leak(read_work_struct);
|
||||
|
||||
INIT_WORK(&read_work_struct->work, diag_rpmsg_notify_rx_work_fn);
|
||||
INIT_LIST_HEAD(&read_work_struct->rx_list_head);
|
||||
spin_lock_init(&read_work_struct->rx_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -815,8 +943,19 @@ void diag_rpmsg_early_exit(void)
|
|||
int peripheral = 0;
|
||||
|
||||
for (peripheral = 0; peripheral < NUM_PERIPHERALS; peripheral++) {
|
||||
if (peripheral != PERIPHERAL_WDSP)
|
||||
switch (peripheral) {
|
||||
case PERIPHERAL_WDSP:
|
||||
break;
|
||||
case PERIPHERAL_WCNSS:
|
||||
break;
|
||||
case PERIPHERAL_MODEM:
|
||||
break;
|
||||
case PERIPHERAL_LPASS:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
mutex_lock(&driver->rpmsginfo_mutex[peripheral]);
|
||||
__diag_rpmsg_exit(&rpmsg_cntl[peripheral]);
|
||||
mutex_unlock(&driver->rpmsginfo_mutex[peripheral]);
|
||||
|
@ -837,72 +976,124 @@ void diag_rpmsg_exit(void)
|
|||
}
|
||||
}
|
||||
|
||||
static struct diag_rpmsg_info *diag_get_rpmsg_ptr(char *name)
|
||||
static struct diag_rpmsg_info *diag_get_rpmsg_ptr(char *name, int pid)
|
||||
{
|
||||
|
||||
if (!name)
|
||||
return NULL;
|
||||
if (!strcmp(name, "DIAG_CMD"))
|
||||
return &rpmsg_cmd[PERIPHERAL_WDSP];
|
||||
else if (!strcmp(name, "DIAG_CTRL"))
|
||||
return &rpmsg_cntl[PERIPHERAL_WDSP];
|
||||
else if (!strcmp(name, "DIAG_DATA"))
|
||||
return &rpmsg_data[PERIPHERAL_WDSP];
|
||||
else if (!strcmp(name, "DIAG_DCI_CMD"))
|
||||
return &rpmsg_dci_cmd[PERIPHERAL_WDSP];
|
||||
else if (!strcmp(name, "DIAG_DCI_DATA"))
|
||||
return &rpmsg_dci[PERIPHERAL_WDSP];
|
||||
else
|
||||
return NULL;
|
||||
if (pid == PERIPHERAL_WDSP) {
|
||||
if (!strcmp(name, "DIAG_CMD"))
|
||||
return &rpmsg_cmd[PERIPHERAL_WDSP];
|
||||
else if (!strcmp(name, "DIAG_CTRL"))
|
||||
return &rpmsg_cntl[PERIPHERAL_WDSP];
|
||||
else if (!strcmp(name, "DIAG_DATA"))
|
||||
return &rpmsg_data[PERIPHERAL_WDSP];
|
||||
else if (!strcmp(name, "DIAG_DCI_CMD"))
|
||||
return &rpmsg_dci_cmd[PERIPHERAL_WDSP];
|
||||
else if (!strcmp(name, "DIAG_DCI_DATA"))
|
||||
return &rpmsg_dci[PERIPHERAL_WDSP];
|
||||
else
|
||||
return NULL;
|
||||
} else if (pid == PERIPHERAL_WCNSS) {
|
||||
if (!strcmp(name, "APPS_RIVA_DATA"))
|
||||
return &rpmsg_data[PERIPHERAL_WCNSS];
|
||||
else if (!strcmp(name, "APPS_RIVA_CTRL"))
|
||||
return &rpmsg_cntl[PERIPHERAL_WCNSS];
|
||||
else
|
||||
return NULL;
|
||||
} else if (pid == PERIPHERAL_MODEM) {
|
||||
if (!strcmp(name, "DIAG_CMD"))
|
||||
return &rpmsg_cmd[PERIPHERAL_MODEM];
|
||||
else if (!strcmp(name, "DIAG_CNTL"))
|
||||
return &rpmsg_cntl[PERIPHERAL_MODEM];
|
||||
else if (!strcmp(name, "DIAG"))
|
||||
return &rpmsg_data[PERIPHERAL_MODEM];
|
||||
else if (!strcmp(name, "DIAG_2_CMD"))
|
||||
return &rpmsg_dci_cmd[PERIPHERAL_MODEM];
|
||||
else if (!strcmp(name, "DIAG_2"))
|
||||
return &rpmsg_dci[PERIPHERAL_MODEM];
|
||||
else
|
||||
return NULL;
|
||||
} else if (pid == PERIPHERAL_LPASS) {
|
||||
if (!strcmp(name, "DIAG"))
|
||||
return &rpmsg_data[PERIPHERAL_LPASS];
|
||||
else if (!strcmp(name, "DIAG_CNTL"))
|
||||
return &rpmsg_cntl[PERIPHERAL_LPASS];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int diag_rpmsg_probe(struct rpmsg_device *rpdev)
|
||||
{
|
||||
struct diag_rpmsg_info *rpmsg_info = NULL;
|
||||
int peripheral = -1;
|
||||
|
||||
if (!rpdev)
|
||||
return 0;
|
||||
if (strcmp(rpdev->dev.parent->of_node->name, "wdsp"))
|
||||
return 0;
|
||||
|
||||
rpmsg_info = diag_get_rpmsg_ptr(rpdev->id.name);
|
||||
if (!strcmp(rpdev->dev.parent->of_node->name, "wdsp"))
|
||||
peripheral = PERIPHERAL_WDSP;
|
||||
else if (!strcmp(rpdev->dev.parent->of_node->name, "wcnss"))
|
||||
peripheral = PERIPHERAL_WCNSS;
|
||||
else if (!strcmp(rpdev->dev.parent->of_node->name, "modem"))
|
||||
peripheral = PERIPHERAL_MODEM;
|
||||
else if (!strcmp(rpdev->dev.parent->of_node->name, "adsp"))
|
||||
peripheral = PERIPHERAL_LPASS;
|
||||
|
||||
rpmsg_info = diag_get_rpmsg_ptr(rpdev->id.name, peripheral);
|
||||
if (rpmsg_info) {
|
||||
|
||||
mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
|
||||
rpmsg_info->hdl = rpdev;
|
||||
atomic_set(&rpmsg_info->opened, 1);
|
||||
mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
|
||||
|
||||
rpmsg_info->probed = 1;
|
||||
dev_set_drvdata(&rpdev->dev, rpmsg_info);
|
||||
diagfwd_channel_read(rpmsg_info->fwd_ctxt);
|
||||
queue_work(rpmsg_info->wq, &rpmsg_info->open_work);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void diag_rpmsg_remove(struct rpmsg_device *rpdev)
|
||||
{
|
||||
struct diag_rpmsg_info *rpmsg_info = NULL;
|
||||
int peripheral = -1;
|
||||
|
||||
if (!rpdev)
|
||||
return;
|
||||
|
||||
rpmsg_info = diag_get_rpmsg_ptr(rpdev->id.name);
|
||||
if (!strcmp(rpdev->dev.parent->of_node->name, "wdsp"))
|
||||
peripheral = PERIPHERAL_WDSP;
|
||||
else if (!strcmp(rpdev->dev.parent->of_node->name, "wcnss"))
|
||||
peripheral = PERIPHERAL_WCNSS;
|
||||
else if (!strcmp(rpdev->dev.parent->of_node->name, "modem"))
|
||||
peripheral = PERIPHERAL_MODEM;
|
||||
else if (!strcmp(rpdev->dev.parent->of_node->name, "adsp"))
|
||||
peripheral = PERIPHERAL_LPASS;
|
||||
|
||||
rpmsg_info = diag_get_rpmsg_ptr(rpdev->id.name, peripheral);
|
||||
if (rpmsg_info) {
|
||||
mutex_lock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
|
||||
atomic_set(&rpmsg_info->opened, 0);
|
||||
mutex_unlock(&driver->rpmsginfo_mutex[PERI_RPMSG]);
|
||||
rpmsg_info->probed = 0;
|
||||
queue_work(rpmsg_info->wq, &rpmsg_info->close_work);
|
||||
}
|
||||
}
|
||||
|
||||
static struct rpmsg_device_id rpmsg_diag_table[] = {
|
||||
{ .name = "DIAG_CMD" },
|
||||
{ .name = "DIAG_CTRL" },
|
||||
{ .name = "DIAG_DATA" },
|
||||
{ .name = "DIAG_DCI_CMD" },
|
||||
{ .name = "DIAG_DCI_DATA" },
|
||||
{ .name = "APPS_RIVA_DATA" },
|
||||
{ .name = "APPS_RIVA_CTRL" },
|
||||
{ .name = "DIAG" },
|
||||
{ .name = "DIAG_CNTL" },
|
||||
{ .name = "DIAG_2" },
|
||||
{ .name = "DIAG_2_CMD" },
|
||||
{ .name = "DIAG_CMD" },
|
||||
{ .name = "DIAG_CTRL" },
|
||||
{ .name = "DIAG_DATA" },
|
||||
{ .name = "DIAG_DCI_CMD" },
|
||||
{ .name = "DIAG_DCI_DATA" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(rpmsg, rpmsg_diag_table);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2017-2018, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef DIAGFWD_RPMSG_H
|
||||
|
@ -12,6 +12,7 @@ struct diag_rpmsg_info {
|
|||
uint8_t peripheral;
|
||||
uint8_t type;
|
||||
uint8_t inited;
|
||||
uint8_t probed;
|
||||
atomic_t opened;
|
||||
atomic_t diag_state;
|
||||
uint32_t fifo_size;
|
||||
|
@ -43,5 +44,7 @@ int diag_rpmsg_init(void);
|
|||
void diag_rpmsg_early_exit(void);
|
||||
void diag_rpmsg_invalidate(void *ctxt, struct diagfwd_info *fwd_ctxt);
|
||||
int diag_rpmsg_check_state(void *ctxt);
|
||||
void rpmsg_mark_buffers_free(uint8_t peripheral, uint8_t type, int buf_num);
|
||||
struct diag_rpmsg_info *diag_get_rpmsg_info_ptr(int type, int peripheral);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
@ -244,6 +244,22 @@ struct diag_socket_info socket_dci_cmd[NUM_PERIPHERALS] = {
|
|||
}
|
||||
};
|
||||
|
||||
struct diag_socket_info *diag_get_socket_info_ptr(int type, int peripheral)
|
||||
{
|
||||
if (type == TYPE_CMD)
|
||||
return &socket_cmd[peripheral];
|
||||
else if (type == TYPE_CNTL)
|
||||
return &socket_cntl[peripheral];
|
||||
else if (type == TYPE_DATA)
|
||||
return &socket_data[peripheral];
|
||||
else if (type == TYPE_DCI_CMD)
|
||||
return &socket_dci_cmd[peripheral];
|
||||
else if (type == TYPE_DCI)
|
||||
return &socket_dci[peripheral];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct restart_notifier_block {
|
||||
unsigned int processor;
|
||||
char *name;
|
||||
|
@ -611,7 +627,9 @@ static void socket_read_work_fn(struct work_struct *work)
|
|||
err = sock_error(info->hdl->sk);
|
||||
mutex_unlock(&info->socket_info_mutex);
|
||||
if (unlikely(err == -ENETRESET)) {
|
||||
info->reset_flag = 1;
|
||||
socket_close_channel(info);
|
||||
info->reset_flag = 0;
|
||||
if (info->port_type == PORT_TYPE_SERVER)
|
||||
socket_init_work_fn(&info->init_work);
|
||||
diag_ws_release();
|
||||
|
@ -831,7 +849,9 @@ static int diag_socket_read(void *ctxt, unsigned char *buf, int buf_len)
|
|||
mutex_lock(channel_mutex);
|
||||
diagfwd_channel_read_done(info->fwd_ctxt, buf, 0);
|
||||
mutex_unlock(channel_mutex);
|
||||
info->reset_flag = 1;
|
||||
socket_close_channel(info);
|
||||
info->reset_flag = 0;
|
||||
if (info->port_type == PORT_TYPE_SERVER)
|
||||
socket_init_work_fn(&info->init_work);
|
||||
return read_len;
|
||||
|
@ -980,6 +1000,7 @@ static void __diag_socket_init(struct diag_socket_info *info)
|
|||
info->hdl = NULL;
|
||||
info->fwd_ctxt = NULL;
|
||||
info->data_ready = 0;
|
||||
info->reset_flag = 0;
|
||||
atomic_set(&info->flow_cnt, 0);
|
||||
spin_lock_init(&info->lock);
|
||||
strlcpy(wq_name, info->name, sizeof(wq_name));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef DIAGFWD_SOCKET_H
|
||||
|
@ -33,6 +33,7 @@ struct diag_socket_info {
|
|||
uint8_t type;
|
||||
uint8_t port_type;
|
||||
uint8_t inited;
|
||||
uint8_t reset_flag;
|
||||
atomic_t opened;
|
||||
atomic_t diag_state;
|
||||
uint32_t pkt_len;
|
||||
|
@ -68,4 +69,5 @@ int diag_socket_check_state(void *ctxt);
|
|||
int diag_socket_init(void);
|
||||
void diag_socket_exit(void);
|
||||
int diag_socket_init_peripheral(uint8_t peripheral);
|
||||
struct diag_socket_info *diag_get_socket_info_ptr(int type, int peripheral);
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2008-2014, 2016-2019 The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2008-2014, 2016-2019, 2021 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
|
@ -143,6 +143,9 @@ void diagmem_setsize(int pool_idx, int itemsize, int poolsize)
|
|||
}
|
||||
|
||||
diag_mempools[pool_idx].itemsize = itemsize;
|
||||
if (diag_mempools[pool_idx].pool)
|
||||
diag_mempools[pool_idx].pool->pool_data =
|
||||
(void *)(uintptr_t)itemsize;
|
||||
diag_mempools[pool_idx].poolsize = poolsize;
|
||||
pr_debug("diag: Mempool %s sizes: itemsize %d poolsize %d\n",
|
||||
diag_mempools[pool_idx].name, diag_mempools[pool_idx].itemsize,
|
||||
|
@ -168,7 +171,8 @@ void *diagmem_alloc(struct diagchar_dev *driver, int size, int pool_type)
|
|||
mempool->name);
|
||||
break;
|
||||
}
|
||||
if (size == 0 || size > mempool->itemsize) {
|
||||
if (size == 0 || size > mempool->itemsize ||
|
||||
size > (int)mempool->pool->pool_data) {
|
||||
pr_err_ratelimited("diag: cannot alloc from mempool %s, invalid size: %d\n",
|
||||
mempool->name, size);
|
||||
break;
|
||||
|
|
977
drivers/char/msm_smd_pkt.c
Normal file
977
drivers/char/msm_smd_pkt.c
Normal file
|
@ -0,0 +1,977 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/ipc_logging.h>
|
||||
#include <linux/refcount.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/rpmsg.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/termios.h>
|
||||
#include <linux/msm_smd_pkt.h>
|
||||
|
||||
#define MODULE_NAME "msm_smdpkt"
|
||||
#define DEVICE_NAME "smdpkt"
|
||||
#define SMD_PKT_IPC_LOG_PAGE_CNT 2
|
||||
|
||||
/**
|
||||
* struct smd_pkt - driver context, relates rpdev to cdev
|
||||
* @dev: smd pkt device
|
||||
* @cdev: cdev for the smd pkt device
|
||||
* @drv: rpmsg driver for registering to rpmsg bus
|
||||
* @lock: synchronization of @rpdev and @open_tout modifications
|
||||
* @ch_open: wait object for opening the smd channel
|
||||
* @refcount: count how many userspace clients have handles
|
||||
* @rpdev: underlaying rpmsg device
|
||||
* @queue_lock: synchronization of @queue operations
|
||||
* @queue: incoming message queue
|
||||
* @readq: wait object for incoming queue
|
||||
* @sig_change: flag to indicate serial signal change
|
||||
* @notify_state_update: notify channel state
|
||||
* @fragmented_read: set from dt node for partial read
|
||||
* @dev_name: /dev/@dev_name for smd_pkt device
|
||||
* @ch_name: smd channel to match to
|
||||
* @edge: smd edge to match to
|
||||
* @open_tout: timeout for open syscall, configurable in sysfs
|
||||
* @rskb: current skb being read
|
||||
* @rdata: data pointer in current skb
|
||||
* @rdata_len: remaining data to be read from skb
|
||||
*/
|
||||
struct smd_pkt_dev {
|
||||
|
||||
struct device dev;
|
||||
struct cdev cdev;
|
||||
struct rpmsg_driver drv;
|
||||
struct mutex lock;
|
||||
struct completion ch_open;
|
||||
refcount_t refcount;
|
||||
struct rpmsg_device *rpdev;
|
||||
|
||||
spinlock_t queue_lock;
|
||||
struct sk_buff_head queue;
|
||||
wait_queue_head_t readq;
|
||||
int sig_change;
|
||||
bool notify_state_update;
|
||||
bool fragmented_read;
|
||||
const char *dev_name;
|
||||
const char *ch_name;
|
||||
const char *edge;
|
||||
int open_tout;
|
||||
struct sk_buff *rskb;
|
||||
unsigned char *rdata;
|
||||
size_t rdata_len;
|
||||
};
|
||||
|
||||
#define dev_to_smd_pkt_devp(_dev) container_of(_dev, struct smd_pkt_dev, dev)
|
||||
#define cdev_to_smd_pkt_devp(_cdev) container_of(_cdev, \
|
||||
struct smd_pkt_dev, cdev)
|
||||
#define drv_to_rpdrv(_drv) container_of(_drv, struct rpmsg_driver, drv)
|
||||
#define rpdrv_to_smd_pkt_devp(_rdrv) container_of(_rdrv, \
|
||||
struct smd_pkt_dev, drv)
|
||||
|
||||
static void *smd_pkt_ilctxt;
|
||||
|
||||
static int smd_pkt_debug_mask;
|
||||
|
||||
module_param_named(debug_mask, smd_pkt_debug_mask, int, 0664);
|
||||
|
||||
enum {
|
||||
SMD_PKT_INFO = 1U << 0,
|
||||
};
|
||||
|
||||
#define SMD_PKT_INFO(x, ...) \
|
||||
do { \
|
||||
if (smd_pkt_debug_mask & SMD_PKT_INFO) { \
|
||||
ipc_log_string(smd_pkt_ilctxt, \
|
||||
"[%s]: "x, __func__, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SMD_PKT_ERR(x, ...) \
|
||||
do { \
|
||||
pr_err_ratelimited("[%s]: "x, __func__, ##__VA_ARGS__); \
|
||||
ipc_log_string(smd_pkt_ilctxt, "[%s]: "x, __func__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define SMD_PKT_IOCTL_QUEUE_RX_INTENT \
|
||||
_IOW(SMD_PKT_IOCTL_MAGIC, 0, unsigned int)
|
||||
|
||||
static dev_t smd_pkt_major;
|
||||
static struct class *smd_pkt_class;
|
||||
static int num_smd_pkt_devs;
|
||||
|
||||
static DEFINE_IDA(smd_pkt_minor_ida);
|
||||
static ssize_t open_timeout_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf,
|
||||
size_t n)
|
||||
{
|
||||
struct smd_pkt_dev *smd_pkt_devp = dev_to_smd_pkt_devp(dev);
|
||||
long tmp;
|
||||
|
||||
mutex_lock(&smd_pkt_devp->lock);
|
||||
if (kstrtol(buf, 0, &tmp)) {
|
||||
mutex_unlock(&smd_pkt_devp->lock);
|
||||
SMD_PKT_ERR("unable to convert:%s to an int for /dev/%s\n",
|
||||
buf, smd_pkt_devp->dev_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
smd_pkt_devp->open_tout = tmp;
|
||||
mutex_unlock(&smd_pkt_devp->lock);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static ssize_t open_timeout_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct smd_pkt_dev *smd_pkt_devp = dev_to_smd_pkt_devp(dev);
|
||||
ssize_t ret;
|
||||
|
||||
mutex_lock(&smd_pkt_devp->lock);
|
||||
ret = scnprintf(buf, PAGE_SIZE, "%d\n", smd_pkt_devp->open_tout);
|
||||
mutex_unlock(&smd_pkt_devp->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(open_timeout, 0664, open_timeout_show, open_timeout_store);
|
||||
|
||||
static int smd_pkt_rpdev_probe(struct rpmsg_device *rpdev)
|
||||
{
|
||||
struct device_driver *drv = rpdev->dev.driver;
|
||||
struct rpmsg_driver *rpdrv = drv_to_rpdrv(drv);
|
||||
struct smd_pkt_dev *smd_pkt_devp = rpdrv_to_smd_pkt_devp(rpdrv);
|
||||
|
||||
mutex_lock(&smd_pkt_devp->lock);
|
||||
smd_pkt_devp->rpdev = rpdev;
|
||||
smd_pkt_devp->notify_state_update = true;
|
||||
mutex_unlock(&smd_pkt_devp->lock);
|
||||
dev_set_drvdata(&rpdev->dev, smd_pkt_devp);
|
||||
complete_all(&smd_pkt_devp->ch_open);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smd_pkt_rpdev_cb(struct rpmsg_device *rpdev, void *buf, int len,
|
||||
void *priv, u32 addr)
|
||||
{
|
||||
struct smd_pkt_dev *smd_pkt_devp = dev_get_drvdata(&rpdev->dev);
|
||||
unsigned long flags;
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!smd_pkt_devp)
|
||||
return -EINVAL;
|
||||
|
||||
skb = alloc_skb(len, GFP_ATOMIC);
|
||||
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
skb_put_data(skb, buf, len);
|
||||
|
||||
spin_lock_irqsave(&smd_pkt_devp->queue_lock, flags);
|
||||
|
||||
skb_queue_tail(&smd_pkt_devp->queue, skb);
|
||||
spin_unlock_irqrestore(&smd_pkt_devp->queue_lock, flags);
|
||||
|
||||
/* wake up any blocking processes, waiting for new data */
|
||||
wake_up_interruptible(&smd_pkt_devp->readq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smd_pkt_rpdev_sigs(struct rpmsg_device *rpdev, u32 old, u32 new)
|
||||
{
|
||||
struct device_driver *drv = rpdev->dev.driver;
|
||||
struct rpmsg_driver *rpdrv = drv_to_rpdrv(drv);
|
||||
struct smd_pkt_dev *smd_pkt_devp = rpdrv_to_smd_pkt_devp(rpdrv);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&smd_pkt_devp->queue_lock, flags);
|
||||
smd_pkt_devp->sig_change = true;
|
||||
spin_unlock_irqrestore(&smd_pkt_devp->queue_lock, flags);
|
||||
|
||||
/* wake up any blocking processes, waiting for new data */
|
||||
wake_up_interruptible(&smd_pkt_devp->readq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* smd_pkt_tiocmset() - set the signals for smd_pkt device
|
||||
* smd_pkt_devp: Pointer to the smd_pkt device structure.
|
||||
* cmd: IOCTL command.
|
||||
* arg: Arguments to the ioctl call.
|
||||
*
|
||||
* This function is used to set the signals on the smd pkt device
|
||||
* when userspace client do a ioctl() system call with TIOCMBIS,
|
||||
* TIOCMBIC and TICOMSET.
|
||||
*/
|
||||
static int smd_pkt_tiocmset(struct smd_pkt_dev *smd_pkt_devp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
u32 lsigs, rsigs, val;
|
||||
int ret;
|
||||
|
||||
ret = get_user(val, (u32 *)arg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rpmsg_get_sigs(smd_pkt_devp->rpdev->ept, &lsigs, &rsigs);
|
||||
if (ret < 0) {
|
||||
SMD_PKT_ERR("Get signals failed[%d]\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case TIOCMBIS:
|
||||
lsigs |= val;
|
||||
break;
|
||||
case TIOCMBIC:
|
||||
lsigs &= ~val;
|
||||
break;
|
||||
case TIOCMSET:
|
||||
lsigs = val;
|
||||
break;
|
||||
}
|
||||
|
||||
return rpmsg_set_sigs(smd_pkt_devp->rpdev->ept, lsigs);
|
||||
SMD_PKT_INFO("sigs[0x%x] ret[%d]\n", lsigs, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* smd_pkt_ioctl() - ioctl() syscall for the smd_pkt device
|
||||
* file: Pointer to the file structure.
|
||||
* cmd: IOCTL command.
|
||||
* arg: Arguments to the ioctl call.
|
||||
*
|
||||
* This function is used to ioctl on the smd pkt device when
|
||||
* userspace client do a ioctl() system call. All input arguments are
|
||||
* validated by the virtual file system before calling this function.
|
||||
*/
|
||||
static long smd_pkt_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct smd_pkt_dev *smd_pkt_devp;
|
||||
unsigned long flags;
|
||||
u32 lsigs, rsigs, resetsigs;
|
||||
int ret;
|
||||
|
||||
smd_pkt_devp = file->private_data;
|
||||
|
||||
if (!smd_pkt_devp || refcount_read(&smd_pkt_devp->refcount) == 1) {
|
||||
SMD_PKT_ERR("invalid device handle\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mutex_lock_interruptible(&smd_pkt_devp->lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (!completion_done(&smd_pkt_devp->ch_open)) {
|
||||
SMD_PKT_ERR("%s channel in reset\n", smd_pkt_devp->ch_name);
|
||||
if ((cmd == TIOCMGET) && (smd_pkt_devp->notify_state_update)) {
|
||||
resetsigs = TIOCM_OUT1 | TIOCM_OUT2;
|
||||
smd_pkt_devp->notify_state_update = false;
|
||||
mutex_unlock(&smd_pkt_devp->lock);
|
||||
|
||||
SMD_PKT_ERR("%s: reset notified resetsigs=%d\n",
|
||||
smd_pkt_devp->ch_name, resetsigs);
|
||||
ret = put_user(resetsigs, (uint32_t __user *)arg);
|
||||
return ret;
|
||||
}
|
||||
mutex_unlock(&smd_pkt_devp->lock);
|
||||
return -ENETRESET;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case TIOCMGET:
|
||||
resetsigs = 0;
|
||||
spin_lock_irqsave(&smd_pkt_devp->queue_lock, flags);
|
||||
smd_pkt_devp->sig_change = false;
|
||||
if (smd_pkt_devp->notify_state_update) {
|
||||
resetsigs = TIOCM_OUT2;
|
||||
smd_pkt_devp->notify_state_update = false;
|
||||
SMD_PKT_ERR("%s: reset notified resetsigs=%d\n",
|
||||
smd_pkt_devp->ch_name, resetsigs);
|
||||
}
|
||||
spin_unlock_irqrestore(&smd_pkt_devp->queue_lock, flags);
|
||||
|
||||
ret = rpmsg_get_sigs(smd_pkt_devp->rpdev->ept, &lsigs, &rsigs);
|
||||
if (!ret)
|
||||
ret = put_user(rsigs | resetsigs,
|
||||
(uint32_t __user *)arg);
|
||||
break;
|
||||
case TIOCMSET:
|
||||
case TIOCMBIS:
|
||||
case TIOCMBIC:
|
||||
ret = smd_pkt_tiocmset(smd_pkt_devp, cmd, arg);
|
||||
break;
|
||||
case SMD_PKT_IOCTL_QUEUE_RX_INTENT:
|
||||
/* Return success to not break userspace client logic */
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
SMD_PKT_ERR("unrecognized ioctl command 0x%x\n", cmd);
|
||||
ret = -ENOIOCTLCMD;
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_unlock(&smd_pkt_devp->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* smd_pkt_read() - read() syscall for the smd_pkt device
|
||||
* file: Pointer to the file structure.
|
||||
* buf: Pointer to the userspace buffer.
|
||||
* count: Number bytes to read from the file.
|
||||
* ppos: Pointer to the position into the file.
|
||||
*
|
||||
* This function is used to Read the data from smd pkt device when
|
||||
* userspace client do a read() system call. All input arguments are
|
||||
* validated by the virtual file system before calling this function.
|
||||
*/
|
||||
ssize_t smd_pkt_read(struct file *file,
|
||||
char __user *buf,
|
||||
size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
|
||||
struct smd_pkt_dev *smd_pkt_devp = file->private_data;
|
||||
unsigned long flags;
|
||||
int use;
|
||||
|
||||
if (!smd_pkt_devp ||
|
||||
refcount_read(&smd_pkt_devp->refcount) == 1) {
|
||||
SMD_PKT_ERR("invalid device handle\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!completion_done(&smd_pkt_devp->ch_open)) {
|
||||
SMD_PKT_ERR("%s channel in reset\n", smd_pkt_devp->ch_name);
|
||||
return -ENETRESET;
|
||||
}
|
||||
|
||||
SMD_PKT_INFO(
|
||||
"begin for %s by %s:%d ref_cnt[%d], remaining[%d], count[%d]\n",
|
||||
smd_pkt_devp->ch_name, current->comm,
|
||||
task_pid_nr(current),
|
||||
refcount_read(&smd_pkt_devp->refcount),
|
||||
smd_pkt_devp->rdata_len, count);
|
||||
|
||||
spin_lock_irqsave(&smd_pkt_devp->queue_lock, flags);
|
||||
|
||||
/* Wait for data in the queue */
|
||||
if (skb_queue_empty(&smd_pkt_devp->queue) && !smd_pkt_devp->rskb) {
|
||||
spin_unlock_irqrestore(&smd_pkt_devp->queue_lock, flags);
|
||||
|
||||
if (file->f_flags & O_NONBLOCK)
|
||||
return -EAGAIN;
|
||||
|
||||
/* Wait until we get data or the endpoint goes away */
|
||||
if (wait_event_interruptible(smd_pkt_devp->readq,
|
||||
!skb_queue_empty(&smd_pkt_devp->queue) ||
|
||||
!completion_done(&smd_pkt_devp->ch_open)))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
spin_lock_irqsave(&smd_pkt_devp->queue_lock, flags);
|
||||
}
|
||||
|
||||
if (!smd_pkt_devp->rskb) {
|
||||
smd_pkt_devp->rskb = skb_dequeue(&smd_pkt_devp->queue);
|
||||
if (!smd_pkt_devp->rskb) {
|
||||
spin_unlock_irqrestore(&smd_pkt_devp->queue_lock,
|
||||
flags);
|
||||
return -EFAULT;
|
||||
}
|
||||
smd_pkt_devp->rdata = smd_pkt_devp->rskb->data;
|
||||
smd_pkt_devp->rdata_len = smd_pkt_devp->rskb->len;
|
||||
}
|
||||
spin_unlock_irqrestore(&smd_pkt_devp->queue_lock, flags);
|
||||
|
||||
use = min_t(size_t, count, smd_pkt_devp->rdata_len);
|
||||
|
||||
if (copy_to_user(buf, smd_pkt_devp->rdata, use))
|
||||
use = -EFAULT;
|
||||
|
||||
if (!smd_pkt_devp->fragmented_read && smd_pkt_devp->rdata_len == use) {
|
||||
struct sk_buff *skb = smd_pkt_devp->rskb;
|
||||
|
||||
spin_lock_irqsave(&smd_pkt_devp->queue_lock, flags);
|
||||
smd_pkt_devp->rskb = NULL;
|
||||
smd_pkt_devp->rdata = NULL;
|
||||
smd_pkt_devp->rdata_len = 0;
|
||||
spin_unlock_irqrestore(&smd_pkt_devp->queue_lock, flags);
|
||||
|
||||
kfree_skb(skb);
|
||||
} else {
|
||||
struct sk_buff *skb = NULL;
|
||||
|
||||
spin_lock_irqsave(&smd_pkt_devp->queue_lock, flags);
|
||||
smd_pkt_devp->rdata += use;
|
||||
smd_pkt_devp->rdata_len -= use;
|
||||
if (smd_pkt_devp->rdata_len == 0) {
|
||||
skb = smd_pkt_devp->rskb;
|
||||
smd_pkt_devp->rskb = NULL;
|
||||
smd_pkt_devp->rdata = NULL;
|
||||
smd_pkt_devp->rdata_len = 0;
|
||||
}
|
||||
spin_unlock_irqrestore(&smd_pkt_devp->queue_lock, flags);
|
||||
if (skb)
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
SMD_PKT_INFO("end for %s by %s:%d ret[%d], remaining[%d]\n",
|
||||
smd_pkt_devp->ch_name, current->comm,
|
||||
task_pid_nr(current), use, smd_pkt_devp->rdata_len);
|
||||
|
||||
return use;
|
||||
}
|
||||
|
||||
/**
|
||||
* smd_pkt_write() - write() syscall for the smd_pkt device
|
||||
* file: Pointer to the file structure.
|
||||
* buf: Pointer to the userspace buffer.
|
||||
* count: Number bytes to read from the file.
|
||||
* ppos: Pointer to the position into the file.
|
||||
*
|
||||
* This function is used to write the data to smd pkt device when
|
||||
* userspace client do a write() system call. All input arguments are
|
||||
* validated by the virtual file system before calling this function.
|
||||
*/
|
||||
ssize_t smd_pkt_write(struct file *file,
|
||||
const char __user *buf,
|
||||
size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct smd_pkt_dev *smd_pkt_devp = file->private_data;
|
||||
void *kbuf;
|
||||
int ret;
|
||||
|
||||
smd_pkt_devp = file->private_data;
|
||||
|
||||
if (!smd_pkt_devp || refcount_read(&smd_pkt_devp->refcount) == 1) {
|
||||
SMD_PKT_ERR("invalid device handle\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
SMD_PKT_INFO("begin to %s buffer_size %zu\n",
|
||||
smd_pkt_devp->ch_name, count);
|
||||
kbuf = memdup_user(buf, count);
|
||||
if (IS_ERR(kbuf))
|
||||
return PTR_ERR(kbuf);
|
||||
|
||||
if (mutex_lock_interruptible(&smd_pkt_devp->lock)) {
|
||||
ret = -ERESTARTSYS;
|
||||
goto free_kbuf;
|
||||
}
|
||||
|
||||
if (!completion_done(&smd_pkt_devp->ch_open) ||
|
||||
!smd_pkt_devp->rpdev) {
|
||||
SMD_PKT_ERR("%s channel in reset\n", smd_pkt_devp->ch_name);
|
||||
ret = -ENETRESET;
|
||||
goto unlock_ch;
|
||||
}
|
||||
|
||||
if (file->f_flags & O_NONBLOCK)
|
||||
ret = rpmsg_trysend(smd_pkt_devp->rpdev->ept, kbuf, count);
|
||||
else
|
||||
ret = rpmsg_send(smd_pkt_devp->rpdev->ept, kbuf, count);
|
||||
|
||||
unlock_ch:
|
||||
mutex_unlock(&smd_pkt_devp->lock);
|
||||
|
||||
free_kbuf:
|
||||
kfree(kbuf);
|
||||
SMD_PKT_INFO("finish to %s ret %d\n", smd_pkt_devp->ch_name, ret);
|
||||
return ret < 0 ? ret : count;
|
||||
}
|
||||
|
||||
/**
|
||||
* smd_pkt_poll() - poll() syscall for the smd_pkt device
|
||||
* file: Pointer to the file structure.
|
||||
* wait: pointer to Poll table.
|
||||
*
|
||||
* This function is used to poll on the smd pkt device when
|
||||
* userspace client do a poll() system call. All input arguments are
|
||||
* validated by the virtual file system before calling this function.
|
||||
*/
|
||||
static unsigned int smd_pkt_poll(struct file *file, poll_table *wait)
|
||||
|
||||
{
|
||||
struct smd_pkt_dev *smd_pkt_devp = file->private_data;
|
||||
unsigned int mask = 0;
|
||||
unsigned long flags;
|
||||
|
||||
smd_pkt_devp = file->private_data;
|
||||
|
||||
if (!smd_pkt_devp || refcount_read(&smd_pkt_devp->refcount) == 1) {
|
||||
SMD_PKT_ERR("invalid device handle\n");
|
||||
return POLLERR;
|
||||
}
|
||||
|
||||
if (!completion_done(&smd_pkt_devp->ch_open)) {
|
||||
SMD_PKT_ERR("%s channel in reset\n", smd_pkt_devp->ch_name);
|
||||
return POLLHUP;
|
||||
}
|
||||
|
||||
poll_wait(file, &smd_pkt_devp->readq, wait);
|
||||
|
||||
mutex_lock(&smd_pkt_devp->lock);
|
||||
|
||||
if (!completion_done(&smd_pkt_devp->ch_open) ||
|
||||
!smd_pkt_devp->rpdev) {
|
||||
SMD_PKT_ERR("%s channel reset after wait\n",
|
||||
smd_pkt_devp->ch_name);
|
||||
mutex_unlock(&smd_pkt_devp->lock);
|
||||
return POLLHUP;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&smd_pkt_devp->queue_lock, flags);
|
||||
if (!skb_queue_empty(&smd_pkt_devp->queue) || smd_pkt_devp->rskb)
|
||||
mask |= POLLIN | POLLRDNORM;
|
||||
|
||||
if (smd_pkt_devp->sig_change)
|
||||
mask |= POLLPRI;
|
||||
spin_unlock_irqrestore(&smd_pkt_devp->queue_lock, flags);
|
||||
|
||||
mask |= rpmsg_poll(smd_pkt_devp->rpdev->ept, file, wait);
|
||||
|
||||
mutex_unlock(&smd_pkt_devp->lock);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static void smd_pkt_rpdev_remove(struct rpmsg_device *rpdev)
|
||||
{
|
||||
struct device_driver *drv = rpdev->dev.driver;
|
||||
struct rpmsg_driver *rpdrv = drv_to_rpdrv(drv);
|
||||
struct smd_pkt_dev *smd_pkt_devp = rpdrv_to_smd_pkt_devp(rpdrv);
|
||||
|
||||
mutex_lock(&smd_pkt_devp->lock);
|
||||
smd_pkt_devp->rpdev = NULL;
|
||||
smd_pkt_devp->notify_state_update = true;
|
||||
mutex_unlock(&smd_pkt_devp->lock);
|
||||
|
||||
dev_set_drvdata(&rpdev->dev, NULL);
|
||||
|
||||
/* wake up any blocked readers */
|
||||
reinit_completion(&smd_pkt_devp->ch_open);
|
||||
wake_up_interruptible(&smd_pkt_devp->readq);
|
||||
}
|
||||
|
||||
/**
|
||||
* smd_pkt_open() - open() syscall for the smd_pkt device
|
||||
* inode: Pointer to the inode structure.
|
||||
* file: Pointer to the file structure.
|
||||
*
|
||||
* This function is used to open the smd pkt device when
|
||||
* userspace client do a open() system call. All input arguments are
|
||||
* validated by the virtual file system before calling this function.
|
||||
*/
|
||||
int smd_pkt_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct smd_pkt_dev *smd_pkt_devp = cdev_to_smd_pkt_devp(inode->i_cdev);
|
||||
int tout = msecs_to_jiffies(smd_pkt_devp->open_tout * 1000);
|
||||
struct device *dev = &smd_pkt_devp->dev;
|
||||
int ret;
|
||||
|
||||
refcount_inc(&smd_pkt_devp->refcount);
|
||||
get_device(dev);
|
||||
|
||||
SMD_PKT_INFO("begin for %s by %s:%d ref_cnt[%d]\n",
|
||||
smd_pkt_devp->ch_name, current->comm,
|
||||
task_pid_nr(current),
|
||||
refcount_read(&smd_pkt_devp->refcount));
|
||||
|
||||
ret = wait_for_completion_interruptible_timeout(&smd_pkt_devp->ch_open,
|
||||
tout);
|
||||
if (ret <= 0) {
|
||||
refcount_dec(&smd_pkt_devp->refcount);
|
||||
put_device(dev);
|
||||
SMD_PKT_INFO("timeout for %s by %s:%d\n", smd_pkt_devp->ch_name,
|
||||
current->comm, task_pid_nr(current));
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
file->private_data = smd_pkt_devp;
|
||||
|
||||
SMD_PKT_INFO("end for %s by %s:%d ref_cnt[%d]\n",
|
||||
smd_pkt_devp->ch_name, current->comm,
|
||||
task_pid_nr(current),
|
||||
refcount_read(&smd_pkt_devp->refcount));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* smd_pkt_release() - release operation on smd_pkt device
|
||||
* inode: Pointer to the inode structure.
|
||||
* file: Pointer to the file structure.
|
||||
*
|
||||
* This function is used to release the smd pkt device when
|
||||
* userspace client do a close() system call. All input arguments are
|
||||
* validated by the virtual file system before calling this function.
|
||||
*/
|
||||
int smd_pkt_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct smd_pkt_dev *smd_pkt_devp = cdev_to_smd_pkt_devp(inode->i_cdev);
|
||||
struct device *dev = &smd_pkt_devp->dev;
|
||||
struct sk_buff *skb;
|
||||
unsigned long flags;
|
||||
|
||||
SMD_PKT_INFO("for %s by %s:%d ref_cnt[%d]\n",
|
||||
smd_pkt_devp->ch_name, current->comm,
|
||||
task_pid_nr(current),
|
||||
refcount_read(&smd_pkt_devp->refcount));
|
||||
|
||||
refcount_dec(&smd_pkt_devp->refcount);
|
||||
if (refcount_read(&smd_pkt_devp->refcount) == 1) {
|
||||
spin_lock_irqsave(&smd_pkt_devp->queue_lock, flags);
|
||||
|
||||
/* Discard all SKBs */
|
||||
if (smd_pkt_devp->rskb) {
|
||||
kfree_skb(smd_pkt_devp->rskb);
|
||||
smd_pkt_devp->rskb = NULL;
|
||||
smd_pkt_devp->rdata = NULL;
|
||||
smd_pkt_devp->rdata_len = 0;
|
||||
}
|
||||
|
||||
while (!skb_queue_empty(&smd_pkt_devp->queue)) {
|
||||
skb = skb_dequeue(&smd_pkt_devp->queue);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
wake_up_interruptible(&smd_pkt_devp->readq);
|
||||
smd_pkt_devp->sig_change = false;
|
||||
spin_unlock_irqrestore(&smd_pkt_devp->queue_lock, flags);
|
||||
}
|
||||
|
||||
put_device(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations smd_pkt_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = smd_pkt_open,
|
||||
.release = smd_pkt_release,
|
||||
.read = smd_pkt_read,
|
||||
.write = smd_pkt_write,
|
||||
.poll = smd_pkt_poll,
|
||||
.unlocked_ioctl = smd_pkt_ioctl,
|
||||
.compat_ioctl = smd_pkt_ioctl,
|
||||
};
|
||||
|
||||
static ssize_t name_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct smd_pkt_dev *smd_pkt_devp = dev_to_smd_pkt_devp(dev);
|
||||
|
||||
return scnprintf(buf, RPMSG_NAME_SIZE, "%s\n", smd_pkt_devp->ch_name);
|
||||
}
|
||||
static DEVICE_ATTR_RO(name);
|
||||
|
||||
static struct attribute *smd_pkt_device_attrs[] = {
|
||||
&dev_attr_name.attr,
|
||||
NULL
|
||||
};
|
||||
ATTRIBUTE_GROUPS(smd_pkt_device);
|
||||
|
||||
/**
|
||||
* parse_smdpkt_devicetree() - parse device tree binding for a subnode
|
||||
*
|
||||
* np: pointer to a device tree node
|
||||
* smd_pkt_devp: pointer to SMD PACKET device
|
||||
*
|
||||
* Return: 0 on success, standard Linux error codes on error.
|
||||
*/
|
||||
static int smd_pkt_parse_devicetree(struct device_node *np,
|
||||
struct smd_pkt_dev *smd_pkt_devp)
|
||||
{
|
||||
char *key;
|
||||
int ret;
|
||||
|
||||
key = "qcom,smdpkt-edge";
|
||||
|
||||
ret = of_property_read_string(np, key, &smd_pkt_devp->edge);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
key = "qcom,smdpkt-ch-name";
|
||||
|
||||
ret = of_property_read_string(np, key, &smd_pkt_devp->ch_name);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
key = "qcom,smdpkt-dev-name";
|
||||
|
||||
ret = of_property_read_string(np, key, &smd_pkt_devp->dev_name);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
key = "qcom,smdpkt-fragmented-read";
|
||||
|
||||
smd_pkt_devp->fragmented_read = of_property_read_bool(np, key);
|
||||
|
||||
SMD_PKT_INFO("Parsed %s:%s /dev/%s\n", smd_pkt_devp->edge,
|
||||
smd_pkt_devp->ch_name,
|
||||
smd_pkt_devp->dev_name,
|
||||
smd_pkt_devp->fragmented_read);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
SMD_PKT_ERR("missing key: %s\n", key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void smd_pkt_release_device(struct device *dev)
|
||||
{
|
||||
struct smd_pkt_dev *smd_pkt_devp = dev_to_smd_pkt_devp(dev);
|
||||
|
||||
ida_simple_remove(&smd_pkt_minor_ida, MINOR(smd_pkt_devp->dev.devt));
|
||||
cdev_del(&smd_pkt_devp->cdev);
|
||||
}
|
||||
|
||||
static int smd_pkt_init_rpmsg(struct smd_pkt_dev *smd_pkt_devp)
|
||||
{
|
||||
struct rpmsg_driver *rpdrv = &smd_pkt_devp->drv;
|
||||
struct device *dev = &smd_pkt_devp->dev;
|
||||
struct rpmsg_device_id *match;
|
||||
char *drv_name;
|
||||
|
||||
/* zalloc array of two to NULL terminate the match list */
|
||||
match = devm_kzalloc(dev, 2 * sizeof(*match), GFP_KERNEL);
|
||||
if (!match)
|
||||
return -ENOMEM;
|
||||
|
||||
snprintf(match->name, RPMSG_NAME_SIZE, "%s", smd_pkt_devp->ch_name);
|
||||
|
||||
drv_name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"%s_%s", "msm_smd_pkt", smd_pkt_devp->dev_name);
|
||||
if (!drv_name)
|
||||
return -ENOMEM;
|
||||
|
||||
rpdrv->probe = smd_pkt_rpdev_probe;
|
||||
rpdrv->remove = smd_pkt_rpdev_remove;
|
||||
rpdrv->callback = smd_pkt_rpdev_cb;
|
||||
rpdrv->signals = smd_pkt_rpdev_sigs;
|
||||
rpdrv->id_table = match;
|
||||
rpdrv->drv.name = drv_name;
|
||||
|
||||
register_rpmsg_driver(rpdrv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* smdpkt - Create smd packet device and add cdev
|
||||
* parent: pointer to the parent device of this smd packet device
|
||||
* np: pointer to device node this smd packet device represents
|
||||
*
|
||||
* return: 0 for success, Standard Linux errors
|
||||
*/
|
||||
static int smd_pkt_create_device(struct device *parent,
|
||||
struct device_node *np)
|
||||
{
|
||||
struct smd_pkt_dev *smd_pkt_devp;
|
||||
struct device *dev;
|
||||
int ret;
|
||||
|
||||
smd_pkt_devp = devm_kzalloc(parent, sizeof(*smd_pkt_devp), GFP_KERNEL);
|
||||
if (!smd_pkt_devp)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = smd_pkt_parse_devicetree(np, smd_pkt_devp);
|
||||
if (ret < 0) {
|
||||
SMD_PKT_ERR("failed to parse dt ret:%d\n", ret);
|
||||
goto free_smd_pkt_devp;
|
||||
}
|
||||
|
||||
dev = &smd_pkt_devp->dev;
|
||||
mutex_init(&smd_pkt_devp->lock);
|
||||
refcount_set(&smd_pkt_devp->refcount, 1);
|
||||
init_completion(&smd_pkt_devp->ch_open);
|
||||
|
||||
/* Default open timeout for open is 120 sec */
|
||||
smd_pkt_devp->open_tout = 120;
|
||||
smd_pkt_devp->sig_change = false;
|
||||
|
||||
spin_lock_init(&smd_pkt_devp->queue_lock);
|
||||
|
||||
smd_pkt_devp->rskb = NULL;
|
||||
smd_pkt_devp->rdata = NULL;
|
||||
smd_pkt_devp->rdata_len = 0;
|
||||
|
||||
skb_queue_head_init(&smd_pkt_devp->queue);
|
||||
init_waitqueue_head(&smd_pkt_devp->readq);
|
||||
|
||||
device_initialize(dev);
|
||||
dev->class = smd_pkt_class;
|
||||
dev->parent = parent;
|
||||
dev->groups = smd_pkt_device_groups;
|
||||
dev_set_drvdata(dev, smd_pkt_devp);
|
||||
|
||||
cdev_init(&smd_pkt_devp->cdev, &smd_pkt_fops);
|
||||
smd_pkt_devp->cdev.owner = THIS_MODULE;
|
||||
ret = ida_simple_get(&smd_pkt_minor_ida, 0, num_smd_pkt_devs,
|
||||
GFP_KERNEL);
|
||||
if (ret < 0)
|
||||
goto free_dev;
|
||||
|
||||
dev->devt = MKDEV(MAJOR(smd_pkt_major), ret);
|
||||
dev_set_name(dev, smd_pkt_devp->dev_name, ret);
|
||||
|
||||
ret = cdev_add(&smd_pkt_devp->cdev, dev->devt, 1);
|
||||
if (ret) {
|
||||
SMD_PKT_ERR("cdev_add failed for %s ret:%d\n",
|
||||
smd_pkt_devp->dev_name, ret);
|
||||
goto free_minor_ida;
|
||||
}
|
||||
|
||||
dev->release = smd_pkt_release_device;
|
||||
ret = device_add(dev);
|
||||
if (ret) {
|
||||
SMD_PKT_ERR("device_create failed for %s ret:%d\n",
|
||||
smd_pkt_devp->dev_name, ret);
|
||||
goto free_minor_ida;
|
||||
}
|
||||
|
||||
if (device_create_file(dev, &dev_attr_open_timeout))
|
||||
SMD_PKT_ERR("device_create_file failed for %s\n",
|
||||
smd_pkt_devp->dev_name);
|
||||
|
||||
if (smd_pkt_init_rpmsg(smd_pkt_devp))
|
||||
goto free_minor_ida;
|
||||
|
||||
return 0;
|
||||
|
||||
free_minor_ida:
|
||||
ida_simple_remove(&smd_pkt_minor_ida, MINOR(dev->devt));
|
||||
free_dev:
|
||||
put_device(dev);
|
||||
|
||||
free_smd_pkt_devp:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* smd_pkt_deinit() - De-initialize this module
|
||||
*
|
||||
* This function frees all the memory and unregisters the char device region.
|
||||
*/
|
||||
static void smd_pkt_deinit(void)
|
||||
{
|
||||
class_destroy(smd_pkt_class);
|
||||
unregister_chrdev_region(MAJOR(smd_pkt_major), num_smd_pkt_devs);
|
||||
}
|
||||
|
||||
/**
|
||||
* smd_pkt_probe() - Probe a SMD packet device
|
||||
*
|
||||
* pdev: Pointer to platform device.
|
||||
*
|
||||
* return: 0 on success, standard Linux error codes on error.
|
||||
*
|
||||
* This function is called when the underlying device tree driver registers
|
||||
* a platform device, mapped to a SMD packet device.
|
||||
*/
|
||||
static int msm_smd_pkt_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *cn;
|
||||
int ret;
|
||||
|
||||
num_smd_pkt_devs = of_get_child_count(dev->of_node);
|
||||
ret = alloc_chrdev_region(&smd_pkt_major, 0, num_smd_pkt_devs,
|
||||
"smdpkt");
|
||||
|
||||
if (ret < 0) {
|
||||
SMD_PKT_ERR("alloc_chrdev_region failed ret:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
smd_pkt_class = class_create(THIS_MODULE, "smdpkt");
|
||||
if (IS_ERR(smd_pkt_class)) {
|
||||
SMD_PKT_ERR("class_create failed ret:%ld\n",
|
||||
PTR_ERR(smd_pkt_class));
|
||||
goto error_deinit;
|
||||
}
|
||||
|
||||
for_each_child_of_node(dev->of_node, cn)
|
||||
smd_pkt_create_device(dev, cn);
|
||||
|
||||
SMD_PKT_INFO("smd Packet Port Driver Initialized\n");
|
||||
return 0;
|
||||
|
||||
error_deinit:
|
||||
smd_pkt_deinit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id msm_smd_pkt_match_table[] = {
|
||||
{ .compatible = "qcom,smdpkt" },
|
||||
{},
|
||||
};
|
||||
|
||||
static struct platform_driver msm_smd_pkt_driver = {
|
||||
.probe = msm_smd_pkt_probe,
|
||||
.driver = {
|
||||
.name = MODULE_NAME,
|
||||
.of_match_table = msm_smd_pkt_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* smd_pkt_init() - Initialization function for this module
|
||||
*
|
||||
* returns: 0 on success, standard Linux error code otherwise.
|
||||
*/
|
||||
static int __init smd_pkt_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = platform_driver_register(&msm_smd_pkt_driver);
|
||||
if (rc) {
|
||||
SMD_PKT_ERR("msm_smd_pkt driver register failed %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
smd_pkt_ilctxt = ipc_log_context_create(SMD_PKT_IPC_LOG_PAGE_CNT,
|
||||
"smd_pkt", 0);
|
||||
return 0;
|
||||
}
|
||||
module_init(smd_pkt_init);
|
||||
|
||||
/**
|
||||
* smd_pkt_exit() - Exit function for this module
|
||||
*
|
||||
* This function is used to cleanup the module during the exit.
|
||||
*/
|
||||
static void __exit smd_pkt_exit(void)
|
||||
{
|
||||
smd_pkt_deinit();
|
||||
}
|
||||
module_exit(smd_pkt_exit);
|
||||
|
||||
MODULE_DESCRIPTION("MSM Shared Memory Packet Port");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -1828,7 +1828,7 @@ urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
|
|||
return urandom_read_nowarn(file, buf, nbytes, ppos);
|
||||
}
|
||||
|
||||
static ssize_t __maybe_unused
|
||||
static ssize_t
|
||||
random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
|
||||
{
|
||||
int ret;
|
||||
|
@ -1958,7 +1958,7 @@ static int random_fasync(int fd, struct file *filp, int on)
|
|||
}
|
||||
|
||||
const struct file_operations random_fops = {
|
||||
.read = urandom_read,
|
||||
.read = random_read,
|
||||
.write = random_write,
|
||||
.poll = random_poll,
|
||||
.unlocked_ioctl = random_ioctl,
|
||||
|
|
|
@ -584,3 +584,27 @@ config CLOCK_CPU_OSM_660
|
|||
frequency and voltage requests for multiple clusters via the
|
||||
existence of multiple OSM domains.
|
||||
Say Y if you want to support OSM clocks.
|
||||
|
||||
config SDM_GCC_429W
|
||||
tristate "SDM429w Global Clock Controller"
|
||||
depends on COMMON_CLK_QCOM
|
||||
help
|
||||
Support for the global clock controller on SDM429w/QM215 devices.
|
||||
Say Y if you want to use peripheral devices such as UART, SPI,
|
||||
I2C, USB, UFS, SDCC, Display, Camera, Video etc.
|
||||
|
||||
config SDM_DEBUGCC_429W
|
||||
tristate "SDM429W Debug Clock Controller"
|
||||
depends on SDM_GCC_429W
|
||||
help
|
||||
Support for the debug clock controller on Qualcomm Technologies, Inc
|
||||
SDM429W/QM215 devices.
|
||||
Say Y if you want to support the clock measurement functionality.
|
||||
|
||||
config CLOCK_CPU_SDM
|
||||
bool "CPU SDM Clock Controller"
|
||||
depends on COMMON_CLK_QCOM
|
||||
help
|
||||
Support for the cpu clock controller on SDM based devices(e.g. QM215/SDM429).
|
||||
Say Y if you want to support CPU clock scaling using
|
||||
CPUfreq drivers for dynamic power management.
|
||||
|
|
|
@ -20,6 +20,7 @@ clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
|
|||
obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
|
||||
obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
|
||||
obj-$(CONFIG_CLOCK_CPU_OSM_660) += clk-cpu-osm-660.o
|
||||
obj-$(CONFIG_CLOCK_CPU_SDM) += clk-cpu-sdm.o
|
||||
obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
|
||||
obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
|
||||
obj-$(CONFIG_IPQ_GCC_8074) += gcc-ipq8074.o
|
||||
|
@ -55,9 +56,11 @@ obj-$(CONFIG_QM_GCC_SCUBA) += gcc-scuba.o
|
|||
obj-$(CONFIG_QM_GPUCC_SCUBA) += gpucc-scuba.o
|
||||
obj-$(CONFIG_QM_DEBUGCC_SCUBA) += debugcc-scuba.o
|
||||
obj-$(CONFIG_SDM_CAMCC_LAGOON) += camcc-lagoon.o
|
||||
obj-$(CONFIG_SDM_DEBUGCC_429W) += debugcc-sdm429w.o
|
||||
obj-$(CONFIG_SDM_DEBUGCC_LAGOON) += debugcc-lagoon.o
|
||||
obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o
|
||||
obj-$(CONFIG_SDM_DISPCC_LAGOON) += dispcc-lagoon.o
|
||||
obj-$(CONFIG_SDM_GCC_429W) += gcc-sdm429w.o
|
||||
obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o
|
||||
obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
|
||||
obj-$(CONFIG_SDM_GCC_LAGOON) += gcc-lagoon.o
|
||||
|
|
|
@ -17,7 +17,15 @@
|
|||
#include "clk-regmap.h"
|
||||
#include "clk-regmap-mux-div.h"
|
||||
|
||||
static const u32 gpll0_a53cc_map[] = { 4, 5 };
|
||||
enum apcs_mux_clk_parent {
|
||||
P_GPLL0,
|
||||
P_APCS_CPU_PLL,
|
||||
};
|
||||
|
||||
static const struct parent_map gpll0_a53cc_map[] = {
|
||||
{ P_GPLL0, 4 },
|
||||
{ P_APCS_CPU_PLL, 5 },
|
||||
};
|
||||
|
||||
static const char * const gpll0_a53cc[] = {
|
||||
"gpll0_vote",
|
||||
|
|
1009
drivers/clk/qcom/clk-cpu-sdm.c
Normal file
1009
drivers/clk/qcom/clk-cpu-sdm.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2016, 2019-2020 The Linux Foundation. All rights reserved. */
|
||||
/* Copyright (c) 2016, 2019-2021 The Linux Foundation. All rights reserved. */
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/export.h>
|
||||
|
@ -15,6 +15,7 @@
|
|||
#include "clk-regmap.h"
|
||||
#include "clk-debug.h"
|
||||
#include "common.h"
|
||||
#include "gdsc-debug.h"
|
||||
|
||||
static struct clk_hw *measure;
|
||||
|
||||
|
@ -413,16 +414,22 @@ EXPORT_SYMBOL(map_debug_bases);
|
|||
|
||||
/**
|
||||
* qcom_clk_dump - dump the HW specific registers associated with this clock
|
||||
* and regulator
|
||||
* @clk: clock source
|
||||
* @regulator: regulator
|
||||
* @calltrace: indicates whether calltrace is required
|
||||
*
|
||||
* This function attempts to print all the registers associated with the
|
||||
* clock and it's parents.
|
||||
* clock, it's parents and regulator.
|
||||
*/
|
||||
void qcom_clk_dump(struct clk *clk, bool calltrace)
|
||||
void qcom_clk_dump(struct clk *clk, struct regulator *regulator,
|
||||
bool calltrace)
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
|
||||
if (!IS_ERR_OR_NULL(regulator))
|
||||
gdsc_debug_print_regs(regulator);
|
||||
|
||||
if (IS_ERR_OR_NULL(clk))
|
||||
return;
|
||||
|
||||
|
@ -437,22 +444,27 @@ EXPORT_SYMBOL(qcom_clk_dump);
|
|||
|
||||
/**
|
||||
* qcom_clk_bulk_dump - dump the HW specific registers associated with clocks
|
||||
* @clks: the clk_bulk_data table of consumer
|
||||
* and regulator
|
||||
* @num_clks: the number of clk_bulk_data
|
||||
* @clks: the clk_bulk_data table of consumer
|
||||
* @regulator: regulator source
|
||||
* @calltrace: indicates whether calltrace is required
|
||||
*
|
||||
* This function attempts to print all the registers associated with the
|
||||
* clock and it's parents for all the clocks in the list.
|
||||
* clocks in the list and regulator.
|
||||
*/
|
||||
void qcom_clk_bulk_dump(int num_clks, struct clk_bulk_data *clks,
|
||||
bool calltrace)
|
||||
struct regulator *regulator, bool calltrace)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!IS_ERR_OR_NULL(regulator))
|
||||
gdsc_debug_print_regs(regulator);
|
||||
|
||||
if (IS_ERR_OR_NULL(clks))
|
||||
return;
|
||||
|
||||
for (i = 0; i < num_clks; i++)
|
||||
qcom_clk_dump(clks[i].clk, calltrace);
|
||||
qcom_clk_dump(clks[i].clk, NULL, calltrace);
|
||||
}
|
||||
EXPORT_SYMBOL(qcom_clk_bulk_dump);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2013, 2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
|
@ -342,3 +342,64 @@ const struct clk_ops clk_pll_sr2_ops = {
|
|||
.determine_rate = clk_pll_determine_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_pll_sr2_ops);
|
||||
|
||||
static int
|
||||
clk_pll_hf_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate)
|
||||
{
|
||||
struct clk_pll *pll = to_clk_pll(hw);
|
||||
bool enabled;
|
||||
u32 mode, l_val;
|
||||
u32 enable_mask = PLL_OUTCTRL | PLL_BYPASSNL | PLL_RESET_N;
|
||||
|
||||
regmap_read(pll->clkr.regmap, pll->mode_reg, &mode);
|
||||
enabled = (mode & enable_mask) == enable_mask;
|
||||
|
||||
if (enabled)
|
||||
clk_pll_disable(hw);
|
||||
|
||||
l_val = rate / prate;
|
||||
|
||||
regmap_update_bits(pll->clkr.regmap, pll->l_reg, 0x3ff, l_val);
|
||||
regmap_update_bits(pll->clkr.regmap, pll->m_reg, 0x7ffff, 0);
|
||||
regmap_update_bits(pll->clkr.regmap, pll->n_reg, 0x7ffff, 1);
|
||||
|
||||
if (enabled)
|
||||
clk_pll_sr2_enable(hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void clk_pll_hf_list_registers(struct seq_file *f, struct clk_hw *hw)
|
||||
{
|
||||
struct clk_pll *pll = to_clk_pll(hw);
|
||||
int size, i, val;
|
||||
|
||||
static struct clk_register_data data[] = {
|
||||
{"PLL_MODE", 0x0},
|
||||
{"PLL_L_VAL", 0x4},
|
||||
{"PLL_M_VAL", 0x8},
|
||||
{"PLL_N_VAL", 0xC},
|
||||
{"PLL_USER_CTL", 0x10},
|
||||
{"PLL_CONFIG_CTL", 0x14},
|
||||
{"PLL_STATUS_CTL", 0x1C},
|
||||
};
|
||||
|
||||
size = ARRAY_SIZE(data);
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
regmap_read(pll->clkr.regmap, pll->mode_reg + data[i].offset,
|
||||
&val);
|
||||
clock_debug_output(f, false,
|
||||
"%20s: 0x%.8x\n", data[i].name, val);
|
||||
}
|
||||
}
|
||||
|
||||
const struct clk_ops clk_pll_hf_ops = {
|
||||
.enable = clk_pll_sr2_enable,
|
||||
.disable = clk_pll_disable,
|
||||
.set_rate = clk_pll_hf_set_rate,
|
||||
.recalc_rate = clk_pll_recalc_rate,
|
||||
.determine_rate = clk_pll_determine_rate,
|
||||
.list_registers = clk_pll_hf_list_registers,
|
||||
};
|
||||
EXPORT_SYMBOL(clk_pll_hf_ops);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2013, 2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
|
@ -63,6 +63,7 @@ struct clk_pll {
|
|||
extern const struct clk_ops clk_pll_ops;
|
||||
extern const struct clk_ops clk_pll_vote_ops;
|
||||
extern const struct clk_ops clk_pll_sr2_ops;
|
||||
extern const struct clk_ops clk_pll_hf_ops;
|
||||
|
||||
#define to_clk_pll(_hw) container_of(to_clk_regmap(_hw), struct clk_pll, clkr)
|
||||
|
||||
|
|
|
@ -56,20 +56,26 @@ int mux_div_set_src_div(struct clk_regmap_mux_div *md, u32 src, u32 div)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(mux_div_set_src_div);
|
||||
|
||||
static void mux_div_get_src_div(struct clk_regmap_mux_div *md, u32 *src,
|
||||
u32 *div)
|
||||
int mux_div_get_src_div(struct clk_regmap_mux_div *md, u32 *src,
|
||||
u32 *div)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 val, d, s;
|
||||
const char *name = clk_hw_get_name(&md->clkr.hw);
|
||||
|
||||
regmap_read(md->clkr.regmap, CMD_RCGR + md->reg_offset, &val);
|
||||
ret = regmap_read(md->clkr.regmap, CMD_RCGR + md->reg_offset, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (val & CMD_RCGR_DIRTY_CFG) {
|
||||
pr_err("%s: RCG configuration is pending\n", name);
|
||||
return;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
regmap_read(md->clkr.regmap, CFG_RCGR + md->reg_offset, &val);
|
||||
ret = regmap_read(md->clkr.regmap, CFG_RCGR + md->reg_offset, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
s = (val >> md->src_shift);
|
||||
s &= BIT(md->src_width) - 1;
|
||||
*src = s;
|
||||
|
@ -77,6 +83,8 @@ static void mux_div_get_src_div(struct clk_regmap_mux_div *md, u32 *src,
|
|||
d = (val >> md->hid_shift);
|
||||
d &= BIT(md->hid_width) - 1;
|
||||
*div = d;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool is_better_rate(unsigned long req, unsigned long best,
|
||||
|
@ -142,7 +150,7 @@ static int __mux_div_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
|
|||
|
||||
if (is_better_rate(rate, best_rate, actual_rate)) {
|
||||
best_rate = actual_rate;
|
||||
best_src = md->parent_map[i];
|
||||
best_src = md->parent_map[i].cfg;
|
||||
best_div = div - 1;
|
||||
}
|
||||
|
||||
|
@ -169,7 +177,7 @@ static u8 mux_div_get_parent(struct clk_hw *hw)
|
|||
mux_div_get_src_div(md, &src, &div);
|
||||
|
||||
for (i = 0; i < clk_hw_get_num_parents(hw); i++)
|
||||
if (src == md->parent_map[i])
|
||||
if (src == md->parent_map[i].cfg)
|
||||
return i;
|
||||
|
||||
pr_err("%s: Can't find parent with src %d\n", name, src);
|
||||
|
@ -180,7 +188,7 @@ static int mux_div_set_parent(struct clk_hw *hw, u8 index)
|
|||
{
|
||||
struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
|
||||
|
||||
return mux_div_set_src_div(md, md->parent_map[index], md->div);
|
||||
return mux_div_set_src_div(md, md->parent_map[index].cfg, md->div);
|
||||
}
|
||||
|
||||
static int mux_div_set_rate(struct clk_hw *hw,
|
||||
|
@ -197,7 +205,7 @@ static int mux_div_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
|
|||
struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
|
||||
|
||||
return __mux_div_set_rate_and_parent(hw, rate, prate,
|
||||
md->parent_map[index]);
|
||||
md->parent_map[index].cfg);
|
||||
}
|
||||
|
||||
static unsigned long mux_div_recalc_rate(struct clk_hw *hw, unsigned long prate)
|
||||
|
@ -209,7 +217,7 @@ static unsigned long mux_div_recalc_rate(struct clk_hw *hw, unsigned long prate)
|
|||
|
||||
mux_div_get_src_div(md, &src, &div);
|
||||
for (i = 0; i < num_parents; i++)
|
||||
if (src == md->parent_map[i]) {
|
||||
if (src == md->parent_map[i].cfg) {
|
||||
struct clk_hw *p = clk_hw_get_parent_by_index(hw, i);
|
||||
unsigned long parent_rate = clk_hw_get_rate(p);
|
||||
|
||||
|
@ -220,7 +228,23 @@ static unsigned long mux_div_recalc_rate(struct clk_hw *hw, unsigned long prate)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mux_div_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
|
||||
|
||||
return mux_div_set_src_div(md, md->src, md->div);
|
||||
}
|
||||
|
||||
static void mux_div_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);
|
||||
|
||||
mux_div_set_src_div(md, md->safe_src, md->safe_div);
|
||||
}
|
||||
|
||||
const struct clk_ops clk_regmap_mux_div_ops = {
|
||||
.enable = mux_div_enable,
|
||||
.disable = mux_div_disable,
|
||||
.get_parent = mux_div_get_parent,
|
||||
.set_parent = mux_div_set_parent,
|
||||
.set_rate = mux_div_set_rate,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define __QCOM_CLK_REGMAP_MUX_DIV_H__
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include "common.h"
|
||||
#include "clk-regmap.h"
|
||||
|
||||
/**
|
||||
|
@ -19,7 +20,19 @@
|
|||
* @src_shift: lowest bit of source select field
|
||||
* @div: the divider raw configuration value
|
||||
* @src: the mux index which will be used if the clock is enabled
|
||||
* @parent_map: map from parent_names index to src_sel field
|
||||
* @safe_src: the safe source mux value we switch to, while the main PLL is
|
||||
* reconfigured
|
||||
* @safe_div: the safe divider value that we set, while the main PLL is
|
||||
* reconfigured
|
||||
* @safe_freq: When switching rates from A to B, the mux div clock will
|
||||
* instead switch from A -> safe_freq -> B. This allows the
|
||||
* mux_div clock to change rates while enabled, even if this
|
||||
* behavior is not supported by the parent clocks.
|
||||
* If changing the rate of parent A also causes the rate of
|
||||
* parent B to change, then safe_freq must be defined.
|
||||
* safe_freq is expected to have a source clock which is always
|
||||
* on and runs at only one rate.
|
||||
* @parent_map: pointer to parent_map struct
|
||||
* @clkr: handle between common and hardware-specific interfaces
|
||||
* @pclk: the input PLL clock
|
||||
* @clk_nb: clock notifier for rate changes of the input PLL
|
||||
|
@ -32,7 +45,10 @@ struct clk_regmap_mux_div {
|
|||
u32 src_shift;
|
||||
u32 div;
|
||||
u32 src;
|
||||
const u32 *parent_map;
|
||||
u32 safe_src;
|
||||
u32 safe_div;
|
||||
unsigned long safe_freq;
|
||||
const struct parent_map *parent_map;
|
||||
struct clk_regmap clkr;
|
||||
struct clk *pclk;
|
||||
struct notifier_block clk_nb;
|
||||
|
@ -40,5 +56,6 @@ struct clk_regmap_mux_div {
|
|||
|
||||
extern const struct clk_ops clk_regmap_mux_div_ops;
|
||||
extern int mux_div_set_src_div(struct clk_regmap_mux_div *md, u32 src, u32 div);
|
||||
int mux_div_get_src_div(struct clk_regmap_mux_div *md, u32 *src, u32 *div);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1080,6 +1080,108 @@ static const struct rpm_smd_clk_desc rpm_clk_sdm660 = {
|
|||
.num_clks = ARRAY_SIZE(sdm660_clks),
|
||||
};
|
||||
|
||||
/* sdm429w SMD clocks */
|
||||
DEFINE_CLK_SMD_RPM_BRANCH(sdm429w, bi_tcxo, bi_tcxo_ao,
|
||||
QCOM_SMD_RPM_MISC_CLK, 0, 19200000);
|
||||
DEFINE_CLK_SMD_RPM(sdm429w, pnoc_clk, pnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
|
||||
DEFINE_CLK_SMD_RPM(sdm429w, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
|
||||
|
||||
DEFINE_CLK_SMD_RPM(sdm429w, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
|
||||
|
||||
DEFINE_CLK_SMD_RPM(sdm429w, sysmmnoc_clk, sysmmnoc_a_clk, QCOM_SMD_RPM_BUS_CLK,
|
||||
2);
|
||||
|
||||
DEFINE_CLK_SMD_RPM_QDSS(sdm429w, qdss_clk, qdss_a_clk, QCOM_SMD_RPM_MISC_CLK,
|
||||
1);
|
||||
|
||||
DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm429w, bb_clk1, bb_clk1_a, 1);
|
||||
DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm429w, bb_clk2, bb_clk2_a, 2);
|
||||
DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm429w, rf_clk2, rf_clk2_a, 5);
|
||||
DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm429w, div_clk2, div_clk2_a, 0xc);
|
||||
|
||||
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(sdm429w, bb_clk1_pin, bb_clk1_a_pin, 1);
|
||||
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(sdm429w, bb_clk2_pin, bb_clk2_a_pin, 2);
|
||||
|
||||
/* Voter clocks */
|
||||
static DEFINE_CLK_VOTER(pnoc_msmbus_clk, pnoc_clk, LONG_MAX);
|
||||
static DEFINE_CLK_VOTER(pnoc_msmbus_a_clk, pnoc_a_clk, LONG_MAX);
|
||||
static DEFINE_CLK_VOTER(pnoc_keepalive_a_clk, pnoc_a_clk, LONG_MAX);
|
||||
|
||||
static DEFINE_CLK_VOTER(sysmmnoc_msmbus_clk, sysmmnoc_clk, LONG_MAX);
|
||||
static DEFINE_CLK_VOTER(sysmmnoc_msmbus_a_clk, sysmmnoc_a_clk, LONG_MAX);
|
||||
|
||||
static DEFINE_CLK_VOTER(pnoc_usb_clk, pnoc_clk, LONG_MAX);
|
||||
static DEFINE_CLK_VOTER(snoc_usb_clk, snoc_clk, LONG_MAX);
|
||||
static DEFINE_CLK_VOTER(bimc_usb_clk, bimc_clk, LONG_MAX);
|
||||
|
||||
static DEFINE_CLK_VOTER(pnoc_usb_a_clk, pnoc_a_clk, LONG_MAX);
|
||||
static DEFINE_CLK_VOTER(snoc_usb_a_clk, snoc_a_clk, LONG_MAX);
|
||||
static DEFINE_CLK_VOTER(bimc_usb_a_clk, bimc_a_clk, LONG_MAX);
|
||||
|
||||
static DEFINE_CLK_VOTER(snoc_wcnss_a_clk, snoc_a_clk, LONG_MAX);
|
||||
static DEFINE_CLK_VOTER(bimc_wcnss_a_clk, bimc_a_clk, LONG_MAX);
|
||||
|
||||
/* Branch Voter clocks */
|
||||
static DEFINE_CLK_BRANCH_VOTER(bi_tcxo_lpm_clk, bi_tcxo);
|
||||
|
||||
static struct clk_hw *qm215_clks[] = {
|
||||
[RPM_SMD_XO_CLK_SRC] = &sdm429w_bi_tcxo.hw,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &sdm429w_bi_tcxo_ao.hw,
|
||||
[RPM_SMD_QDSS_CLK] = &sdm429w_qdss_clk.hw,
|
||||
[RPM_SMD_QDSS_A_CLK] = &sdm429w_qdss_a_clk.hw,
|
||||
[RPM_SMD_PNOC_CLK] = &sdm429w_pnoc_clk.hw,
|
||||
[RPM_SMD_PNOC_A_CLK] = &sdm429w_pnoc_a_clk.hw,
|
||||
[RPM_SMD_SNOC_CLK] = &sdm429w_snoc_clk.hw,
|
||||
[RPM_SMD_SNOC_A_CLK] = &sdm429w_snoc_a_clk.hw,
|
||||
[RPM_SMD_BIMC_CLK] = &sdm429w_bimc_clk.hw,
|
||||
[RPM_SMD_BIMC_A_CLK] = &sdm429w_bimc_a_clk.hw,
|
||||
[RPM_SMD_BIMC_GPU_CLK] = &scuba_bimc_gpu_clk.hw,
|
||||
[RPM_SMD_BIMC_GPU_A_CLK] = &scuba_bimc_gpu_a_clk.hw,
|
||||
[RPM_SMD_SYSMMNOC_CLK] = &sdm429w_sysmmnoc_clk.hw,
|
||||
[RPM_SMD_SYSMMNOC_A_CLK] = &sdm429w_sysmmnoc_a_clk.hw,
|
||||
[RPM_SMD_BB_CLK1] = &sdm429w_bb_clk1.hw,
|
||||
[RPM_SMD_BB_CLK1_A] = &sdm429w_bb_clk1_a.hw,
|
||||
[RPM_SMD_BB_CLK2] = &sdm429w_bb_clk2.hw,
|
||||
[RPM_SMD_BB_CLK2_A] = &sdm429w_bb_clk2_a.hw,
|
||||
[RPM_SMD_BB_CLK1_PIN] = &sdm429w_bb_clk1_pin.hw,
|
||||
[RPM_SMD_BB_CLK1_A_PIN] = &sdm429w_bb_clk1_a_pin.hw,
|
||||
[RPM_SMD_BB_CLK2_PIN] = &sdm429w_bb_clk2_pin.hw,
|
||||
[RPM_SMD_BB_CLK2_A_PIN] = &sdm429w_bb_clk2_a_pin.hw,
|
||||
[RPM_SMD_RF_CLK2] = &sdm429w_rf_clk2.hw,
|
||||
[RPM_SMD_RF_CLK2_A] = &sdm429w_rf_clk2_a.hw,
|
||||
[RPM_SMD_DIV_CLK2] = &sdm429w_div_clk2.hw,
|
||||
[RPM_SMD_DIV_A_CLK2] = &sdm429w_div_clk2_a.hw,
|
||||
[PNOC_MSMBUS_CLK] = &pnoc_msmbus_clk.hw,
|
||||
[PNOC_MSMBUS_A_CLK] = &pnoc_msmbus_a_clk.hw,
|
||||
[PNOC_KEEPALIVE_A_CLK] = &pnoc_keepalive_a_clk.hw,
|
||||
[SNOC_MSMBUS_CLK] = &snoc_msmbus_clk.hw,
|
||||
[SNOC_MSMBUS_A_CLK] = &snoc_msmbus_a_clk.hw,
|
||||
[BIMC_MSMBUS_CLK] = &bimc_msmbus_clk.hw,
|
||||
[BIMC_MSMBUS_A_CLK] = &bimc_msmbus_a_clk.hw,
|
||||
[PNOC_USB_CLK] = &pnoc_usb_clk.hw,
|
||||
[PNOC_USB_A_CLK] = &pnoc_usb_a_clk.hw,
|
||||
[SNOC_USB_CLK] = &snoc_usb_clk.hw,
|
||||
[SNOC_USB_A_CLK] = &snoc_usb_a_clk.hw,
|
||||
[BIMC_USB_CLK] = &bimc_usb_clk.hw,
|
||||
[BIMC_USB_A_CLK] = &bimc_usb_a_clk.hw,
|
||||
[SNOC_WCNSS_A_CLK] = &snoc_wcnss_a_clk.hw,
|
||||
[BIMC_WCNSS_A_CLK] = &bimc_wcnss_a_clk.hw,
|
||||
[SYSMMNOC_MSMBUS_CLK] = &sysmmnoc_msmbus_clk.hw,
|
||||
[SYSMMNOC_MSMBUS_A_CLK] = &sysmmnoc_msmbus_a_clk.hw,
|
||||
[CXO_SMD_OTG_CLK] = &bi_tcxo_otg_clk.hw,
|
||||
[CXO_SMD_LPM_CLK] = &bi_tcxo_lpm_clk.hw,
|
||||
[CXO_SMD_PIL_PRONTO_CLK] = &bi_tcxo_pil_pronto_clk.hw,
|
||||
[CXO_SMD_PIL_MSS_CLK] = &bi_tcxo_pil_mss_clk.hw,
|
||||
[CXO_SMD_WLAN_CLK] = &bi_tcxo_wlan_clk.hw,
|
||||
[CXO_SMD_PIL_LPASS_CLK] = &bi_tcxo_pil_lpass_clk.hw,
|
||||
};
|
||||
|
||||
static const struct rpm_smd_clk_desc rpm_clk_qm215 = {
|
||||
.clks = qm215_clks,
|
||||
.num_rpm_clks = RPM_SMD_SYSMMNOC_A_CLK,
|
||||
.num_clks = ARRAY_SIZE(qm215_clks),
|
||||
};
|
||||
|
||||
static const struct of_device_id rpm_smd_clk_match_table[] = {
|
||||
{ .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 },
|
||||
{ .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 },
|
||||
|
@ -1087,6 +1189,7 @@ static const struct of_device_id rpm_smd_clk_match_table[] = {
|
|||
{ .compatible = "qcom,rpmcc-bengal", .data = &rpm_clk_bengal},
|
||||
{ .compatible = "qcom,rpmcc-scuba", .data = &rpm_clk_scuba},
|
||||
{ .compatible = "qcom,rpmcc-sdm660", .data = &rpm_clk_sdm660 },
|
||||
{ .compatible = "qcom,rpmcc-qm215", .data = &rpm_clk_qm215 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table);
|
||||
|
@ -1097,7 +1200,7 @@ static int rpm_smd_clk_probe(struct platform_device *pdev)
|
|||
struct clk *clk;
|
||||
struct rpm_cc *rcc;
|
||||
struct clk_onecell_data *data;
|
||||
int ret, is_bengal, is_scuba, is_sdm660;
|
||||
int ret, is_bengal, is_scuba, is_sdm660, is_qm215;
|
||||
size_t num_clks, i;
|
||||
struct clk_hw **hw_clks;
|
||||
const struct rpm_smd_clk_desc *desc;
|
||||
|
@ -1115,12 +1218,22 @@ static int rpm_smd_clk_probe(struct platform_device *pdev)
|
|||
|
||||
is_sdm660 = of_device_is_compatible(pdev->dev.of_node,
|
||||
"qcom,rpmcc-sdm660");
|
||||
|
||||
is_qm215 = of_device_is_compatible(pdev->dev.of_node,
|
||||
"qcom,rpmcc-qm215");
|
||||
|
||||
if (is_sdm660) {
|
||||
ret = clk_vote_bimc(&sdm660_bimc_clk.hw, INT_MAX);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (is_qm215) {
|
||||
ret = clk_vote_bimc(&sdm429w_bimc_clk.hw, INT_MAX);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
desc = of_device_get_match_data(&pdev->dev);
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
@ -1204,6 +1317,15 @@ static int rpm_smd_clk_probe(struct platform_device *pdev)
|
|||
/* Hold an active set vote for the cnoc_periph resource */
|
||||
clk_set_rate(cnoc_periph_keepalive_a_clk.hw.clk, 19200000);
|
||||
clk_prepare_enable(cnoc_periph_keepalive_a_clk.hw.clk);
|
||||
} else if (is_qm215) {
|
||||
clk_prepare_enable(sdm429w_bi_tcxo_ao.hw.clk);
|
||||
|
||||
/*
|
||||
* Hold an active set vote for the pnoc_periph PCNOC AHB
|
||||
* resource. Sleep set vote is 0
|
||||
*/
|
||||
clk_set_rate(pnoc_keepalive_a_clk.hw.clk, 19200000);
|
||||
clk_prepare_enable(pnoc_keepalive_a_clk.hw.clk);
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "Registered RPM clocks\n");
|
||||
|
|
385
drivers/clk/qcom/debugcc-sdm429w.c
Normal file
385
drivers/clk/qcom/debugcc-sdm429w.c
Normal file
|
@ -0,0 +1,385 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "clk: %s: " fmt, __func__
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "clk-debug.h"
|
||||
#include "common.h"
|
||||
|
||||
static struct measure_clk_data debug_mux_priv = {
|
||||
.ctl_reg = 0x74004,
|
||||
.status_reg = 0x74008,
|
||||
.xo_div4_cbcr = 0x30034,
|
||||
};
|
||||
|
||||
static const char *const gcc_debug_mux_parent_names[] = {
|
||||
"gcc_ahb_clk",
|
||||
"gcc_apss_ahb_clk",
|
||||
"gcc_apss_axi_clk",
|
||||
"gcc_bimc_gfx_clk",
|
||||
"gcc_bimc_gpu_clk",
|
||||
"gcc_blsp1_ahb_clk",
|
||||
"gcc_blsp1_qup2_i2c_apps_clk",
|
||||
"gcc_blsp1_qup2_spi_apps_clk",
|
||||
"gcc_blsp1_qup3_i2c_apps_clk",
|
||||
"gcc_blsp1_qup3_spi_apps_clk",
|
||||
"gcc_blsp1_qup4_i2c_apps_clk",
|
||||
"gcc_blsp1_qup4_spi_apps_clk",
|
||||
"gcc_blsp1_sleep_clk",
|
||||
"gcc_blsp1_uart1_apps_clk",
|
||||
"gcc_blsp1_uart1_sim_clk",
|
||||
"gcc_blsp1_uart2_apps_clk",
|
||||
"gcc_blsp1_uart2_sim_clk",
|
||||
"gcc_blsp2_ahb_clk",
|
||||
"gcc_blsp2_qup1_i2c_apps_clk",
|
||||
"gcc_blsp2_qup1_spi_apps_clk",
|
||||
"gcc_blsp2_qup2_i2c_apps_clk",
|
||||
"gcc_blsp2_qup2_spi_apps_clk",
|
||||
"gcc_blsp2_qup3_i2c_apps_clk",
|
||||
"gcc_blsp2_qup3_spi_apps_clk",
|
||||
"gcc_blsp2_sleep_clk",
|
||||
"gcc_blsp2_uart1_apps_clk",
|
||||
"gcc_blsp2_uart1_sim_clk",
|
||||
"gcc_blsp2_uart2_apps_clk",
|
||||
"gcc_blsp2_uart2_sim_clk",
|
||||
"gcc_boot_rom_ahb_clk",
|
||||
"gcc_camss_ahb_clk",
|
||||
"gcc_camss_cci_ahb_clk",
|
||||
"gcc_camss_cci_clk",
|
||||
"gcc_camss_cpp_ahb_clk",
|
||||
"gcc_camss_cpp_axi_clk",
|
||||
"gcc_camss_cpp_clk",
|
||||
"gcc_camss_csi0_ahb_clk",
|
||||
"gcc_camss_csi0_clk",
|
||||
"gcc_camss_csi0phy_clk",
|
||||
"gcc_camss_csi0phytimer_clk",
|
||||
"gcc_camss_csi0pix_clk",
|
||||
"gcc_camss_csi0rdi_clk",
|
||||
"gcc_camss_csi1_ahb_clk",
|
||||
"gcc_camss_csi1_clk",
|
||||
"gcc_camss_csi1phy_clk",
|
||||
"gcc_camss_csi1phytimer_clk",
|
||||
"gcc_camss_csi1pix_clk",
|
||||
"gcc_camss_csi1rdi_clk",
|
||||
"gcc_camss_csi2_ahb_clk",
|
||||
"gcc_camss_csi2_clk",
|
||||
"gcc_camss_csi2phy_clk",
|
||||
"gcc_camss_csi2pix_clk",
|
||||
"gcc_camss_csi2rdi_clk",
|
||||
"gcc_camss_csi_vfe0_clk",
|
||||
"gcc_camss_csi_vfe1_clk",
|
||||
"gcc_camss_gp0_clk",
|
||||
"gcc_camss_gp1_clk",
|
||||
"gcc_camss_ispif_ahb_clk",
|
||||
"gcc_camss_jpeg0_clk",
|
||||
"gcc_camss_jpeg_ahb_clk",
|
||||
"gcc_camss_jpeg_axi_clk",
|
||||
"gcc_camss_mclk0_clk",
|
||||
"gcc_camss_mclk1_clk",
|
||||
"gcc_camss_mclk2_clk",
|
||||
"gcc_camss_micro_ahb_clk",
|
||||
"gcc_camss_top_ahb_clk",
|
||||
"gcc_camss_vfe0_clk",
|
||||
"gcc_camss_vfe1_ahb_clk",
|
||||
"gcc_camss_vfe1_axi_clk",
|
||||
"gcc_camss_vfe1_clk",
|
||||
"gcc_camss_vfe_ahb_clk",
|
||||
"gcc_camss_vfe_axi_clk",
|
||||
"gcc_crypto_ahb_clk",
|
||||
"gcc_crypto_axi_clk",
|
||||
"gcc_crypto_clk",
|
||||
"gcc_gp1_clk",
|
||||
"gcc_gp2_clk",
|
||||
"gcc_gp3_clk",
|
||||
"gcc_im_sleep_clk",
|
||||
"gcc_lpass_mport_axi_clk",
|
||||
"gcc_lpass_q6_axi_clk",
|
||||
"gcc_lpass_sway_clk",
|
||||
"gcc_mdss_ahb_clk",
|
||||
"gcc_mdss_axi_clk",
|
||||
"gcc_mdss_byte0_clk",
|
||||
"gcc_mdss_esc0_clk",
|
||||
"gcc_mdss_mdp_clk",
|
||||
"gcc_mdss_pclk0_clk",
|
||||
"gcc_mdss_vsync_clk",
|
||||
"gcc_mpm_ahb_clk",
|
||||
"gcc_msg_ram_ahb_clk",
|
||||
"gcc_oxili_ahb_clk",
|
||||
"gcc_oxili_aon_clk",
|
||||
"gcc_oxili_gfx3d_clk",
|
||||
"gcc_pcnoc_mpu_cfg_ahb_clk",
|
||||
"gcc_pdm2_clk",
|
||||
"gcc_pdm_ahb_clk",
|
||||
"gcc_pdm_xo4_clk",
|
||||
"gcc_prng_ahb_clk",
|
||||
"gcc_q6_mpu_cfg_ahb_clk",
|
||||
"gcc_rpm_cfg_xpu_clk",
|
||||
"gcc_sdcc1_ahb_clk",
|
||||
"gcc_sdcc1_apps_clk",
|
||||
"gcc_sdcc1_ice_core_clk",
|
||||
"gcc_sdcc2_ahb_clk",
|
||||
"gcc_sdcc2_apps_clk",
|
||||
"gcc_sec_ctrl_acc_clk",
|
||||
"gcc_sec_ctrl_ahb_clk",
|
||||
"gcc_sec_ctrl_boot_rom_patch_clk",
|
||||
"gcc_sec_ctrl_clk",
|
||||
"gcc_sec_ctrl_sense_clk",
|
||||
"gcc_tcsr_ahb_clk",
|
||||
"gcc_tlmm_ahb_clk",
|
||||
"gcc_tlmm_clk",
|
||||
"gcc_usb2a_phy_sleep_clk",
|
||||
"gcc_usb_hs_ahb_clk",
|
||||
"gcc_usb_hs_inactivity_timers_clk",
|
||||
"gcc_usb_hs_phy_cfg_ahb_clk",
|
||||
"gcc_usb_hs_system_clk",
|
||||
"gcc_venus0_ahb_clk",
|
||||
"gcc_venus0_axi_clk",
|
||||
"gcc_venus0_core0_vcodec0_clk",
|
||||
"gcc_venus0_vcodec0_clk",
|
||||
"gcc_xo_clk",
|
||||
"gcc_xo_div4_clk",
|
||||
"gcc_gfx_tbu_clk",
|
||||
"gcc_gfx_tcu_clk",
|
||||
"gcc_gtcu_ahb_clk",
|
||||
"gcc_bimc_clk",
|
||||
"gcc_smmu_cfg_clk",
|
||||
};
|
||||
|
||||
static int gcc_debug_mux_sels[] = {
|
||||
0x148, /* gcc_ahb_clk */
|
||||
0x168, /* gcc_apss_ahb_clk */
|
||||
0x169, /* gcc_apss_axi_clk */
|
||||
0x2D, /* gcc_bimc_gfx_clk */
|
||||
0x157, /* gcc_bimc_gpu_clk */
|
||||
0x88, /* gcc_blsp1_ahb_clk */
|
||||
0x90, /* gcc_blsp1_qup2_i2c_apps_clk */
|
||||
0x8E, /* gcc_blsp1_qup2_spi_apps_clk */
|
||||
0x94, /* gcc_blsp1_qup3_i2c_apps_clk */
|
||||
0x93, /* gcc_blsp1_qup3_spi_apps_clk */
|
||||
0x96, /* gcc_blsp1_qup4_i2c_apps_clk */
|
||||
0x95, /* gcc_blsp1_qup4_spi_apps_clk */
|
||||
0x89, /* gcc_blsp1_sleep_clk */
|
||||
0x8C, /* gcc_blsp1_uart1_apps_clk */
|
||||
0x8D, /* gcc_blsp1_uart1_sim_clk */
|
||||
0x91, /* gcc_blsp1_uart2_apps_clk */
|
||||
0x92, /* gcc_blsp1_uart2_sim_clk */
|
||||
0x98, /* gcc_blsp2_ahb_clk */
|
||||
0x9B, /* gcc_blsp2_qup1_i2c_apps_clk */
|
||||
0x9A, /* gcc_blsp2_qup1_spi_apps_clk */
|
||||
0xA0, /* gcc_blsp2_qup2_i2c_apps_clk */
|
||||
0x9E, /* gcc_blsp2_qup2_spi_apps_clk */
|
||||
0xA4, /* gcc_blsp2_qup3_i2c_apps_clk */
|
||||
0xA3, /* gcc_blsp2_qup3_spi_apps_clk */
|
||||
0x99, /* gcc_blsp2_sleep_clk */
|
||||
0x9C, /* gcc_blsp2_uart1_apps_clk */
|
||||
0x9D, /* gcc_blsp2_uart1_sim_clk */
|
||||
0x9A, /* gcc_blsp2_uart2_apps_clk */
|
||||
0xA2, /* gcc_blsp2_uart2_sim_clk */
|
||||
0xF8, /* gcc_boot_rom_ahb_clk */
|
||||
0xA8, /* gcc_camss_ahb_clk */
|
||||
0xB0, /* gcc_camss_cci_ahb_clk */
|
||||
0xAF, /* gcc_camss_cci_clk */
|
||||
0xBA, /* gcc_camss_cpp_ahb_clk */
|
||||
0x1A3, /* gcc_camss_cpp_axi_clk */
|
||||
0xB9, /* gcc_camss_cpp_clk */
|
||||
0xC1, /* gcc_camss_csi0_ahb_clk */
|
||||
0xC0, /* gcc_camss_csi0_clk */
|
||||
0xC2, /* gcc_camss_csi0phy_clk */
|
||||
0xB1, /* gcc_camss_csi0phytimer_clk */
|
||||
0xC4, /* gcc_camss_csi0pix_clk */
|
||||
0xC3, /* gcc_camss_csi0rdi_clk */
|
||||
0xC6, /* gcc_camss_csi1_ahb_clk */
|
||||
0xC5, /* gcc_camss_csi1_clk */
|
||||
0xC7, /* gcc_camss_csi1phy_clk */
|
||||
0xB2, /* gcc_camss_csi1phytimer_clk */
|
||||
0xE1, /* gcc_camss_csi1pix_clk */
|
||||
0xE0, /* gcc_camss_csi1rdi_clk */
|
||||
0xE4, /* gcc_camss_csi2_ahb_clk */
|
||||
0xE3, /* gcc_camss_csi2_clk */
|
||||
0xE5, /* gcc_camss_csi2phy_clk */
|
||||
0xE7, /* gcc_camss_csi2pix_clk */
|
||||
0xE6, /* gcc_camss_csi2rdi_clk */
|
||||
0xBF, /* gcc_camss_csi_vfe0_clk */
|
||||
0x1A0, /* gcc_camss_csi_vfe1_clk */
|
||||
0xAB, /* gcc_camss_gp0_clk */
|
||||
0xAC, /* gcc_camss_gp1_clk */
|
||||
0xE2, /* gcc_camss_ispif_ahb_clk */
|
||||
0xB3, /* gcc_camss_jpeg0_clk */
|
||||
0xB4, /* gcc_camss_jpeg_ahb_clk */
|
||||
0xB5, /* gcc_camss_jpeg_axi_clk */
|
||||
0xAD, /* gcc_camss_mclk0_clk */
|
||||
0xAE, /* gcc_camss_mclk1_clk */
|
||||
0x1BD, /* gcc_camss_mclk2_clk */
|
||||
0xAA, /* gcc_camss_micro_ahb_clk */
|
||||
0xA9, /* gcc_camss_top_ahb_clk */
|
||||
0xB8, /* gcc_camss_vfe0_clk */
|
||||
0x1A2, /* gcc_camss_vfe1_ahb_clk */
|
||||
0x1A4, /* gcc_camss_vfe1_axi_clk */
|
||||
0x1A1, /* gcc_camss_vfe1_clk */
|
||||
0xBB, /* gcc_camss_vfe_ahb_clk */
|
||||
0xBC, /* gcc_camss_vfe_axi_clk */
|
||||
0x13A, /* gcc_crypto_ahb_clk */
|
||||
0x139, /* gcc_crypto_axi_clk */
|
||||
0x138, /* gcc_crypto_clk */
|
||||
0x10, /* gcc_gp1_clk */
|
||||
0x11, /* gcc_gp2_clk */
|
||||
0x12, /* gcc_gp3_clk */
|
||||
0x14B, /* gcc_im_sleep_clk */
|
||||
0x162, /* gcc_lpass_mport_axi_clk */
|
||||
0x160, /* gcc_lpass_q6_axi_clk */
|
||||
0x163, /* gcc_lpass_sway_clk */
|
||||
0x1F6, /* gcc_mdss_ahb_clk */
|
||||
0x1F7, /* gcc_mdss_axi_clk */
|
||||
0x1FC, /* gcc_mdss_byte0_clk */
|
||||
0x1FD, /* gcc_mdss_esc0_clk */
|
||||
0x1F9, /* gcc_mdss_mdp_clk */
|
||||
0x1F8, /* gcc_mdss_pclk0_clk */
|
||||
0x1FB, /* gcc_mdss_vsync_clk */
|
||||
0x110, /* gcc_mpm_ahb_clk */
|
||||
0x100, /* gcc_msg_ram_ahb_clk */
|
||||
0x1EB, /* gcc_oxili_ahb_clk */
|
||||
0xEE, /* gcc_oxili_aon_clk */
|
||||
0x1EA, /* gcc_oxili_gfx3d_clk */
|
||||
0xC9, /* gcc_pcnoc_mpu_cfg_ahb_clk */
|
||||
0xD2, /* gcc_pdm2_clk */
|
||||
0xD0, /* gcc_pdm_ahb_clk */
|
||||
0xD1, /* gcc_pdm_xo4_clk */
|
||||
0xD8, /* gcc_prng_ahb_clk */
|
||||
0xC8, /* gcc_q6_mpu_cfg_ahb_clk */
|
||||
0x38, /* gcc_rpm_cfg_xpu_clk */
|
||||
0x69, /* gcc_sdcc1_ahb_clk */
|
||||
0x68, /* gcc_sdcc1_apps_clk */
|
||||
0x6A, /* gcc_sdcc1_ice_core_clk */
|
||||
0x71, /* gcc_sdcc2_ahb_clk */
|
||||
0x70, /* gcc_sdcc2_apps_clk */
|
||||
0x120, /* gcc_sec_ctrl_acc_clk */
|
||||
0x121, /* gcc_sec_ctrl_ahb_clk */
|
||||
0x124, /* gcc_sec_ctrl_boot_rom_patch_clk */
|
||||
0x122, /* gcc_sec_ctrl_clk */
|
||||
0x123, /* gcc_sec_ctrl_sense_clk */
|
||||
0xE8, /* gcc_tcsr_ahb_clk */
|
||||
0x108, /* gcc_tlmm_ahb_clk */
|
||||
0x109, /* gcc_tlmm_clk */
|
||||
0x63, /* gcc_usb2a_phy_sleep_clk */
|
||||
0x61, /* gcc_usb_hs_ahb_clk */
|
||||
0x62, /* gcc_usb_hs_inactivity_timers_clk */
|
||||
0x64, /* gcc_usb_hs_phy_cfg_ahb_clk */
|
||||
0x60, /* gcc_usb_hs_system_clk */
|
||||
0x1F3, /* gcc_venus0_ahb_clk */
|
||||
0x1F2, /* gcc_venus0_axi_clk */
|
||||
0x1B8, /* gcc_venus0_core0_vcodec0_clk */
|
||||
0x1F1, /* gcc_venus0_vcodec0_clk */
|
||||
0x149, /* gcc_xo_clk */
|
||||
0x14A, /* gcc_xo_div4_clk */
|
||||
0x52, /* gcc_gfx_tbu_clk */
|
||||
0x53, /* gcc_gfx_tcu_clk */
|
||||
0x58, /* gcc_gtcu_ahb_clk */
|
||||
0x15A, /* gcc_bimc_clk */
|
||||
0x5B, /* gcc_smmu_cfg_clk */
|
||||
};
|
||||
|
||||
static struct clk_debug_mux gcc_debug_mux = {
|
||||
.priv = &debug_mux_priv,
|
||||
.en_mask = BIT(16),
|
||||
.debug_offset = 0x74000,
|
||||
.post_div_offset = 0x74000,
|
||||
.cbcr_offset = 0x74000,
|
||||
.src_sel_mask = 0x1FF,
|
||||
.src_sel_shift = 0,
|
||||
.post_div_mask = 0xF000,
|
||||
.post_div_shift = 12,
|
||||
.post_div_val = 1,
|
||||
.mux_sels = gcc_debug_mux_sels,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_debug_mux",
|
||||
.ops = &clk_debug_mux_ops,
|
||||
.parent_names = gcc_debug_mux_parent_names,
|
||||
.num_parents = ARRAY_SIZE(gcc_debug_mux_parent_names),
|
||||
.flags = CLK_IS_MEASURE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct mux_regmap_names mux_list[] = {
|
||||
{ .mux = &gcc_debug_mux, .regmap_name = "qcom,gcc" },
|
||||
};
|
||||
|
||||
static const struct of_device_id clk_debug_match_table[] = {
|
||||
{ .compatible = "qcom,sdm429w-debugcc" },
|
||||
{ .compatible = "qcom,qm215-debugcc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static int clk_debug_sdm429w_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk;
|
||||
int ret, i;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(gcc_debug_mux_parent_names) !=
|
||||
ARRAY_SIZE(gcc_debug_mux_sels));
|
||||
|
||||
clk = devm_clk_get(&pdev->dev, "xo_clk_src");
|
||||
if (IS_ERR(clk)) {
|
||||
if (PTR_ERR(clk) != -EPROBE_DEFER)
|
||||
dev_err(&pdev->dev, "Unable to get xo clock\n");
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
|
||||
debug_mux_priv.cxo = clk;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mux_list); i++) {
|
||||
ret = map_debug_bases(pdev, mux_list[i].regmap_name,
|
||||
mux_list[i].mux);
|
||||
if (ret == -EBADR)
|
||||
continue;
|
||||
else if (ret)
|
||||
return ret;
|
||||
|
||||
clk = devm_clk_register(&pdev->dev, &mux_list[i].mux->hw);
|
||||
if (IS_ERR(clk)) {
|
||||
dev_err(&pdev->dev, "Unable to register %s, err:(%d)\n",
|
||||
clk_hw_get_name(&mux_list[i].mux->hw),
|
||||
PTR_ERR(clk));
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
}
|
||||
|
||||
ret = clk_debug_measure_register(&gcc_debug_mux.hw);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Could not register Measure clocks\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "Registered debug measure clocks\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver clk_debug_driver = {
|
||||
.probe = clk_debug_sdm429w_probe,
|
||||
.driver = {
|
||||
.name = "sdm429w-debugcc",
|
||||
.of_match_table = clk_debug_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init clk_debug_sdm429w_init(void)
|
||||
{
|
||||
return platform_driver_register(&clk_debug_driver);
|
||||
}
|
||||
fs_initcall(clk_debug_sdm429w_init);
|
||||
|
||||
MODULE_DESCRIPTION("QTI DEBUG CC SDM429W Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
4461
drivers/clk/qcom/gcc-sdm429w.c
Normal file
4461
drivers/clk/qcom/gcc-sdm429w.c
Normal file
File diff suppressed because it is too large
Load diff
11
drivers/clk/qcom/gdsc-debug.h
Normal file
11
drivers/clk/qcom/gdsc-debug.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __QCOM_GDSC_DEBUG_H__
|
||||
#define __QCOM_GDSC_DEBUG_H__
|
||||
|
||||
void gdsc_debug_print_regs(struct regulator *regulator);
|
||||
|
||||
#endif /* __QCOM_GDSC_DEBUG_H__ */
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
@ -22,6 +22,8 @@
|
|||
#include <linux/clk/qcom.h>
|
||||
|
||||
#include <dt-bindings/regulator/qcom,rpmh-regulator-levels.h>
|
||||
#include "../../regulator/internal.h"
|
||||
#include "gdsc-debug.h"
|
||||
|
||||
/* GDSCR */
|
||||
#define PWR_ON_MASK BIT(31)
|
||||
|
@ -615,13 +617,38 @@ static struct regulator_ops gdsc_ops = {
|
|||
.get_mode = gdsc_get_mode,
|
||||
};
|
||||
|
||||
static const struct regmap_config gdsc_regmap_config = {
|
||||
static struct regmap_config gdsc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x8,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
void gdsc_debug_print_regs(struct regulator *regulator)
|
||||
{
|
||||
struct gdsc *sc = rdev_get_drvdata(regulator->rdev);
|
||||
uint32_t regvals[3] = {0};
|
||||
int ret;
|
||||
|
||||
if (!sc) {
|
||||
pr_err("Failed to get GDSC Handle\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = regmap_bulk_read(sc->regmap, REG_OFFSET, regvals,
|
||||
gdsc_regmap_config.max_register ? 3 : 1);
|
||||
if (ret) {
|
||||
pr_err("Failed to read %s registers\n", sc->rdesc.name);
|
||||
return;
|
||||
}
|
||||
|
||||
pr_info("Dumping %s Registers:\n", sc->rdesc.name);
|
||||
pr_info("GDSCR: 0x%.8x CFG: 0x%.8x CFG2: 0x%.8x\n",
|
||||
regvals[0], regvals[1], regvals[2]);
|
||||
}
|
||||
EXPORT_SYMBOL(gdsc_debug_print_regs);
|
||||
|
||||
static int gdsc_parse_dt_data(struct gdsc *sc, struct device *dev,
|
||||
struct regulator_init_data **init_data)
|
||||
{
|
||||
|
@ -732,6 +759,9 @@ static int gdsc_get_resources(struct gdsc *sc, struct platform_device *pdev)
|
|||
if (sc->gdscr == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
if (of_property_read_bool(dev->of_node, "qcom,no-config-gdscr"))
|
||||
gdsc_regmap_config.max_register = 0;
|
||||
|
||||
sc->regmap = devm_regmap_init_mmio(dev, sc->gdscr, &gdsc_regmap_config);
|
||||
if (!sc->regmap) {
|
||||
dev_err(dev, "Couldn't get regmap\n");
|
||||
|
|
|
@ -4,3 +4,7 @@ obj-$(CONFIG_MDSS_PLL) += mdss-pll.o
|
|||
obj-$(CONFIG_MDSS_PLL) += mdss-dsi-pll-14nm.o
|
||||
obj-$(CONFIG_MDSS_PLL) += mdss-dsi-pll-14nm-util.o
|
||||
obj-$(CONFIG_MDSS_PLL) += mdss-dp-pll-14nm.o
|
||||
obj-$(CONFIG_MDSS_PLL) += mdss-dsi-pll-28lpm.o
|
||||
obj-$(CONFIG_MDSS_PLL) += mdss-dsi-pll-28nm-util.o
|
||||
obj-$(CONFIG_MDSS_PLL) += mdss-dsi-pll-12nm.o
|
||||
obj-$(CONFIG_MDSS_PLL) += mdss-dsi-pll-12nm-util.o
|
||||
|
|
979
drivers/clk/qcom/mdss/mdss-dsi-pll-12nm-util.c
Normal file
979
drivers/clk/qcom/mdss/mdss-dsi-pll-12nm-util.c
Normal file
|
@ -0,0 +1,979 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */
|
||||
|
||||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "mdss-pll.h"
|
||||
#include "mdss-dsi-pll.h"
|
||||
#include "mdss-dsi-pll-12nm.h"
|
||||
|
||||
#define DSI_PLL_POLL_MAX_READS 15
|
||||
#define DSI_PLL_POLL_TIMEOUT_US 1000
|
||||
|
||||
int pixel_div_set_div(void *context, unsigned int reg,
|
||||
unsigned int div)
|
||||
{
|
||||
struct mdss_pll_resources *pll = context;
|
||||
struct dsi_pll_db *pdb;
|
||||
|
||||
pdb = (struct dsi_pll_db *)pll->priv;
|
||||
|
||||
/* Programming during vco_prepare. Keep this value */
|
||||
pdb->param.pixel_divhf = (div - 1);
|
||||
|
||||
pr_debug("ndx=%d div=%d divhf=%d\n",
|
||||
pll->index, div, pdb->param.pixel_divhf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pixel_div_get_div(void *context, unsigned int reg,
|
||||
unsigned int *div)
|
||||
{
|
||||
int rc;
|
||||
struct mdss_pll_resources *pll = context;
|
||||
|
||||
if (is_gdsc_disabled(pll))
|
||||
return 0;
|
||||
|
||||
rc = mdss_pll_resource_enable(pll, true);
|
||||
if (rc) {
|
||||
pr_err("Failed to enable mdss dsi pll resources\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
*div = (MDSS_PLL_REG_R(pll->pll_base, DSIPHY_SSC9) & 0x7F);
|
||||
pr_debug("pixel_div = %d\n", (*div+1));
|
||||
|
||||
mdss_pll_resource_enable(pll, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_post_div_mux_sel(void *context, unsigned int reg,
|
||||
unsigned int sel)
|
||||
{
|
||||
struct mdss_pll_resources *pll = context;
|
||||
struct dsi_pll_db *pdb;
|
||||
|
||||
pdb = (struct dsi_pll_db *)pll->priv;
|
||||
|
||||
/* Programming during vco_prepare. Keep this value */
|
||||
pdb->param.post_div_mux = sel;
|
||||
|
||||
pr_debug("ndx=%d post_div_mux_sel=%d p_div=%d\n",
|
||||
pll->index, sel, (u32) BIT(sel));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_post_div_mux_sel(void *context, unsigned int reg,
|
||||
unsigned int *sel)
|
||||
{
|
||||
u32 vco_cntrl = 0, cpbias_cntrl = 0;
|
||||
int rc;
|
||||
struct mdss_pll_resources *pll = context;
|
||||
|
||||
if (is_gdsc_disabled(pll))
|
||||
return 0;
|
||||
|
||||
rc = mdss_pll_resource_enable(pll, true);
|
||||
if (rc) {
|
||||
pr_err("Failed to enable mdss dsi pll resources\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
vco_cntrl = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_PLL_VCO_CTRL);
|
||||
vco_cntrl &= 0x30;
|
||||
|
||||
cpbias_cntrl = MDSS_PLL_REG_R(pll->pll_base,
|
||||
DSIPHY_PLL_CHAR_PUMP_BIAS_CTRL);
|
||||
cpbias_cntrl = ((cpbias_cntrl >> 6) & 0x1);
|
||||
|
||||
if (cpbias_cntrl == 0) {
|
||||
if (vco_cntrl == 0x00)
|
||||
*sel = 0;
|
||||
else if (vco_cntrl == 0x10)
|
||||
*sel = 2;
|
||||
else if (vco_cntrl == 0x20)
|
||||
*sel = 3;
|
||||
else if (vco_cntrl == 0x30)
|
||||
*sel = 4;
|
||||
} else if (cpbias_cntrl == 1) {
|
||||
if (vco_cntrl == 0x30)
|
||||
*sel = 2;
|
||||
else if (vco_cntrl == 0x00)
|
||||
*sel = 5;
|
||||
}
|
||||
|
||||
mdss_pll_resource_enable(pll, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_gp_mux_sel(void *context, unsigned int reg,
|
||||
unsigned int sel)
|
||||
{
|
||||
struct mdss_pll_resources *pll = context;
|
||||
struct dsi_pll_db *pdb;
|
||||
|
||||
pdb = (struct dsi_pll_db *)pll->priv;
|
||||
|
||||
/* Programming during vco_prepare. Keep this value */
|
||||
pdb->param.gp_div_mux = sel;
|
||||
|
||||
pr_debug("ndx=%d gp_div_mux_sel=%d gp_cntrl=%d\n",
|
||||
pll->index, sel, (u32) BIT(sel));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_gp_mux_sel(void *context, unsigned int reg,
|
||||
unsigned int *sel)
|
||||
{
|
||||
int rc;
|
||||
struct mdss_pll_resources *pll = context;
|
||||
u32 reg_val;
|
||||
|
||||
if (is_gdsc_disabled(pll))
|
||||
return 0;
|
||||
|
||||
rc = mdss_pll_resource_enable(pll, true);
|
||||
if (rc) {
|
||||
pr_err("Failed to enable mdss dsi pll resources\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
reg_val = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_PLL_CTRL);
|
||||
*sel = (reg_val >> 5) & 0x7;
|
||||
pr_debug("gp_cntrl = %d\n", *sel);
|
||||
|
||||
mdss_pll_resource_enable(pll, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool pll_is_pll_locked_12nm(struct mdss_pll_resources *pll,
|
||||
bool is_handoff)
|
||||
{
|
||||
u32 status;
|
||||
bool pll_locked;
|
||||
|
||||
/* poll for PLL ready status */
|
||||
if (readl_poll_timeout_atomic((pll->pll_base +
|
||||
DSIPHY_STAT0),
|
||||
status,
|
||||
((status & BIT(1)) > 0),
|
||||
DSI_PLL_POLL_MAX_READS,
|
||||
DSI_PLL_POLL_TIMEOUT_US)) {
|
||||
if (!is_handoff)
|
||||
pr_err("DSI PLL ndx=%d status=%x failed to Lock\n",
|
||||
pll->index, status);
|
||||
pll_locked = false;
|
||||
} else {
|
||||
pll_locked = true;
|
||||
}
|
||||
|
||||
return pll_locked;
|
||||
}
|
||||
|
||||
int dsi_pll_enable_seq_12nm(struct mdss_pll_resources *pll)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dsi_pll_db *pdb;
|
||||
void __iomem *pll_base;
|
||||
|
||||
if (!pll) {
|
||||
pr_err("Invalid PLL resources\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pdb = (struct dsi_pll_db *)pll->priv;
|
||||
if (!pdb) {
|
||||
pr_err("No priv found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pll_base = pll->pll_base;
|
||||
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SYS_CTRL, 0x49);
|
||||
wmb(); /* make sure register committed before enabling branch clocks */
|
||||
udelay(5); /* h/w recommended delay */
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SYS_CTRL, 0xc9);
|
||||
wmb(); /* make sure register committed before enabling branch clocks */
|
||||
udelay(50); /* h/w recommended delay */
|
||||
|
||||
if (!pll_is_pll_locked_12nm(pll, false)) {
|
||||
pr_err("DSI PLL ndx=%d lock failed!\n",
|
||||
pll->index);
|
||||
rc = -EINVAL;
|
||||
goto init_lock_err;
|
||||
}
|
||||
|
||||
pr_debug("DSI PLL ndx:%d Locked!\n", pll->index);
|
||||
|
||||
init_lock_err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int dsi_pll_enable(struct clk_hw *hw)
|
||||
{
|
||||
int i, rc = 0;
|
||||
struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
|
||||
struct mdss_pll_resources *pll = vco->priv;
|
||||
|
||||
/* Try all enable sequences until one succeeds */
|
||||
for (i = 0; i < vco->pll_en_seq_cnt; i++) {
|
||||
rc = vco->pll_enable_seqs[i](pll);
|
||||
pr_debug("DSI PLL %s after sequence #%d\n",
|
||||
rc ? "unlocked" : "locked", i + 1);
|
||||
if (!rc)
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc)
|
||||
pr_err("ndx=%d DSI PLL failed to lock\n", pll->index);
|
||||
else
|
||||
pll->pll_on = true;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int dsi_pll_relock(struct mdss_pll_resources *pll)
|
||||
{
|
||||
void __iomem *pll_base = pll->pll_base;
|
||||
u32 data = 0;
|
||||
int rc = 0;
|
||||
|
||||
data = MDSS_PLL_REG_R(pll_base, DSIPHY_PLL_POWERUP_CTRL);
|
||||
data &= ~BIT(1); /* remove ONPLL_OVR_EN bit */
|
||||
data |= 0x1; /* set ONPLL_OVN to 0x1 */
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_POWERUP_CTRL, data);
|
||||
ndelay(500); /* h/w recommended delay */
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SYS_CTRL, 0x49);
|
||||
wmb(); /* make sure register committed before enabling branch clocks */
|
||||
udelay(5); /* h/w recommended delay */
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SYS_CTRL, 0xc9);
|
||||
wmb(); /* make sure register committed before enabling branch clocks */
|
||||
udelay(50); /* h/w recommended delay */
|
||||
|
||||
if (!pll_is_pll_locked_12nm(pll, false)) {
|
||||
pr_err("DSI PLL ndx=%d lock failed!\n",
|
||||
pll->index);
|
||||
rc = -EINVAL;
|
||||
goto relock_err;
|
||||
}
|
||||
ndelay(50); /* h/w recommended delay */
|
||||
|
||||
data = MDSS_PLL_REG_R(pll_base, DSIPHY_PLL_CTRL);
|
||||
data |= 0x01; /* set CLK_SEL bits to 0x1 */
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CTRL, data);
|
||||
ndelay(500); /* h/w recommended delay */
|
||||
wmb(); /* make sure register committed before enabling branch clocks */
|
||||
pll->pll_on = true;
|
||||
relock_err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void dsi_pll_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
|
||||
struct mdss_pll_resources *pll = vco->priv;
|
||||
void __iomem *pll_base = pll->pll_base;
|
||||
u32 data = 0;
|
||||
|
||||
if (!pll->pll_on &&
|
||||
mdss_pll_resource_enable(pll, true)) {
|
||||
pr_err("Failed to enable mdss dsi pll=%d\n", pll->index);
|
||||
return;
|
||||
}
|
||||
|
||||
data = MDSS_PLL_REG_R(pll_base, DSIPHY_SSC0);
|
||||
data &= ~BIT(6); /* disable GP_CLK_EN */
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC0, data);
|
||||
ndelay(500); /* h/w recommended delay */
|
||||
|
||||
data = MDSS_PLL_REG_R(pll_base, DSIPHY_PLL_CTRL);
|
||||
data &= ~0x03; /* remove CLK_SEL bits */
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CTRL, data);
|
||||
ndelay(500); /* h/w recommended delay */
|
||||
|
||||
data = MDSS_PLL_REG_R(pll_base, DSIPHY_PLL_POWERUP_CTRL);
|
||||
data &= ~0x1; /* remove ONPLL_OVR bit */
|
||||
data |= BIT(1); /* set ONPLL_OVR_EN to 0x1 */
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_POWERUP_CTRL, data);
|
||||
ndelay(500); /* h/w recommended delay */
|
||||
wmb(); /* make sure register committed before disabling branch clocks */
|
||||
pll->handoff_resources = false;
|
||||
|
||||
mdss_pll_resource_enable(pll, false);
|
||||
|
||||
pll->pll_on = false;
|
||||
|
||||
pr_debug("DSI PLL ndx=%d Disabled\n", pll->index);
|
||||
}
|
||||
|
||||
static u32 __mdss_dsi_get_hsfreqrange(u64 target_freq)
|
||||
{
|
||||
u64 bitclk_rate_mhz = div_u64((target_freq * 2), 1000000);
|
||||
|
||||
if (bitclk_rate_mhz >= 80 && bitclk_rate_mhz < 90)
|
||||
return 0x00;
|
||||
else if (bitclk_rate_mhz >= 90 && bitclk_rate_mhz < 100)
|
||||
return 0x10;
|
||||
else if (bitclk_rate_mhz >= 100 && bitclk_rate_mhz < 110)
|
||||
return 0x20;
|
||||
else if (bitclk_rate_mhz >= 110 && bitclk_rate_mhz < 120)
|
||||
return 0x30;
|
||||
else if (bitclk_rate_mhz >= 120 && bitclk_rate_mhz < 130)
|
||||
return 0x01;
|
||||
else if (bitclk_rate_mhz >= 130 && bitclk_rate_mhz < 140)
|
||||
return 0x11;
|
||||
else if (bitclk_rate_mhz >= 140 && bitclk_rate_mhz < 150)
|
||||
return 0x21;
|
||||
else if (bitclk_rate_mhz >= 150 && bitclk_rate_mhz < 160)
|
||||
return 0x31;
|
||||
else if (bitclk_rate_mhz >= 160 && bitclk_rate_mhz < 170)
|
||||
return 0x02;
|
||||
else if (bitclk_rate_mhz >= 170 && bitclk_rate_mhz < 180)
|
||||
return 0x12;
|
||||
else if (bitclk_rate_mhz >= 180 && bitclk_rate_mhz < 190)
|
||||
return 0x22;
|
||||
else if (bitclk_rate_mhz >= 190 && bitclk_rate_mhz < 205)
|
||||
return 0x32;
|
||||
else if (bitclk_rate_mhz >= 205 && bitclk_rate_mhz < 220)
|
||||
return 0x03;
|
||||
else if (bitclk_rate_mhz >= 220 && bitclk_rate_mhz < 235)
|
||||
return 0x13;
|
||||
else if (bitclk_rate_mhz >= 235 && bitclk_rate_mhz < 250)
|
||||
return 0x23;
|
||||
else if (bitclk_rate_mhz >= 250 && bitclk_rate_mhz < 275)
|
||||
return 0x33;
|
||||
else if (bitclk_rate_mhz >= 275 && bitclk_rate_mhz < 300)
|
||||
return 0x04;
|
||||
else if (bitclk_rate_mhz >= 300 && bitclk_rate_mhz < 325)
|
||||
return 0x14;
|
||||
else if (bitclk_rate_mhz >= 325 && bitclk_rate_mhz < 350)
|
||||
return 0x25;
|
||||
else if (bitclk_rate_mhz >= 350 && bitclk_rate_mhz < 400)
|
||||
return 0x35;
|
||||
else if (bitclk_rate_mhz >= 400 && bitclk_rate_mhz < 450)
|
||||
return 0x05;
|
||||
else if (bitclk_rate_mhz >= 450 && bitclk_rate_mhz < 500)
|
||||
return 0x16;
|
||||
else if (bitclk_rate_mhz >= 500 && bitclk_rate_mhz < 550)
|
||||
return 0x26;
|
||||
else if (bitclk_rate_mhz >= 550 && bitclk_rate_mhz < 600)
|
||||
return 0x37;
|
||||
else if (bitclk_rate_mhz >= 600 && bitclk_rate_mhz < 650)
|
||||
return 0x07;
|
||||
else if (bitclk_rate_mhz >= 650 && bitclk_rate_mhz < 700)
|
||||
return 0x18;
|
||||
else if (bitclk_rate_mhz >= 700 && bitclk_rate_mhz < 750)
|
||||
return 0x28;
|
||||
else if (bitclk_rate_mhz >= 750 && bitclk_rate_mhz < 800)
|
||||
return 0x39;
|
||||
else if (bitclk_rate_mhz >= 800 && bitclk_rate_mhz < 850)
|
||||
return 0x09;
|
||||
else if (bitclk_rate_mhz >= 850 && bitclk_rate_mhz < 900)
|
||||
return 0x19;
|
||||
else if (bitclk_rate_mhz >= 900 && bitclk_rate_mhz < 950)
|
||||
return 0x29;
|
||||
else if (bitclk_rate_mhz >= 950 && bitclk_rate_mhz < 1000)
|
||||
return 0x3a;
|
||||
else if (bitclk_rate_mhz >= 1000 && bitclk_rate_mhz < 1050)
|
||||
return 0x0a;
|
||||
else if (bitclk_rate_mhz >= 1050 && bitclk_rate_mhz < 1100)
|
||||
return 0x1a;
|
||||
else if (bitclk_rate_mhz >= 1100 && bitclk_rate_mhz < 1150)
|
||||
return 0x2a;
|
||||
else if (bitclk_rate_mhz >= 1150 && bitclk_rate_mhz < 1200)
|
||||
return 0x3b;
|
||||
else if (bitclk_rate_mhz >= 1200 && bitclk_rate_mhz < 1250)
|
||||
return 0x0b;
|
||||
else if (bitclk_rate_mhz >= 1250 && bitclk_rate_mhz < 1300)
|
||||
return 0x1b;
|
||||
else if (bitclk_rate_mhz >= 1300 && bitclk_rate_mhz < 1350)
|
||||
return 0x2b;
|
||||
else if (bitclk_rate_mhz >= 1350 && bitclk_rate_mhz < 1400)
|
||||
return 0x3c;
|
||||
else if (bitclk_rate_mhz >= 1400 && bitclk_rate_mhz < 1450)
|
||||
return 0x0c;
|
||||
else if (bitclk_rate_mhz >= 1450 && bitclk_rate_mhz < 1500)
|
||||
return 0x1c;
|
||||
else if (bitclk_rate_mhz >= 1500 && bitclk_rate_mhz < 1550)
|
||||
return 0x2c;
|
||||
else if (bitclk_rate_mhz >= 1550 && bitclk_rate_mhz < 1600)
|
||||
return 0x3d;
|
||||
else if (bitclk_rate_mhz >= 1600 && bitclk_rate_mhz < 1650)
|
||||
return 0x0d;
|
||||
else if (bitclk_rate_mhz >= 1650 && bitclk_rate_mhz < 1700)
|
||||
return 0x1d;
|
||||
else if (bitclk_rate_mhz >= 1700 && bitclk_rate_mhz < 1750)
|
||||
return 0x2e;
|
||||
else if (bitclk_rate_mhz >= 1750 && bitclk_rate_mhz < 1800)
|
||||
return 0x3e;
|
||||
else if (bitclk_rate_mhz >= 1800 && bitclk_rate_mhz < 1850)
|
||||
return 0x0e;
|
||||
else if (bitclk_rate_mhz >= 1850 && bitclk_rate_mhz < 1900)
|
||||
return 0x1e;
|
||||
else if (bitclk_rate_mhz >= 1900 && bitclk_rate_mhz < 1950)
|
||||
return 0x2f;
|
||||
else if (bitclk_rate_mhz >= 1950 && bitclk_rate_mhz < 2000)
|
||||
return 0x3f;
|
||||
else if (bitclk_rate_mhz >= 2000 && bitclk_rate_mhz < 2050)
|
||||
return 0x0f;
|
||||
else if (bitclk_rate_mhz >= 2050 && bitclk_rate_mhz < 2100)
|
||||
return 0x40;
|
||||
else if (bitclk_rate_mhz >= 2100 && bitclk_rate_mhz < 2150)
|
||||
return 0x41;
|
||||
else if (bitclk_rate_mhz >= 2150 && bitclk_rate_mhz < 2200)
|
||||
return 0x42;
|
||||
else if (bitclk_rate_mhz >= 2200 && bitclk_rate_mhz <= 2249)
|
||||
return 0x43;
|
||||
else if (bitclk_rate_mhz > 2249 && bitclk_rate_mhz < 2300)
|
||||
return 0x44;
|
||||
else if (bitclk_rate_mhz >= 2300 && bitclk_rate_mhz < 2350)
|
||||
return 0x45;
|
||||
else if (bitclk_rate_mhz >= 2350 && bitclk_rate_mhz < 2400)
|
||||
return 0x46;
|
||||
else if (bitclk_rate_mhz >= 2400 && bitclk_rate_mhz < 2450)
|
||||
return 0x47;
|
||||
else if (bitclk_rate_mhz >= 2450 && bitclk_rate_mhz < 2500)
|
||||
return 0x48;
|
||||
else
|
||||
return 0x49;
|
||||
}
|
||||
|
||||
static void __mdss_dsi_get_pll_vco_cntrl(u64 target_freq, u32 post_div_mux,
|
||||
u32 *vco_cntrl, u32 *cpbias_cntrl)
|
||||
{
|
||||
u64 target_freq_mhz = div_u64(target_freq, 1000000);
|
||||
u32 p_div = BIT(post_div_mux);
|
||||
|
||||
if (p_div == 1) {
|
||||
*vco_cntrl = 0x00;
|
||||
*cpbias_cntrl = 0;
|
||||
} else if (p_div == 2) {
|
||||
*vco_cntrl = 0x30;
|
||||
*cpbias_cntrl = 1;
|
||||
} else if (p_div == 4) {
|
||||
*vco_cntrl = 0x10;
|
||||
*cpbias_cntrl = 0;
|
||||
} else if (p_div == 8) {
|
||||
*vco_cntrl = 0x20;
|
||||
*cpbias_cntrl = 0;
|
||||
} else if (p_div == 16) {
|
||||
*vco_cntrl = 0x30;
|
||||
*cpbias_cntrl = 0;
|
||||
} else {
|
||||
*vco_cntrl = 0x00;
|
||||
*cpbias_cntrl = 1;
|
||||
}
|
||||
|
||||
if (target_freq_mhz <= 1250 && target_freq_mhz >= 1092)
|
||||
*vco_cntrl = *vco_cntrl | 2;
|
||||
else if (target_freq_mhz < 1092 && target_freq_mhz >= 950)
|
||||
*vco_cntrl = *vco_cntrl | 3;
|
||||
else if (target_freq_mhz < 950 && target_freq_mhz >= 712)
|
||||
*vco_cntrl = *vco_cntrl | 1;
|
||||
else if (target_freq_mhz < 712 && target_freq_mhz >= 546)
|
||||
*vco_cntrl = *vco_cntrl | 2;
|
||||
else if (target_freq_mhz < 546 && target_freq_mhz >= 475)
|
||||
*vco_cntrl = *vco_cntrl | 3;
|
||||
else if (target_freq_mhz < 475 && target_freq_mhz >= 356)
|
||||
*vco_cntrl = *vco_cntrl | 1;
|
||||
else if (target_freq_mhz < 356 && target_freq_mhz >= 273)
|
||||
*vco_cntrl = *vco_cntrl | 2;
|
||||
else if (target_freq_mhz < 273 && target_freq_mhz >= 237)
|
||||
*vco_cntrl = *vco_cntrl | 3;
|
||||
else if (target_freq_mhz < 237 && target_freq_mhz >= 178)
|
||||
*vco_cntrl = *vco_cntrl | 1;
|
||||
else if (target_freq_mhz < 178 && target_freq_mhz >= 136)
|
||||
*vco_cntrl = *vco_cntrl | 2;
|
||||
else if (target_freq_mhz < 136 && target_freq_mhz >= 118)
|
||||
*vco_cntrl = *vco_cntrl | 3;
|
||||
else if (target_freq_mhz < 118 && target_freq_mhz >= 89)
|
||||
*vco_cntrl = *vco_cntrl | 1;
|
||||
else if (target_freq_mhz < 89 && target_freq_mhz >= 68)
|
||||
*vco_cntrl = *vco_cntrl | 2;
|
||||
else if (target_freq_mhz < 68 && target_freq_mhz >= 57)
|
||||
*vco_cntrl = *vco_cntrl | 3;
|
||||
else if (target_freq_mhz < 57 && target_freq_mhz >= 44)
|
||||
*vco_cntrl = *vco_cntrl | 1;
|
||||
else
|
||||
*vco_cntrl = *vco_cntrl | 2;
|
||||
}
|
||||
|
||||
static u32 __mdss_dsi_get_osc_freq_target(u64 target_freq)
|
||||
{
|
||||
u64 target_freq_mhz = div_u64(target_freq, 1000000);
|
||||
|
||||
if (target_freq_mhz <= 1000)
|
||||
return 1315;
|
||||
else if (target_freq_mhz > 1000 && target_freq_mhz <= 1500)
|
||||
return 1839;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u64 __mdss_dsi_pll_get_m_div(u64 vco_rate)
|
||||
{
|
||||
return div_u64((vco_rate * 4), 19200000);
|
||||
}
|
||||
|
||||
static u32 __mdss_dsi_get_fsm_ovr_ctrl(u64 target_freq)
|
||||
{
|
||||
u64 bitclk_rate_mhz = div_u64((target_freq * 2), 1000000);
|
||||
|
||||
if (bitclk_rate_mhz > 1500 && bitclk_rate_mhz <= 2500)
|
||||
return 0;
|
||||
else
|
||||
return BIT(6);
|
||||
}
|
||||
|
||||
static void mdss_dsi_pll_12nm_calc_reg(struct mdss_pll_resources *pll,
|
||||
struct dsi_pll_db *pdb)
|
||||
{
|
||||
struct dsi_pll_param *param = &pdb->param;
|
||||
u64 target_freq = 0;
|
||||
|
||||
target_freq = div_u64(pll->vco_current_rate,
|
||||
BIT(pdb->param.post_div_mux));
|
||||
|
||||
param->hsfreqrange = __mdss_dsi_get_hsfreqrange(target_freq);
|
||||
__mdss_dsi_get_pll_vco_cntrl(target_freq, param->post_div_mux,
|
||||
¶m->vco_cntrl, ¶m->cpbias_cntrl);
|
||||
param->osc_freq_target = __mdss_dsi_get_osc_freq_target(target_freq);
|
||||
param->m_div = (u32) __mdss_dsi_pll_get_m_div(pll->vco_current_rate);
|
||||
param->fsm_ovr_ctrl = __mdss_dsi_get_fsm_ovr_ctrl(target_freq);
|
||||
param->prop_cntrl = 0x05;
|
||||
param->int_cntrl = 0x00;
|
||||
param->gmp_cntrl = 0x1;
|
||||
}
|
||||
|
||||
static u32 __mdss_dsi_get_multi_intX100(u64 vco_rate, u32 *rem)
|
||||
{
|
||||
u32 reminder = 0;
|
||||
u64 temp = 0;
|
||||
const u32 ref_clk_rate = 19200000, quarterX100 = 25;
|
||||
|
||||
temp = div_u64_rem(vco_rate, ref_clk_rate, &reminder);
|
||||
temp *= 100;
|
||||
|
||||
/*
|
||||
* Multiplication integer needs to be floored in steps of 0.25
|
||||
* Hence multi_intX100 needs to be rounded off in steps of 25
|
||||
*/
|
||||
if (reminder < (ref_clk_rate / 4)) {
|
||||
*rem = reminder;
|
||||
return temp;
|
||||
} else if ((reminder >= (ref_clk_rate / 4)) &&
|
||||
reminder < (ref_clk_rate / 2)) {
|
||||
*rem = (reminder - (ref_clk_rate / 4));
|
||||
return (temp + quarterX100);
|
||||
} else if ((reminder >= (ref_clk_rate / 2)) &&
|
||||
(reminder < ((3 * ref_clk_rate) / 4))) {
|
||||
*rem = (reminder - (ref_clk_rate / 2));
|
||||
return (temp + (quarterX100 * 2));
|
||||
}
|
||||
|
||||
*rem = (reminder - ((3 * ref_clk_rate) / 4));
|
||||
return (temp + (quarterX100 * 3));
|
||||
}
|
||||
|
||||
static u32 __calc_gcd(u32 num1, u32 num2)
|
||||
{
|
||||
if (num2 != 0)
|
||||
return __calc_gcd(num2, (num1 % num2));
|
||||
else
|
||||
return num1;
|
||||
}
|
||||
|
||||
static void mdss_dsi_pll_12nm_calc_ssc(struct mdss_pll_resources *pll,
|
||||
struct dsi_pll_db *pdb)
|
||||
{
|
||||
struct dsi_pll_param *param = &pdb->param;
|
||||
u64 multi_intX100 = 0, temp = 0;
|
||||
u32 temp_rem1 = 0, temp_rem2 = 0;
|
||||
const u64 power_2_17 = 131072, power_2_10 = 1024;
|
||||
const u32 ref_clk_rate = 19200000;
|
||||
|
||||
multi_intX100 = __mdss_dsi_get_multi_intX100(pll->vco_current_rate,
|
||||
&temp_rem1);
|
||||
|
||||
/* Calculation for mpll_ssc_peak_i */
|
||||
temp = (multi_intX100 * pll->ssc_ppm * power_2_17);
|
||||
temp = div_u64(temp, 100); /* 100 div for multi_intX100 */
|
||||
param->mpll_ssc_peak_i =
|
||||
(u32) div_u64(temp, 1000000); /*10^6 for SSC PPM */
|
||||
|
||||
/* Calculation for mpll_stepsize_i */
|
||||
param->mpll_stepsize_i = (u32) div_u64((param->mpll_ssc_peak_i *
|
||||
pll->ssc_freq * power_2_10), ref_clk_rate);
|
||||
|
||||
/* Calculation for mpll_mint_i */
|
||||
param->mpll_mint_i = (u32) (div_u64((multi_intX100 * 4), 100) - 32);
|
||||
|
||||
/* Calculation for mpll_frac_den */
|
||||
param->mpll_frac_den = (u32) div_u64(ref_clk_rate,
|
||||
__calc_gcd((u32)pll->vco_current_rate, ref_clk_rate));
|
||||
|
||||
/* Calculation for mpll_frac_quot_i */
|
||||
temp = (temp_rem1 * power_2_17);
|
||||
param->mpll_frac_quot_i =
|
||||
(u32) div_u64_rem(temp, ref_clk_rate, &temp_rem2);
|
||||
|
||||
/* Calculation for mpll_frac_rem */
|
||||
param->mpll_frac_rem = (u32) div_u64(((u64)temp_rem2 *
|
||||
param->mpll_frac_den), ref_clk_rate);
|
||||
|
||||
pr_debug("mpll_ssc_peak_i=%d mpll_stepsize_i=%d mpll_mint_i=%d\n",
|
||||
param->mpll_ssc_peak_i, param->mpll_stepsize_i,
|
||||
param->mpll_mint_i);
|
||||
pr_debug("mpll_frac_den=%d mpll_frac_quot_i=%d mpll_frac_rem=%d\n",
|
||||
param->mpll_frac_den, param->mpll_frac_quot_i,
|
||||
param->mpll_frac_rem);
|
||||
}
|
||||
|
||||
static void pll_db_commit_12nm_ssc(struct mdss_pll_resources *pll,
|
||||
struct dsi_pll_db *pdb)
|
||||
{
|
||||
void __iomem *pll_base = pll->pll_base;
|
||||
struct dsi_pll_param *param = &pdb->param;
|
||||
char data = 0;
|
||||
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC0, 0x27);
|
||||
|
||||
data = (param->mpll_mint_i & 0xff);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC7, data);
|
||||
|
||||
data = ((param->mpll_mint_i & 0xff00) >> 8);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC8, data);
|
||||
|
||||
data = (param->mpll_ssc_peak_i & 0xff);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC1, data);
|
||||
|
||||
data = ((param->mpll_ssc_peak_i & 0xff00) >> 8);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC2, data);
|
||||
|
||||
data = ((param->mpll_ssc_peak_i & 0xf0000) >> 16);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC3, data);
|
||||
|
||||
data = (param->mpll_stepsize_i & 0xff);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC4, data);
|
||||
|
||||
data = ((param->mpll_stepsize_i & 0xff00) >> 8);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC5, data);
|
||||
|
||||
data = ((param->mpll_stepsize_i & 0x1f0000) >> 16);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC6, data);
|
||||
|
||||
data = (param->mpll_frac_quot_i & 0xff);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC10, data);
|
||||
|
||||
data = ((param->mpll_frac_quot_i & 0xff00) >> 8);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC11, data);
|
||||
|
||||
data = (param->mpll_frac_rem & 0xff);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC12, data);
|
||||
|
||||
data = ((param->mpll_frac_rem & 0xff00) >> 8);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC13, data);
|
||||
|
||||
data = (param->mpll_frac_den & 0xff);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC14, data);
|
||||
|
||||
data = ((param->mpll_frac_den & 0xff00) >> 8);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC15, data);
|
||||
}
|
||||
|
||||
static void pll_db_commit_12nm(struct mdss_pll_resources *pll,
|
||||
struct dsi_pll_db *pdb)
|
||||
{
|
||||
void __iomem *pll_base = pll->pll_base;
|
||||
struct dsi_pll_param *param = &pdb->param;
|
||||
char data = 0;
|
||||
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_CTRL0, 0x01);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CTRL, 0x05);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SLEWRATE_DDL_LOOP_CTRL, 0x01);
|
||||
|
||||
data = ((param->hsfreqrange & 0x7f) | BIT(7));
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_HS_FREQ_RAN_SEL, data);
|
||||
|
||||
data = ((param->vco_cntrl & 0x3f) | BIT(6));
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_VCO_CTRL, data);
|
||||
|
||||
data = (param->osc_freq_target & 0x7f);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SLEWRATE_DDL_CYC_FRQ_ADJ_0, data);
|
||||
|
||||
data = ((param->osc_freq_target & 0xf80) >> 7);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SLEWRATE_DDL_CYC_FRQ_ADJ_1, data);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_INPUT_LOOP_DIV_RAT_CTRL, 0x30);
|
||||
|
||||
data = (param->m_div & 0x3f);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_LOOP_DIV_RATIO_0, data);
|
||||
|
||||
data = ((param->m_div & 0xfc0) >> 6);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_LOOP_DIV_RATIO_1, data);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_INPUT_DIV_PLL_OVR, 0x60);
|
||||
|
||||
data = (param->prop_cntrl & 0x3f);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PROP_CHRG_PUMP_CTRL, data);
|
||||
|
||||
data = (param->int_cntrl & 0x3f);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_INTEG_CHRG_PUMP_CTRL, data);
|
||||
|
||||
data = ((param->gmp_cntrl & 0x3) << 4);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_GMP_CTRL_DIG_TST, data);
|
||||
|
||||
data = ((param->cpbias_cntrl & 0x1) << 6) | BIT(4);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CHAR_PUMP_BIAS_CTRL, data);
|
||||
|
||||
data = ((param->gp_div_mux & 0x7) << 5) | 0x5;
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_CTRL, data);
|
||||
|
||||
data = (param->pixel_divhf & 0x7f);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_SSC9, data);
|
||||
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_ANA_PROG_CTRL, 0x03);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_ANA_TST_LOCK_ST_OVR_CTRL, 0x50);
|
||||
MDSS_PLL_REG_W(pll_base,
|
||||
DSIPHY_SLEWRATE_FSM_OVR_CTRL, param->fsm_ovr_ctrl);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PHA_ERR_CTRL_0, 0x01);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PHA_ERR_CTRL_1, 0x00);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_LOCK_FILTER, 0xff);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_UNLOCK_FILTER, 0x03);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_PRO_DLY_RELOCK, 0x0c);
|
||||
MDSS_PLL_REG_W(pll_base, DSIPHY_PLL_LOCK_DET_MODE_SEL, 0x02);
|
||||
|
||||
if (pll->ssc_en)
|
||||
pll_db_commit_12nm_ssc(pll, pdb);
|
||||
|
||||
pr_debug("pll:%d\n", pll->index);
|
||||
wmb(); /* make sure register committed before preparing the clocks */
|
||||
}
|
||||
|
||||
int pll_vco_set_rate_12nm(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
|
||||
struct mdss_pll_resources *pll = vco->priv;
|
||||
struct dsi_pll_db *pdb;
|
||||
|
||||
pdb = (struct dsi_pll_db *)pll->priv;
|
||||
if (!pdb) {
|
||||
pr_err("pll pdb not found\n");
|
||||
rc = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
pr_debug("%s: ndx=%d rate=%lu\n", __func__, pll->index, rate);
|
||||
|
||||
pll->vco_current_rate = rate;
|
||||
pll->vco_ref_clk_rate = vco->ref_clk_rate;
|
||||
error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static unsigned long pll_vco_get_rate_12nm(struct clk_hw *hw)
|
||||
{
|
||||
u64 vco_rate = 0;
|
||||
u32 m_div_5_0 = 0, m_div_11_6 = 0, m_div = 0;
|
||||
struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
|
||||
u64 ref_clk = vco->ref_clk_rate;
|
||||
int rc;
|
||||
struct mdss_pll_resources *pll = vco->priv;
|
||||
|
||||
if (is_gdsc_disabled(pll))
|
||||
return 0;
|
||||
|
||||
rc = mdss_pll_resource_enable(pll, true);
|
||||
if (rc) {
|
||||
pr_err("Failed to enable mdss dsi pll=%d\n", pll->index);
|
||||
return rc;
|
||||
}
|
||||
|
||||
m_div_5_0 = MDSS_PLL_REG_R(pll->pll_base,
|
||||
DSIPHY_PLL_LOOP_DIV_RATIO_0);
|
||||
m_div_5_0 &= 0x3f;
|
||||
pr_debug("m_div_5_0 = 0x%x\n", m_div_5_0);
|
||||
|
||||
m_div_11_6 = MDSS_PLL_REG_R(pll->pll_base,
|
||||
DSIPHY_PLL_LOOP_DIV_RATIO_1);
|
||||
m_div_11_6 &= 0x3f;
|
||||
pr_debug("m_div_11_6 = 0x%x\n", m_div_11_6);
|
||||
|
||||
m_div = ((m_div_11_6 << 6) | (m_div_5_0));
|
||||
|
||||
vco_rate = div_u64((ref_clk * m_div), 4);
|
||||
|
||||
pr_debug("returning vco rate = %lu\n", (unsigned long)vco_rate);
|
||||
|
||||
mdss_pll_resource_enable(pll, false);
|
||||
|
||||
return (unsigned long)vco_rate;
|
||||
}
|
||||
|
||||
long pll_vco_round_rate_12nm(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
unsigned long rrate = rate;
|
||||
struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
|
||||
|
||||
if (rate < vco->min_rate)
|
||||
rrate = vco->min_rate;
|
||||
if (rate > vco->max_rate)
|
||||
rrate = vco->max_rate;
|
||||
|
||||
*parent_rate = rrate;
|
||||
|
||||
return rrate;
|
||||
}
|
||||
|
||||
unsigned long vco_12nm_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
|
||||
struct mdss_pll_resources *pll = vco->priv;
|
||||
unsigned long rate = 0;
|
||||
int rc;
|
||||
|
||||
if (!pll && is_gdsc_disabled(pll)) {
|
||||
pr_err("gdsc disabled\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = mdss_pll_resource_enable(pll, true);
|
||||
if (rc) {
|
||||
pr_err("Failed to enable mdss dsi pll=%d\n", pll->index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pll_is_pll_locked_12nm(pll, true)) {
|
||||
pll->handoff_resources = true;
|
||||
pll->pll_on = true;
|
||||
rate = pll_vco_get_rate_12nm(hw);
|
||||
} else {
|
||||
mdss_pll_resource_enable(pll, false);
|
||||
}
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
int pll_vco_prepare_12nm(struct clk_hw *hw)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
|
||||
struct mdss_pll_resources *pll = vco->priv;
|
||||
struct dsi_pll_db *pdb;
|
||||
u32 data = 0;
|
||||
|
||||
if (!pll) {
|
||||
pr_err("Dsi pll resources are not available\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pdb = (struct dsi_pll_db *)pll->priv;
|
||||
if (!pdb) {
|
||||
pr_err("No prov found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = mdss_pll_resource_enable(pll, true);
|
||||
if (rc) {
|
||||
pr_err("ndx=%d Failed to enable mdss dsi pll resources\n",
|
||||
pll->index);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if ((pll->vco_cached_rate != 0)
|
||||
&& (pll->vco_cached_rate == clk_hw_get_rate(hw))) {
|
||||
rc = hw->init->ops->set_rate(hw, pll->vco_cached_rate,
|
||||
pll->vco_cached_rate);
|
||||
if (rc) {
|
||||
pr_err("index=%d vco_set_rate failed. rc=%d\n",
|
||||
pll->index, rc);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For cases where DSI PHY is already enabled like:
|
||||
* 1.) LP-11 during static screen
|
||||
* 2.) ULPS during static screen
|
||||
* 3.) Boot up with cont splash enabled where PHY is programmed in LK
|
||||
* Execute the Re-lock sequence to enable the DSI PLL.
|
||||
*/
|
||||
data = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_SYS_CTRL);
|
||||
if (data & BIT(7)) {
|
||||
rc = dsi_pll_relock(pll);
|
||||
if (rc)
|
||||
goto error;
|
||||
else
|
||||
goto end;
|
||||
}
|
||||
|
||||
mdss_dsi_pll_12nm_calc_reg(pll, pdb);
|
||||
if (pll->ssc_en)
|
||||
mdss_dsi_pll_12nm_calc_ssc(pll, pdb);
|
||||
|
||||
/* commit DSI vco */
|
||||
pll_db_commit_12nm(pll, pdb);
|
||||
|
||||
rc = dsi_pll_enable(hw);
|
||||
|
||||
error:
|
||||
if (rc) {
|
||||
mdss_pll_resource_enable(pll, false);
|
||||
pr_err("ndx=%d failed to enable dsi pll\n", pll->index);
|
||||
}
|
||||
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void pll_vco_unprepare_12nm(struct clk_hw *hw)
|
||||
{
|
||||
struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
|
||||
struct mdss_pll_resources *pll = vco->priv;
|
||||
|
||||
if (!pll) {
|
||||
pr_err("Dsi pll resources are not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pll->vco_cached_rate = clk_hw_get_rate(hw);
|
||||
dsi_pll_disable(hw);
|
||||
}
|
||||
|
||||
int pll_vco_enable_12nm(struct clk_hw *hw)
|
||||
{
|
||||
struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
|
||||
struct mdss_pll_resources *pll = vco->priv;
|
||||
u32 data = 0;
|
||||
|
||||
if (!pll) {
|
||||
pr_err("Dsi pll resources are not available\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!pll->pll_on) {
|
||||
pr_err("DSI PLL not enabled, return\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data = MDSS_PLL_REG_R(pll->pll_base, DSIPHY_SSC0);
|
||||
data |= BIT(6); /* enable GP_CLK_EN */
|
||||
MDSS_PLL_REG_W(pll->pll_base, DSIPHY_SSC0, data);
|
||||
wmb(); /* make sure register committed before enabling branch clocks */
|
||||
|
||||
return 0;
|
||||
}
|
709
drivers/clk/qcom/mdss/mdss-dsi-pll-12nm.c
Normal file
709
drivers/clk/qcom/mdss/mdss-dsi-pll-12nm.c
Normal file
|
@ -0,0 +1,709 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */
|
||||
|
||||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/delay.h>
|
||||
#include "mdss-dsi-pll.h"
|
||||
#include "mdss-pll.h"
|
||||
#include <dt-bindings/clock/mdss-12nm-pll-clk.h>
|
||||
#include "mdss-dsi-pll-12nm.h"
|
||||
|
||||
#define VCO_DELAY_USEC 1
|
||||
|
||||
static struct regmap_config dsi_pll_12nm_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x800,
|
||||
};
|
||||
|
||||
static const struct clk_ops clk_ops_vco_12nm = {
|
||||
.recalc_rate = vco_12nm_recalc_rate,
|
||||
.set_rate = pll_vco_set_rate_12nm,
|
||||
.round_rate = pll_vco_round_rate_12nm,
|
||||
.prepare = pll_vco_prepare_12nm,
|
||||
.unprepare = pll_vco_unprepare_12nm,
|
||||
};
|
||||
|
||||
static struct regmap_bus pclk_div_regmap_bus = {
|
||||
.reg_write = pixel_div_set_div,
|
||||
.reg_read = pixel_div_get_div,
|
||||
};
|
||||
|
||||
static struct regmap_bus post_div_mux_regmap_bus = {
|
||||
.reg_write = set_post_div_mux_sel,
|
||||
.reg_read = get_post_div_mux_sel,
|
||||
};
|
||||
|
||||
static struct regmap_bus gp_div_mux_regmap_bus = {
|
||||
.reg_write = set_gp_mux_sel,
|
||||
.reg_read = get_gp_mux_sel,
|
||||
};
|
||||
|
||||
/*
|
||||
* Clock tree model for generating DSI byte clock and pclk for 12nm DSI PLL
|
||||
*
|
||||
*
|
||||
* +---------------+
|
||||
* +----------| vco_clk |----------+
|
||||
* | +---------------+ |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* +---------+---------+----+----+---------+---------+ |
|
||||
* | | | | | | |
|
||||
* | | | | | | |
|
||||
* | | | | | | |
|
||||
* +---v---+ +---v---+ +---v---+ +---v---+ +---v---+ +---v---+ |
|
||||
* | DIV(1)| | DIV(2)| | DIV(4)| | DIV(8)| |DIV(16)| |DIV(32)| |
|
||||
* +---+---+ +---+---+ +---+---+ +---+---+ +---+---+ +---+---+ |
|
||||
* | | | | | | |
|
||||
* | | +---+ +---+ | | |
|
||||
* | +-----------+ | | +-----------+ | |
|
||||
* +-------------------+ | | | | +-------------------+ |
|
||||
* | | | | | | |
|
||||
* +--v-v-v-v-v-v---+ |
|
||||
* \ post_div_mux / |
|
||||
* \ / |
|
||||
* +-----+----+ +---------------------+
|
||||
* | |
|
||||
* +------------------------+ |
|
||||
* | |
|
||||
* +----v----+ +---------+---------+----+----+---------+---------+
|
||||
* | DIV-4 | | | | | | |
|
||||
* +----+----+ | | | | | |
|
||||
* | +---v---+ +---v---+ +---v---+ +---v---+ +---v---+ +---v---+
|
||||
* | | DIV(1)| | DIV(2)| | DIV(4)| | DIV(8)| |DIV(16)| |DIV(32)|
|
||||
* | +---+---+ +---+---+ +---+---+ +---+---+ +---+---+ +---+---+
|
||||
* | | | | | | |
|
||||
* v | | +---+ +---+ | |
|
||||
* byte_clk_src | +-----------+ | | +-----------+ |
|
||||
* +-------------------+ | | | | +-------------------+
|
||||
* | | | | | |
|
||||
* +--v-v-v-v-v-v---+
|
||||
* \ gp_cntrl_mux /
|
||||
* \ /
|
||||
* +-----+----+
|
||||
* |
|
||||
* |
|
||||
* +-------v-------+
|
||||
* | (DIV + 1) |
|
||||
* | DIV = 0...127 |
|
||||
* +-------+-------+
|
||||
* |
|
||||
* |
|
||||
* v
|
||||
* dsi_pclk input to Clock Controller MND
|
||||
*/
|
||||
|
||||
static struct dsi_pll_db pll_db[DSI_PLL_MAX];
|
||||
|
||||
static struct dsi_pll_vco_clk dsi0pll_vco_clk = {
|
||||
.ref_clk_rate = 19200000UL,
|
||||
.min_rate = 1000000000UL,
|
||||
.max_rate = 2000000000UL,
|
||||
.pll_en_seq_cnt = 1,
|
||||
.pll_enable_seqs[0] = dsi_pll_enable_seq_12nm,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_vco_clk",
|
||||
.parent_names = (const char *[]){"bi_tcxo"},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_ops_vco_12nm,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct dsi_pll_vco_clk dsi1pll_vco_clk = {
|
||||
.ref_clk_rate = 19200000UL,
|
||||
.min_rate = 1000000000UL,
|
||||
.max_rate = 2000000000UL,
|
||||
.pll_en_seq_cnt = 1,
|
||||
.pll_enable_seqs[0] = dsi_pll_enable_seq_12nm,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_vco_clk",
|
||||
.parent_names = (const char *[]){"bi_tcxo"},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_ops_vco_12nm,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi0pll_post_div1 = {
|
||||
.div = 1,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_post_div1",
|
||||
.parent_names = (const char *[]){"dsi0pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi0pll_post_div2 = {
|
||||
.div = 2,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_post_div2",
|
||||
.parent_names = (const char *[]){"dsi0pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi0pll_post_div4 = {
|
||||
.div = 4,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_post_div4",
|
||||
.parent_names = (const char *[]){"dsi0pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi0pll_post_div8 = {
|
||||
.div = 8,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_post_div8",
|
||||
.parent_names = (const char *[]){"dsi0pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi0pll_post_div16 = {
|
||||
.div = 16,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_post_div16",
|
||||
.parent_names = (const char *[]){"dsi0pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi0pll_post_div32 = {
|
||||
.div = 32,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_post_div32",
|
||||
.parent_names = (const char *[]){"dsi0pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_mux dsi0pll_post_div_mux = {
|
||||
.reg = DSIPHY_PLL_VCO_CTRL,
|
||||
.shift = 4,
|
||||
.width = 2,
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_post_div_mux",
|
||||
.parent_names = (const char *[]){"dsi0pll_post_div1",
|
||||
"dsi0pll_post_div2",
|
||||
"dsi0pll_post_div4",
|
||||
"dsi0pll_post_div8",
|
||||
"dsi0pll_post_div16",
|
||||
"dsi0pll_post_div32"},
|
||||
.num_parents = 6,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_regmap_mux_closest_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi1pll_post_div1 = {
|
||||
.div = 1,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_post_div1",
|
||||
.parent_names = (const char *[]){"dsi1pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi1pll_post_div2 = {
|
||||
.div = 2,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_post_div2",
|
||||
.parent_names = (const char *[]){"dsi1pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi1pll_post_div4 = {
|
||||
.div = 4,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_post_div4",
|
||||
.parent_names = (const char *[]){"dsi1pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi1pll_post_div8 = {
|
||||
.div = 8,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_post_div8",
|
||||
.parent_names = (const char *[]){"dsi1pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi1pll_post_div16 = {
|
||||
.div = 16,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_post_div16",
|
||||
.parent_names = (const char *[]){"dsi1pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi1pll_post_div32 = {
|
||||
.div = 32,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_post_div32",
|
||||
.parent_names = (const char *[]){"dsi1pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_mux dsi1pll_post_div_mux = {
|
||||
.reg = DSIPHY_PLL_VCO_CTRL,
|
||||
.shift = 4,
|
||||
.width = 2,
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_post_div_mux",
|
||||
.parent_names = (const char *[]){"dsi1pll_post_div1",
|
||||
"dsi1pll_post_div2",
|
||||
"dsi1pll_post_div4",
|
||||
"dsi1pll_post_div8",
|
||||
"dsi1pll_post_div16",
|
||||
"dsi1pll_post_div32"},
|
||||
.num_parents = 6,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_regmap_mux_closest_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi0pll_gp_div1 = {
|
||||
.div = 1,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_gp_div1",
|
||||
.parent_names = (const char *[]){"dsi0pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi0pll_gp_div2 = {
|
||||
.div = 2,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_gp_div2",
|
||||
.parent_names = (const char *[]){"dsi0pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi0pll_gp_div4 = {
|
||||
.div = 4,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_gp_div4",
|
||||
.parent_names = (const char *[]){"dsi0pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi0pll_gp_div8 = {
|
||||
.div = 8,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_gp_div8",
|
||||
.parent_names = (const char *[]){"dsi0pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi0pll_gp_div16 = {
|
||||
.div = 16,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_gp_div16",
|
||||
.parent_names = (const char *[]){"dsi0pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi0pll_gp_div32 = {
|
||||
.div = 32,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_gp_div32",
|
||||
.parent_names = (const char *[]){"dsi0pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_mux dsi0pll_gp_div_mux = {
|
||||
.reg = DSIPHY_PLL_CTRL,
|
||||
.shift = 5,
|
||||
.width = 3,
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_gp_div_mux",
|
||||
.parent_names = (const char *[]){"dsi0pll_gp_div1",
|
||||
"dsi0pll_gp_div2",
|
||||
"dsi0pll_gp_div4",
|
||||
"dsi0pll_gp_div8",
|
||||
"dsi0pll_gp_div16",
|
||||
"dsi0pll_gp_div32"},
|
||||
.num_parents = 6,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_regmap_mux_closest_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi1pll_gp_div1 = {
|
||||
.div = 1,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_gp_div1",
|
||||
.parent_names = (const char *[]){"dsi1pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi1pll_gp_div2 = {
|
||||
.div = 2,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_gp_div2",
|
||||
.parent_names = (const char *[]){"dsi1pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi1pll_gp_div4 = {
|
||||
.div = 4,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_gp_div4",
|
||||
.parent_names = (const char *[]){"dsi1pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi1pll_gp_div8 = {
|
||||
.div = 8,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_gp_div8",
|
||||
.parent_names = (const char *[]){"dsi1pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi1pll_gp_div16 = {
|
||||
.div = 16,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_gp_div16",
|
||||
.parent_names = (const char *[]){"dsi1pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi1pll_gp_div32 = {
|
||||
.div = 32,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_gp_div32",
|
||||
.parent_names = (const char *[]){"dsi1pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_mux dsi1pll_gp_div_mux = {
|
||||
.reg = DSIPHY_PLL_CTRL,
|
||||
.shift = 5,
|
||||
.width = 3,
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_gp_div_mux",
|
||||
.parent_names = (const char *[]){"dsi1pll_gp_div1",
|
||||
"dsi1pll_gp_div2",
|
||||
"dsi1pll_gp_div4",
|
||||
"dsi1pll_gp_div8",
|
||||
"dsi1pll_gp_div16",
|
||||
"dsi1pll_gp_div32"},
|
||||
.num_parents = 6,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_regmap_mux_closest_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_div dsi0pll_pclk_src = {
|
||||
.reg = DSIPHY_SSC9,
|
||||
.shift = 0,
|
||||
.width = 6,
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_pclk_src",
|
||||
.parent_names = (const char *[]){
|
||||
"dsi0pll_gp_div_mux"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_regmap_div_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_div dsi1pll_pclk_src = {
|
||||
.reg = DSIPHY_SSC9,
|
||||
.shift = 0,
|
||||
.width = 6,
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_pclk_src",
|
||||
.parent_names = (const char *[]){
|
||||
"dsi1pll_gp_div_mux"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_regmap_div_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi0pll_byte_clk_src = {
|
||||
.div = 4,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_byte_clk_src",
|
||||
.parent_names = (const char *[]){"dsi0pll_post_div_mux"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi1pll_byte_clk_src = {
|
||||
.div = 4,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_byte_clk_src",
|
||||
.parent_names = (const char *[]){"dsi1pll_post_div_mux"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static struct clk_hw *mdss_dsi_pllcc_12nm[] = {
|
||||
[VCO_CLK_0] = &dsi0pll_vco_clk.hw,
|
||||
[POST_DIV1_0_CLK] = &dsi0pll_post_div1.hw,
|
||||
[POST_DIV2_0_CLK] = &dsi0pll_post_div2.hw,
|
||||
[POST_DIV4_0_CLK] = &dsi0pll_post_div4.hw,
|
||||
[POST_DIV8_0_CLK] = &dsi0pll_post_div8.hw,
|
||||
[POST_DIV16_0_CLK] = &dsi0pll_post_div16.hw,
|
||||
[POST_DIV32_0_CLK] = &dsi0pll_post_div32.hw,
|
||||
[POST_DIV_MUX_0_CLK] = &dsi0pll_post_div_mux.clkr.hw,
|
||||
[GP_DIV1_0_CLK] = &dsi0pll_gp_div1.hw,
|
||||
[GP_DIV2_0_CLK] = &dsi0pll_gp_div2.hw,
|
||||
[GP_DIV4_0_CLK] = &dsi0pll_gp_div4.hw,
|
||||
[GP_DIV8_0_CLK] = &dsi0pll_gp_div8.hw,
|
||||
[GP_DIV16_0_CLK] = &dsi0pll_gp_div16.hw,
|
||||
[GP_DIV32_0_CLK] = &dsi0pll_gp_div32.hw,
|
||||
[GP_DIV_MUX_0_CLK] = &dsi0pll_gp_div_mux.clkr.hw,
|
||||
[PCLK_SRC_MUX_0_CLK] = &dsi0pll_pclk_src.clkr.hw,
|
||||
[BYTE_CLK_SRC_0_CLK] = &dsi0pll_byte_clk_src.hw,
|
||||
[VCO_CLK_1] = &dsi1pll_vco_clk.hw,
|
||||
[POST_DIV1_1_CLK] = &dsi1pll_post_div1.hw,
|
||||
[POST_DIV2_1_CLK] = &dsi1pll_post_div2.hw,
|
||||
[POST_DIV4_1_CLK] = &dsi1pll_post_div4.hw,
|
||||
[POST_DIV8_1_CLK] = &dsi1pll_post_div8.hw,
|
||||
[POST_DIV16_1_CLK] = &dsi1pll_post_div16.hw,
|
||||
[POST_DIV32_1_CLK] = &dsi1pll_post_div32.hw,
|
||||
[POST_DIV_MUX_1_CLK] = &dsi1pll_post_div_mux.clkr.hw,
|
||||
[GP_DIV1_1_CLK] = &dsi1pll_gp_div1.hw,
|
||||
[GP_DIV2_1_CLK] = &dsi1pll_gp_div2.hw,
|
||||
[GP_DIV4_1_CLK] = &dsi1pll_gp_div4.hw,
|
||||
[GP_DIV8_1_CLK] = &dsi1pll_gp_div8.hw,
|
||||
[GP_DIV16_1_CLK] = &dsi1pll_gp_div16.hw,
|
||||
[GP_DIV32_1_CLK] = &dsi1pll_gp_div32.hw,
|
||||
[GP_DIV_MUX_1_CLK] = &dsi1pll_gp_div_mux.clkr.hw,
|
||||
[PCLK_SRC_MUX_1_CLK] = &dsi1pll_pclk_src.clkr.hw,
|
||||
[BYTE_CLK_SRC_1_CLK] = &dsi1pll_byte_clk_src.hw,
|
||||
};
|
||||
|
||||
int dsi_pll_clock_register_12nm(struct platform_device *pdev,
|
||||
struct mdss_pll_resources *pll_res)
|
||||
{
|
||||
int rc = 0, ndx, i;
|
||||
struct clk *clk;
|
||||
struct clk_onecell_data *clk_data;
|
||||
int num_clks = ARRAY_SIZE(mdss_dsi_pllcc_12nm);
|
||||
struct regmap *rmap;
|
||||
struct dsi_pll_db *pdb;
|
||||
|
||||
if (!pdev || !pdev->dev.of_node ||
|
||||
!pll_res || !pll_res->pll_base || !pll_res->phy_base) {
|
||||
pr_err("Invalid params\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ndx = pll_res->index;
|
||||
|
||||
if (ndx >= DSI_PLL_MAX) {
|
||||
pr_err("pll index(%d) NOT supported\n", ndx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pdb = &pll_db[ndx];
|
||||
pll_res->priv = pdb;
|
||||
pll_res->vco_delay = VCO_DELAY_USEC;
|
||||
pdb->pll = pll_res;
|
||||
ndx++;
|
||||
ndx %= DSI_PLL_MAX;
|
||||
pdb->next = &pll_db[ndx];
|
||||
|
||||
clk_data = devm_kzalloc(&pdev->dev, sizeof(struct clk_onecell_data),
|
||||
GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
clk_data->clks = devm_kzalloc(&pdev->dev, (num_clks *
|
||||
sizeof(struct clk *)), GFP_KERNEL);
|
||||
if (!clk_data->clks)
|
||||
return -ENOMEM;
|
||||
clk_data->clk_num = num_clks;
|
||||
|
||||
/* Establish client data */
|
||||
if (ndx == 0) {
|
||||
rmap = devm_regmap_init(&pdev->dev, &post_div_mux_regmap_bus,
|
||||
pll_res, &dsi_pll_12nm_config);
|
||||
dsi0pll_post_div_mux.clkr.regmap = rmap;
|
||||
|
||||
rmap = devm_regmap_init(&pdev->dev, &gp_div_mux_regmap_bus,
|
||||
pll_res, &dsi_pll_12nm_config);
|
||||
dsi0pll_gp_div_mux.clkr.regmap = rmap;
|
||||
|
||||
rmap = devm_regmap_init(&pdev->dev, &pclk_div_regmap_bus,
|
||||
pll_res, &dsi_pll_12nm_config);
|
||||
dsi0pll_pclk_src.clkr.regmap = rmap;
|
||||
|
||||
dsi0pll_vco_clk.priv = pll_res;
|
||||
for (i = VCO_CLK_0; i <= BYTE_CLK_SRC_0_CLK; i++) {
|
||||
clk = devm_clk_register(&pdev->dev,
|
||||
mdss_dsi_pllcc_12nm[i]);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("clk registration failed for DSI clock:%d\n",
|
||||
pll_res->index);
|
||||
rc = -EINVAL;
|
||||
goto clk_register_fail;
|
||||
}
|
||||
clk_data->clks[i] = clk;
|
||||
|
||||
}
|
||||
|
||||
rc = of_clk_add_provider(pdev->dev.of_node,
|
||||
of_clk_src_onecell_get, clk_data);
|
||||
|
||||
|
||||
} else {
|
||||
rmap = devm_regmap_init(&pdev->dev, &post_div_mux_regmap_bus,
|
||||
pll_res, &dsi_pll_12nm_config);
|
||||
dsi1pll_post_div_mux.clkr.regmap = rmap;
|
||||
|
||||
rmap = devm_regmap_init(&pdev->dev, &gp_div_mux_regmap_bus,
|
||||
pll_res, &dsi_pll_12nm_config);
|
||||
dsi1pll_gp_div_mux.clkr.regmap = rmap;
|
||||
|
||||
rmap = devm_regmap_init(&pdev->dev, &pclk_div_regmap_bus,
|
||||
pll_res, &dsi_pll_12nm_config);
|
||||
dsi1pll_pclk_src.clkr.regmap = rmap;
|
||||
|
||||
dsi1pll_vco_clk.priv = pll_res;
|
||||
|
||||
for (i = VCO_CLK_1; i <= BYTE_CLK_SRC_1_CLK; i++) {
|
||||
clk = devm_clk_register(&pdev->dev,
|
||||
mdss_dsi_pllcc_12nm[i]);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("clk registration failed for DSI clock:%d\n",
|
||||
pll_res->index);
|
||||
rc = -EINVAL;
|
||||
goto clk_register_fail;
|
||||
}
|
||||
clk_data->clks[i] = clk;
|
||||
|
||||
}
|
||||
|
||||
rc = of_clk_add_provider(pdev->dev.of_node,
|
||||
of_clk_src_onecell_get, clk_data);
|
||||
}
|
||||
if (!rc) {
|
||||
pr_info("Registered DSI PLL ndx=%d,clocks successfully\n", ndx);
|
||||
|
||||
return rc;
|
||||
}
|
||||
clk_register_fail:
|
||||
return rc;
|
||||
}
|
113
drivers/clk/qcom/mdss/mdss-dsi-pll-12nm.h
Normal file
113
drivers/clk/qcom/mdss/mdss-dsi-pll-12nm.h
Normal file
|
@ -0,0 +1,113 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */
|
||||
|
||||
#ifndef MDSS_DSI_PLL_12NM_H
|
||||
#define MDSS_DSI_PLL_12NM_H
|
||||
|
||||
#define DSIPHY_PLL_POWERUP_CTRL 0x034
|
||||
#define DSIPHY_PLL_PROP_CHRG_PUMP_CTRL 0x038
|
||||
#define DSIPHY_PLL_INTEG_CHRG_PUMP_CTRL 0x03c
|
||||
#define DSIPHY_PLL_ANA_TST_LOCK_ST_OVR_CTRL 0x044
|
||||
#define DSIPHY_PLL_VCO_CTRL 0x048
|
||||
#define DSIPHY_PLL_GMP_CTRL_DIG_TST 0x04c
|
||||
#define DSIPHY_PLL_PHA_ERR_CTRL_0 0x050
|
||||
#define DSIPHY_PLL_LOCK_FILTER 0x054
|
||||
#define DSIPHY_PLL_UNLOCK_FILTER 0x058
|
||||
#define DSIPHY_PLL_INPUT_DIV_PLL_OVR 0x05c
|
||||
#define DSIPHY_PLL_LOOP_DIV_RATIO_0 0x060
|
||||
#define DSIPHY_PLL_INPUT_LOOP_DIV_RAT_CTRL 0x064
|
||||
#define DSIPHY_PLL_PRO_DLY_RELOCK 0x06c
|
||||
#define DSIPHY_PLL_CHAR_PUMP_BIAS_CTRL 0x070
|
||||
#define DSIPHY_PLL_LOCK_DET_MODE_SEL 0x074
|
||||
#define DSIPHY_PLL_ANA_PROG_CTRL 0x07c
|
||||
#define DSIPHY_HS_FREQ_RAN_SEL 0x110
|
||||
#define DSIPHY_SLEWRATE_FSM_OVR_CTRL 0x280
|
||||
#define DSIPHY_SLEWRATE_DDL_LOOP_CTRL 0x28c
|
||||
#define DSIPHY_SLEWRATE_DDL_CYC_FRQ_ADJ_0 0x290
|
||||
#define DSIPHY_PLL_PHA_ERR_CTRL_1 0x2e4
|
||||
#define DSIPHY_PLL_LOOP_DIV_RATIO_1 0x2e8
|
||||
#define DSIPHY_SLEWRATE_DDL_CYC_FRQ_ADJ_1 0x328
|
||||
#define DSIPHY_SSC0 0x394
|
||||
#define DSIPHY_SSC7 0x3b0
|
||||
#define DSIPHY_SSC8 0x3b4
|
||||
#define DSIPHY_SSC1 0x398
|
||||
#define DSIPHY_SSC2 0x39c
|
||||
#define DSIPHY_SSC3 0x3a0
|
||||
#define DSIPHY_SSC4 0x3a4
|
||||
#define DSIPHY_SSC5 0x3a8
|
||||
#define DSIPHY_SSC6 0x3ac
|
||||
#define DSIPHY_SSC10 0x360
|
||||
#define DSIPHY_SSC11 0x364
|
||||
#define DSIPHY_SSC12 0x368
|
||||
#define DSIPHY_SSC13 0x36c
|
||||
#define DSIPHY_SSC14 0x370
|
||||
#define DSIPHY_SSC15 0x374
|
||||
#define DSIPHY_SSC7 0x3b0
|
||||
#define DSIPHY_SSC8 0x3b4
|
||||
#define DSIPHY_SSC9 0x3b8
|
||||
#define DSIPHY_STAT0 0x3e0
|
||||
#define DSIPHY_CTRL0 0x3e8
|
||||
#define DSIPHY_SYS_CTRL 0x3f0
|
||||
#define DSIPHY_PLL_CTRL 0x3f8
|
||||
|
||||
struct dsi_pll_param {
|
||||
u32 hsfreqrange;
|
||||
u32 vco_cntrl;
|
||||
u32 osc_freq_target;
|
||||
u32 m_div;
|
||||
u32 prop_cntrl;
|
||||
u32 int_cntrl;
|
||||
u32 gmp_cntrl;
|
||||
u32 cpbias_cntrl;
|
||||
|
||||
/* mux and dividers */
|
||||
u32 gp_div_mux;
|
||||
u32 post_div_mux;
|
||||
u32 pixel_divhf;
|
||||
u32 fsm_ovr_ctrl;
|
||||
|
||||
/* ssc_params */
|
||||
u32 mpll_ssc_peak_i;
|
||||
u32 mpll_stepsize_i;
|
||||
u32 mpll_mint_i;
|
||||
u32 mpll_frac_den;
|
||||
u32 mpll_frac_quot_i;
|
||||
u32 mpll_frac_rem;
|
||||
};
|
||||
|
||||
enum {
|
||||
DSI_PLL_0,
|
||||
DSI_PLL_1,
|
||||
DSI_PLL_MAX
|
||||
};
|
||||
|
||||
struct dsi_pll_db {
|
||||
struct dsi_pll_db *next;
|
||||
struct mdss_pll_resources *pll;
|
||||
struct dsi_pll_param param;
|
||||
};
|
||||
|
||||
int pll_vco_set_rate_12nm(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate);
|
||||
long pll_vco_round_rate_12nm(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate);
|
||||
unsigned long vco_12nm_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate);
|
||||
int pll_vco_prepare_12nm(struct clk_hw *hw);
|
||||
void pll_vco_unprepare_12nm(struct clk_hw *hw);
|
||||
int pll_vco_enable_12nm(struct clk_hw *hw);
|
||||
int pixel_div_set_div(void *context, unsigned int reg,
|
||||
unsigned int div);
|
||||
int pixel_div_get_div(void *context, unsigned int reg,
|
||||
unsigned int *div);
|
||||
int set_post_div_mux_sel(void *context, unsigned int reg,
|
||||
unsigned int sel);
|
||||
int get_post_div_mux_sel(void *context, unsigned int reg,
|
||||
unsigned int *sel);
|
||||
int set_gp_mux_sel(void *context, unsigned int reg,
|
||||
unsigned int sel);
|
||||
int get_gp_mux_sel(void *context, unsigned int reg,
|
||||
unsigned int *sel);
|
||||
int dsi_pll_enable_seq_12nm(struct mdss_pll_resources *pll);
|
||||
|
||||
#endif /* MDSS_DSI_PLL_12NM_H */
|
557
drivers/clk/qcom/mdss/mdss-dsi-pll-28lpm.c
Normal file
557
drivers/clk/qcom/mdss/mdss-dsi-pll-28lpm.c
Normal file
|
@ -0,0 +1,557 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2012-2018, 2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
#include <dt-bindings/clock/mdss-28nm-pll-clk.h>
|
||||
|
||||
#include "mdss-pll.h"
|
||||
#include "mdss-dsi-pll.h"
|
||||
#include "mdss-dsi-pll-28nm.h"
|
||||
|
||||
#define VCO_DELAY_USEC 1000
|
||||
|
||||
enum {
|
||||
DSI_PLL_0,
|
||||
DSI_PLL_1,
|
||||
DSI_PLL_MAX
|
||||
};
|
||||
|
||||
static struct lpfr_cfg lpfr_lut_struct[] = {
|
||||
{479500000, 8},
|
||||
{480000000, 11},
|
||||
{575500000, 8},
|
||||
{576000000, 12},
|
||||
{610500000, 8},
|
||||
{659500000, 9},
|
||||
{671500000, 10},
|
||||
{672000000, 14},
|
||||
{708500000, 10},
|
||||
{750000000, 11},
|
||||
};
|
||||
|
||||
static void dsi_pll_sw_reset(struct mdss_pll_resources *rsc)
|
||||
{
|
||||
/*
|
||||
* DSI PLL software reset. Add HW recommended delays after toggling
|
||||
* the software reset bit off and back on.
|
||||
*/
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_TEST_CFG, 0x01);
|
||||
ndelay(500);
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_TEST_CFG, 0x00);
|
||||
}
|
||||
|
||||
static void dsi_pll_toggle_lock_detect(
|
||||
struct mdss_pll_resources *rsc)
|
||||
{
|
||||
/* DSI PLL toggle lock detect setting */
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_LKDET_CFG2, 0x04);
|
||||
ndelay(500);
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_LKDET_CFG2, 0x05);
|
||||
udelay(512);
|
||||
}
|
||||
|
||||
static int dsi_pll_check_lock_status(
|
||||
struct mdss_pll_resources *rsc)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc = dsi_pll_lock_status(rsc);
|
||||
if (rc)
|
||||
pr_debug("PLL Locked\n");
|
||||
else
|
||||
pr_err("PLL failed to lock\n");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int dsi_pll_enable_seq_gf2(struct mdss_pll_resources *rsc)
|
||||
{
|
||||
int pll_locked = 0;
|
||||
|
||||
dsi_pll_sw_reset(rsc);
|
||||
|
||||
/*
|
||||
* GF PART 2 PLL power up sequence.
|
||||
* Add necessary delays recommended by hardware.
|
||||
*/
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG1, 0x04);
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x01);
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x05);
|
||||
udelay(3);
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x0f);
|
||||
udelay(500);
|
||||
|
||||
dsi_pll_toggle_lock_detect(rsc);
|
||||
|
||||
pll_locked = dsi_pll_check_lock_status(rsc);
|
||||
return pll_locked ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
static int dsi_pll_enable_seq_gf1(struct mdss_pll_resources *rsc)
|
||||
{
|
||||
int pll_locked = 0;
|
||||
|
||||
dsi_pll_sw_reset(rsc);
|
||||
/*
|
||||
* GF PART 1 PLL power up sequence.
|
||||
* Add necessary delays recommended by hardware.
|
||||
*/
|
||||
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG1, 0x14);
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x01);
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x05);
|
||||
udelay(3);
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x0f);
|
||||
udelay(500);
|
||||
|
||||
dsi_pll_toggle_lock_detect(rsc);
|
||||
|
||||
pll_locked = dsi_pll_check_lock_status(rsc);
|
||||
return pll_locked ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
static int dsi_pll_enable_seq_tsmc(struct mdss_pll_resources *rsc)
|
||||
{
|
||||
int pll_locked = 0;
|
||||
|
||||
dsi_pll_sw_reset(rsc);
|
||||
/*
|
||||
* TSMC PLL power up sequence.
|
||||
* Add necessary delays recommended by hardware.
|
||||
*/
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG1, 0x34);
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x01);
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x05);
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x0f);
|
||||
udelay(500);
|
||||
|
||||
dsi_pll_toggle_lock_detect(rsc);
|
||||
|
||||
pll_locked = dsi_pll_check_lock_status(rsc);
|
||||
return pll_locked ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
static struct regmap_config dsi_pll_28lpm_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0xF4,
|
||||
};
|
||||
|
||||
static struct regmap_bus analog_postdiv_regmap_bus = {
|
||||
.reg_write = analog_postdiv_reg_write,
|
||||
.reg_read = analog_postdiv_reg_read,
|
||||
};
|
||||
|
||||
static struct regmap_bus byteclk_src_mux_regmap_bus = {
|
||||
.reg_write = byteclk_mux_write_sel,
|
||||
.reg_read = byteclk_mux_read_sel,
|
||||
};
|
||||
|
||||
static struct regmap_bus pclk_src_regmap_bus = {
|
||||
.reg_write = pixel_clk_set_div,
|
||||
.reg_read = pixel_clk_get_div,
|
||||
};
|
||||
|
||||
static const struct clk_ops clk_ops_vco_28lpm = {
|
||||
.recalc_rate = vco_28nm_recalc_rate,
|
||||
.set_rate = vco_28nm_set_rate,
|
||||
.round_rate = vco_28nm_round_rate,
|
||||
.prepare = vco_28nm_prepare,
|
||||
.unprepare = vco_28nm_unprepare,
|
||||
};
|
||||
|
||||
static struct dsi_pll_vco_clk dsi0pll_vco_clk = {
|
||||
.ref_clk_rate = 19200000UL,
|
||||
.min_rate = 350000000UL,
|
||||
.max_rate = 750000000UL,
|
||||
.pll_en_seq_cnt = 9,
|
||||
.pll_enable_seqs[0] = dsi_pll_enable_seq_tsmc,
|
||||
.pll_enable_seqs[1] = dsi_pll_enable_seq_tsmc,
|
||||
.pll_enable_seqs[2] = dsi_pll_enable_seq_tsmc,
|
||||
.pll_enable_seqs[3] = dsi_pll_enable_seq_gf1,
|
||||
.pll_enable_seqs[4] = dsi_pll_enable_seq_gf1,
|
||||
.pll_enable_seqs[5] = dsi_pll_enable_seq_gf1,
|
||||
.pll_enable_seqs[6] = dsi_pll_enable_seq_gf2,
|
||||
.pll_enable_seqs[7] = dsi_pll_enable_seq_gf2,
|
||||
.pll_enable_seqs[8] = dsi_pll_enable_seq_gf2,
|
||||
.lpfr_lut_size = 10,
|
||||
.lpfr_lut = lpfr_lut_struct,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_vco_clk",
|
||||
.parent_names = (const char *[]){"bi_tcxo"},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_ops_vco_28lpm,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct dsi_pll_vco_clk dsi1pll_vco_clk = {
|
||||
.ref_clk_rate = 19200000UL,
|
||||
.min_rate = 350000000UL,
|
||||
.max_rate = 750000000UL,
|
||||
.pll_en_seq_cnt = 9,
|
||||
.pll_enable_seqs[0] = dsi_pll_enable_seq_tsmc,
|
||||
.pll_enable_seqs[1] = dsi_pll_enable_seq_tsmc,
|
||||
.pll_enable_seqs[2] = dsi_pll_enable_seq_tsmc,
|
||||
.pll_enable_seqs[3] = dsi_pll_enable_seq_gf1,
|
||||
.pll_enable_seqs[4] = dsi_pll_enable_seq_gf1,
|
||||
.pll_enable_seqs[5] = dsi_pll_enable_seq_gf1,
|
||||
.pll_enable_seqs[6] = dsi_pll_enable_seq_gf2,
|
||||
.pll_enable_seqs[7] = dsi_pll_enable_seq_gf2,
|
||||
.pll_enable_seqs[8] = dsi_pll_enable_seq_gf2,
|
||||
.lpfr_lut_size = 10,
|
||||
.lpfr_lut = lpfr_lut_struct,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_vco_clk",
|
||||
.parent_names = (const char *[]){"bi_tcxo"},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_ops_vco_28lpm,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_div dsi0pll_analog_postdiv = {
|
||||
.reg = DSI_PHY_PLL_UNIPHY_PLL_POSTDIV1_CFG,
|
||||
.shift = 0,
|
||||
.width = 4,
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_analog_postdiv",
|
||||
.parent_names = (const char *[]){"dsi0pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_regmap_div_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_div dsi1pll_analog_postdiv = {
|
||||
.reg = DSI_PHY_PLL_UNIPHY_PLL_POSTDIV1_CFG,
|
||||
.shift = 0,
|
||||
.width = 4,
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_analog_postdiv",
|
||||
.parent_names = (const char *[]){"dsi1pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_regmap_div_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi0pll_indirect_path_src = {
|
||||
.div = 2,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_indirect_path_src",
|
||||
.parent_names = (const char *[]){"dsi0pll_analog_postdiv"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi1pll_indirect_path_src = {
|
||||
.div = 2,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_indirect_path_src",
|
||||
.parent_names = (const char *[]){"dsi1pll_analog_postdiv"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_mux dsi0pll_byteclk_src_mux = {
|
||||
.reg = DSI_PHY_PLL_UNIPHY_PLL_VREG_CFG,
|
||||
.shift = 1,
|
||||
.width = 1,
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0pll_byteclk_src_mux",
|
||||
.parent_names = (const char *[]){
|
||||
"dsi0pll_vco_clk",
|
||||
"dsi0pll_indirect_path_src"},
|
||||
.num_parents = 2,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_regmap_mux_closest_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_mux dsi1pll_byteclk_src_mux = {
|
||||
.reg = DSI_PHY_PLL_UNIPHY_PLL_VREG_CFG,
|
||||
.shift = 1,
|
||||
.width = 1,
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1pll_byteclk_src_mux",
|
||||
.parent_names = (const char *[]){
|
||||
"dsi1pll_vco_clk",
|
||||
"dsi1pll_indirect_path_src"},
|
||||
.num_parents = 2,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_regmap_mux_closest_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi0pll_byteclk_src = {
|
||||
.div = 4,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0_phy_pll_out_byteclk",
|
||||
.parent_names = (const char *[]){
|
||||
"dsi0pll_byteclk_src_mux"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor dsi1pll_byteclk_src = {
|
||||
.div = 4,
|
||||
.mult = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1_phy_pll_out_byteclk",
|
||||
.parent_names = (const char *[]){
|
||||
"dsi1pll_byteclk_src_mux"},
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_div dsi0pll_pclk_src = {
|
||||
.reg = DSI_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG,
|
||||
.shift = 0,
|
||||
.width = 8,
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi0_phy_pll_out_dsiclk",
|
||||
.parent_names = (const char *[]){"dsi0pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.ops = &clk_regmap_div_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_div dsi1pll_pclk_src = {
|
||||
.reg = DSI_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG,
|
||||
.shift = 0,
|
||||
.width = 8,
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi1_phy_pll_out_dsiclk",
|
||||
.parent_names = (const char *[]){"dsi1pll_vco_clk"},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
.ops = &clk_regmap_div_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_hw *mdss_dsi_pllcc_28lpm[] = {
|
||||
[VCO_CLK_0] = &dsi0pll_vco_clk.hw,
|
||||
[ANALOG_POSTDIV_0_CLK] = &dsi0pll_analog_postdiv.clkr.hw,
|
||||
[INDIRECT_PATH_SRC_0_CLK] = &dsi0pll_indirect_path_src.hw,
|
||||
[BYTECLK_SRC_MUX_0_CLK] = &dsi0pll_byteclk_src_mux.clkr.hw,
|
||||
[BYTECLK_SRC_0_CLK] = &dsi0pll_byteclk_src.hw,
|
||||
[PCLK_SRC_0_CLK] = &dsi0pll_pclk_src.clkr.hw,
|
||||
[VCO_CLK_1] = &dsi1pll_vco_clk.hw,
|
||||
[ANALOG_POSTDIV_1_CLK] = &dsi1pll_analog_postdiv.clkr.hw,
|
||||
[INDIRECT_PATH_SRC_1_CLK] = &dsi1pll_indirect_path_src.hw,
|
||||
[BYTECLK_SRC_MUX_1_CLK] = &dsi1pll_byteclk_src_mux.clkr.hw,
|
||||
[BYTECLK_SRC_1_CLK] = &dsi1pll_byteclk_src.hw,
|
||||
[PCLK_SRC_1_CLK] = &dsi1pll_pclk_src.clkr.hw,
|
||||
};
|
||||
|
||||
int dsi_pll_clock_register_28lpm(struct platform_device *pdev,
|
||||
struct mdss_pll_resources *pll_res)
|
||||
{
|
||||
int rc = 0, ndx, i;
|
||||
struct clk *clk;
|
||||
struct clk_onecell_data *clk_data;
|
||||
int num_clks = ARRAY_SIZE(mdss_dsi_pllcc_28lpm);
|
||||
struct regmap *rmap;
|
||||
|
||||
int const ssc_freq_min = 30000; /* min. recommended freq. value */
|
||||
int const ssc_freq_max = 33000; /* max. recommended freq. value */
|
||||
int const ssc_ppm_max = 5000; /* max. recommended ppm */
|
||||
|
||||
if (!pdev || !pdev->dev.of_node ||
|
||||
!pll_res || !pll_res->pll_base) {
|
||||
pr_err("Invalid params\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ndx = pll_res->index;
|
||||
|
||||
if (ndx >= DSI_PLL_MAX) {
|
||||
pr_err("pll index(%d) NOT supported\n", ndx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pll_res->vco_delay = VCO_DELAY_USEC;
|
||||
|
||||
if (pll_res->ssc_en) {
|
||||
if (!pll_res->ssc_freq || (pll_res->ssc_freq < ssc_freq_min) ||
|
||||
(pll_res->ssc_freq > ssc_freq_max)) {
|
||||
pll_res->ssc_freq = ssc_freq_min;
|
||||
pr_debug("SSC frequency out of recommended range. Set to default=%d\n",
|
||||
pll_res->ssc_freq);
|
||||
}
|
||||
|
||||
if (!pll_res->ssc_ppm || (pll_res->ssc_ppm > ssc_ppm_max)) {
|
||||
pll_res->ssc_ppm = ssc_ppm_max;
|
||||
pr_debug("SSC PPM out of recommended range. Set to default=%d\n",
|
||||
pll_res->ssc_ppm);
|
||||
}
|
||||
}
|
||||
|
||||
clk_data = devm_kzalloc(&pdev->dev, sizeof(struct clk_onecell_data),
|
||||
GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
clk_data->clks = devm_kzalloc(&pdev->dev, (num_clks *
|
||||
sizeof(struct clk *)), GFP_KERNEL);
|
||||
if (!clk_data->clks)
|
||||
return -ENOMEM;
|
||||
clk_data->clk_num = num_clks;
|
||||
|
||||
/* Establish client data */
|
||||
if (ndx == 0) {
|
||||
rmap = devm_regmap_init(&pdev->dev, &byteclk_src_mux_regmap_bus,
|
||||
pll_res, &dsi_pll_28lpm_config);
|
||||
if (IS_ERR(rmap)) {
|
||||
pr_err("regmap init failed for DSI clock:%d\n",
|
||||
pll_res->index);
|
||||
return -EINVAL;
|
||||
}
|
||||
dsi0pll_byteclk_src_mux.clkr.regmap = rmap;
|
||||
|
||||
rmap = devm_regmap_init(&pdev->dev, &analog_postdiv_regmap_bus,
|
||||
pll_res, &dsi_pll_28lpm_config);
|
||||
if (IS_ERR(rmap)) {
|
||||
pr_err("regmap init failed for DSI clock:%d\n",
|
||||
pll_res->index);
|
||||
return -EINVAL;
|
||||
}
|
||||
dsi0pll_analog_postdiv.clkr.regmap = rmap;
|
||||
|
||||
rmap = devm_regmap_init(&pdev->dev, &pclk_src_regmap_bus,
|
||||
pll_res, &dsi_pll_28lpm_config);
|
||||
if (IS_ERR(rmap)) {
|
||||
pr_err("regmap init failed for DSI clock:%d\n",
|
||||
pll_res->index);
|
||||
return -EINVAL;
|
||||
}
|
||||
dsi0pll_pclk_src.clkr.regmap = rmap;
|
||||
|
||||
dsi0pll_vco_clk.priv = pll_res;
|
||||
for (i = VCO_CLK_0; i <= PCLK_SRC_0_CLK; i++) {
|
||||
clk = devm_clk_register(&pdev->dev,
|
||||
mdss_dsi_pllcc_28lpm[i]);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("clk registration failed for DSI clock:%d\n",
|
||||
pll_res->index);
|
||||
rc = -EINVAL;
|
||||
goto clk_register_fail;
|
||||
}
|
||||
clk_data->clks[i] = clk;
|
||||
|
||||
}
|
||||
|
||||
rc = of_clk_add_provider(pdev->dev.of_node,
|
||||
of_clk_src_onecell_get, clk_data);
|
||||
|
||||
} else {
|
||||
rmap = devm_regmap_init(&pdev->dev, &byteclk_src_mux_regmap_bus,
|
||||
pll_res, &dsi_pll_28lpm_config);
|
||||
if (IS_ERR(rmap)) {
|
||||
pr_err("regmap init failed for DSI clock:%d\n",
|
||||
pll_res->index);
|
||||
return -EINVAL;
|
||||
}
|
||||
dsi1pll_byteclk_src_mux.clkr.regmap = rmap;
|
||||
|
||||
rmap = devm_regmap_init(&pdev->dev, &analog_postdiv_regmap_bus,
|
||||
pll_res, &dsi_pll_28lpm_config);
|
||||
if (IS_ERR(rmap)) {
|
||||
pr_err("regmap init failed for DSI clock:%d\n",
|
||||
pll_res->index);
|
||||
return -EINVAL;
|
||||
}
|
||||
dsi1pll_analog_postdiv.clkr.regmap = rmap;
|
||||
|
||||
rmap = devm_regmap_init(&pdev->dev, &pclk_src_regmap_bus,
|
||||
pll_res, &dsi_pll_28lpm_config);
|
||||
if (IS_ERR(rmap)) {
|
||||
pr_err("regmap init failed for DSI clock:%d\n",
|
||||
pll_res->index);
|
||||
return -EINVAL;
|
||||
}
|
||||
dsi1pll_pclk_src.clkr.regmap = rmap;
|
||||
|
||||
dsi1pll_vco_clk.priv = pll_res;
|
||||
for (i = VCO_CLK_1; i <= PCLK_SRC_1_CLK; i++) {
|
||||
clk = devm_clk_register(&pdev->dev,
|
||||
mdss_dsi_pllcc_28lpm[i]);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("clk registration failed for DSI clock:%d\n",
|
||||
pll_res->index);
|
||||
rc = -EINVAL;
|
||||
goto clk_register_fail;
|
||||
}
|
||||
clk_data->clks[i] = clk;
|
||||
|
||||
}
|
||||
|
||||
rc = of_clk_add_provider(pdev->dev.of_node,
|
||||
of_clk_src_onecell_get, clk_data);
|
||||
}
|
||||
if (!rc) {
|
||||
pr_info("Registered DSI PLL ndx=%d,clocks successfully\n", ndx);
|
||||
return rc;
|
||||
}
|
||||
|
||||
clk_register_fail:
|
||||
return rc;
|
||||
}
|
665
drivers/clk/qcom/mdss/mdss-dsi-pll-28nm-util.c
Normal file
665
drivers/clk/qcom/mdss/mdss-dsi-pll-28nm-util.c
Normal file
|
@ -0,0 +1,665 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2012-2018, 2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "mdss-pll.h"
|
||||
#include "mdss-dsi-pll.h"
|
||||
#include "mdss-dsi-pll-28nm.h"
|
||||
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_REFCLK_CFG (0x0)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_CHGPUMP_CFG (0x0008)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_VCOLPF_CFG (0x000C)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_PWRGEN_CFG (0x0014)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_POSTDIV2_CFG (0x0024)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_LPFR_CFG (0x002C)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_LPFC1_CFG (0x0030)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_LPFC2_CFG (0x0034)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG0 (0x0038)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG1 (0x003C)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG2 (0x0040)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG3 (0x0044)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG4 (0x0048)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_SSC_CFG0 (0x004C)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_SSC_CFG1 (0x0050)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_SSC_CFG2 (0x0054)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_SSC_CFG3 (0x0058)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG0 (0x006C)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG2 (0x0074)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG3 (0x0078)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG4 (0x007C)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG5 (0x0080)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG6 (0x0084)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG7 (0x0088)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG8 (0x008C)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG9 (0x0090)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG10 (0x0094)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG11 (0x0098)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_EFUSE_CFG (0x009C)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_STATUS (0x00C0)
|
||||
|
||||
#define DSI_PLL_POLL_DELAY_US 50
|
||||
#define DSI_PLL_POLL_TIMEOUT_US 500
|
||||
|
||||
int analog_postdiv_reg_read(void *context, unsigned int reg,
|
||||
unsigned int *div)
|
||||
{
|
||||
int rc = 0;
|
||||
struct mdss_pll_resources *rsc = context;
|
||||
|
||||
rc = mdss_pll_resource_enable(rsc, true);
|
||||
if (rc) {
|
||||
pr_err("Failed to enable dsi pll resources, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
*div = MDSS_PLL_REG_R(rsc->pll_base, reg);
|
||||
|
||||
pr_debug("analog_postdiv div = %d\n", *div);
|
||||
|
||||
(void)mdss_pll_resource_enable(rsc, false);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int analog_postdiv_reg_write(void *context, unsigned int reg,
|
||||
unsigned int div)
|
||||
{
|
||||
int rc = 0;
|
||||
struct mdss_pll_resources *rsc = context;
|
||||
|
||||
rc = mdss_pll_resource_enable(rsc, true);
|
||||
if (rc) {
|
||||
pr_err("Failed to enable dsi pll resources, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
pr_debug("analog_postdiv div = %d\n", div);
|
||||
|
||||
MDSS_PLL_REG_W(rsc->pll_base, reg, div);
|
||||
|
||||
(void)mdss_pll_resource_enable(rsc, false);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int byteclk_mux_read_sel(void *context, unsigned int reg,
|
||||
unsigned int *val)
|
||||
{
|
||||
int rc = 0;
|
||||
struct mdss_pll_resources *rsc = context;
|
||||
|
||||
rc = mdss_pll_resource_enable(rsc, true);
|
||||
if (rc) {
|
||||
pr_err("Failed to enable dsi pll resources, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
*val = (MDSS_PLL_REG_R(rsc->pll_base, reg) & BIT(1));
|
||||
pr_debug("byteclk mux mode = %s\n", *val ? "indirect" : "direct");
|
||||
|
||||
(void)mdss_pll_resource_enable(rsc, false);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int byteclk_mux_write_sel(void *context, unsigned int reg,
|
||||
unsigned int val)
|
||||
{
|
||||
int rc = 0;
|
||||
u32 reg_val = 0;
|
||||
struct mdss_pll_resources *rsc = context;
|
||||
|
||||
rc = mdss_pll_resource_enable(rsc, true);
|
||||
if (rc) {
|
||||
pr_err("Failed to enable dsi pll resources, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
pr_debug("byteclk mux set to %s mode\n", val ? "indirect" : "direct");
|
||||
|
||||
reg_val = MDSS_PLL_REG_R(rsc->pll_base, reg);
|
||||
reg_val &= ~0x02;
|
||||
reg_val |= val;
|
||||
|
||||
MDSS_PLL_REG_W(rsc->pll_base, reg, reg_val);
|
||||
|
||||
(void)mdss_pll_resource_enable(rsc, false);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int pixel_clk_get_div(void *context, unsigned int reg,
|
||||
unsigned int *div)
|
||||
{
|
||||
int rc = 0;
|
||||
struct mdss_pll_resources *rsc = context;
|
||||
|
||||
rc = mdss_pll_resource_enable(rsc, true);
|
||||
if (rc) {
|
||||
pr_err("Failed to enable dsi pll resources, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
*div = MDSS_PLL_REG_R(rsc->pll_base, reg);
|
||||
|
||||
pr_debug("pclk_src div = %d\n", *div);
|
||||
|
||||
(void)mdss_pll_resource_enable(rsc, false);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int pixel_clk_set_div(void *context, unsigned int reg,
|
||||
unsigned int div)
|
||||
{
|
||||
int rc = 0;
|
||||
struct mdss_pll_resources *rsc = context;
|
||||
|
||||
rc = mdss_pll_resource_enable(rsc, true);
|
||||
if (rc) {
|
||||
pr_err("Failed to enable dsi pll resources, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
pr_debug("pclk_src div = %d\n", div);
|
||||
|
||||
MDSS_PLL_REG_W(rsc->pll_base, reg, div);
|
||||
|
||||
(void)mdss_pll_resource_enable(rsc, false);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int dsi_pll_lock_status(struct mdss_pll_resources *rsc)
|
||||
{
|
||||
u32 status;
|
||||
int pll_locked;
|
||||
|
||||
/* poll for PLL ready status */
|
||||
if (readl_poll_timeout_atomic((rsc->pll_base +
|
||||
DSI_PHY_PLL_UNIPHY_PLL_STATUS),
|
||||
status,
|
||||
((status & BIT(0)) == 1),
|
||||
DSI_PLL_POLL_DELAY_US,
|
||||
DSI_PLL_POLL_TIMEOUT_US)) {
|
||||
pr_debug("DSI PLL status=%x failed to Lock\n", status);
|
||||
pll_locked = 0;
|
||||
} else {
|
||||
pll_locked = 1;
|
||||
}
|
||||
|
||||
return pll_locked;
|
||||
}
|
||||
|
||||
static int pll_28nm_vco_rate_calc(struct dsi_pll_vco_clk *vco,
|
||||
struct mdss_dsi_vco_calc *vco_calc, unsigned long vco_clk_rate)
|
||||
{
|
||||
s32 rem;
|
||||
s64 frac_n_mode, ref_doubler_en_b;
|
||||
s64 ref_clk_to_pll, div_fb, frac_n_value;
|
||||
int i;
|
||||
|
||||
/* Configure the Loop filter resistance */
|
||||
for (i = 0; i < vco->lpfr_lut_size; i++)
|
||||
if (vco_clk_rate <= vco->lpfr_lut[i].vco_rate)
|
||||
break;
|
||||
if (i == vco->lpfr_lut_size) {
|
||||
pr_err("unable to get loop filter resistance. vco=%ld\n",
|
||||
vco_clk_rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
vco_calc->lpfr_lut_res = vco->lpfr_lut[i].r;
|
||||
|
||||
div_s64_rem(vco_clk_rate, vco->ref_clk_rate, &rem);
|
||||
if (rem) {
|
||||
vco_calc->refclk_cfg = 0x1;
|
||||
frac_n_mode = 1;
|
||||
ref_doubler_en_b = 0;
|
||||
} else {
|
||||
vco_calc->refclk_cfg = 0x0;
|
||||
frac_n_mode = 0;
|
||||
ref_doubler_en_b = 1;
|
||||
}
|
||||
|
||||
pr_debug("refclk_cfg = %lld\n", vco_calc->refclk_cfg);
|
||||
|
||||
ref_clk_to_pll = ((vco->ref_clk_rate * 2 * (vco_calc->refclk_cfg))
|
||||
+ (ref_doubler_en_b * vco->ref_clk_rate));
|
||||
|
||||
div_fb = div_s64_rem(vco_clk_rate, ref_clk_to_pll, &rem);
|
||||
frac_n_value = div_s64(((s64)rem * (1 << 16)), ref_clk_to_pll);
|
||||
vco_calc->gen_vco_clk = vco_clk_rate;
|
||||
|
||||
pr_debug("ref_clk_to_pll = %lld\n", ref_clk_to_pll);
|
||||
pr_debug("div_fb = %lld\n", div_fb);
|
||||
pr_debug("frac_n_value = %lld\n", frac_n_value);
|
||||
|
||||
pr_debug("Generated VCO Clock: %lld\n", vco_calc->gen_vco_clk);
|
||||
rem = 0;
|
||||
if (frac_n_mode) {
|
||||
vco_calc->sdm_cfg0 = 0;
|
||||
vco_calc->sdm_cfg1 = (div_fb & 0x3f) - 1;
|
||||
vco_calc->sdm_cfg3 = div_s64_rem(frac_n_value, 256, &rem);
|
||||
vco_calc->sdm_cfg2 = rem;
|
||||
} else {
|
||||
vco_calc->sdm_cfg0 = (0x1 << 5);
|
||||
vco_calc->sdm_cfg0 |= (div_fb & 0x3f) - 1;
|
||||
vco_calc->sdm_cfg1 = 0;
|
||||
vco_calc->sdm_cfg2 = 0;
|
||||
vco_calc->sdm_cfg3 = 0;
|
||||
}
|
||||
|
||||
pr_debug("sdm_cfg0=%lld\n", vco_calc->sdm_cfg0);
|
||||
pr_debug("sdm_cfg1=%lld\n", vco_calc->sdm_cfg1);
|
||||
pr_debug("sdm_cfg2=%lld\n", vco_calc->sdm_cfg2);
|
||||
pr_debug("sdm_cfg3=%lld\n", vco_calc->sdm_cfg3);
|
||||
|
||||
vco_calc->cal_cfg11 = div_s64_rem(vco_calc->gen_vco_clk,
|
||||
256 * 1000000, &rem);
|
||||
vco_calc->cal_cfg10 = rem / 1000000;
|
||||
pr_debug("cal_cfg10=%lld, cal_cfg11=%lld\n",
|
||||
vco_calc->cal_cfg10, vco_calc->cal_cfg11);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pll_28nm_ssc_param_calc(struct dsi_pll_vco_clk *vco,
|
||||
struct mdss_dsi_vco_calc *vco_calc)
|
||||
{
|
||||
struct mdss_pll_resources *rsc = vco->priv;
|
||||
s64 ppm_freq, incr, spread_freq, div_rf, frac_n_value;
|
||||
s32 rem;
|
||||
|
||||
if (!rsc->ssc_en) {
|
||||
pr_debug("DSI PLL SSC not enabled\n");
|
||||
return;
|
||||
}
|
||||
|
||||
vco_calc->ssc.kdiv = DIV_ROUND_CLOSEST(vco->ref_clk_rate,
|
||||
1000000) - 1;
|
||||
vco_calc->ssc.triang_steps = DIV_ROUND_CLOSEST(vco->ref_clk_rate,
|
||||
rsc->ssc_freq * (vco_calc->ssc.kdiv + 1));
|
||||
ppm_freq = div_s64(vco_calc->gen_vco_clk * rsc->ssc_ppm,
|
||||
1000000);
|
||||
incr = div64_s64(ppm_freq * 65536, vco->ref_clk_rate * 2 *
|
||||
vco_calc->ssc.triang_steps);
|
||||
|
||||
vco_calc->ssc.triang_inc_7_0 = incr & 0xff;
|
||||
vco_calc->ssc.triang_inc_9_8 = (incr >> 8) & 0x3;
|
||||
|
||||
if (!rsc->ssc_center)
|
||||
spread_freq = vco_calc->gen_vco_clk - ppm_freq;
|
||||
else
|
||||
spread_freq = vco_calc->gen_vco_clk - (ppm_freq / 2);
|
||||
|
||||
div_rf = div_s64(spread_freq, 2 * vco->ref_clk_rate);
|
||||
vco_calc->ssc.dc_offset = (div_rf - 1);
|
||||
|
||||
div_s64_rem(spread_freq, 2 * vco->ref_clk_rate, &rem);
|
||||
frac_n_value = div_s64((s64)rem * 65536, 2 * vco->ref_clk_rate);
|
||||
|
||||
vco_calc->ssc.freq_seed_7_0 = frac_n_value & 0xff;
|
||||
vco_calc->ssc.freq_seed_15_8 = (frac_n_value >> 8) & 0xff;
|
||||
}
|
||||
|
||||
static void pll_28nm_vco_config(struct dsi_pll_vco_clk *vco,
|
||||
struct mdss_dsi_vco_calc *vco_calc)
|
||||
{
|
||||
struct mdss_pll_resources *rsc = vco->priv;
|
||||
void __iomem *pll_base = rsc->pll_base;
|
||||
u32 vco_delay_us = rsc->vco_delay;
|
||||
bool ssc_en = rsc->ssc_en;
|
||||
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_LPFR_CFG,
|
||||
vco_calc->lpfr_lut_res);
|
||||
|
||||
/* Loop filter capacitance values : c1 and c2 */
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_LPFC1_CFG, 0x70);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_LPFC2_CFG, 0x15);
|
||||
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CHGPUMP_CFG, 0x02);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG3, 0x2b);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG4, 0x66);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_LKDET_CFG2, 0x0d);
|
||||
|
||||
if (!ssc_en) {
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG1,
|
||||
(u32)(vco_calc->sdm_cfg1 & 0xff));
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG2,
|
||||
(u32)(vco_calc->sdm_cfg2 & 0xff));
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG3,
|
||||
(u32)(vco_calc->sdm_cfg3 & 0xff));
|
||||
} else {
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG1,
|
||||
(u32)vco_calc->ssc.dc_offset);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG2,
|
||||
(u32)vco_calc->ssc.freq_seed_7_0);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG3,
|
||||
(u32)vco_calc->ssc.freq_seed_15_8);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SSC_CFG0,
|
||||
(u32)vco_calc->ssc.kdiv);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SSC_CFG1,
|
||||
(u32)vco_calc->ssc.triang_inc_7_0);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SSC_CFG2,
|
||||
(u32)vco_calc->ssc.triang_inc_9_8);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SSC_CFG3,
|
||||
(u32)vco_calc->ssc.triang_steps);
|
||||
}
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG4, 0x00);
|
||||
|
||||
/* Add hardware recommended delay for correct PLL configuration */
|
||||
if (vco_delay_us)
|
||||
udelay(vco_delay_us);
|
||||
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_REFCLK_CFG,
|
||||
(u32)vco_calc->refclk_cfg);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_PWRGEN_CFG, 0x00);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_VCOLPF_CFG, 0x71);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG0,
|
||||
(u32)vco_calc->sdm_cfg0);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG0, 0x12);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG6, 0x30);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG7, 0x00);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG8, 0x60);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG9, 0x00);
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG10,
|
||||
(u32)(vco_calc->cal_cfg10 & 0xff));
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG11,
|
||||
(u32)(vco_calc->cal_cfg11 & 0xff));
|
||||
MDSS_PLL_REG_W(pll_base, DSI_PHY_PLL_UNIPHY_PLL_EFUSE_CFG, 0x20);
|
||||
MDSS_PLL_REG_W(pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_POSTDIV2_CFG, 0x3); /* Fixed div-4 */
|
||||
}
|
||||
|
||||
static int vco_set_rate(struct dsi_pll_vco_clk *vco, unsigned long rate)
|
||||
{
|
||||
struct mdss_dsi_vco_calc vco_calc = {0};
|
||||
int rc = 0;
|
||||
|
||||
rc = pll_28nm_vco_rate_calc(vco, &vco_calc, rate);
|
||||
if (rc) {
|
||||
pr_err("vco rate calculation failed\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
pll_28nm_ssc_param_calc(vco, &vco_calc);
|
||||
pll_28nm_vco_config(vco, &vco_calc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long vco_get_rate(struct dsi_pll_vco_clk *vco)
|
||||
{
|
||||
struct mdss_pll_resources *rsc = vco->priv;
|
||||
int rc;
|
||||
u32 sdm0, doubler, sdm_byp_div;
|
||||
u64 vco_rate;
|
||||
u32 sdm_dc_off, sdm_freq_seed, sdm2, sdm3;
|
||||
u64 ref_clk = vco->ref_clk_rate;
|
||||
|
||||
rc = mdss_pll_resource_enable(rsc, true);
|
||||
if (rc) {
|
||||
pr_err("Failed to enable mdss dsi pll resources\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Check to see if the ref clk doubler is enabled */
|
||||
doubler = MDSS_PLL_REG_R(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_REFCLK_CFG) & BIT(0);
|
||||
ref_clk += (doubler * vco->ref_clk_rate);
|
||||
|
||||
/* see if it is integer mode or sdm mode */
|
||||
sdm0 = MDSS_PLL_REG_R(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG0);
|
||||
if (sdm0 & BIT(6)) {
|
||||
/* integer mode */
|
||||
sdm_byp_div = (MDSS_PLL_REG_R(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG0) & 0x3f) + 1;
|
||||
vco_rate = ref_clk * sdm_byp_div;
|
||||
} else {
|
||||
/* sdm mode */
|
||||
sdm_dc_off = MDSS_PLL_REG_R(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG1) & 0xFF;
|
||||
pr_debug("sdm_dc_off = %d\n", sdm_dc_off);
|
||||
sdm2 = MDSS_PLL_REG_R(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG2) & 0xFF;
|
||||
sdm3 = MDSS_PLL_REG_R(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_SDM_CFG3) & 0xFF;
|
||||
sdm_freq_seed = (sdm3 << 8) | sdm2;
|
||||
pr_debug("sdm_freq_seed = %d\n", sdm_freq_seed);
|
||||
|
||||
vco_rate = (ref_clk * (sdm_dc_off + 1)) +
|
||||
mult_frac(ref_clk, sdm_freq_seed, BIT(16));
|
||||
pr_debug("vco rate = %lld\n", vco_rate);
|
||||
}
|
||||
|
||||
pr_debug("returning vco rate = %lu\n", (unsigned long)vco_rate);
|
||||
|
||||
mdss_pll_resource_enable(rsc, false);
|
||||
|
||||
return (unsigned long)vco_rate;
|
||||
}
|
||||
|
||||
static int dsi_pll_enable(struct dsi_pll_vco_clk *vco)
|
||||
{
|
||||
int i, rc;
|
||||
struct mdss_pll_resources *rsc = vco->priv;
|
||||
|
||||
rc = mdss_pll_resource_enable(rsc, true);
|
||||
if (rc) {
|
||||
pr_err("failed to enable dsi pll(%d) resources\n",
|
||||
rsc->index);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Try all enable sequences until one succeeds */
|
||||
for (i = 0; i < vco->pll_en_seq_cnt; i++) {
|
||||
rc = vco->pll_enable_seqs[i](rsc);
|
||||
pr_debug("DSI PLL %s after sequence #%d\n",
|
||||
rc ? "unlocked" : "locked", i + 1);
|
||||
if (!rc)
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
mdss_pll_resource_enable(rsc, false);
|
||||
pr_err("DSI PLL failed to lock\n");
|
||||
}
|
||||
rsc->pll_on = true;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void dsi_pll_disable(struct dsi_pll_vco_clk *vco)
|
||||
{
|
||||
struct mdss_pll_resources *rsc = vco->priv;
|
||||
|
||||
if (!rsc->pll_on &&
|
||||
mdss_pll_resource_enable(rsc, true)) {
|
||||
pr_err("failed to enable dsi pll(%d) resources\n",
|
||||
rsc->index);
|
||||
return;
|
||||
}
|
||||
|
||||
rsc->handoff_resources = false;
|
||||
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG, 0x00);
|
||||
|
||||
mdss_pll_resource_enable(rsc, false);
|
||||
rsc->pll_on = false;
|
||||
|
||||
pr_debug("DSI PLL Disabled\n");
|
||||
}
|
||||
|
||||
int vco_28nm_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
|
||||
struct mdss_pll_resources *rsc = vco->priv;
|
||||
int rc;
|
||||
|
||||
if (!rsc) {
|
||||
pr_err("pll resource not found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (rsc->pll_on)
|
||||
return 0;
|
||||
|
||||
pr_debug("ndx=%d, rate=%lu\n", rsc->index, rate);
|
||||
|
||||
rc = mdss_pll_resource_enable(rsc, true);
|
||||
if (rc) {
|
||||
pr_err("failed to enable mdss dsi pll(%d), rc=%d\n",
|
||||
rsc->index, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* DSI PLL software reset. Add HW recommended delays after toggling
|
||||
* the software reset bit off and back on.
|
||||
*/
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_TEST_CFG, 0x01);
|
||||
udelay(1000);
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_TEST_CFG, 0x00);
|
||||
udelay(1000);
|
||||
|
||||
rc = vco_set_rate(vco, rate);
|
||||
rsc->vco_current_rate = rate;
|
||||
|
||||
mdss_pll_resource_enable(rsc, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
long vco_28nm_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
unsigned long rrate = rate;
|
||||
struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
|
||||
|
||||
if (rate < vco->min_rate)
|
||||
rrate = vco->min_rate;
|
||||
if (rate > vco->max_rate)
|
||||
rrate = vco->max_rate;
|
||||
|
||||
*parent_rate = rrate;
|
||||
|
||||
return rrate;
|
||||
}
|
||||
|
||||
unsigned long vco_28nm_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
|
||||
struct mdss_pll_resources *rsc = vco->priv;
|
||||
int rc;
|
||||
u64 vco_rate = 0;
|
||||
|
||||
if (!rsc) {
|
||||
pr_err("dsi pll resources not available\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rsc->vco_current_rate)
|
||||
return (unsigned long)rsc->vco_current_rate;
|
||||
|
||||
if (is_gdsc_disabled(rsc))
|
||||
return 0;
|
||||
|
||||
rc = mdss_pll_resource_enable(rsc, true);
|
||||
if (rc) {
|
||||
pr_err("failed to enable dsi pll(%d) resources\n",
|
||||
rsc->index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dsi_pll_lock_status(rsc)) {
|
||||
rsc->handoff_resources = true;
|
||||
rsc->cont_splash_enabled = true;
|
||||
rsc->pll_on = true;
|
||||
vco_rate = vco_get_rate(vco);
|
||||
} else {
|
||||
mdss_pll_resource_enable(rsc, false);
|
||||
}
|
||||
|
||||
return (unsigned long)vco_rate;
|
||||
}
|
||||
|
||||
int vco_28nm_prepare(struct clk_hw *hw)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
|
||||
struct mdss_pll_resources *rsc = vco->priv;
|
||||
|
||||
if (!rsc) {
|
||||
pr_err("dsi pll resources not available\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((rsc->vco_cached_rate != 0)
|
||||
&& (rsc->vco_cached_rate == clk_hw_get_rate(hw))) {
|
||||
rc = hw->init->ops->set_rate(hw, rsc->vco_cached_rate,
|
||||
rsc->vco_cached_rate);
|
||||
if (rc) {
|
||||
pr_err("pll(%d ) set_rate failed. rc=%d\n",
|
||||
rsc->index, rc);
|
||||
goto error;
|
||||
}
|
||||
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_POSTDIV1_CFG,
|
||||
rsc->cached_postdiv1);
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG,
|
||||
rsc->cached_postdiv3);
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_VREG_CFG,
|
||||
rsc->cached_vreg_cfg);
|
||||
} else if (!rsc->handoff_resources && rsc->cont_splash_enabled) {
|
||||
MDSS_PLL_REG_W(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_VREG_CFG,
|
||||
rsc->cached_vreg_cfg);
|
||||
}
|
||||
|
||||
rc = dsi_pll_enable(vco);
|
||||
|
||||
error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void vco_28nm_unprepare(struct clk_hw *hw)
|
||||
{
|
||||
struct dsi_pll_vco_clk *vco = to_vco_clk_hw(hw);
|
||||
struct mdss_pll_resources *rsc = vco->priv;
|
||||
|
||||
if (!rsc) {
|
||||
pr_err("dsi pll resources not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
rsc->cached_postdiv1 = MDSS_PLL_REG_R(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_POSTDIV1_CFG);
|
||||
rsc->cached_postdiv3 = MDSS_PLL_REG_R(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG);
|
||||
rsc->cached_vreg_cfg = MDSS_PLL_REG_R(rsc->pll_base,
|
||||
DSI_PHY_PLL_UNIPHY_PLL_VREG_CFG);
|
||||
|
||||
rsc->vco_cached_rate = clk_hw_get_rate(hw);
|
||||
|
||||
dsi_pll_disable(vco);
|
||||
}
|
73
drivers/clk/qcom/mdss/mdss-dsi-pll-28nm.h
Normal file
73
drivers/clk/qcom/mdss/mdss-dsi-pll-28nm.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2012-2018, 2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MDSS_DSI_PLL_28NM_H
|
||||
#define __MDSS_DSI_PLL_28NM_H
|
||||
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_GLB_CFG (0x0020)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_LKDET_CFG2 (0x0064)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_TEST_CFG (0x0068)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_CAL_CFG1 (0x0070)
|
||||
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_POSTDIV1_CFG (0x0004)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_POSTDIV3_CFG (0x0028)
|
||||
#define DSI_PHY_PLL_UNIPHY_PLL_VREG_CFG (0x0010)
|
||||
|
||||
struct ssc_params {
|
||||
s32 kdiv;
|
||||
s64 triang_inc_7_0;
|
||||
s64 triang_inc_9_8;
|
||||
s64 triang_steps;
|
||||
s64 dc_offset;
|
||||
s64 freq_seed_7_0;
|
||||
s64 freq_seed_15_8;
|
||||
};
|
||||
|
||||
struct mdss_dsi_vco_calc {
|
||||
s64 sdm_cfg0;
|
||||
s64 sdm_cfg1;
|
||||
s64 sdm_cfg2;
|
||||
s64 sdm_cfg3;
|
||||
s64 cal_cfg10;
|
||||
s64 cal_cfg11;
|
||||
s64 refclk_cfg;
|
||||
s64 gen_vco_clk;
|
||||
u32 lpfr_lut_res;
|
||||
struct ssc_params ssc;
|
||||
};
|
||||
|
||||
unsigned long vco_28nm_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate);
|
||||
int vco_28nm_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate);
|
||||
long vco_28nm_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate);
|
||||
int vco_28nm_prepare(struct clk_hw *hw);
|
||||
void vco_28nm_unprepare(struct clk_hw *hw);
|
||||
|
||||
int analog_postdiv_reg_write(void *context,
|
||||
unsigned int reg, unsigned int div);
|
||||
int analog_postdiv_reg_read(void *context,
|
||||
unsigned int reg, unsigned int *div);
|
||||
int byteclk_mux_write_sel(void *context,
|
||||
unsigned int reg, unsigned int val);
|
||||
int byteclk_mux_read_sel(void *context,
|
||||
unsigned int reg, unsigned int *val);
|
||||
int pixel_clk_set_div(void *context,
|
||||
unsigned int reg, unsigned int div);
|
||||
int pixel_clk_get_div(void *context,
|
||||
unsigned int reg, unsigned int *div);
|
||||
|
||||
int dsi_pll_lock_status(struct mdss_pll_resources *rsc);
|
||||
#endif /* __MDSS_DSI_PLL_28NM_H */
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2012-2018, 2020 The Linux Foundation. All rights reserved. */
|
||||
/* Copyright (c) 2012-2018, 2020-2021, The Linux Foundation. All rights reserved. */
|
||||
|
||||
#ifndef __MDSS_DSI_PLL_H
|
||||
#define __MDSS_DSI_PLL_H
|
||||
|
@ -39,4 +39,8 @@ static inline struct dsi_pll_vco_clk *to_vco_clk_hw(struct clk_hw *hw)
|
|||
|
||||
int dsi_pll_clock_register_14nm(struct platform_device *pdev,
|
||||
struct mdss_pll_resources *pll_res);
|
||||
int dsi_pll_clock_register_28lpm(struct platform_device *pdev,
|
||||
struct mdss_pll_resources *pll_res);
|
||||
int dsi_pll_clock_register_12nm(struct platform_device *pdev,
|
||||
struct mdss_pll_resources *pll_res);
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. */
|
||||
/* Copyright (c) 2013-2021, The Linux Foundation. All rights reserved. */
|
||||
|
||||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
|
||||
|
@ -128,7 +128,9 @@ static int mdss_pll_resource_parse(struct platform_device *pdev,
|
|||
pll_res->pll_interface_type = MDSS_DP_PLL_14NM;
|
||||
pll_res->target_id = MDSS_PLL_TARGET_SDM660;
|
||||
pll_res->revision = 2;
|
||||
} else
|
||||
} else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_28lpm"))
|
||||
pll_res->pll_interface_type = MDSS_DSI_PLL_28LPM;
|
||||
else
|
||||
goto err;
|
||||
|
||||
return rc;
|
||||
|
@ -156,6 +158,12 @@ static int mdss_pll_clock_register(struct platform_device *pdev,
|
|||
case MDSS_DP_PLL_14NM:
|
||||
rc = dp_pll_clock_register_14nm(pdev, pll_res);
|
||||
break;
|
||||
case MDSS_DSI_PLL_28LPM:
|
||||
rc = dsi_pll_clock_register_28lpm(pdev, pll_res);
|
||||
break;
|
||||
case MDSS_DSI_PLL_12NM:
|
||||
rc = dsi_pll_clock_register_12nm(pdev, pll_res);
|
||||
break;
|
||||
case MDSS_UNKNOWN_PLL:
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
|
@ -386,6 +394,8 @@ static const struct of_device_id mdss_pll_dt_match[] = {
|
|||
{.compatible = "qcom,mdss_dp_pll_14nm"},
|
||||
{.compatible = "qcom,mdss_dsi_pll_sdm660"},
|
||||
{.compatible = "qcom,mdss_dp_pll_sdm660"},
|
||||
{.compatible = "qcom,mdss_dsi_pll_12nm"},
|
||||
{.compatible = "qcom,mdss_dsi_pll_28lpm"},
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. */
|
||||
/* Copyright (c) 2013-2021, The Linux Foundation. All rights reserved. */
|
||||
|
||||
#ifndef __MDSS_PLL_H
|
||||
#define __MDSS_PLL_H
|
||||
|
@ -146,6 +146,7 @@ struct mdss_pll_resources {
|
|||
* feature is disabled.
|
||||
*/
|
||||
bool handoff_resources;
|
||||
bool cont_splash_enabled;
|
||||
|
||||
/*
|
||||
* caching the pll trim codes in the case of dynamic refresh
|
||||
|
@ -218,7 +219,8 @@ static inline bool is_gdsc_disabled(struct mdss_pll_resources *pll_res)
|
|||
WARN(1, "gdsc_base register is not defined\n");
|
||||
return true;
|
||||
}
|
||||
if (pll_res->target_id == MDSS_PLL_TARGET_SDM660)
|
||||
if ((pll_res->target_id == MDSS_PLL_TARGET_SDM660) ||
|
||||
(pll_res->pll_interface_type == MDSS_DSI_PLL_28LPM))
|
||||
ret = ((readl_relaxed(pll_res->gdsc_base + 0x4) & BIT(31)) &&
|
||||
(!(readl_relaxed(pll_res->gdsc_base) & BIT(0)))) ? false : true;
|
||||
else
|
||||
|
|
27
drivers/clk/qcom/vdd-level-cpu.h
Normal file
27
drivers/clk/qcom/vdd-level-cpu.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __DRIVERS_CLK_QCOM_VDD_LEVEL_CPU_H
|
||||
#define __DRIVERS_CLK_QCOM_VDD_LEVEL_CPU_H
|
||||
|
||||
#include <linux/regulator/rpm-smd-regulator.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
enum vdd_hf_pll_levels {
|
||||
VDD_HF_PLL_OFF,
|
||||
VDD_HF_PLL_SVS,
|
||||
VDD_HF_PLL_NOM,
|
||||
VDD_HF_PLL_TUR,
|
||||
VDD_HF_PLL_NUM,
|
||||
};
|
||||
|
||||
static int vdd_hf_levels[] = {
|
||||
0, RPM_REGULATOR_LEVEL_NONE, /* VDD_HF_PLL_OFF */
|
||||
1800000, RPM_REGULATOR_LEVEL_SVS, /* VDD_HF_PLL_SVS */
|
||||
1800000, RPM_REGULATOR_LEVEL_NOM, /* VDD_HF_PLL_NOM */
|
||||
1800000, RPM_REGULATOR_LEVEL_TURBO, /* VDD_HF_PLL_TUR */
|
||||
};
|
||||
|
||||
#endif
|
31
drivers/clk/qcom/vdd-level-sdm429w.h
Normal file
31
drivers/clk/qcom/vdd-level-sdm429w.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __DRIVERS_CLK_QCOM_VDD_LEVEL_SDM429W_H
|
||||
#define __DRIVERS_CLK_QCOM_VDD_LEVEL_SDM429W_H
|
||||
|
||||
#include <linux/regulator/rpm-smd-regulator.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
enum vdd_levels {
|
||||
VDD_NONE,
|
||||
VDD_LOW,
|
||||
VDD_LOW_L1,
|
||||
VDD_NOMINAL,
|
||||
VDD_NOMINAL_L1,
|
||||
VDD_HIGH,
|
||||
VDD_NUM
|
||||
};
|
||||
|
||||
static int vdd_corner[] = {
|
||||
RPM_REGULATOR_LEVEL_NONE, /* VDD_NONE */
|
||||
RPM_REGULATOR_LEVEL_SVS, /* VDD_SVS */
|
||||
RPM_REGULATOR_LEVEL_SVS_PLUS, /* VDD_SVS_PLUS */
|
||||
RPM_REGULATOR_LEVEL_NOM, /* VDD_NOM */
|
||||
RPM_REGULATOR_LEVEL_NOM_PLUS, /* VDD_NOM_PLUS */
|
||||
RPM_REGULATOR_LEVEL_TURBO, /* VDD_TURBO */
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2013-2015,2017,2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (C) 2020 XiaoMi, Inc.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "cpu-boost: " fmt
|
||||
|
@ -41,16 +40,13 @@ struct cpu_sync {
|
|||
int cpu;
|
||||
unsigned int input_boost_min;
|
||||
unsigned int input_boost_freq;
|
||||
unsigned int powerkey_input_boost_freq;
|
||||
};
|
||||
|
||||
|
||||
static DEFINE_PER_CPU(struct cpu_sync, sync_info);
|
||||
static struct workqueue_struct *cpu_boost_wq;
|
||||
|
||||
static struct work_struct input_boost_work;
|
||||
|
||||
static struct work_struct powerkey_input_boost_work;
|
||||
static bool input_boost_enabled;
|
||||
|
||||
static unsigned int input_boost_ms = 40;
|
||||
|
@ -58,22 +54,11 @@ show_one(input_boost_ms);
|
|||
store_one(input_boost_ms);
|
||||
cpu_boost_attr_rw(input_boost_ms);
|
||||
|
||||
static unsigned int powerkey_input_boost_ms = 400;
|
||||
show_one(powerkey_input_boost_ms);
|
||||
store_one(powerkey_input_boost_ms);
|
||||
cpu_boost_attr_rw(powerkey_input_boost_ms);
|
||||
|
||||
static unsigned int sched_boost_on_input;
|
||||
show_one(sched_boost_on_input);
|
||||
store_one(sched_boost_on_input);
|
||||
cpu_boost_attr_rw(sched_boost_on_input);
|
||||
|
||||
|
||||
static bool sched_boost_on_powerkey_input = true;
|
||||
show_one(sched_boost_on_powerkey_input);
|
||||
store_one(sched_boost_on_powerkey_input);
|
||||
cpu_boost_attr_rw(sched_boost_on_powerkey_input);
|
||||
|
||||
static bool sched_boost_active;
|
||||
|
||||
static struct delayed_work input_boost_rem;
|
||||
|
@ -145,72 +130,6 @@ static ssize_t show_input_boost_freq(struct kobject *kobj,
|
|||
}
|
||||
|
||||
cpu_boost_attr_rw(input_boost_freq);
|
||||
static ssize_t store_powerkey_input_boost_freq(struct kobject *kobj,
|
||||
struct kobj_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int i, ntokens = 0;
|
||||
unsigned int val, cpu;
|
||||
const char *cp = buf;
|
||||
bool enabled = false;
|
||||
|
||||
while ((cp = strpbrk(cp + 1, " :")))
|
||||
ntokens++;
|
||||
|
||||
/* single number: apply to all CPUs */
|
||||
if (!ntokens) {
|
||||
if (sscanf(buf, "%u\n", &val) != 1)
|
||||
return -EINVAL;
|
||||
for_each_possible_cpu(i)
|
||||
per_cpu(sync_info, i).powerkey_input_boost_freq = val;
|
||||
goto check_enable;
|
||||
}
|
||||
|
||||
/* CPU:value pair */
|
||||
if (!(ntokens % 2))
|
||||
return -EINVAL;
|
||||
|
||||
cp = buf;
|
||||
for (i = 0; i < ntokens; i += 2) {
|
||||
if (sscanf(cp, "%u:%u", &cpu, &val) != 2)
|
||||
return -EINVAL;
|
||||
if (cpu >= num_possible_cpus())
|
||||
return -EINVAL;
|
||||
per_cpu(sync_info, cpu).powerkey_input_boost_freq = val;
|
||||
cp = strnchr(cp, PAGE_SIZE - (cp - buf), ' ');
|
||||
cp++;
|
||||
}
|
||||
|
||||
check_enable:
|
||||
for_each_possible_cpu(i) {
|
||||
if (per_cpu(sync_info, i).powerkey_input_boost_freq) {
|
||||
enabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
input_boost_enabled = enabled;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_powerkey_input_boost_freq(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
int cnt = 0, cpu;
|
||||
struct cpu_sync *s;
|
||||
unsigned int boost_freq = 0;
|
||||
for_each_possible_cpu(cpu) {
|
||||
s = &per_cpu(sync_info, cpu);
|
||||
boost_freq = s->powerkey_input_boost_freq;
|
||||
cnt += snprintf(buf + cnt, PAGE_SIZE - cnt,
|
||||
"%d:%u ", cpu, boost_freq);
|
||||
}
|
||||
cnt += snprintf(buf + cnt, PAGE_SIZE - cnt, "\n");
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
cpu_boost_attr_rw(powerkey_input_boost_freq);
|
||||
|
||||
/*
|
||||
* The CPUFREQ_ADJUST notifier is used to override the current policy min to
|
||||
|
@ -318,40 +237,6 @@ static void do_input_boost(struct work_struct *work)
|
|||
msecs_to_jiffies(input_boost_ms));
|
||||
}
|
||||
|
||||
static void do_powerkey_input_boost(struct work_struct *work)
|
||||
{
|
||||
|
||||
unsigned int i, ret;
|
||||
struct cpu_sync *i_sync_info;
|
||||
cancel_delayed_work_sync(&input_boost_rem);
|
||||
if (sched_boost_active) {
|
||||
sched_set_boost(0);
|
||||
sched_boost_active = false;
|
||||
}
|
||||
|
||||
/* Set the powerkey_input_boost_min for all CPUs in the system */
|
||||
pr_debug("Setting powerkey input boost min for all CPUs\n");
|
||||
for_each_possible_cpu(i) {
|
||||
i_sync_info = &per_cpu(sync_info, i);
|
||||
i_sync_info->input_boost_min = i_sync_info->powerkey_input_boost_freq;
|
||||
}
|
||||
|
||||
/* Update policies for all online CPUs */
|
||||
update_policy_online();
|
||||
|
||||
/* Enable scheduler boost to migrate tasks to big cluster */
|
||||
if (sched_boost_on_powerkey_input) {
|
||||
ret = sched_set_boost(1);
|
||||
if (ret)
|
||||
pr_err("cpu-boost: HMP boost enable failed\n");
|
||||
else
|
||||
sched_boost_active = true;
|
||||
}
|
||||
|
||||
queue_delayed_work(cpu_boost_wq, &input_boost_rem,
|
||||
msecs_to_jiffies(powerkey_input_boost_ms));
|
||||
}
|
||||
|
||||
static void cpuboost_input_event(struct input_handle *handle,
|
||||
unsigned int type, unsigned int code, int value)
|
||||
{
|
||||
|
@ -367,11 +252,7 @@ static void cpuboost_input_event(struct input_handle *handle,
|
|||
if (work_pending(&input_boost_work))
|
||||
return;
|
||||
|
||||
if (type == EV_KEY && code == KEY_POWER) {
|
||||
queue_work(cpu_boost_wq, &powerkey_input_boost_work);
|
||||
} else {
|
||||
queue_work(cpu_boost_wq, &input_boost_work);
|
||||
}
|
||||
queue_work(cpu_boost_wq, &input_boost_work);
|
||||
last_input_time = ktime_to_us(ktime_get());
|
||||
}
|
||||
|
||||
|
@ -457,7 +338,6 @@ static int cpu_boost_init(void)
|
|||
return -EFAULT;
|
||||
|
||||
INIT_WORK(&input_boost_work, do_input_boost);
|
||||
INIT_WORK(&powerkey_input_boost_work, do_powerkey_input_boost);
|
||||
INIT_DELAYED_WORK(&input_boost_rem, do_input_boost_rem);
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
|
@ -475,27 +355,15 @@ static int cpu_boost_init(void)
|
|||
if (ret)
|
||||
pr_err("Failed to create input_boost_ms node: %d\n", ret);
|
||||
|
||||
ret = sysfs_create_file(cpu_boost_kobj, &powerkey_input_boost_ms_attr.attr);
|
||||
if (ret)
|
||||
pr_err("Failed to create powerkey_input_boost_ms node: %d\n", ret);
|
||||
|
||||
ret = sysfs_create_file(cpu_boost_kobj, &input_boost_freq_attr.attr);
|
||||
if (ret)
|
||||
pr_err("Failed to create input_boost_freq node: %d\n", ret);
|
||||
ret = sysfs_create_file(cpu_boost_kobj, &powerkey_input_boost_freq_attr.attr);
|
||||
if (ret)
|
||||
pr_err("Failed to create powerkey_input_boost_freq node: %d\n", ret);
|
||||
|
||||
ret = sysfs_create_file(cpu_boost_kobj,
|
||||
&sched_boost_on_input_attr.attr);
|
||||
if (ret)
|
||||
pr_err("Failed to create sched_boost_on_input node: %d\n", ret);
|
||||
|
||||
ret = sysfs_create_file(cpu_boost_kobj,
|
||||
&sched_boost_on_powerkey_input_attr.attr);
|
||||
if (ret)
|
||||
pr_err("Failed to create sched_boost_on_powerkey_input node: %d\n", ret);
|
||||
|
||||
ret = input_register_handler(&cpuboost_input_handler);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2270,9 +2270,6 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
|
|||
blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
|
||||
CPUFREQ_INCOMPATIBLE, new_policy);
|
||||
|
||||
blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
|
||||
CPUFREQ_THERMAL, new_policy);
|
||||
|
||||
/*
|
||||
* verify the cpu speed can be set within this limit, which might be
|
||||
* different to the first one
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (C) 2020 XiaoMi, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/cpufreq.h>
|
||||
|
|
|
@ -250,17 +250,17 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
|
|||
if (!cpuidle_state_is_coupled(drv, index))
|
||||
local_irq_enable();
|
||||
|
||||
diff = ktime_us_delta(time_end, time_start);
|
||||
if (diff > INT_MAX)
|
||||
diff = INT_MAX;
|
||||
|
||||
dev->last_residency = (int) diff;
|
||||
|
||||
if (entered_state >= 0) {
|
||||
/*
|
||||
* Update cpuidle counters
|
||||
* This can be moved to within driver enter routine,
|
||||
/* Update cpuidle counters */
|
||||
/* This can be moved to within driver enter routine
|
||||
* but that results in multiple copies of same code.
|
||||
*/
|
||||
diff = ktime_us_delta(time_end, time_start);
|
||||
if (diff > INT_MAX)
|
||||
diff = INT_MAX;
|
||||
|
||||
dev->last_residency = (int)diff;
|
||||
dev->states_usage[entered_state].time += dev->last_residency;
|
||||
dev->states_usage[entered_state].usage++;
|
||||
} else {
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <soc/qcom/event_timer.h>
|
||||
#include <soc/qcom/lpm_levels.h>
|
||||
#include <soc/qcom/lpm-stats.h>
|
||||
#include <soc/qcom/minidump.h>
|
||||
#include <asm/arch_timer.h>
|
||||
#include <asm/suspend.h>
|
||||
#include <asm/cpuidle.h>
|
||||
|
@ -47,6 +48,30 @@
|
|||
#define PSCI_POWER_STATE(reset) (reset << 30)
|
||||
#define PSCI_AFFINITY_LEVEL(lvl) ((lvl & 0x3) << 24)
|
||||
|
||||
enum {
|
||||
MSM_LPM_LVL_DBG_SUSPEND_LIMITS = BIT(0),
|
||||
MSM_LPM_LVL_DBG_IDLE_LIMITS = BIT(1),
|
||||
};
|
||||
|
||||
enum debug_event {
|
||||
CPU_ENTER,
|
||||
CPU_EXIT,
|
||||
CLUSTER_ENTER,
|
||||
CLUSTER_EXIT,
|
||||
CPU_HP_STARTING,
|
||||
CPU_HP_DYING,
|
||||
};
|
||||
|
||||
struct lpm_debug {
|
||||
u64 time;
|
||||
enum debug_event evt;
|
||||
int cpu;
|
||||
uint32_t arg1;
|
||||
uint32_t arg2;
|
||||
uint32_t arg3;
|
||||
uint32_t arg4;
|
||||
};
|
||||
|
||||
static struct system_pm_ops *sys_pm_ops;
|
||||
|
||||
|
||||
|
@ -83,6 +108,9 @@ static bool suspend_in_progress;
|
|||
static struct hrtimer lpm_hrtimer;
|
||||
static DEFINE_PER_CPU(struct hrtimer, histtimer);
|
||||
static DEFINE_PER_CPU(struct hrtimer, biastimer);
|
||||
static struct lpm_debug *lpm_debug;
|
||||
static phys_addr_t lpm_debug_phys;
|
||||
static const int num_dbg_elements = 0x100;
|
||||
|
||||
static void cluster_unprepare(struct lpm_cluster *cluster,
|
||||
const struct cpumask *cpu, int child_idx, bool from_idle,
|
||||
|
@ -254,10 +282,38 @@ int lpm_get_latency(struct latency_level *level, uint32_t *latency)
|
|||
}
|
||||
EXPORT_SYMBOL(lpm_get_latency);
|
||||
|
||||
static void update_debug_pc_event(enum debug_event event, uint32_t arg1,
|
||||
uint32_t arg2, uint32_t arg3, uint32_t arg4)
|
||||
{
|
||||
struct lpm_debug *dbg;
|
||||
int idx;
|
||||
static DEFINE_SPINLOCK(debug_lock);
|
||||
static int pc_event_index;
|
||||
|
||||
if (!lpm_debug)
|
||||
return;
|
||||
|
||||
spin_lock(&debug_lock);
|
||||
idx = pc_event_index++;
|
||||
dbg = &lpm_debug[idx & (num_dbg_elements - 1)];
|
||||
|
||||
dbg->evt = event;
|
||||
dbg->time = arch_counter_get_cntvct();
|
||||
dbg->cpu = raw_smp_processor_id();
|
||||
dbg->arg1 = arg1;
|
||||
dbg->arg2 = arg2;
|
||||
dbg->arg3 = arg3;
|
||||
dbg->arg4 = arg4;
|
||||
spin_unlock(&debug_lock);
|
||||
}
|
||||
|
||||
static int lpm_dying_cpu(unsigned int cpu)
|
||||
{
|
||||
struct lpm_cluster *cluster = per_cpu(cpu_lpm, cpu)->parent;
|
||||
|
||||
update_debug_pc_event(CPU_HP_DYING, cpu,
|
||||
cluster->num_children_in_sync.bits[0],
|
||||
cluster->child_cpus.bits[0], false);
|
||||
cluster_prepare(cluster, get_cpu_mask(cpu), NR_LPM_LEVELS, false, 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -266,6 +322,9 @@ static int lpm_starting_cpu(unsigned int cpu)
|
|||
{
|
||||
struct lpm_cluster *cluster = per_cpu(cpu_lpm, cpu)->parent;
|
||||
|
||||
update_debug_pc_event(CPU_HP_STARTING, cpu,
|
||||
cluster->num_children_in_sync.bits[0],
|
||||
cluster->child_cpus.bits[0], false);
|
||||
cluster_unprepare(cluster, get_cpu_mask(cpu), NR_LPM_LEVELS, false,
|
||||
0, true);
|
||||
return 0;
|
||||
|
@ -1048,6 +1107,9 @@ static int cluster_configure(struct lpm_cluster *cluster, int idx,
|
|||
return -EPERM;
|
||||
|
||||
if (idx != cluster->default_level) {
|
||||
update_debug_pc_event(CLUSTER_ENTER, idx,
|
||||
cluster->num_children_in_sync.bits[0],
|
||||
cluster->child_cpus.bits[0], from_idle);
|
||||
trace_cluster_enter(cluster->cluster_name, idx,
|
||||
cluster->num_children_in_sync.bits[0],
|
||||
cluster->child_cpus.bits[0], from_idle);
|
||||
|
@ -1201,6 +1263,9 @@ static void cluster_unprepare(struct lpm_cluster *cluster,
|
|||
if (sys_pm_ops && sys_pm_ops->exit)
|
||||
sys_pm_ops->exit(success);
|
||||
|
||||
update_debug_pc_event(CLUSTER_EXIT, cluster->last_level,
|
||||
cluster->num_children_in_sync.bits[0],
|
||||
cluster->child_cpus.bits[0], from_idle);
|
||||
trace_cluster_exit(cluster->cluster_name, cluster->last_level,
|
||||
cluster->num_children_in_sync.bits[0],
|
||||
cluster->child_cpus.bits[0], from_idle);
|
||||
|
@ -1312,11 +1377,15 @@ static bool psci_enter_sleep(struct lpm_cpu *cpu, int idx, bool from_idle)
|
|||
affinity_level = PSCI_AFFINITY_LEVEL(affinity_level);
|
||||
state_id += power_state + affinity_level + cpu->levels[idx].psci_id;
|
||||
|
||||
update_debug_pc_event(CPU_ENTER, state_id,
|
||||
0xdeaffeed, 0xdeaffeed, from_idle);
|
||||
stop_critical_timings();
|
||||
|
||||
success = !arm_cpuidle_suspend(state_id);
|
||||
|
||||
start_critical_timings();
|
||||
update_debug_pc_event(CPU_EXIT, state_id,
|
||||
success, 0xdeaffeed, from_idle);
|
||||
|
||||
if (from_idle && cpu->levels[idx].use_bc_timer)
|
||||
tick_broadcast_exit();
|
||||
|
@ -1704,9 +1773,11 @@ static const struct platform_s2idle_ops lpm_s2idle_ops = {
|
|||
static int lpm_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
int size;
|
||||
unsigned int cpu;
|
||||
struct hrtimer *cpu_histtimer;
|
||||
struct kobject *module_kobj = NULL;
|
||||
struct md_region md_entry;
|
||||
|
||||
get_online_cpus();
|
||||
lpm_root_node = lpm_of_parse_cluster(pdev);
|
||||
|
@ -1738,6 +1809,10 @@ static int lpm_probe(struct platform_device *pdev)
|
|||
|
||||
cluster_timer_init(lpm_root_node);
|
||||
|
||||
size = num_dbg_elements * sizeof(struct lpm_debug);
|
||||
lpm_debug = dma_alloc_coherent(&pdev->dev, size,
|
||||
&lpm_debug_phys, GFP_KERNEL);
|
||||
|
||||
register_cluster_lpm_stats(lpm_root_node, NULL);
|
||||
|
||||
ret = cluster_cpuidle_register(lpm_root_node);
|
||||
|
@ -1768,6 +1843,15 @@ static int lpm_probe(struct platform_device *pdev)
|
|||
|
||||
set_update_ipi_history_callback(update_ipi_history);
|
||||
|
||||
/* Add lpm_debug to Minidump*/
|
||||
strlcpy(md_entry.name, "KLPMDEBUG", sizeof(md_entry.name));
|
||||
md_entry.virt_addr = (uintptr_t)lpm_debug;
|
||||
md_entry.phys_addr = lpm_debug_phys;
|
||||
md_entry.size = size;
|
||||
md_entry.id = MINIDUMP_DEFAULT_ID;
|
||||
if (msm_minidump_add_region(&md_entry) < 0)
|
||||
pr_info("Failed to add lpm_debug in Minidump\n");
|
||||
|
||||
return 0;
|
||||
failed:
|
||||
free_cluster_node(lpm_root_node);
|
||||
|
|
|
@ -58,7 +58,6 @@
|
|||
|
||||
#define ICE_CRYPTO_CXT_FDE 1
|
||||
#define ICE_CRYPTO_CXT_FBE 2
|
||||
#define ICE_INSTANCE_TYPE_LENGTH 12
|
||||
|
||||
static int ice_fde_flag;
|
||||
|
||||
|
@ -584,33 +583,37 @@ static int register_ice_device(struct ice_device *ice_dev)
|
|||
unsigned int baseminor = 0;
|
||||
unsigned int count = 1;
|
||||
struct device *class_dev;
|
||||
char ice_type[ICE_INSTANCE_TYPE_LENGTH];
|
||||
|
||||
if (!strcmp(ice_dev->ice_instance_type, "sdcc"))
|
||||
strlcpy(ice_type, QCOM_SDCC_ICE_DEV, sizeof(ice_type));
|
||||
else if (!strcmp(ice_dev->ice_instance_type, "ufscard"))
|
||||
strlcpy(ice_type, QCOM_UFS_CARD_ICE_DEV, sizeof(ice_type));
|
||||
else
|
||||
strlcpy(ice_type, QCOM_UFS_ICE_DEV, sizeof(ice_type));
|
||||
int is_sdcc_ice = !strcmp(ice_dev->ice_instance_type, "sdcc");
|
||||
int is_ufscard_ice = !strcmp(ice_dev->ice_instance_type, "ufscard");
|
||||
|
||||
rc = alloc_chrdev_region(&ice_dev->device_no, baseminor, count,
|
||||
ice_type);
|
||||
is_sdcc_ice ? QCOM_SDCC_ICE_DEV : is_ufscard_ice ?
|
||||
QCOM_UFS_CARD_ICE_DEV : QCOM_UFS_ICE_DEV);
|
||||
if (rc < 0) {
|
||||
pr_err("alloc_chrdev_region failed %d for %s\n", rc,
|
||||
ice_type);
|
||||
is_sdcc_ice ? QCOM_SDCC_ICE_DEV : is_ufscard_ice ?
|
||||
QCOM_UFS_CARD_ICE_DEV : QCOM_UFS_ICE_DEV);
|
||||
return rc;
|
||||
}
|
||||
ice_dev->driver_class = class_create(THIS_MODULE, ice_type);
|
||||
ice_dev->driver_class = class_create(THIS_MODULE,
|
||||
is_sdcc_ice ? QCOM_SDCC_ICE_DEV : is_ufscard_ice ?
|
||||
QCOM_UFS_CARD_ICE_DEV : QCOM_UFS_ICE_DEV);
|
||||
if (IS_ERR(ice_dev->driver_class)) {
|
||||
rc = -ENOMEM;
|
||||
pr_err("class_create failed %d for %s\n", rc, ice_type);
|
||||
pr_err("class_create failed %d for %s\n", rc,
|
||||
is_sdcc_ice ? QCOM_SDCC_ICE_DEV : is_ufscard_ice ?
|
||||
QCOM_UFS_CARD_ICE_DEV : QCOM_UFS_ICE_DEV);
|
||||
goto exit_unreg_chrdev_region;
|
||||
}
|
||||
class_dev = device_create(ice_dev->driver_class, NULL,
|
||||
ice_dev->device_no, NULL, ice_type);
|
||||
ice_dev->device_no, NULL,
|
||||
is_sdcc_ice ? QCOM_SDCC_ICE_DEV : is_ufscard_ice ?
|
||||
QCOM_UFS_CARD_ICE_DEV : QCOM_UFS_ICE_DEV);
|
||||
|
||||
if (!class_dev) {
|
||||
pr_err("class_device_create failed %d for %s\n", rc, ice_type);
|
||||
pr_err("class_device_create failed %d for %s\n", rc,
|
||||
is_sdcc_ice ? QCOM_SDCC_ICE_DEV : is_ufscard_ice ?
|
||||
QCOM_UFS_CARD_ICE_DEV : QCOM_UFS_ICE_DEV);
|
||||
rc = -ENOMEM;
|
||||
goto exit_destroy_class;
|
||||
}
|
||||
|
@ -620,7 +623,9 @@ static int register_ice_device(struct ice_device *ice_dev)
|
|||
|
||||
rc = cdev_add(&ice_dev->cdev, MKDEV(MAJOR(ice_dev->device_no), 0), 1);
|
||||
if (rc < 0) {
|
||||
pr_err("cdev_add failed %d for %s\n", rc, ice_type);
|
||||
pr_err("cdev_add failed %d for %s\n", rc,
|
||||
is_sdcc_ice ? QCOM_SDCC_ICE_DEV : is_ufscard_ice ?
|
||||
QCOM_UFS_CARD_ICE_DEV : QCOM_UFS_ICE_DEV);
|
||||
goto exit_destroy_device;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* QTI Crypto Engine driver.
|
||||
*
|
||||
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "QCE50: %s: " fmt, __func__
|
||||
|
@ -922,6 +922,11 @@ static int _ce_setup_cipher(struct qce_device *pce_dev, struct qce_req *creq,
|
|||
break;
|
||||
case CIPHER_ALG_3DES:
|
||||
if (creq->mode != QCE_MODE_ECB) {
|
||||
if (ivsize > MAX_IV_LENGTH) {
|
||||
pr_err("%s: error: Invalid length parameter\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
_byte_stream_to_net_words(enciv32, creq->iv, ivsize);
|
||||
pce = cmdlistinfo->encr_cntr_iv;
|
||||
pce->data = enciv32[0];
|
||||
|
@ -970,6 +975,11 @@ static int _ce_setup_cipher(struct qce_device *pce_dev, struct qce_req *creq,
|
|||
}
|
||||
}
|
||||
if (creq->mode != QCE_MODE_ECB) {
|
||||
if (ivsize > MAX_IV_LENGTH) {
|
||||
pr_err("%s: error: Invalid length parameter\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (creq->mode == QCE_MODE_XTS)
|
||||
_byte_stream_swap_to_net_words(enciv32,
|
||||
creq->iv, ivsize);
|
||||
|
|
|
@ -1400,9 +1400,7 @@ static int __init devfreq_init(void)
|
|||
return PTR_ERR(devfreq_class);
|
||||
}
|
||||
|
||||
devfreq_wq = alloc_workqueue("devfreq_wq",
|
||||
WQ_HIGHPRI | WQ_UNBOUND | WQ_FREEZABLE |
|
||||
WQ_MEM_RECLAIM, 0);
|
||||
devfreq_wq = create_freezable_workqueue("devfreq_wq");
|
||||
if (!devfreq_wq) {
|
||||
class_destroy(devfreq_class);
|
||||
pr_err("%s: couldn't create workqueue\n", __FILE__);
|
||||
|
|
|
@ -124,6 +124,36 @@ struct dma_fence *sync_file_get_fence(int fd)
|
|||
}
|
||||
EXPORT_SYMBOL(sync_file_get_fence);
|
||||
|
||||
/**
|
||||
* sync_file_get_name - get the name of the sync_file
|
||||
* @sync_file: sync_file to get the fence from
|
||||
* @buf: destination buffer to copy sync_file name into
|
||||
* @len: available size of destination buffer.
|
||||
*
|
||||
* Each sync_file may have a name assigned either by the user (when merging
|
||||
* sync_files together) or created from the fence it contains. In the latter
|
||||
* case construction of the name is deferred until use, and so requires
|
||||
* sync_file_get_name().
|
||||
*
|
||||
* Returns: a string representing the name.
|
||||
*/
|
||||
char *sync_file_get_name(struct sync_file *sync_file, char *buf, int len)
|
||||
{
|
||||
if (sync_file->user_name[0]) {
|
||||
strlcpy(buf, sync_file->user_name, len);
|
||||
} else {
|
||||
struct dma_fence *fence = sync_file->fence;
|
||||
|
||||
snprintf(buf, len, "%s-%s%llu-%d",
|
||||
fence->ops->get_driver_name(fence),
|
||||
fence->ops->get_timeline_name(fence),
|
||||
fence->context,
|
||||
fence->seqno);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int sync_file_set_fence(struct sync_file *sync_file,
|
||||
struct dma_fence **fences, int num_fences)
|
||||
{
|
||||
|
@ -186,7 +216,7 @@ static void add_fence(struct dma_fence **fences,
|
|||
* @a and @b. @a and @b remain valid, independent sync_file. Returns the
|
||||
* new merged sync_file or NULL in case of error.
|
||||
*/
|
||||
static struct sync_file *sync_file_merge(struct sync_file *a,
|
||||
static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
|
||||
struct sync_file *b)
|
||||
{
|
||||
struct sync_file *sync_file;
|
||||
|
@ -261,6 +291,7 @@ static struct sync_file *sync_file_merge(struct sync_file *a,
|
|||
goto err;
|
||||
}
|
||||
|
||||
strlcpy(sync_file->user_name, name, sizeof(sync_file->user_name));
|
||||
return sync_file;
|
||||
|
||||
err:
|
||||
|
@ -304,14 +335,11 @@ static long sync_file_ioctl_merge(struct sync_file *sync_file,
|
|||
int err;
|
||||
struct sync_file *fence2, *fence3;
|
||||
struct sync_merge_data data;
|
||||
size_t len;
|
||||
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
arg += offsetof(typeof(data), fd2);
|
||||
len = sizeof(data) - offsetof(typeof(data), fd2);
|
||||
if (copy_from_user(&data.fd2, (void __user *)arg, len)) {
|
||||
if (copy_from_user(&data, (void __user *)arg, sizeof(data))) {
|
||||
err = -EFAULT;
|
||||
goto err_put_fd;
|
||||
}
|
||||
|
@ -327,14 +355,15 @@ static long sync_file_ioctl_merge(struct sync_file *sync_file,
|
|||
goto err_put_fd;
|
||||
}
|
||||
|
||||
fence3 = sync_file_merge(sync_file, fence2);
|
||||
data.name[sizeof(data.name) - 1] = '\0';
|
||||
fence3 = sync_file_merge(data.name, sync_file, fence2);
|
||||
if (!fence3) {
|
||||
err = -ENOMEM;
|
||||
goto err_put_fence2;
|
||||
}
|
||||
|
||||
data.fence = fd;
|
||||
if (copy_to_user((void __user *)arg, &data.fd2, len)) {
|
||||
if (copy_to_user((void __user *)arg, &data, sizeof(data))) {
|
||||
err = -EFAULT;
|
||||
goto err_put_fence3;
|
||||
}
|
||||
|
@ -357,6 +386,11 @@ static long sync_file_ioctl_merge(struct sync_file *sync_file,
|
|||
static int sync_fill_fence_info(struct dma_fence *fence,
|
||||
struct sync_fence_info *info)
|
||||
{
|
||||
strlcpy(info->obj_name, fence->ops->get_timeline_name(fence),
|
||||
sizeof(info->obj_name));
|
||||
strlcpy(info->driver_name, fence->ops->get_driver_name(fence),
|
||||
sizeof(info->driver_name));
|
||||
|
||||
info->status = dma_fence_get_status(fence);
|
||||
while (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags) &&
|
||||
!test_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags))
|
||||
|
@ -373,13 +407,12 @@ static long sync_file_ioctl_fence_info(struct sync_file *sync_file,
|
|||
unsigned long arg)
|
||||
{
|
||||
struct sync_file_info info;
|
||||
struct sync_fence_info *fence_info = NULL;
|
||||
struct dma_fence **fences;
|
||||
size_t len, offset;
|
||||
int num_fences, i;
|
||||
__u32 size;
|
||||
int num_fences, ret, i;
|
||||
|
||||
arg += offsetof(typeof(info), status);
|
||||
len = sizeof(info) - offsetof(typeof(info), status);
|
||||
if (copy_from_user(&info.status, (void __user *)arg, len))
|
||||
if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
|
||||
return -EFAULT;
|
||||
|
||||
if (info.flags || info.pad)
|
||||
|
@ -403,31 +436,35 @@ static long sync_file_ioctl_fence_info(struct sync_file *sync_file,
|
|||
if (info.num_fences < num_fences)
|
||||
return -EINVAL;
|
||||
|
||||
offset = offsetof(struct sync_fence_info, status);
|
||||
for (i = 0; i < num_fences; i++) {
|
||||
struct {
|
||||
__s32 status;
|
||||
__u32 flags;
|
||||
__u64 timestamp_ns;
|
||||
} fence_info;
|
||||
struct sync_fence_info *finfo = (void *)&fence_info - offset;
|
||||
int status = sync_fill_fence_info(fences[i], finfo);
|
||||
u64 dest;
|
||||
size = num_fences * sizeof(*fence_info);
|
||||
fence_info = kzalloc(size, GFP_KERNEL);
|
||||
if (!fence_info)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Don't leak kernel memory to userspace via finfo->flags */
|
||||
finfo->flags = 0;
|
||||
for (i = 0; i < num_fences; i++) {
|
||||
int status = sync_fill_fence_info(fences[i], &fence_info[i]);
|
||||
info.status = info.status <= 0 ? info.status : status;
|
||||
dest = info.sync_fence_info + i * sizeof(*finfo) + offset;
|
||||
if (copy_to_user(u64_to_user_ptr(dest), &fence_info,
|
||||
sizeof(fence_info)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (copy_to_user(u64_to_user_ptr(info.sync_fence_info), fence_info,
|
||||
size)) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
no_fences:
|
||||
sync_file_get_name(sync_file, info.name, sizeof(info.name));
|
||||
info.num_fences = num_fences;
|
||||
if (copy_to_user((void __user *)arg, &info.status, len))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
if (copy_to_user((void __user *)arg, &info, sizeof(info)))
|
||||
ret = -EFAULT;
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
kfree(fence_info);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long sync_file_ioctl(struct file *file, unsigned int cmd,
|
||||
|
|
|
@ -739,6 +739,7 @@ static int device_pca953x_init(struct pca953x_chip *chip, u32 invert)
|
|||
memset(val, 0, NBANK(chip));
|
||||
|
||||
ret = pca953x_write_regs(chip, PCA953X_INVERT, val);
|
||||
pr_err("device_pca953x_init %d\n",ret);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
@ -771,7 +772,10 @@ static int device_pca957x_init(struct pca953x_chip *chip, u32 invert)
|
|||
memset(val, 0x02, NBANK(chip));
|
||||
ret = pca953x_write_regs(chip, PCA957X_BKEN, val);
|
||||
if (ret)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
pr_err("device_pca957x_init %d\n",ret);
|
||||
|
||||
return 0;
|
||||
out:
|
||||
|
@ -788,7 +792,8 @@ static int pca953x_probe(struct i2c_client *client,
|
|||
int irq_base = 0;
|
||||
int ret;
|
||||
u32 invert = 0;
|
||||
struct regulator *reg;
|
||||
//struct regulator *reg;
|
||||
dev_err(&client->dev,"pca953x_probe\n");
|
||||
|
||||
chip = devm_kzalloc(&client->dev,
|
||||
sizeof(struct pca953x_chip), GFP_KERNEL);
|
||||
|
@ -822,7 +827,7 @@ static int pca953x_probe(struct i2c_client *client,
|
|||
|
||||
chip->client = client;
|
||||
|
||||
reg = devm_regulator_get(&client->dev, "vcc");
|
||||
/*reg = devm_regulator_get(&client->dev, "vcc");
|
||||
if (IS_ERR(reg)) {
|
||||
ret = PTR_ERR(reg);
|
||||
if (ret != -EPROBE_DEFER)
|
||||
|
@ -834,7 +839,7 @@ static int pca953x_probe(struct i2c_client *client,
|
|||
dev_err(&client->dev, "reg en err: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
chip->regulator = reg;
|
||||
chip->regulator = reg;*/
|
||||
|
||||
if (i2c_id) {
|
||||
chip->driver_data = i2c_id->driver_data;
|
||||
|
@ -919,7 +924,7 @@ static int pca953x_probe(struct i2c_client *client,
|
|||
return 0;
|
||||
|
||||
err_exit:
|
||||
regulator_disable(chip->regulator);
|
||||
//regulator_disable(chip->regulator);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -939,7 +944,7 @@ static int pca953x_remove(struct i2c_client *client)
|
|||
ret = 0;
|
||||
}
|
||||
|
||||
regulator_disable(chip->regulator);
|
||||
//regulator_disable(chip->regulator);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#include <linux/delay.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
|
@ -27,7 +28,7 @@
|
|||
/* Include the master list of GPU cores that are supported */
|
||||
#include "adreno-gpulist.h"
|
||||
|
||||
static void adreno_pwr_on_work(struct work_struct *work);
|
||||
static void adreno_input_work(struct work_struct *work);
|
||||
static unsigned int counter_delta(struct kgsl_device *device,
|
||||
unsigned int reg, unsigned int *counter);
|
||||
|
||||
|
@ -56,6 +57,8 @@ static struct adreno_device device_3d0 = {
|
|||
.ft_policy = KGSL_FT_DEFAULT_POLICY,
|
||||
.ft_pf_policy = KGSL_FT_PAGEFAULT_DEFAULT_POLICY,
|
||||
.long_ib_detect = 1,
|
||||
.input_work = __WORK_INITIALIZER(device_3d0.input_work,
|
||||
adreno_input_work),
|
||||
.pwrctrl_flag = BIT(ADRENO_THROTTLING_CTRL) | BIT(ADRENO_HWCG_CTRL),
|
||||
.profile.enabled = false,
|
||||
.active_list = LIST_HEAD_INIT(device_3d0.active_list),
|
||||
|
@ -67,8 +70,6 @@ static struct adreno_device device_3d0 = {
|
|||
.skipsaverestore = 1,
|
||||
.usesgmem = 1,
|
||||
},
|
||||
.pwr_on_work = __WORK_INITIALIZER(device_3d0.pwr_on_work,
|
||||
adreno_pwr_on_work),
|
||||
};
|
||||
|
||||
/* Ptr to array for the current set of fault detect registers */
|
||||
|
@ -90,6 +91,9 @@ static unsigned int adreno_ft_regs_default[] = {
|
|||
/* Nice level for the higher priority GPU start thread */
|
||||
int adreno_wake_nice = -7;
|
||||
|
||||
/* Number of milliseconds to stay active active after a wake on touch */
|
||||
unsigned int adreno_wake_timeout = 100;
|
||||
|
||||
void adreno_reglist_write(struct adreno_device *adreno_dev,
|
||||
const struct adreno_reglist *list, u32 count)
|
||||
{
|
||||
|
@ -353,17 +357,152 @@ void adreno_gmu_send_nmi(struct adreno_device *adreno_dev)
|
|||
wmb();
|
||||
}
|
||||
|
||||
static void adreno_pwr_on_work(struct work_struct *work)
|
||||
/*
|
||||
* A workqueue callback responsible for actually turning on the GPU after a
|
||||
* touch event. kgsl_pwrctrl_change_state(ACTIVE) is used without any
|
||||
* active_count protection to avoid the need to maintain state. Either
|
||||
* somebody will start using the GPU or the idle timer will fire and put the
|
||||
* GPU back into slumber.
|
||||
*/
|
||||
static void adreno_input_work(struct work_struct *work)
|
||||
{
|
||||
struct adreno_device *adreno_dev =
|
||||
container_of(work, typeof(*adreno_dev), pwr_on_work);
|
||||
struct adreno_device *adreno_dev = container_of(work,
|
||||
struct adreno_device, input_work);
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
|
||||
mutex_lock(&device->mutex);
|
||||
|
||||
device->flags |= KGSL_FLAG_WAKE_ON_TOUCH;
|
||||
|
||||
/*
|
||||
* Don't schedule adreno_start in a high priority workqueue, we are
|
||||
* already in a workqueue which should be sufficient
|
||||
*/
|
||||
kgsl_pwrctrl_change_state(device, KGSL_STATE_ACTIVE);
|
||||
|
||||
/*
|
||||
* When waking up from a touch event we want to stay active long enough
|
||||
* for the user to send a draw command. The default idle timer timeout
|
||||
* is shorter than we want so go ahead and push the idle timer out
|
||||
* further for this special case
|
||||
*/
|
||||
mod_timer(&device->idle_timer,
|
||||
jiffies + msecs_to_jiffies(adreno_wake_timeout));
|
||||
mutex_unlock(&device->mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process input events and schedule work if needed. At this point we are only
|
||||
* interested in groking EV_ABS touchscreen events
|
||||
*/
|
||||
static void adreno_input_event(struct input_handle *handle, unsigned int type,
|
||||
unsigned int code, int value)
|
||||
{
|
||||
struct kgsl_device *device = handle->handler->private;
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
|
||||
|
||||
/* Only consider EV_ABS (touch) events */
|
||||
if (type != EV_ABS)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Don't do anything if anything hasn't been rendered since we've been
|
||||
* here before
|
||||
*/
|
||||
|
||||
if (device->flags & KGSL_FLAG_WAKE_ON_TOUCH)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If the device is in nap, kick the idle timer to make sure that we
|
||||
* don't go into slumber before the first render. If the device is
|
||||
* already in slumber schedule the wake.
|
||||
*/
|
||||
|
||||
if (device->state == KGSL_STATE_NAP) {
|
||||
/*
|
||||
* Set the wake on touch bit to keep from coming back here and
|
||||
* keeping the device in nap without rendering
|
||||
*/
|
||||
|
||||
device->flags |= KGSL_FLAG_WAKE_ON_TOUCH;
|
||||
|
||||
mod_timer(&device->idle_timer,
|
||||
jiffies + device->pwrctrl.interval_timeout);
|
||||
} else if (device->state == KGSL_STATE_SLUMBER) {
|
||||
schedule_work(&adreno_dev->input_work);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_INPUT
|
||||
static int adreno_input_connect(struct input_handler *handler,
|
||||
struct input_dev *dev, const struct input_device_id *id)
|
||||
{
|
||||
struct input_handle *handle;
|
||||
int ret;
|
||||
|
||||
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
|
||||
if (handle == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
handle->dev = dev;
|
||||
handle->handler = handler;
|
||||
handle->name = handler->name;
|
||||
|
||||
ret = input_register_handle(handle);
|
||||
if (ret) {
|
||||
kfree(handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = input_open_device(handle);
|
||||
if (ret) {
|
||||
input_unregister_handle(handle);
|
||||
kfree(handle);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void adreno_input_disconnect(struct input_handle *handle)
|
||||
{
|
||||
input_close_device(handle);
|
||||
input_unregister_handle(handle);
|
||||
kfree(handle);
|
||||
}
|
||||
#else
|
||||
static int adreno_input_connect(struct input_handler *handler,
|
||||
struct input_dev *dev, const struct input_device_id *id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static void adreno_input_disconnect(struct input_handle *handle) {}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We are only interested in EV_ABS events so only register handlers for those
|
||||
* input devices that have EV_ABS events
|
||||
*/
|
||||
static const struct input_device_id adreno_input_ids[] = {
|
||||
{
|
||||
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
|
||||
.evbit = { BIT_MASK(EV_ABS) },
|
||||
/* assumption: MT_.._X & MT_.._Y are in the same long */
|
||||
.absbit = { [BIT_WORD(ABS_MT_POSITION_X)] =
|
||||
BIT_MASK(ABS_MT_POSITION_X) |
|
||||
BIT_MASK(ABS_MT_POSITION_Y) },
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct input_handler adreno_input_handler = {
|
||||
.event = adreno_input_event,
|
||||
.connect = adreno_input_connect,
|
||||
.disconnect = adreno_input_disconnect,
|
||||
.name = "kgsl",
|
||||
.id_table = adreno_input_ids,
|
||||
};
|
||||
|
||||
/*
|
||||
* _soft_reset() - Soft reset GPU
|
||||
* @adreno_dev: Pointer to adreno device
|
||||
|
@ -887,6 +1026,7 @@ static void adreno_of_get_initial_pwrlevel(struct adreno_device *adreno_dev,
|
|||
init_level = 1;
|
||||
|
||||
pwr->active_pwrlevel = init_level;
|
||||
pwr->default_pwrlevel = init_level;
|
||||
}
|
||||
|
||||
static void adreno_of_get_limits(struct adreno_device *adreno_dev,
|
||||
|
@ -1070,13 +1210,16 @@ static int adreno_of_get_power(struct adreno_device *adreno_dev,
|
|||
device->pwrctrl.pm_qos_wakeup_latency = 101;
|
||||
|
||||
if (of_property_read_u32(node, "qcom,idle-timeout", &timeout))
|
||||
timeout = 58;
|
||||
timeout = 80;
|
||||
|
||||
device->pwrctrl.interval_timeout = msecs_to_jiffies(timeout);
|
||||
|
||||
device->pwrctrl.bus_control = of_property_read_bool(node,
|
||||
"qcom,bus-control");
|
||||
|
||||
device->pwrctrl.input_disable = of_property_read_bool(node,
|
||||
"qcom,disable-wake-on-touch");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1407,6 +1550,21 @@ static int adreno_probe(struct platform_device *pdev)
|
|||
dev_warn(device->dev,
|
||||
"Failed to get gpuhtw LLC slice descriptor %ld\n",
|
||||
PTR_ERR(adreno_dev->gpuhtw_llc_slice));
|
||||
|
||||
#ifdef CONFIG_INPUT
|
||||
if (!device->pwrctrl.input_disable) {
|
||||
adreno_input_handler.private = device;
|
||||
/*
|
||||
* It isn't fatal if we cannot register the input handler. Sad,
|
||||
* perhaps, but not fatal
|
||||
*/
|
||||
if (input_register_handler(&adreno_input_handler)) {
|
||||
adreno_input_handler.private = NULL;
|
||||
dev_err(device->dev,
|
||||
"Unable to register the input handler\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
out:
|
||||
if (status) {
|
||||
adreno_ringbuffer_close(adreno_dev);
|
||||
|
@ -1462,6 +1620,10 @@ static int adreno_remove(struct platform_device *pdev)
|
|||
/* The memory is fading */
|
||||
_adreno_free_memories(adreno_dev);
|
||||
|
||||
#ifdef CONFIG_INPUT
|
||||
if (adreno_input_handler.private)
|
||||
input_unregister_handler(&adreno_input_handler);
|
||||
#endif
|
||||
adreno_sysfs_close(adreno_dev);
|
||||
|
||||
adreno_coresight_remove(adreno_dev);
|
||||
|
@ -3871,6 +4033,19 @@ static bool adreno_is_hwcg_on(struct kgsl_device *device)
|
|||
return test_bit(ADRENO_HWCG_CTRL, &adreno_dev->pwrctrl_flag);
|
||||
}
|
||||
|
||||
u32 adreno_get_ucode_version(const u32 *data)
|
||||
{
|
||||
u32 version;
|
||||
|
||||
version = data[1];
|
||||
|
||||
if ((version & 0xf) != 0xa)
|
||||
return version;
|
||||
|
||||
version &= ~0xfff;
|
||||
return version | ((data[3] & 0xfff000) >> 12);
|
||||
}
|
||||
|
||||
static const struct kgsl_functable adreno_functable = {
|
||||
/* Mandatory functions */
|
||||
.regread = adreno_regread,
|
||||
|
|
|
@ -279,8 +279,8 @@ enum adreno_preempt_states {
|
|||
/**
|
||||
* struct adreno_preemption
|
||||
* @state: The current state of preemption
|
||||
* @counters: Memory descriptor for the memory where the GPU writes the
|
||||
* preemption counters on switch
|
||||
* @scratch: Memory descriptor for the memory where the GPU writes the
|
||||
* current ctxt record address and preemption counters on switch
|
||||
* @timer: A timer to make sure preemption doesn't stall
|
||||
* @work: A work struct for the preemption worker (for 5XX)
|
||||
* preempt_level: The level of preemption (for 6XX)
|
||||
|
@ -290,7 +290,7 @@ enum adreno_preempt_states {
|
|||
*/
|
||||
struct adreno_preemption {
|
||||
atomic_t state;
|
||||
struct kgsl_memdesc counters;
|
||||
struct kgsl_memdesc scratch;
|
||||
struct timer_list timer;
|
||||
struct work_struct work;
|
||||
unsigned int preempt_level;
|
||||
|
@ -428,7 +428,7 @@ enum gpu_coresight_sources {
|
|||
* @dispatcher: Container for adreno GPU dispatcher
|
||||
* @pwron_fixup: Command buffer to run a post-power collapse shader workaround
|
||||
* @pwron_fixup_dwords: Number of dwords in the command buffer
|
||||
* @pwr_on_work: Work struct for turning on the GPU
|
||||
* @input_work: Work struct for turning on the GPU after a touch event
|
||||
* @busy_data: Struct holding GPU VBIF busy stats
|
||||
* @ram_cycles_lo: Number of DDR clock cycles for the monitor session (Only
|
||||
* DDR channel 0 read cycles in case of GBIF)
|
||||
|
@ -508,7 +508,7 @@ struct adreno_device {
|
|||
struct adreno_dispatcher dispatcher;
|
||||
struct kgsl_memdesc pwron_fixup;
|
||||
unsigned int pwron_fixup_dwords;
|
||||
struct work_struct pwr_on_work;
|
||||
struct work_struct input_work;
|
||||
struct adreno_busy_data busy_data;
|
||||
unsigned int ram_cycles_lo;
|
||||
unsigned int ram_cycles_lo_ch1_read;
|
||||
|
@ -896,6 +896,7 @@ struct adreno_gpudev {
|
|||
|
||||
struct adreno_irq *irq;
|
||||
int num_prio_levels;
|
||||
int cp_rb_cntl;
|
||||
unsigned int vbif_xin_halt_ctrl0_mask;
|
||||
unsigned int gbif_client_halt_mask;
|
||||
unsigned int gbif_arb_halt_mask;
|
||||
|
@ -1042,6 +1043,7 @@ extern struct adreno_gpudev adreno_a5xx_gpudev;
|
|||
extern struct adreno_gpudev adreno_a6xx_gpudev;
|
||||
|
||||
extern int adreno_wake_nice;
|
||||
extern unsigned int adreno_wake_timeout;
|
||||
|
||||
int adreno_start(struct kgsl_device *device, int priority);
|
||||
int adreno_soft_reset(struct kgsl_device *device);
|
||||
|
@ -1123,6 +1125,7 @@ void adreno_rscc_regread(struct adreno_device *adreno_dev,
|
|||
unsigned int offsetwords, unsigned int *value);
|
||||
void adreno_isense_regread(struct adreno_device *adreno_dev,
|
||||
unsigned int offsetwords, unsigned int *value);
|
||||
u32 adreno_get_ucode_version(const u32 *data);
|
||||
|
||||
|
||||
#define ADRENO_TARGET(_name, _id) \
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2019,2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/clk/qcom.h>
|
||||
|
@ -1094,8 +1094,14 @@ struct {
|
|||
{ A3XX_CP_PROTECT_REG_0 + 13, 0x0cc0, 0 },
|
||||
/* VBIF */
|
||||
{ A3XX_CP_PROTECT_REG_0 + 14, 0x3000, 6 },
|
||||
/* SMMU */
|
||||
{ A3XX_CP_PROTECT_REG_0 + 15, 0xa000, 12 },
|
||||
/*
|
||||
* SMMU
|
||||
* For A3xx, base offset for smmu region is 0xa000 and length is
|
||||
* 0x1000 bytes. Offset must be in dword and length of the block
|
||||
* must be ilog2(dword length).
|
||||
* 0xa000 >> 2 = 0x2800, ilog2(0x1000 >> 2) = 10.
|
||||
*/
|
||||
{ A3XX_CP_PROTECT_REG_0 + 15, 0x2800, 10 },
|
||||
/* There are no remaining protected mode registers for a3xx */
|
||||
};
|
||||
|
||||
|
|
|
@ -1724,12 +1724,15 @@ static int a5xx_post_start(struct adreno_device *adreno_dev)
|
|||
*cmds++ = 0xF;
|
||||
}
|
||||
|
||||
if (adreno_is_preemption_enabled(adreno_dev))
|
||||
if (adreno_is_preemption_enabled(adreno_dev)) {
|
||||
cmds += _preemption_init(adreno_dev, rb, cmds, NULL);
|
||||
rb->_wptr = rb->_wptr - (42 - (cmds - start));
|
||||
ret = adreno_ringbuffer_submit_spin_nosync(rb, NULL, 2000);
|
||||
} else {
|
||||
rb->_wptr = rb->_wptr - (42 - (cmds - start));
|
||||
ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000);
|
||||
}
|
||||
|
||||
rb->_wptr = rb->_wptr - (42 - (cmds - start));
|
||||
|
||||
ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000);
|
||||
if (ret)
|
||||
adreno_spin_idle_debug(adreno_dev,
|
||||
"hw initialization failed to idle\n");
|
||||
|
@ -2038,7 +2041,7 @@ static int _load_firmware(struct kgsl_device *device, const char *fwfile,
|
|||
|
||||
memcpy(firmware->memdesc.hostptr, &fw->data[4], fw->size - 4);
|
||||
firmware->size = (fw->size - 4) / sizeof(uint32_t);
|
||||
firmware->version = *(unsigned int *)&fw->data[4];
|
||||
firmware->version = adreno_get_ucode_version((u32 *)fw->data);
|
||||
|
||||
done:
|
||||
release_firmware(fw);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2015-2017,2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2017,2019-2020 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _ADRENO_A5XX_H_
|
||||
|
@ -134,7 +134,7 @@ void a5xx_crashdump_init(struct adreno_device *adreno_dev);
|
|||
|
||||
void a5xx_hwcg_set(struct adreno_device *adreno_dev, bool on);
|
||||
|
||||
#define A5XX_CP_RB_CNTL_DEFAULT (((ilog2(4) << 8) & 0x1F00) | \
|
||||
#define A5XX_CP_RB_CNTL_DEFAULT ((1 << 27) | ((ilog2(4) << 8) & 0x1F00) | \
|
||||
(ilog2(KGSL_RB_DWORDS >> 1) & 0x3F))
|
||||
/* GPMU interrupt multiplexor */
|
||||
#define FW_INTR_INFO (0)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2014-2017,2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2014-2017,2019-2020 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "adreno.h"
|
||||
|
@ -570,7 +570,7 @@ static void _preemption_close(struct adreno_device *adreno_dev)
|
|||
unsigned int i;
|
||||
|
||||
del_timer(&preempt->timer);
|
||||
kgsl_free_global(device, &preempt->counters);
|
||||
kgsl_free_global(device, &preempt->scratch);
|
||||
a5xx_preemption_iommu_close(adreno_dev);
|
||||
|
||||
FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
|
||||
|
@ -604,14 +604,14 @@ int a5xx_preemption_init(struct adreno_device *adreno_dev)
|
|||
timer_setup(&preempt->timer, _a5xx_preemption_timer, 0);
|
||||
|
||||
/* Allocate mem for storing preemption counters */
|
||||
ret = kgsl_allocate_global(device, &preempt->counters,
|
||||
ret = kgsl_allocate_global(device, &preempt->scratch,
|
||||
adreno_dev->num_ringbuffers *
|
||||
A5XX_CP_CTXRECORD_PREEMPTION_COUNTER_SIZE, 0, 0,
|
||||
"preemption_counters");
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
addr = preempt->counters.gpuaddr;
|
||||
addr = preempt->scratch.gpuaddr;
|
||||
|
||||
/* Allocate mem for storing preemption switch record */
|
||||
FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue