[Feature] add GA346 baseline version
Change-Id: Ic62933698569507dcf98240cdf5d9931ae34348f
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/Android.mk b/src/kernel/modules/connectivity/2.0/conninfra_driver/Android.mk
new file mode 100755
index 0000000..6f3f05a
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/Android.mk
@@ -0,0 +1,24 @@
+LOCAL_PATH := $(call my-dir)
+
+ifneq ($(filter yes,$(sort $(MTK_WLAN_SUPPORT) $(MTK_BT_SUPPORT) $(MTK_GPS_SUPPORT) $(MTK_FM_SUPPORT))),)
+
+ifneq (true,$(strip $(TARGET_NO_KERNEL)))
+ifneq ($(filter yes,$(MTK_COMBO_SUPPORT)),)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := conninfra.ko
+LOCAL_PROPRIETARY_MODULE := true
+LOCAL_MODULE_OWNER := mtk
+
+LOCAL_INIT_RC := init.conninfra.rc
+LOCAL_SRC_FILES := $(patsubst $(LOCAL_PATH)/%,%,$(shell find $(LOCAL_PATH) -type f -name '*.[cho]')) Makefile
+LOCAL_REQUIRED_MODULES :=
+
+include $(MTK_KERNEL_MODULE)
+
+else
+ $(warning wmt_drv-MTK_COMBO_SUPPORT: [$(MTK_COMBO_SUPPORT)])
+endif
+endif
+
+endif
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/Makefile b/src/kernel/modules/connectivity/2.0/conninfra_driver/Makefile
new file mode 100755
index 0000000..74d255c7
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/Makefile
@@ -0,0 +1,190 @@
+###############################################################################
+# Necessary Check
+
+#ifeq ($(AUTOCONF_H),)
+ #$(error AUTOCONF_H is not defined)
+#endif
+
+
+
+#ccflags-y += -imacros $(AUTOCONF_H)
+
+ifeq ($(CONFIG_MTK_COMBO_CHIP),)
+ $(error CONFIG_MTK_COMBO_CHIP not defined)
+endif
+
+$(info $$CONFIG_MTK_COMBO_CHIP is [${CONFIG_MTK_COMBO_CHIP}])
+
+
+# Force build fail on modpost warning
+KBUILD_MODPOST_FAIL_ON_WARNINGS := y
+###############################################################################
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/include
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/$(MTK_PLATFORM)
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include/clkbuf_v1
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include/clkbuf_v1/$(MTK_PLATFORM)
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci/$(MTK_PLATFORM)
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/eemcs
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/mach/$(MTK_PLATFORM)/include/mach
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/emi/submodule
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/emi/$(MTK_PLATFORM)
+ccflags-y += -I$(srctree)/drivers/mmc/core
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/connectivity/common
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/pmic/include/
+###############################################################################
+
+ccflags-y += -Werror
+ccflags-y += -Wno-error=format
+ccflags-y += -Wno-error=format-extra-args
+
+###############################################################################
+MODULE_NAME := conninfra
+ifeq ($(CONFIG_WLAN_DRV_BUILD_IN),y)
+$(warning $(MODULE_NAME) build-in boot.img)
+obj-y += $(MODULE_NAME).o
+else
+$(warning $(MODULE_NAME) is kernel module)
+obj-m += $(MODULE_NAME).o
+endif
+
+# Local config
+ccflags-y += -D MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE=1
+ccflags-y += -D CONFIG_CONNINFRA_UT_SUPPORT=1
+ccflags-y += -D CONFIG_CONNINFRA_DBG_SUPPORT=1
+ccflags-y += -D CONFIG_CONNINFRA_DEVAPC_SUPPORT=0
+ccflags-y += -D CONFIG_CONNINFRA_COREDUMP_SUPPORT=0
+ccflags-y += -D CONFIG_CONNINFRA_FW_LOG_SUPPORT=0
+ccflags-y += -D CONFIG_CONNINFRA_STEP_SUPPORT=0
+ccflags-y += -D CONFIG_CONNINFRA_POWER_STATUS_SUPPORT=1
+ccflags-y += -D CONFIG_CONNINFRA_BUS_HANG_DEBUG_SUPPORT=1
+ccflags-y += -D CONFIG_CONNINFRA_EMI_SUPPORT=0
+ccflags-y += -D CONFIG_CONNINFRA_PRE_CAL_BLOCKING=0
+ccflags-y += -D CONFIG_CONNINFRA_PRE_CAL_SUPPORT=0
+
+ifneq (,$(filter fpga%,$(SUBTARGET)))
+ccflags-y += -D CONFIG_CONNINFRA_PMIC_SUPPORT=0
+ccflags-y += -D CONFIG_CONNINFRA_THERMAL_SUPPORT=0
+else
+ccflags-y += -D CONFIG_CONNINFRA_PMIC_SUPPORT=1
+ccflags-y += -D CONFIG_CONNINFRA_THERMAL_SUPPORT=1
+endif
+
+$(patsubst CONFIG_%, -DCFG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \
+$(patsubst CONFIG_%, -DCFG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG)))) \
+$(patsubst CONFIG_%, -DCFG_%=0, $(patsubst %=n,%,$(filter %=n,$(EXTRA_KCONFIG)))) \
+
+
+# Local config
+EXTRA_KCONFIG:= \
+ CONFIG_CONNINFRA_UT_SUPPORT=y \
+ CONFIG_CONNINFRA_DBG_SUPPORT=y \
+ CONFIG_CONNINFRA_DEVAPC_SUPPORT=n \
+ CONFIG_CONNINFRA_COREDUMP_SUPPORT=n \
+ CONFIG_CONNINFRA_FW_LOG_SUPPORT=n \
+ CONFIG_CONNINFRA_STEP_SUPPORT=n \
+ CONFIG_CONNINFRA_POWER_STATUS_SUPPORT=y \
+ CONFIG_CONNINFRA_BUS_HANG_DEBUG_SUPPORT=y \
+ CONFIG_CONNINFRA_EMI_SUPPORT=n \
+ CONFIG_CONNINFRA_PRE_CAL_BLOCKING=n \
+ CONFIG_CONNINFRA_PRE_CAL_SUPPORT=n
+
+ifneq (,$(filter fpga%,$(SUBTARGET)))
+EXTRA_KCONFIG += \
+ CONFIG_CONNINFRA_PMIC_SUPPORT=n \
+ CONFIG_CONNINFRA_THERMAL_SUPPORT=n
+else
+EXTRA_KCONFIG += \
+ CONFIG_CONNINFRA_PMIC_SUPPORT=y \
+ CONFIG_CONNINFRA_THERMAL_SUPPORT=y
+endif
+
+# Transfer local kernel config to compile option
+EXTRA_CFLAGS:= \
+ $(patsubst CONFIG_%, -DCFG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \
+ $(patsubst CONFIG_%, -DCFG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG)))) \
+ $(patsubst CONFIG_%, -DCFG_%=0, $(patsubst %=n,%,$(filter %=n,$(EXTRA_KCONFIG)))) \
+
+$(info $$EXTRA_CFLAGS is [${EXTRA_CFLAGS}])
+
+###############################################################################
+# common_main
+###############################################################################
+ccflags-y += -I$(src)/include
+ccflags-y += -I$(src)/base/include
+ccflags-y += -I$(src)/core/include
+ccflags-y += -I$(src)/conf/include
+ccflags-y += -I$(src)/platform/include
+ccflags-y += -I$(src)/debug_utility
+ccflags-y += -I$(src)/debug_utility/include
+ccflags-y += -I$(src)/debug_utility/connsyslog
+ccflags-y += -I$(src)/debug_utility/connsyslog/platform/include
+ccflags-y += -I$(src)/debug_utility/coredump
+ccflags-y += -I$(src)/debug_utility/coredump/platform/include
+ccflags-y += -I$(src)/debug_utility/step/include
+ccflags-y += -I$(src)/test/include
+
+# By Plaftfrom
+ccflags-y += -I$(src)/platform/mt6880/include
+
+# Temp for FPGA
+ccflags-y += -D MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE=1
+
+# Temp for kernel config
+ifneq (,$(filter fpga%,$(SUBTARGET)))
+ccflags-y += -D CONFIG_FPGA_EARLY_PORTING
+endif
+
+ifneq ($(TARGET_BUILD_VARIANT), user)
+ ccflags-y += -D CONNINFRA_DBG_SUPPORT=1
+else
+ ccflags-y += -D CONNINFRA_DBG_SUPPORT=0
+endif
+
+$(MODULE_NAME)-objs += base/ring.o
+$(MODULE_NAME)-objs += base/osal.o
+$(MODULE_NAME)-objs += base/msg_thread.o
+$(MODULE_NAME)-objs += core/conninfra_core.o
+$(MODULE_NAME)-objs += src/conninfra_dev.o
+$(MODULE_NAME)-objs += src/conninfra.o
+$(MODULE_NAME)-objs += conf/conninfra_conf.o
+$(MODULE_NAME)-objs += platform/consys_hw.o
+$(MODULE_NAME)-objs += platform/consys_hw_plat_data.o
+$(MODULE_NAME)-objs += platform/clock_mng.o
+$(MODULE_NAME)-objs += platform/pmic_mng.o
+$(MODULE_NAME)-objs += platform/emi_mng.o
+$(MODULE_NAME)-objs += platform/consys_reg_mng.o
+
+$(MODULE_NAME)-objs += debug_utility/conninfra_dbg.o
+
+# By Plaftfrom
+# MT6880
+$(MODULE_NAME)-objs += platform/mt6880/mt6880.o
+$(MODULE_NAME)-objs += platform/mt6880/mt6880_pmic.o
+$(MODULE_NAME)-objs += platform/mt6880/mt6880_consys_reg.o
+$(MODULE_NAME)-objs += platform/mt6880/mt6880_pos.o
+$(MODULE_NAME)-objs += platform/mt6880/mt6880_emi.o
+
+###############################################################################
+# test
+###############################################################################
+ifneq ($(TARGET_BUILD_VARIANT), user)
+ccflags-y += -D CFG_CONNINFRA_UT_SUPPORT
+endif
+
+#mark for temp start
+#ifeq ($(CFG_CONNINFRA_UT_SUPPORT), y)
+#ccflags-y += -D CFG_CONNINFRA_UT_SUPPORT=1
+
+$(MODULE_NAME)-objs += test/conf_test.o
+$(MODULE_NAME)-objs += test/cal_test.o
+$(MODULE_NAME)-objs += test/msg_evt_test.o
+$(MODULE_NAME)-objs += test/chip_rst_test.o
+$(MODULE_NAME)-objs += test/conninfra_test.o
+$(MODULE_NAME)-objs += test/mailbox_test.o
+#endif
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/Makefile.ce b/src/kernel/modules/connectivity/2.0/conninfra_driver/Makefile.ce
new file mode 100644
index 0000000..7fa78c8
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/Makefile.ce
@@ -0,0 +1,32 @@
+# Makefile for MT66xx conninfra driver
+
+##############################################################
+# Common settings
+##############################################################
+
+
+##############################################################
+# Platform specific
+##############################################################
+
+
+##############################################################
+# Compile settings
+##############################################################
+
+all: driver
+
+driver:
+ +cd $(DRIVER_DIR) && make -C $(LINUX_SRC) M=$(DRIVER_DIR) MODULE_NAME=$(MODULE_NAME) PLATFORM_FLAGS="$(PLATFORM_FLAGS)" PLATFORM=${PLATFORM} modules
+
+
+clean: driver_clean
+
+
+driver_clean:
+ cd $(DRIVER_DIR) && make -C $(LINUX_SRC) M=$(DRIVER_DIR) MODULE_NAME=$(MODULE_NAME) clean
+ if [ -e $(DRIVER_DIR)/$(MODULE_NAME).ko ]; then rm $(DRIVER_DIR)/$(MODULE_NAME).ko; fi;
+
+
+.PHONY: all clean driver driver_clean
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/NOTICE b/src/kernel/modules/connectivity/2.0/conninfra_driver/NOTICE
new file mode 100755
index 0000000..52c1cac
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/NOTICE
@@ -0,0 +1,202 @@
+The GNU General Public License (GPL)
+
+Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU
+General Public License is intended to guarantee your freedom to share and change free software--to make sure the
+software is free for all its users. This General Public License applies to most of the Free Software Foundation's
+software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is
+covered by the GNU Library General Public License instead.) You can apply it to your programs, too.
+
+When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make
+sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you
+receive source code or can get it if you want it, that you can change the software or use pieces of it in new free
+programs; and that you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to
+surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the
+software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all
+the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them
+these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty
+for this free software. If the software is modified by someone else and passed on, we want its recipients to know that
+what they have is not the original, so that any problems introduced by others will not reflect on the original authors'
+reputations.
+
+Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors
+of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this,
+we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it
+may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or
+work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to
+say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into
+another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is
+addressed as "you".
+
+Activities other than copying, distribution and modification are not covered by this License; they are outside its
+scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents
+constitute a work based on the Program (independent of having been made by running the Program). Whether that is true
+depends on what the Program does.
+
+1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided
+that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of
+warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other
+recipients of the Program a copy of this License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection
+in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and
+copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of
+these conditions:
+
+a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any
+change.
+
+b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the
+Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this
+License.
+
+c) If the modified program normally reads commands interactively when run, you must cause it, when started running for
+such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright
+notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may
+redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if
+the Program itself is interactive but does not normally print such an announcement, your work based on the Program is
+not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the
+Program, and can be reasonably considered independent and separate works in themselves, then this License, and its
+terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same
+sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part
+regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you;
+rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the
+Program.
+
+In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the
+Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
+
+3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you also do one of the following:
+
+a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms
+of Sections 1 and 2 above on a medium customarily used for software interchange; or,
+
+b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than
+your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source
+code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange;
+or,
+
+c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This
+alternative is allowed only for noncommercial distribution and only if you received the program in object code or
+executable form with such an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for making modifications to it. For an executable work,
+complete source code means all the source code for all modules it contains, plus any associated interface definition
+files, plus the scripts used to control compilation and installation of the executable. However, as a special exception,
+the source code distributed need not include anything that is normally distributed (in either source or binary form)
+with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless
+that component itself accompanies the executable.
+
+If distribution of executable or object code is made by offering access to copy from a designated place, then offering
+equivalent access to copy the source code from the same place counts as distribution of the source code, even though
+third parties are not compelled to copy the source along with the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your
+rights under this License. However, parties who have received copies, or rights, from you under this License will not
+have their licenses terminated so long as such parties remain in full compliance.
+
+5. You are not required to accept this License, since you have not signed it. However, nothing else grants you
+permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do
+not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you
+indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or
+modifying the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a
+license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You
+may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not
+responsible for enforcing compliance by third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to
+patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the
+conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as
+to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence
+you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution
+of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy
+both it and this License would be to refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the
+section is intended to apply and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest
+validity of any such claims; this section has the sole purpose of protecting the integrity of the free software
+distribution system, which is implemented by public license practices. Many people have made generous contributions to
+the wide range of software distributed through that system in reliance on consistent application of that system; it is
+up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee
+cannot impose that choice.
+
+This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted
+interfaces, the original copyright holder who places the Program under this License may add an explicit geographical
+distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if written in the body of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time.
+Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or
+concerns.
+
+Each version is given a distinguishing version number. If the Program specifies a version number of this License which
+applies to it and "any later version", you have the option of following the terms and conditions either of that version
+or of any later version published by the Free Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are
+different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation,
+write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two
+goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of
+software generally.
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM
+"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
+CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY
+WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
+SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT
+LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
+THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY
+OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
+
+
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/base/include/msg_thread.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/base/include/msg_thread.h
new file mode 100755
index 0000000..6cb4628
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/base/include/msg_thread.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _BASE_MSG_THREAD_H_
+#define _BASE_MSG_THREAD_H_
+
+#include "osal.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+#define MSG_THREAD_OP_DATA_SIZE 8
+#define MSG_THREAD_OP_BUF_SIZE 64
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+struct msg_op_data {
+ unsigned int op_id; /* Event ID */
+ unsigned int info_bit; /* Reserved */
+ size_t op_data[MSG_THREAD_OP_DATA_SIZE]; /* OP Data */
+};
+
+struct msg_op {
+ struct msg_op_data op;
+ OSAL_SIGNAL signal;
+ int result;
+ atomic_t ref_count;
+};
+
+
+struct msg_op_q {
+ OSAL_SLEEPABLE_LOCK lock;
+ unsigned int write;
+ unsigned int read;
+ unsigned int size;
+ struct msg_op *queue[MSG_THREAD_OP_BUF_SIZE];
+};
+
+typedef OSAL_OP_DAT msg_evt_op;
+typedef int(*msg_opid_func) (struct msg_op_data *);
+
+struct msg_thread_ctx {
+ OSAL_THREAD thread; /* core thread */
+ OSAL_EVENT evt;
+
+ struct msg_op_q free_op_q; /* free op queue */
+ struct msg_op_q active_op_q; /* active op queue */
+ struct msg_op op_q_inst[MSG_THREAD_OP_BUF_SIZE]; /* real op instances */
+ struct msg_op *cur_op; /* current op */
+
+ int op_func_size;
+ const msg_opid_func *op_func;
+
+ struct osal_op_history op_history;
+};
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+#define MSG_OP_TIMEOUT 20000
+
+int msg_thread_init(struct msg_thread_ctx *ctx, const char *name,
+ const msg_opid_func *func, int op_size);
+int msg_thread_deinit(struct msg_thread_ctx *ctx);
+
+/* timeout:
+ * 0: default value (by MSG_OP_TIMEOUT define)
+ * >0: cutom timeout (ms)
+ */
+int msg_thread_send(struct msg_thread_ctx *ctx, int opid);
+int msg_thread_send_1(struct msg_thread_ctx *ctx, int opid,
+ size_t param1);
+int msg_thread_send_2(struct msg_thread_ctx *ctx, int opid,
+ size_t param1, size_t param2);
+
+int msg_thread_send_wait(struct msg_thread_ctx *ctx, int opid,
+ int timeout);
+int msg_thread_send_wait_1(struct msg_thread_ctx *ctx, int opid,
+ int timeout, size_t param1);
+int msg_thread_send_wait_2(struct msg_thread_ctx *ctx, int opid,
+ int timeout, size_t param1, size_t param2);
+int msg_thread_send_wait_3(struct msg_thread_ctx *ctx, int opid, int timeout, size_t param1,
+ size_t param2,size_t param3);
+
+int msg_thread_dump(struct msg_thread_ctx *ctx);
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _BASE_MSG_THREAD_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/base/include/osal.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/base/include/osal.h
new file mode 100755
index 0000000..0c511ce
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/base/include/osal.h
@@ -0,0 +1,405 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+
+/*! \file
+ * \brief Declaration of library functions
+ * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+ */
+
+#ifndef _OSAL_H_
+#define _OSAL_H_
+
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/completion.h>
+#include <linux/wait.h>
+#include "ring.h"
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+#define OS_BIT_OPS_SUPPORT 1
+
+#ifndef MTK_CONN_BOOL_TRUE
+#define MTK_CONN_BOOL_FALSE ((MTK_CONN_BOOL) 0)
+#define MTK_CONN_BOOL_TRUE ((MTK_CONN_BOOL) 1)
+#endif
+
+#define _osal_inline_ inline
+
+#define MAX_THREAD_NAME_LEN 16
+#define MAX_HISTORY_NAME_LEN 16
+#define OSAL_OP_BUF_SIZE 64
+
+
+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD))
+#define OSAL_OP_DATA_SIZE 8
+#else
+#define OSAL_OP_DATA_SIZE 32
+#endif
+
+#define DBG_LOG_STR_SIZE 256
+
+#define osal_sizeof(x) sizeof(x)
+
+#define osal_array_size(x) ARRAY_SIZE(x)
+
+#ifndef NAME_MAX
+#define NAME_MAX 256
+#endif
+
+#define WMT_OP_BIT(x) (0x1UL << x)
+#define WMT_OP_HIF_BIT WMT_OP_BIT(0)
+
+#define GET_BIT_MASK(value, mask) ((value) & (mask))
+#define SET_BIT_MASK(pdest, value, mask) (*(pdest) = (GET_BIT_MASK(*(pdest), ~(mask)) | GET_BIT_MASK(value, mask)))
+#define GET_BIT_RANGE(data, end, begin) ((data) & GENMASK(end, begin))
+#define SET_BIT_RANGE(pdest, data, end, begin) (SET_BIT_MASK(pdest, data, GENMASK(end, begin)))
+
+#define RB_LATEST(prb) ((prb)->write - 1)
+#define RB_SIZE(prb) ((prb)->size)
+#define RB_MASK(prb) (RB_SIZE(prb) - 1)
+#define RB_COUNT(prb) ((prb)->write - (prb)->read)
+#define RB_FULL(prb) (RB_COUNT(prb) >= RB_SIZE(prb))
+#define RB_EMPTY(prb) ((prb)->write == (prb)->read)
+
+#define RB_INIT(prb, qsize) \
+do { \
+ (prb)->read = (prb)->write = 0; \
+ (prb)->size = (qsize); \
+} while (0)
+
+#define RB_PUT(prb, value) \
+do { \
+ if (!RB_FULL(prb)) { \
+ (prb)->queue[(prb)->write & RB_MASK(prb)] = value; \
+ ++((prb)->write); \
+ } \
+ else { \
+ pr_warn("RB is full!"); \
+ } \
+} while (0)
+
+#define RB_GET(prb, value) \
+do { \
+ if (!RB_EMPTY(prb)) { \
+ value = (prb)->queue[(prb)->read & RB_MASK(prb)]; \
+ ++((prb)->read); \
+ if (RB_EMPTY(prb)) { \
+ (prb)->read = (prb)->write = 0; \
+ } \
+ } \
+ else { \
+ value = NULL; \
+ pr_warn("RB is empty!"); \
+ } \
+} while (0)
+
+#define RB_GET_LATEST(prb, value) \
+do { \
+ if (!RB_EMPTY(prb)) { \
+ value = (prb)->queue[RB_LATEST(prb) & RB_MASK(prb)]; \
+ if (RB_EMPTY(prb)) { \
+ (prb)->read = (prb)->write = 0; \
+ } \
+ } \
+ else { \
+ value = NULL; \
+ } \
+} while (0)
+
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+typedef int MTK_CONN_BOOL;
+
+typedef int(*P_COND) (void *);
+
+typedef struct _OSAL_UNSLEEPABLE_LOCK_ {
+ spinlock_t lock;
+ unsigned long flag;
+} OSAL_UNSLEEPABLE_LOCK, *P_OSAL_UNSLEEPABLE_LOCK;
+
+typedef struct _OSAL_SLEEPABLE_LOCK_ {
+ struct mutex lock;
+} OSAL_SLEEPABLE_LOCK, *P_OSAL_SLEEPABLE_LOCK;
+
+typedef struct _OSAL_SIGNAL_ {
+ struct completion comp;
+ unsigned int timeoutValue;
+ unsigned int timeoutExtension; /* max number of timeout caused by thread not able to acquire CPU */
+} OSAL_SIGNAL, *P_OSAL_SIGNAL;
+
+typedef struct _OSAL_EVENT_ {
+ wait_queue_head_t waitQueue;
+ unsigned int timeoutValue;
+ int waitFlag;
+
+} OSAL_EVENT, *P_OSAL_EVENT;
+
+/* Data collected from sched_entity and sched_statistics */
+typedef struct _OSAL_THREAD_SCHEDSTATS_ {
+ unsigned long long time; /* when marked: the profiling start time(ms), when unmarked: total duration(ms) */
+ unsigned long long exec; /* time spent in exec (sum_exec_runtime) */
+ unsigned long long runnable; /* time spent in run-queue while not being scheduled (wait_sum) */
+ unsigned long long iowait; /* time spent waiting for I/O (iowait_sum) */
+} OSAL_THREAD_SCHEDSTATS, *P_OSAL_THREAD_SCHEDSTATS;
+
+typedef struct _OSAL_THREAD_ {
+ struct task_struct *pThread;
+ void *pThreadFunc;
+ void *pThreadData;
+ char threadName[MAX_THREAD_NAME_LEN];
+} OSAL_THREAD, *P_OSAL_THREAD;
+
+
+typedef struct _OSAL_FIFO_ {
+ /*fifo definition */
+ void *pFifoBody;
+ spinlock_t fifoSpinlock;
+ /*fifo operations */
+ int (*FifoInit)(struct _OSAL_FIFO_ *pFifo, unsigned char *buf, unsigned int);
+ int (*FifoDeInit)(struct _OSAL_FIFO_ *pFifo);
+ int (*FifoReset)(struct _OSAL_FIFO_ *pFifo);
+ int (*FifoSz)(struct _OSAL_FIFO_ *pFifo);
+ int (*FifoAvailSz)(struct _OSAL_FIFO_ *pFifo);
+ int (*FifoLen)(struct _OSAL_FIFO_ *pFifo);
+ int (*FifoIsEmpty)(struct _OSAL_FIFO_ *pFifo);
+ int (*FifoIsFull)(struct _OSAL_FIFO_ *pFifo);
+ int (*FifoDataIn)(struct _OSAL_FIFO_ *pFifo, const void *buf, unsigned int len);
+ int (*FifoDataOut)(struct _OSAL_FIFO_ *pFifo, void *buf, unsigned int len);
+} OSAL_FIFO, *P_OSAL_FIFO;
+
+typedef struct firmware osal_firmware;
+
+typedef struct _OSAL_OP_DAT {
+ unsigned int opId; /* Event ID */
+ unsigned int u4InfoBit; /* Reserved */
+ size_t au4OpData[OSAL_OP_DATA_SIZE]; /* OP Data */
+} OSAL_OP_DAT, *P_OSAL_OP_DAT;
+
+typedef struct _OSAL_LXOP_ {
+ OSAL_OP_DAT op;
+ OSAL_SIGNAL signal;
+ int result;
+ atomic_t ref_count;
+} OSAL_OP, *P_OSAL_OP;
+
+typedef struct _OSAL_LXOP_Q {
+ OSAL_SLEEPABLE_LOCK sLock;
+ unsigned int write;
+ unsigned int read;
+ unsigned int size;
+ P_OSAL_OP queue[OSAL_OP_BUF_SIZE];
+} OSAL_OP_Q, *P_OSAL_OP_Q;
+
+typedef struct _OSAL_BIT_OP_VAR_ {
+ unsigned long data;
+ OSAL_UNSLEEPABLE_LOCK opLock;
+} OSAL_BIT_OP_VAR, *P_OSAL_BIT_OP_VAR;
+
+typedef unsigned int (*P_OSAL_EVENT_CHECKER) (P_OSAL_THREAD pThread);
+
+struct osal_op_history_entry {
+ void *opbuf_address;
+ unsigned int op_id;
+ unsigned int opbuf_ref_count;
+ unsigned int op_info_bit;
+ size_t param_0;
+ size_t param_1;
+ size_t param_2;
+ size_t param_3;
+ unsigned long long ts;
+ unsigned long usec;
+};
+
+struct osal_op_history {
+ struct ring ring_buffer;
+ struct osal_op_history_entry *queue;
+ spinlock_t lock;
+ struct ring dump_ring_buffer;
+ struct work_struct dump_work;
+ unsigned char name[MAX_HISTORY_NAME_LEN];
+};
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+unsigned int osal_strlen(const char *str);
+int osal_strcmp(const char *dst, const char *src);
+int osal_strncmp(const char *dst, const char *src, unsigned int len);
+char *osal_strcpy(char *dst, const char *src);
+char *osal_strncpy(char *dst, const char *src, unsigned int len);
+char *osal_strcat(char *dst, const char *src);
+char *osal_strncat(char *dst, const char *src, unsigned int len);
+char *osal_strchr(const char *str, unsigned char c);
+char *osal_strsep(char **str, const char *c);
+int osal_strtol(const char *str, unsigned int adecimal, long *res);
+char *osal_strstr(char *str1, const char *str2);
+char *osal_strnstr(char *str1, const char *str2, int n);
+
+void osal_bug_on(unsigned int val);
+
+int osal_snprintf(char *buf, unsigned int len, const char *fmt, ...);
+
+int osal_sprintf(char *str, const char *format, ...);
+void *osal_malloc(unsigned int size);
+void osal_free(const void *dst);
+void *osal_memset(void *buf, int i, unsigned int len);
+void *osal_memcpy(void *dst, const void *src, unsigned int len);
+void osal_memcpy_fromio(void *dst, const void *src, unsigned int len);
+void osal_memcpy_toio(void *dst, const void *src, unsigned int len);
+int osal_memcmp(const void *buf1, const void *buf2, unsigned int len);
+
+void osal_thread_show_stack(P_OSAL_THREAD pThread);
+
+int osal_sleep_ms(unsigned int ms);
+int osal_udelay(unsigned int us);
+int osal_usleep_range(unsigned long min, unsigned long max);
+
+int osal_fifo_init(P_OSAL_FIFO pFifo, unsigned char *buffer, unsigned int size);
+void osal_fifo_deinit(P_OSAL_FIFO pFifo);
+int osal_fifo_reset(P_OSAL_FIFO pFifo);
+unsigned int osal_fifo_in(P_OSAL_FIFO pFifo, unsigned char *buffer,
+ unsigned int size);
+unsigned int osal_fifo_out(P_OSAL_FIFO pFifo, unsigned char *buffer,
+ unsigned int size);
+unsigned int osal_fifo_len(P_OSAL_FIFO pFifo);
+unsigned int osal_fifo_sz(P_OSAL_FIFO pFifo);
+unsigned int osal_fifo_avail(P_OSAL_FIFO pFifo);
+unsigned int osal_fifo_is_empty(P_OSAL_FIFO pFifo);
+unsigned int osal_fifo_is_full(P_OSAL_FIFO pFifo);
+
+#if defined(CONFIG_PROVE_LOCKING)
+#define osal_unsleepable_lock_init(l) { spin_lock_init(&((l)->lock)); }
+#else
+int osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK);
+#endif
+int osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK);
+int osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK);
+int osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK);
+
+#if defined(CONFIG_PROVE_LOCKING)
+#define osal_sleepable_lock_init(l) { mutex_init(&((l)->lock)); }
+#else
+int osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK);
+#endif
+int osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK);
+int osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK);
+int osal_trylock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK);
+int osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK);
+
+int osal_signal_init(P_OSAL_SIGNAL);
+int osal_wait_for_signal(P_OSAL_SIGNAL);
+int osal_wait_for_signal_timeout(P_OSAL_SIGNAL, P_OSAL_THREAD);
+int osal_raise_signal(P_OSAL_SIGNAL);
+int osal_signal_active_state(P_OSAL_SIGNAL pSignal);
+int osal_signal_deinit(P_OSAL_SIGNAL);
+
+int osal_event_init(P_OSAL_EVENT);
+int osal_wait_for_event(P_OSAL_EVENT, P_COND, void*);
+int osal_wait_for_event_timeout(P_OSAL_EVENT, P_COND, void*);
+extern int osal_trigger_event(P_OSAL_EVENT);
+
+int osal_event_deinit(P_OSAL_EVENT);
+long osal_wait_for_event_bit_set(P_OSAL_EVENT pEvent, unsigned long *pState, unsigned int bitOffset);
+long osal_wait_for_event_bit_clr(P_OSAL_EVENT pEvent, unsigned long *pState, unsigned int bitOffset);
+
+int osal_thread_create(P_OSAL_THREAD);
+int osal_thread_run(P_OSAL_THREAD);
+int osal_thread_should_stop(P_OSAL_THREAD);
+int osal_thread_stop(P_OSAL_THREAD);
+/*int osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT);*/
+int osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT, P_OSAL_EVENT_CHECKER);
+/*check pOsalLxOp and OSAL_THREAD_SHOULD_STOP*/
+int osal_thread_destroy(P_OSAL_THREAD);
+int osal_thread_sched_mark(P_OSAL_THREAD, P_OSAL_THREAD_SCHEDSTATS schedstats);
+int osal_thread_sched_unmark(P_OSAL_THREAD pThread, P_OSAL_THREAD_SCHEDSTATS schedstats);
+
+int osal_clear_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData);
+int osal_set_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData);
+int osal_test_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData);
+int osal_test_and_clear_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData);
+int osal_test_and_set_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData);
+
+int osal_gettimeofday(int *sec, int *usec);
+//int osal_printtimeofday(const unsigned char *prefix);
+void osal_get_local_time(unsigned long long *sec, unsigned long *nsec);
+unsigned long long osal_elapsed_us(unsigned long long ts, unsigned long usec);
+
+void osal_buffer_dump(const unsigned char *buf, const unsigned char *title, unsigned int len, unsigned int limit);
+void osal_buffer_dump_data(const unsigned int *buf, const unsigned char *title, const unsigned int len, const unsigned int limit,
+ const int flag);
+
+unsigned int osal_op_get_id(P_OSAL_OP pOp);
+MTK_CONN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp);
+void osal_op_raise_signal(P_OSAL_OP pOp, int result);
+void osal_set_op_result(P_OSAL_OP pOp, int result);
+void osal_opq_dump(const char *qName, P_OSAL_OP_Q pOpQ);
+void osal_opq_dump_locked(const char *qName, P_OSAL_OP_Q pOpQ);
+MTK_CONN_BOOL osal_opq_has_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp);
+
+int osal_ftrace_print(const char *str, ...);
+int osal_ftrace_print_ctrl(int flag);
+
+void osal_dump_thread_state(const unsigned char *name);
+void osal_op_history_init(struct osal_op_history *log_history, int queue_size);
+void osal_op_history_save(struct osal_op_history *log_history, P_OSAL_OP pOp);
+void osal_op_history_print(struct osal_op_history *log_history, char *name);
+
+void osal_systrace_major_b(const char *name, ...);
+void osal_systrace_major_e(void);
+
+void osal_systrace_minor_b(const char *name, ...);
+void osal_systrace_minor_e(void);
+void osal_systrace_minor_c(int val, const char *name, ...);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _OSAL_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/base/include/ring.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/base/include/ring.h
new file mode 100755
index 0000000..81168ce
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/base/include/ring.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+#ifndef _RING_H_
+#define _RING_H_
+
+struct ring {
+ /* addr where ring buffer starts */
+ void *base;
+ /* addr storing the next writable pos, guaranteed to be >= read except when write overflow, but it's ok. */
+ unsigned int write;
+ /* addr storing the next readable pos, except when read == write as buffer empty */
+ unsigned int read;
+ /* must be power of 2 */
+ unsigned int max_size;
+};
+
+struct ring_segment {
+ /* addr points into ring buffer for read/write */
+ void *ring_pt;
+ /* size to read/write */
+ unsigned int sz;
+ /* pos in external data buffer to read/write */
+ unsigned int data_pos;
+ /* the size to be read/write after this segment completed */
+ unsigned int remain;
+};
+
+void ring_init(void *base, unsigned int max_size, unsigned int read,
+ unsigned int write, struct ring *ring);
+unsigned int ring_read_prepare(unsigned int sz, struct ring_segment *seg, struct ring *ring);
+#define ring_read_all_prepare(seg, ring) ring_read_prepare((ring)->max_size, seg, ring)
+unsigned int ring_write_prepare(unsigned int sz, struct ring_segment *seg, struct ring *ring);
+unsigned int ring_overwrite_prepare(unsigned int sz,
+ struct ring_segment *seg, struct ring *ring);
+
+/* making sure max_size is power of 2 */
+#define RING_VALIDATE_SIZE(max_size) WARN_ON(!max_size || (max_size & (max_size - 1)))
+
+#define RING_EMPTY(ring) ((ring)->read == (ring)->write)
+/* equation works even when write overflow */
+#define RING_SIZE(ring) ((ring)->write - (ring)->read)
+#define RING_FULL(ring) (RING_SIZE(ring) == (ring)->max_size)
+#define RING_WRITE_REMAIN_SIZE(ring) ((ring)->max_size - RING_SIZE(ring))
+
+#define RING_READ_FOR_EACH(_sz, _seg, _ring) \
+ for (ring_read_prepare(_sz, &(_seg), _ring), \
+ _ring_segment_prepare((_ring)->read, &(_seg), (_ring)); \
+ (_seg).sz > 0; \
+ _ring_read_commit(&(_seg), (_ring)), _ring_segment_prepare((_ring)->read, \
+ &(_seg), (_ring)))
+
+#define RING_READ_ALL_FOR_EACH(seg, ring) RING_READ_FOR_EACH((ring)->max_size, seg, ring)
+
+#define RING_READ_FOR_EACH_ITEM(_sz, _seg, _ring) \
+ for (ring_read_prepare(_sz, &(_seg), _ring), \
+ _ring_segment_prepare_item((_ring)->read, &(_seg), (_ring)); \
+ (_seg).sz > 0; \
+ _ring_read_commit(&(_seg), (_ring)), _ring_segment_prepare_item((_ring)->read, \
+ &(_seg), (_ring)))
+
+#define RING_WRITE_FOR_EACH(_sz, _seg, _ring) \
+ for (ring_write_prepare(_sz, &(_seg), _ring),\
+ _ring_segment_prepare((_ring)->write, &(_seg), (_ring)); \
+ (_seg).sz > 0; \
+ _ring_write_commit(&(_seg), (_ring)), _ring_segment_prepare((_ring)->write, \
+ &(_seg), (_ring)))
+
+#define RING_OVERWRITE_FOR_EACH(_sz, _seg, _ring) \
+ for (ring_overwrite_prepare(_sz, &(_seg), _ring), \
+ _ring_segment_prepare((_ring)->write, &(_seg), (_ring)); \
+ (_seg).sz > 0; \
+ _ring_write_commit(&(_seg), (_ring)), _ring_segment_prepare((_ring)->write, \
+ &(_seg), (_ring)))
+
+void ring_dump(const char *title, struct ring *ring);
+void ring_dump_segment(const char *title, struct ring_segment *seg);
+
+
+/* ring Buffer Internal API */
+void _ring_segment_prepare(unsigned int from, struct ring_segment *seg, struct ring *ring);
+void _ring_segment_prepare_item(unsigned int from, struct ring_segment *seg, struct ring *ring);
+void _ring_read_commit(struct ring_segment *seg, struct ring *ring);
+void _ring_write_commit(struct ring_segment *seg, struct ring *ring);
+
+#endif
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/base/msg_thread.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/base/msg_thread.c
new file mode 100755
index 0000000..873c0f7
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/base/msg_thread.c
@@ -0,0 +1,716 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__
+#include <linux/delay.h>
+#include "msg_thread.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+static void msg_opq_dump(const char *qName, struct msg_op_q *op_q);
+static void _msg_opq_dump(const char *qName, struct msg_op_q *op_q);
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#define MSG_OP_SIZE(prb) ((prb)->size)
+#define MSG_OP_MASK(prb) (MSG_OP_SIZE(prb) - 1)
+#define MSG_OP_COUNT(prb) ((prb)->write - (prb)->read)
+#define MSG_OP_FULL(prb) (MSG_OP_COUNT(prb) >= MSG_OP_SIZE(prb))
+#define MSG_OP_EMPTY(prb) ((prb)->write == (prb)->read)
+
+#define MSG_OP_INIT(prb, qsize) \
+do { \
+ (prb)->read = (prb)->write = 0; \
+ (prb)->size = (qsize); \
+} while (0)
+
+#define MSG_OP_PUT(prb, value) \
+do { \
+ if (!MSG_OP_FULL(prb)) { \
+ (prb)->queue[(prb)->write & MSG_OP_MASK(prb)] = value; \
+ ++((prb)->write); \
+ } \
+ else { \
+ pr_warn("Message queue is full."); \
+ } \
+} while (0)
+
+#define MSG_OP_GET(prb, value) \
+do { \
+ if (!MSG_OP_EMPTY(prb)) { \
+ value = (prb)->queue[(prb)->read & MSG_OP_MASK(prb)]; \
+ ++((prb)->read); \
+ if (MSG_OP_EMPTY(prb)) { \
+ (prb)->read = (prb)->write = 0; \
+ } \
+ } \
+ else { \
+ value = NULL; \
+ pr_warn("Message queue is empty."); \
+ } \
+} while (0)
+
+
+
+#if defined(CONFIG_MTK_ENG_BUILD) || defined(CONFIG_MT_ENG_BUILD)
+static bool msg_evt_opq_has_op(struct msg_op_q *op_q, struct msg_op *op)
+{
+ unsigned int rd;
+ unsigned int wt;
+ struct msg_op *tmp_op;
+
+ rd = op_q->read;
+ wt = op_q->write;
+
+ while (rd != wt) {
+ tmp_op = op_q->queue[rd & MSG_OP_MASK(op_q)];
+ if (op == tmp_op)
+ return true;
+ rd++;
+ }
+ return false;
+}
+#endif
+
+/*
+ * Utility functions
+ */
+static int msg_evt_put_op_to_q(struct msg_op_q *op_q, struct msg_op *op)
+{
+ int ret;
+
+ if (!op_q || !op) {
+ pr_err("invalid input param: pOpQ(0x%p), pLxOp(0x%p)\n", op_q, op);
+ return -1;
+ }
+
+ ret = osal_lock_sleepable_lock(&op_q->lock);
+ if (ret) {
+ pr_warn("osal_lock_sleepable_lock iRet(%d)\n", ret);
+ return -2;
+ }
+
+#if defined(CONFIG_MTK_ENG_BUILD) || defined(CONFIG_MT_ENG_BUILD)
+ if (msg_evt_opq_has_op(op_q, op)) {
+ pr_err("Op(%p) already exists in queue(%p)\n", op, op_q);
+ ret = -3;
+ }
+#endif
+
+ /* acquire lock success */
+ if (!MSG_OP_FULL(op_q))
+ MSG_OP_PUT(op_q, op);
+ else {
+ pr_warn("MSG_OP_FULL(%p -> %p)\n", op, op_q);
+ ret = -4;
+ }
+
+ osal_unlock_sleepable_lock(&op_q->lock);
+
+ if (ret) {
+ //osal_opq_dump("FreeOpQ", &g_conninfra_ctx.rFreeOpQ);
+ //osal_opq_dump("ActiveOpQ", &g_conninfra_ctx.rActiveOpQ);
+ return ret;
+ }
+ return 0;
+}
+
+
+/*
+ * Utility functions
+ */
+static struct msg_op *msg_evt_get_op_from_q(struct msg_op_q *op_q)
+{
+ struct msg_op *op;
+ int ret;
+
+ if (op_q == NULL) {
+ pr_err("pOpQ = NULL\n");
+ return NULL;
+ }
+
+ ret = osal_lock_sleepable_lock(&op_q->lock);
+ if (ret) {
+ pr_err("osal_lock_sleepable_lock iRet(%d)\n", ret);
+ return NULL;
+ }
+
+ /* acquire lock success */
+ MSG_OP_GET(op_q, op);
+ osal_unlock_sleepable_lock(&op_q->lock);
+
+ if (op == NULL) {
+ pr_warn("MSG_OP_GET(%p) return NULL\n", op_q);
+ //osal_opq_dump("FreeOpQ", &g_conninfra_ctx.rFreeOpQ);
+ //osal_opq_dump("ActiveOpQ", &g_conninfra_ctx.rActiveOpQ);
+ }
+
+ return op;
+}
+
+static void _msg_opq_dump(const char *qName, struct msg_op_q *op_q)
+{
+ /* Line format:
+ * [LogicalIdx(PhysicalIdx)]Address:OpId(Ref)(Result)-Info-OpData0,OpData1,OpData2,OpData3,OpData5_
+ * [LogicalIdx] max 10+2=12 chars (decimal)
+ * (PhysicalIdx) max 10+2=12 chars (decimal)
+ * Address: max 16+1=17 chars (hex)
+ * OpId max 10 chars (decimal)
+ * (Ref) max 2+2=4 chars (should only be 1 digit, reserve 2 in case of negative number)
+ * (Result) max 11+2=13 chars (signed decimal)
+ * -Info- max 8+2=10 chars (hex)
+ * OpData, max 16+1=17 chars (hex)
+ */
+#define OPQ_DUMP_OP_PER_LINE 1
+#define OPQ_DUMP_OPDATA_PER_OP 6
+#define OPQ_DUMP_OP_BUF_SIZE (12 + 12 + 17 + 10 + 4 + 13 + 10 + (17 * (OPQ_DUMP_OPDATA_PER_OP)) + 1)
+#define OPQ_DUMP_LINE_BUF_SIZE ((OPQ_DUMP_OP_BUF_SIZE * OPQ_DUMP_OP_PER_LINE) + 1)
+ unsigned int rd;
+ unsigned int wt;
+ unsigned int idx = 0;
+ unsigned int op_data_idx;
+ unsigned int buf_idx;
+ int printed;
+ struct msg_op *op;
+ char buf[OPQ_DUMP_LINE_BUF_SIZE];
+
+ rd = op_q->read;
+ wt = op_q->write;
+
+ pr_info("%s(%p), sz:%u/%u, rd:%u, wt:%u\n",
+ qName, op_q, RB_COUNT(op_q), RB_SIZE(op_q), rd, wt);
+ while (rd != wt && idx < RB_SIZE(op_q)) {
+ buf_idx = idx % OPQ_DUMP_OP_PER_LINE;
+ op = op_q->queue[rd & RB_MASK(op_q)];
+
+ if (buf_idx == 0) {
+ printed = 0;
+ buf[0] = 0;
+ }
+
+ if (op) {
+ printed += snprintf(buf + printed, OPQ_DUMP_LINE_BUF_SIZE - printed,
+ "[%u(%u)]%p:%u(%d)(%d)-%u-",
+ idx,
+ (rd & RB_MASK(op_q)),
+ op,
+ op->op.op_id,
+ atomic_read(&op->ref_count),
+ op->result,
+ op->op.info_bit);
+ for (op_data_idx = 0; op_data_idx < OPQ_DUMP_OPDATA_PER_OP; op_data_idx++)
+ printed += snprintf(buf + printed, OPQ_DUMP_LINE_BUF_SIZE - printed,
+ "%zx,", op->op.op_data[op_data_idx]);
+ buf[printed-1] = ' ';
+ } else {
+ printed += snprintf(buf + printed, OPQ_DUMP_LINE_BUF_SIZE - printed,
+ "[%u(%u)]%p ", idx, (rd & RB_MASK(op_q)), op);
+ }
+ buf[printed++] = ' ';
+
+ if (buf_idx == OPQ_DUMP_OP_PER_LINE - 1 || rd == wt - 1) {
+ buf[printed - 1] = 0;
+ pr_info("%s\n", buf);
+ }
+ rd++;
+ idx++;
+ }
+}
+
+void msg_opq_dump(const char *qName, struct msg_op_q *op_q)
+{
+ int err;
+
+ err = osal_lock_sleepable_lock(&op_q->lock);
+ if (err) {
+ pr_info("Failed to lock queue (%d)\n", err);
+ return;
+ }
+
+ _msg_opq_dump(qName, op_q);
+
+ osal_unlock_sleepable_lock(&op_q->lock);
+}
+
+/*
+ * msg_evt_thread API
+ */
+
+int msg_evt_put_op_to_free_queue(struct msg_thread_ctx *ctx, struct msg_op *op)
+{
+ if (msg_evt_put_op_to_q(&ctx->free_op_q, op))
+ return -1;
+ return 0;
+}
+
+
+struct msg_op *msg_evt_get_free_op(struct msg_thread_ctx *ctx)
+{
+ struct msg_op *op = NULL;
+
+ if (ctx == NULL) {
+ pr_warn("ctx is null.");
+ return op;
+ }
+ op = msg_evt_get_op_from_q(&ctx->free_op_q);
+ if (op)
+ osal_memset(op, 0, osal_sizeof(struct msg_op));
+ return op;
+}
+
+int msg_evt_put_op_to_active(struct msg_thread_ctx *ctx, struct msg_op *op)
+{
+ P_OSAL_SIGNAL signal = NULL;
+ int wait_ret = -1;
+ int ret = 0;
+
+ do {
+ if (!ctx || !op) {
+ pr_err("msg_thread_ctx(0x%p), op(0x%p)\n", ctx, op);
+ break;
+ }
+
+ signal = &op->signal;
+ if (signal->timeoutValue) {
+ op->result = -9;
+ osal_signal_init(signal);
+ atomic_set(&op->ref_count, 1);
+ } else
+ atomic_set(&op->ref_count, 0);
+
+ /* Increment ref_count by 1 as wmtd thread will hold a reference also,
+ * this must be done here instead of on target thread, because
+ * target thread might not be scheduled until a much later time,
+ * allowing current thread to decrement ref_count at the end of function,
+ * putting op back to free queue before target thread has a chance to process.
+ */
+ atomic_inc(&op->ref_count);
+
+ /* put to active Q */
+ ret = msg_evt_put_op_to_q(&ctx->active_op_q, op);
+ if (ret) {
+ pr_warn("put to active queue fail\n");
+ atomic_dec(&op->ref_count);
+ break;
+ }
+
+ /* wake up conninfra_cored */
+ osal_trigger_event(&ctx->evt);
+
+ if (signal->timeoutValue == 0) {
+ //ret = -1;
+ /* Not set timeout, don't wait */
+ /* pr_info("[%s] timeout is zero", __func__);*/
+ break;
+ }
+
+ /* check result */
+ wait_ret = osal_wait_for_signal_timeout(signal, &ctx->thread);
+ /*pr_info("osal_wait_for_signal_timeout:%d result=[%d]\n",
+ wait_ret, op->result);*/
+
+ if (wait_ret == 0)
+ pr_warn("opId(%d) completion timeout\n", op->op.op_id);
+ else if (op->result)
+ pr_info("opId(%d) result:%d\n",
+ op->op.op_id, op->result);
+
+ /* op completes, check result */
+ ret = op->result;
+ } while (0);
+
+ if (op != NULL && signal != NULL && signal->timeoutValue &&
+ atomic_dec_and_test(&op->ref_count)) {
+ /* put Op back to freeQ */
+ msg_evt_put_op_to_free_queue(ctx, op);
+ }
+
+ return ret;
+}
+
+
+int msg_thread_send(struct msg_thread_ctx *ctx, int opid)
+{
+ return msg_thread_send_2(ctx, opid, 0, 0);
+}
+
+int msg_thread_send_1(struct msg_thread_ctx *ctx, int opid,
+ size_t param1)
+{
+ return msg_thread_send_2(ctx, opid, param1, 0);
+}
+
+int msg_thread_send_2(struct msg_thread_ctx *ctx, int opid,
+ size_t param1, size_t param2)
+{
+ struct msg_op *op = NULL;
+ P_OSAL_SIGNAL signal;
+ int ret;
+
+ op = msg_evt_get_free_op(ctx);
+ if (!op) {
+ pr_err("[%s] can't get free op\n", __func__);
+ return -1;
+ }
+ op->op.op_id = opid;
+ op->op.op_data[0] = param1;
+ op->op.op_data[1] = param2;
+
+ signal = &op->signal;
+ //signal->timeoutValue = timeout > 0 ? timeout : MSG_OP_TIMEOUT;
+ signal->timeoutValue = 0;
+ ret = msg_evt_put_op_to_active(ctx, op);
+
+ return ret;
+}
+
+int msg_thread_send_wait(struct msg_thread_ctx *ctx, int opid,
+ int timeout)
+{
+ return msg_thread_send_wait_3(ctx, opid, timeout, 0, 0, 0);
+}
+
+int msg_thread_send_wait_1(struct msg_thread_ctx *ctx,
+ int opid, int timeout,
+ size_t param1)
+{
+ return msg_thread_send_wait_3(ctx, opid, timeout, param1, 0, 0);
+}
+
+
+int msg_thread_send_wait_2(struct msg_thread_ctx *ctx,
+ int opid, int timeout,
+ size_t param1,
+ size_t param2)
+{
+ return msg_thread_send_wait_3(ctx, opid, timeout, param1, param2, 0);
+}
+
+int msg_thread_send_wait_3(struct msg_thread_ctx *ctx,
+ int opid, int timeout,
+ size_t param1,
+ size_t param2,
+ size_t param3)
+{
+ struct msg_op *op = NULL;
+ P_OSAL_SIGNAL signal;
+ int ret;
+
+ op = msg_evt_get_free_op(ctx);
+ if (!op) {
+ pr_err("[%s] can't get free op for 0x%x\n", __func__, opid);
+ return -1;
+ }
+ op->op.op_id = opid;
+ op->op.op_data[0] = param1;
+ op->op.op_data[1] = param2;
+ op->op.op_data[2] = param3;
+
+ signal = &op->signal;
+ signal->timeoutValue = timeout > 0 ? timeout : MSG_OP_TIMEOUT;
+ ret = msg_evt_put_op_to_active(ctx, op);
+ return ret;
+
+}
+
+void msg_op_history_save(struct osal_op_history *log_history, struct msg_op *op)
+{
+ struct osal_op_history_entry *entry = NULL;
+ struct ring_segment seg;
+ int index;
+ unsigned long long sec = 0;
+ unsigned long usec = 0;
+ unsigned long flags;
+
+ if (log_history->queue == NULL)
+ return;
+
+ osal_get_local_time(&sec, &usec);
+
+ spin_lock_irqsave(&(log_history->lock), flags);
+ RING_OVERWRITE_FOR_EACH(1, seg, &log_history->ring_buffer) {
+ index = seg.ring_pt - log_history->ring_buffer.base;
+ entry = &log_history->queue[index];
+ }
+
+ if (entry == NULL) {
+ pr_info("Entry is null, size %d\n",
+ RING_SIZE(&log_history->ring_buffer));
+ spin_unlock_irqrestore(&(log_history->lock), flags);
+ return;
+ }
+
+ entry->opbuf_address = op;
+ entry->op_id = op->op.op_id;
+ entry->opbuf_ref_count = atomic_read(&op->ref_count);
+ entry->op_info_bit = op->op.info_bit;
+ entry->param_0 = op->op.op_data[0];
+ entry->param_1 = op->op.op_data[1];
+ entry->param_2 = op->op.op_data[2];
+ entry->param_3 = op->op.op_data[3];
+ entry->ts = sec;
+ entry->usec = usec;
+ spin_unlock_irqrestore(&(log_history->lock), flags);
+}
+
+unsigned int msg_evt_wait_event_checker(P_OSAL_THREAD thread)
+{
+ struct msg_thread_ctx *ctx = NULL;
+
+ if (thread) {
+ ctx = (struct msg_thread_ctx *) (thread->pThreadData);
+ return !MSG_OP_EMPTY(&ctx->active_op_q);
+ }
+ return 0;
+}
+
+int msg_evt_set_current_op(struct msg_thread_ctx *ctx, struct msg_op *op)
+{
+ ctx->cur_op = op;
+ return 0;
+}
+
+int msg_evt_opid_handler(struct msg_thread_ctx *ctx, struct msg_op_data *op)
+{
+ int opid, ret;
+
+ /*sanity check */
+ if (op == NULL) {
+ pr_warn("null op\n");
+ return -1;
+ }
+ if (ctx == NULL) {
+ pr_warn("null evt thread ctx\n");
+ return -2;
+ }
+
+ opid = op->op_id;
+
+ if (opid >= ctx->op_func_size) {
+ pr_err("msg_evt_thread invalid OPID(%d)\n", opid);
+ return -3;
+ }
+
+ if (ctx->op_func[opid] == NULL) {
+ pr_err("null handler (%d)\n", opid);
+ return -4;
+ }
+ ret = (*(ctx->op_func[opid])) (op);
+ return ret;
+}
+
+static int msg_evt_thread(void *pvData)
+{
+ struct msg_thread_ctx *ctx = (struct msg_thread_ctx *)pvData;
+ P_OSAL_EVENT evt = NULL;
+ struct msg_op *op;
+ int ret;
+
+ if (ctx == NULL) {
+ pr_err("msg_evt_thread (NULL)\n");
+ return -1;
+ }
+
+ evt = &(ctx->evt);
+
+ for (;;) {
+ op = NULL;
+ evt->timeoutValue = 0;
+
+ osal_thread_wait_for_event(&ctx->thread, evt, msg_evt_wait_event_checker);
+
+ if (osal_thread_should_stop(&ctx->thread)) {
+ pr_info("msg_evt_thread thread should stop now...\n");
+ /* TODO: clean up active opQ */
+ break;
+ }
+ /* get Op from activeQ */
+ op = msg_evt_get_op_from_q(&ctx->active_op_q);
+ if (!op) {
+ pr_warn("get op from activeQ fail\n");
+ continue;
+ }
+
+ /* TODO: save op history */
+ msg_op_history_save(&ctx->op_history, op);
+ msg_evt_set_current_op(ctx, op);
+ ret = msg_evt_opid_handler(ctx, &op->op);
+ msg_evt_set_current_op(ctx, NULL);
+
+ if (ret)
+ pr_warn("opid (0x%x) failed, ret(%d)\n",
+ op->op.op_id, ret);
+
+ if (atomic_dec_and_test(&op->ref_count)) {
+ /* msg_evt_free_op(ctx) */
+ msg_evt_put_op_to_free_queue(ctx, op);
+ } else if (op->signal.timeoutValue) {
+ op->result = ret;
+ osal_raise_signal(&op->signal);
+ }
+ }
+
+ pr_debug("msg evt thread exists\n");
+ return 0;
+}
+
+int msg_thread_dump(struct msg_thread_ctx *ctx)
+{
+ P_OSAL_THREAD p_thread;
+ struct msg_op *cur_op;
+
+ if (ctx == NULL) {
+ pr_err("%s get NULL input\n", __func__);
+ return 0;
+ }
+ p_thread = &ctx->thread;
+ pr_info("Dump msg_thread_ctx: %s\n", p_thread->threadName);
+ cur_op = ctx->cur_op;
+ if (cur_op) {
+ pr_info("cur_op: %x(%x)-%zx,%zx,%zx,%zx\n",
+ cur_op->op.op_id, cur_op->op.info_bit,
+ cur_op->op.op_data[0], cur_op->op.op_data[1],
+ cur_op->op.op_data[2], cur_op->op.op_data[3]);
+ }
+ osal_dump_thread_state(p_thread->threadName);
+ osal_op_history_print(&(ctx->op_history), p_thread->threadName);
+ msg_opq_dump("ActiveOpQ", &ctx->active_op_q);
+
+ return 0;
+}
+
+int msg_thread_init(struct msg_thread_ctx *ctx,
+ const char *thread_name, const msg_opid_func *funcs,
+ int op_size)
+{
+ int r = 0, i;
+ P_OSAL_THREAD p_thread;
+
+ osal_memset(ctx, 0, sizeof(struct msg_thread_ctx));
+
+ ctx->op_func = funcs;
+ ctx->op_func_size = op_size;
+
+ /* init thread inst */
+ p_thread = &ctx->thread;
+
+ osal_strncpy(p_thread->threadName, thread_name,
+ sizeof(p_thread->threadName));
+
+ p_thread->pThreadData = (void *) ctx;
+ p_thread->pThreadFunc = (void *) msg_evt_thread;
+ r = osal_thread_create(p_thread);
+
+ if (r) {
+ pr_err("osal_thread_create(0x%p) fail(%d)\n", p_thread, r);
+ return -1;
+ }
+
+ osal_event_init(&ctx->evt);
+ osal_sleepable_lock_init(&ctx->active_op_q.lock);
+ osal_sleepable_lock_init(&ctx->free_op_q.lock);
+
+ /* Initialize op queue */
+ MSG_OP_INIT(&ctx->free_op_q, MSG_THREAD_OP_BUF_SIZE);
+ MSG_OP_INIT(&ctx->active_op_q, MSG_THREAD_OP_BUF_SIZE);
+
+ /* Put all to free Q */
+ for (i = 0; i < MSG_THREAD_OP_BUF_SIZE; i++) {
+ osal_signal_init(&(ctx->op_q_inst[i].signal));
+ msg_evt_put_op_to_free_queue(ctx, &(ctx->op_q_inst[i]));
+ }
+
+ osal_op_history_init(&ctx->op_history, 16);
+
+ r = osal_thread_run(p_thread);
+ if (r) {
+ pr_err("osal_thread_run(evt_thread 0x%p) fail(%d)\n",
+ p_thread, r);
+ return -2;
+ }
+ return r;
+}
+
+int msg_thread_deinit(struct msg_thread_ctx *ctx)
+{
+ int r, i;
+ P_OSAL_THREAD p_thraed = &ctx->thread;
+
+ r = osal_thread_stop(p_thraed);
+ if (r) {
+ pr_err("osal_thread_stop(0x%p) fail(%d)\n", p_thraed, r);
+ return -1;
+ }
+
+ for (i = 0; i < MSG_THREAD_OP_BUF_SIZE; i++)
+ osal_signal_deinit(&(ctx->op_q_inst[i].signal));
+
+ osal_sleepable_lock_deinit(&ctx->free_op_q.lock);
+ osal_sleepable_lock_deinit(&ctx->active_op_q.lock);
+
+ r = osal_thread_destroy(p_thraed);
+ if (r) {
+ pr_err("osal_thread_stop(0x%p) fail(%d)\n", p_thraed, r);
+ return -2;
+ }
+
+ osal_memset(ctx, 0, sizeof(struct msg_thread_ctx));
+
+ pr_debug("[%s] DONE\n", __func__);
+ return 0;
+}
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/base/osal.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/base/osal.c
new file mode 100755
index 0000000..ab0d550
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/base/osal.c
@@ -0,0 +1,1630 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+/*! \file
+ * \brief Declaration of library functions
+ * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+ */
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/kallsyms.h>
+#include <linux/trace_events.h>
+#include <linux/kthread.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <asm/current.h>
+#include <linux/kfifo.h>
+#include "connectivity_build_in_adapter.h"
+#include "osal.h"
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+#define GPIO_ASSERT 70
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+int ftrace_flag = 1;
+
+static unsigned long __read_mostly mark_addr;
+static unsigned int g_pid;
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+/*string operations*/
+unsigned int osal_strlen(const char *str)
+{
+ return strlen(str);
+}
+
+int osal_strcmp(const char *dst, const char *src)
+{
+ return strcmp(dst, src);
+}
+
+int osal_strncmp(const char *dst, const char *src, unsigned int len)
+{
+ return strncmp(dst, src, len);
+}
+
+char *osal_strcpy(char *dst, const char *src)
+{
+ return strncpy(dst, src, strlen(src)+1);
+}
+
+char *osal_strncpy(char *dst, const char *src, unsigned int len)
+{
+ return strncpy(dst, src, len);
+}
+
+char *osal_strcat(char *dst, const char *src)
+{
+ return strncat(dst, src, strlen(src));
+}
+
+char *osal_strncat(char *dst, const char *src, unsigned int len)
+{
+ return strncat(dst, src, len);
+}
+
+char *osal_strchr(const char *str, unsigned char c)
+{
+ return strchr(str, c);
+}
+
+char *osal_strsep(char **str, const char *c)
+{
+ return strsep(str, c);
+}
+
+int osal_strtol(const char *str, unsigned int adecimal, long *res)
+{
+ if (sizeof(long) == 4)
+ return kstrtou32(str, adecimal, (unsigned int *) res);
+ else
+ return kstrtol(str, adecimal, res);
+}
+
+char *osal_strstr(char *str1, const char *str2)
+{
+ return strstr(str1, str2);
+}
+
+char *osal_strnstr(char *str1, const char *str2, int n)
+{
+ return strnstr(str1, str2, n);
+}
+
+void osal_bug_on(unsigned int val)
+{
+ WARN_ON(val);
+}
+
+int osal_snprintf(char *buf, unsigned int len, const char *fmt, ...)
+{
+ int iRet = 0;
+ va_list args;
+
+ /*va_start(args, fmt); */
+ va_start(args, fmt);
+ /*iRet = snprintf(buf, len, fmt, args); */
+ iRet = vsnprintf(buf, len, fmt, args);
+ va_end(args);
+
+ return iRet;
+}
+
+int osal_sprintf(char *str, const char *format, ...)
+{
+ int iRet = 0;
+ va_list args;
+
+ va_start(args, format);
+ iRet = vsnprintf(str, DBG_LOG_STR_SIZE, format, args);
+ va_end(args);
+
+ return iRet;
+}
+
+void *osal_malloc(unsigned int size)
+{
+ return vmalloc(size);
+}
+
+void osal_free(const void *dst)
+{
+ vfree(dst);
+}
+
+void *osal_memset(void *buf, int i, unsigned int len)
+{
+ return memset(buf, i, len);
+}
+
+void *osal_memcpy(void *dst, const void *src, unsigned int len)
+{
+ return memcpy(dst, src, len);
+}
+
+void osal_memcpy_fromio(void *dst, const void *src, unsigned int len)
+{
+ return memcpy_fromio(dst, src, len);
+}
+
+void osal_memcpy_toio(void *dst, const void *src, unsigned int len)
+{
+ return memcpy_toio(dst, src, len);
+}
+
+int osal_memcmp(const void *buf1, const void *buf2, unsigned int len)
+{
+ return memcmp(buf1, buf2, len);
+}
+
+void osal_dump_thread_state(const unsigned char *name)
+{
+ return connectivity_export_dump_thread_state(name);
+}
+
+static inline bool __osal_is_valid_thread(P_OSAL_THREAD pThread)
+{
+ if ((pThread) && !IS_ERR_OR_NULL(pThread->pThread))
+ return true;
+ else
+ return false;
+}
+
+void osal_thread_show_stack(P_OSAL_THREAD pThread)
+{
+ if (__osal_is_valid_thread(pThread))
+ KERNEL_show_stack(pThread->pThread, NULL);
+}
+
+/*
+ * OSAL layer Thread Opeartion related APIs
+ *
+ */
+int osal_thread_create(P_OSAL_THREAD pThread)
+{
+ struct task_struct *task;
+
+ if (!pThread)
+ return -1;
+
+ task = kthread_create(pThread->pThreadFunc,
+ pThread->pThreadData, pThread->threadName);
+ if (IS_ERR(task)) {
+ pr_err("[%s] create %s thread fail", __func__, pThread->threadName);
+ return -1;
+ }
+
+ pThread->pThread = task;
+ return 0;
+}
+
+int osal_thread_run(P_OSAL_THREAD pThread)
+{
+ if (__osal_is_valid_thread(pThread)) {
+ wake_up_process(pThread->pThread);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+int osal_thread_stop(P_OSAL_THREAD pThread)
+{
+ int iRet;
+
+ if (__osal_is_valid_thread(pThread)) {
+ iRet = kthread_stop(pThread->pThread);
+ pThread->pThread = NULL;
+ return iRet;
+ }
+ return -1;
+}
+
+int osal_thread_should_stop(P_OSAL_THREAD pThread)
+{
+ if (__osal_is_valid_thread(pThread))
+ return kthread_should_stop();
+ else
+ return 1;
+
+}
+
+int osal_thread_wait_for_event(P_OSAL_THREAD pThread,
+ P_OSAL_EVENT pEvent, P_OSAL_EVENT_CHECKER pChecker)
+{
+ /* P_DEV_WMT pDevWmt;*/
+
+ if (__osal_is_valid_thread(pThread) && (pEvent) && (pChecker)) {
+ return wait_event_interruptible(pEvent->waitQueue, (
+ osal_thread_should_stop(pThread)
+ || (*pChecker) (pThread)));
+ }
+ return -1;
+}
+
+int osal_thread_destroy(P_OSAL_THREAD pThread)
+{
+ if (__osal_is_valid_thread(pThread)) {
+ kthread_stop(pThread->pThread);
+ pThread->pThread = NULL;
+ }
+ return 0;
+}
+
+/*
+ * osal_thread_sched_retrieve
+ * Retrieve thread's current scheduling statistics and stored in output "sched".
+ * Return value:
+ * 0 : Schedstats successfully retrieved
+ * -1 : Kernel's schedstats feature not enabled
+ * -2 : pThread not yet initialized or sched is a NULL pointer
+ */
+static int osal_thread_sched_retrieve(P_OSAL_THREAD pThread,
+ P_OSAL_THREAD_SCHEDSTATS sched)
+{
+#ifdef CONFIG_SCHEDSTATS
+ struct sched_entity se;
+ unsigned long long sec;
+ unsigned long usec;
+
+ if (!sched)
+ return -2;
+
+ /* always clear sched to simplify error handling at caller side */
+ memset(sched, 0, sizeof(OSAL_THREAD_SCHEDSTATS));
+
+ if (!__osal_is_valid_thread(pThread))
+ return -2;
+
+ memcpy(&se, &pThread->pThread->se, sizeof(struct sched_entity));
+ osal_get_local_time(&sec, &usec);
+
+ sched->time = sec*1000 + usec/1000;
+ sched->exec = se.sum_exec_runtime;
+ sched->runnable = se.statistics.wait_sum;
+ sched->iowait = se.statistics.iowait_sum;
+
+ return 0;
+#else
+ /* always clear sched to simplify error handling at caller side */
+ if (sched)
+ memset(sched, 0, sizeof(OSAL_THREAD_SCHEDSTATS));
+ return -1;
+#endif
+}
+
+/*
+ * osal_thread_sched_mark
+ * Record the thread's current schedstats and stored
+ * in output "schedstats" parameter for profiling at
+ * later time.
+ * Return value:
+ * 0 : Schedstats successfully recorded
+ * -1 : Kernel's schedstats feature not enabled
+ * -2 : pThread not yet initialized or invalid parameters
+ */
+int osal_thread_sched_mark(P_OSAL_THREAD pThread,
+ P_OSAL_THREAD_SCHEDSTATS schedstats)
+{
+ return osal_thread_sched_retrieve(pThread, schedstats);
+}
+
+/*
+ * osal_thread_sched_unmark
+ * Calculate scheduling statistics against the previously marked point.
+ * The result will be filled back into the schedstats output parameter.
+ * Return value:
+ * 0 : Schedstats successfully calculated
+ * -1 : Kernel's schedstats feature not enabled
+ * -2 : pThread not yet initialized or invalid parameters
+ */
+int osal_thread_sched_unmark(P_OSAL_THREAD pThread,
+ P_OSAL_THREAD_SCHEDSTATS schedstats)
+{
+ int ret;
+ OSAL_THREAD_SCHEDSTATS sched_now;
+
+ if (unlikely(!schedstats)) {
+ ret = -2;
+ } else {
+ ret = osal_thread_sched_retrieve(pThread, &sched_now);
+ if (ret == 0) {
+ schedstats->time = sched_now.time - schedstats->time;
+ schedstats->exec = sched_now.exec - schedstats->exec;
+ schedstats->runnable =
+ sched_now.runnable - schedstats->runnable;
+ schedstats->iowait =
+ sched_now.iowait - schedstats->iowait;
+ }
+ }
+ return ret;
+}
+
+/*
+ * OSAL layer Signal Opeartion related APIs
+ * initialization
+ * wait for signal
+ * wait for signal timerout
+ * raise signal
+ * destroy a signal
+ *
+ */
+
+int osal_signal_init(P_OSAL_SIGNAL pSignal)
+{
+ if (pSignal) {
+ init_completion(&pSignal->comp);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+int osal_wait_for_signal(P_OSAL_SIGNAL pSignal)
+{
+ if (pSignal) {
+ wait_for_completion_interruptible(&pSignal->comp);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+/*
+ * osal_wait_for_signal_timeout
+ *
+ * Wait for a signal to be triggered by the corresponding thread, within the
+ * expected timeout specified by the signal's timeoutValue.
+ * When the pThread parameter is specified, the thread's scheduling ability is
+ * considered, the timeout will be extended when thread cannot acquire CPU
+ * resource, and will only extend for a number of times specified by the
+ * signal's timeoutExtension should the situation continues.
+ *
+ * Return value:
+ * 0 : timeout
+ * >0 : signal triggered
+ */
+int osal_wait_for_signal_timeout(P_OSAL_SIGNAL pSignal, P_OSAL_THREAD pThread)
+{
+ OSAL_THREAD_SCHEDSTATS schedstats;
+ int waitRet;
+
+ /* [ChangeFeature][George] gps driver may be closed by -ERESTARTSYS.
+ * Avoid using *interruptible" version in order to complete our jobs,
+ * such as function off gracefully.
+ */
+ if (!pThread || !pThread->pThread)
+ return wait_for_completion_timeout(&pSignal->comp,
+ msecs_to_jiffies(pSignal->timeoutValue));
+
+ do {
+ osal_thread_sched_mark(pThread, &schedstats);
+ waitRet = wait_for_completion_timeout(&pSignal->comp,
+ msecs_to_jiffies(pSignal->timeoutValue));
+ osal_thread_sched_unmark(pThread, &schedstats);
+
+ if (waitRet > 0)
+ break;
+
+ if (schedstats.runnable > schedstats.exec) {
+ pr_err(
+ "[E]%s:wait completion timeout, %s cannot get CPU, extension(%d), show backtrace:\n",
+ __func__,
+ pThread->threadName,
+ pSignal->timeoutExtension);
+ } else {
+ pr_err(
+ "[E]%s:wait completion timeout, show %s backtrace:\n",
+ __func__,
+ pThread->threadName);
+ pSignal->timeoutExtension = 0;
+ }
+ pr_err(
+ "[E]%s:\tduration:%llums, sched(x%llu/r%llu/i%llu)\n",
+ __func__,
+ schedstats.time,
+ schedstats.exec,
+ schedstats.runnable,
+ schedstats.iowait);
+ /*
+ * no need to disginguish combo or A/D die projects
+ * osal_dump_thread_state will just return if target
+ * thread does not exist
+ */
+ osal_dump_thread_state("mtk_wmtd");
+ osal_dump_thread_state("mtk_wmtd_worker");
+ osal_dump_thread_state("btif_rxd");
+ osal_dump_thread_state("mtk_stp_psm");
+ osal_dump_thread_state("mtk_stp_btm");
+ osal_dump_thread_state("stp_sdio_tx_rx");
+ } while (pSignal->timeoutExtension--);
+ return waitRet;
+}
+
+int osal_raise_signal(P_OSAL_SIGNAL pSignal)
+{
+ if (pSignal) {
+ complete(&pSignal->comp);
+ return 0;
+ } else
+ return -1;
+}
+
+int osal_signal_active_state(P_OSAL_SIGNAL pSignal)
+{
+ if (pSignal)
+ return pSignal->timeoutValue;
+ else
+ return -1;
+}
+
+int osal_signal_deinit(P_OSAL_SIGNAL pSignal)
+{
+ if (pSignal) {
+ pSignal->timeoutValue = 0;
+ return 0;
+ } else
+ return -1;
+}
+
+/*
+ * OSAL layer Event Opeartion related APIs
+ * initialization
+ * wait for signal
+ * wait for signal timerout
+ * raise signal
+ * destroy a signal
+ *
+ */
+
+int osal_event_init(P_OSAL_EVENT pEvent)
+{
+ if (pEvent) {
+ init_waitqueue_head(&pEvent->waitQueue);
+ return 0;
+ }
+ return -1;
+}
+
+int osal_trigger_event(P_OSAL_EVENT pEvent)
+{
+ int ret = 0;
+
+ if (pEvent) {
+ wake_up_interruptible(&pEvent->waitQueue);
+ return ret;
+ }
+ return -1;
+}
+
+int osal_wait_for_event(P_OSAL_EVENT pEvent,
+ int (*condition)(void *), void *cond_pa)
+{
+ if (pEvent)
+ return wait_event_interruptible(pEvent->waitQueue,
+ condition(cond_pa));
+ else
+ return -1;
+}
+
+int osal_wait_for_event_timeout(P_OSAL_EVENT pEvent,
+ int (*condition)(void *), void *cond_pa)
+{
+ if (pEvent)
+ return wait_event_interruptible_timeout(pEvent->waitQueue,
+ condition(cond_pa),
+ msecs_to_jiffies(pEvent->timeoutValue));
+ return -1;
+}
+
+
+int osal_event_deinit(P_OSAL_EVENT pEvent)
+{
+ return 0;
+}
+
+long osal_wait_for_event_bit_set(P_OSAL_EVENT pEvent,
+ unsigned long *pState, unsigned int bitOffset)
+{
+ unsigned int ms = 0;
+
+ if (pEvent) {
+ ms = pEvent->timeoutValue;
+ if (ms != 0)
+ return wait_event_interruptible_timeout(
+ pEvent->waitQueue,
+ test_bit(bitOffset, pState),
+ msecs_to_jiffies(ms));
+ else
+ return wait_event_interruptible(pEvent->waitQueue,
+ test_bit(bitOffset, pState));
+ } else
+ return -1;
+
+}
+
+long osal_wait_for_event_bit_clr(P_OSAL_EVENT pEvent,
+ unsigned long *pState, unsigned int bitOffset)
+{
+ unsigned int ms = 0;
+
+ if (pEvent) {
+ ms = pEvent->timeoutValue;
+ if (ms != 0)
+ return wait_event_interruptible_timeout(
+ pEvent->waitQueue,
+ !test_bit(bitOffset, pState),
+ msecs_to_jiffies(ms));
+ else
+ return wait_event_interruptible(pEvent->waitQueue,
+ !test_bit(bitOffset, pState));
+ } else
+ return -1;
+}
+
+/*
+ * bit test and set/clear operations APIs
+ */
+#if OS_BIT_OPS_SUPPORT
+#define osal_bit_op_lock(x)
+#define osal_bit_op_unlock(x)
+#else
+
+int osal_bit_op_lock(P_OSAL_UNSLEEPABLE_LOCK pLock)
+{
+
+ return 0;
+}
+
+int osal_bit_op_unlock(P_OSAL_UNSLEEPABLE_LOCK pLock)
+{
+
+ return 0;
+}
+#endif
+int osal_clear_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData)
+{
+ osal_bit_op_lock(&(pData->opLock));
+ clear_bit(bitOffset, &pData->data);
+ osal_bit_op_unlock(&(pData->opLock));
+ return 0;
+}
+
+int osal_set_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData)
+{
+ osal_bit_op_lock(&(pData->opLock));
+ set_bit(bitOffset, &pData->data);
+ osal_bit_op_unlock(&(pData->opLock));
+ return 0;
+}
+
+int osal_test_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData)
+{
+ unsigned int iRet = 0;
+
+ osal_bit_op_lock(&(pData->opLock));
+ iRet = test_bit(bitOffset, &pData->data);
+ osal_bit_op_unlock(&(pData->opLock));
+ return iRet;
+}
+
+int osal_test_and_clear_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData)
+{
+ unsigned int iRet = 0;
+
+ osal_bit_op_lock(&(pData->opLock));
+ iRet = test_and_clear_bit(bitOffset, &pData->data);
+ osal_bit_op_unlock(&(pData->opLock));
+ return iRet;
+
+}
+
+int osal_test_and_set_bit(unsigned int bitOffset, P_OSAL_BIT_OP_VAR pData)
+{
+ unsigned int iRet = 0;
+
+ osal_bit_op_lock(&(pData->opLock));
+ iRet = test_and_set_bit(bitOffset, &pData->data);
+ osal_bit_op_unlock(&(pData->opLock));
+ return iRet;
+}
+
+int _osal_fifo_init(OSAL_FIFO *pFifo, unsigned char *buf, unsigned int size)
+{
+ struct kfifo *fifo = NULL;
+ int ret = -1;
+
+ if (!pFifo) {
+ pr_err("pFifo must be !NULL\n");
+ return -1;
+ }
+ if (pFifo->pFifoBody) {
+ pr_err("pFifo->pFifoBody must be NULL\n");
+ pr_err("pFifo(0x%p), pFifo->pFifoBody(0x%p)\n",
+ pFifo, pFifo->pFifoBody);
+ return -1;
+ }
+ fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC);
+ if (!buf) {
+ /*fifo's buffer is not ready, we allocate automatically */
+ ret = kfifo_alloc(fifo, size, /*GFP_KERNEL */ GFP_ATOMIC);
+ } else {
+ if (is_power_of_2(size)) {
+ kfifo_init(fifo, buf, size);
+ ret = 0;
+ } else {
+ kfree(fifo);
+ fifo = NULL;
+ ret = -1;
+ }
+ }
+
+ pFifo->pFifoBody = fifo;
+ return (ret < 0) ? (-1) : (0);
+}
+
+int _osal_fifo_deinit(OSAL_FIFO *pFifo)
+{
+ struct kfifo *fifo = NULL;
+
+ if (!pFifo || !pFifo->pFifoBody) {
+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n",
+ __func__);
+ return -1;
+ }
+
+ fifo = (struct kfifo *)pFifo->pFifoBody;
+
+ if (fifo)
+ kfifo_free(fifo);
+
+ return 0;
+}
+
+int _osal_fifo_size(OSAL_FIFO *pFifo)
+{
+ struct kfifo *fifo = NULL;
+ int ret = 0;
+
+ if (!pFifo || !pFifo->pFifoBody) {
+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n",
+ __func__);
+ return -1;
+ }
+
+ fifo = (struct kfifo *)pFifo->pFifoBody;
+
+ if (fifo)
+ ret = kfifo_size(fifo);
+
+ return ret;
+}
+
+/*returns unused bytes in fifo*/
+int _osal_fifo_avail_size(OSAL_FIFO *pFifo)
+{
+ struct kfifo *fifo = NULL;
+ int ret = 0;
+
+ if (!pFifo || !pFifo->pFifoBody) {
+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n",
+ __func__);
+ return -1;
+ }
+
+ fifo = (struct kfifo *)pFifo->pFifoBody;
+
+ if (fifo)
+ ret = kfifo_avail(fifo);
+
+ return ret;
+}
+
+/*returns used bytes in fifo*/
+int _osal_fifo_len(OSAL_FIFO *pFifo)
+{
+ struct kfifo *fifo = NULL;
+ int ret = 0;
+
+ if (!pFifo || !pFifo->pFifoBody) {
+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n",
+ __func__);
+ return -1;
+ }
+
+ fifo = (struct kfifo *)pFifo->pFifoBody;
+
+ if (fifo)
+ ret = kfifo_len(fifo);
+
+ return ret;
+}
+
+int _osal_fifo_is_empty(OSAL_FIFO *pFifo)
+{
+ struct kfifo *fifo = NULL;
+ int ret = 0;
+
+ if (!pFifo || !pFifo->pFifoBody) {
+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n",
+ __func__);
+ return -1;
+ }
+
+ fifo = (struct kfifo *)pFifo->pFifoBody;
+
+ if (fifo)
+ ret = kfifo_is_empty(fifo);
+
+ return ret;
+}
+
+int _osal_fifo_is_full(OSAL_FIFO *pFifo)
+{
+ struct kfifo *fifo = NULL;
+ int ret = 0;
+
+ if (!pFifo || !pFifo->pFifoBody) {
+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n",
+ __func__);
+ return -1;
+ }
+
+ fifo = (struct kfifo *)pFifo->pFifoBody;
+
+ if (fifo)
+ ret = kfifo_is_full(fifo);
+
+ return ret;
+}
+
+int _osal_fifo_data_in(OSAL_FIFO *pFifo, const void *buf, unsigned int len)
+{
+ struct kfifo *fifo = NULL;
+ int ret = 0;
+
+ if (!pFifo || !pFifo->pFifoBody) {
+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n",
+ __func__);
+ return -1;
+ }
+
+ fifo = (struct kfifo *)pFifo->pFifoBody;
+
+ if (fifo && buf && (len <= _osal_fifo_avail_size(pFifo))) {
+ ret = kfifo_in(fifo, buf, len);
+ } else {
+ pr_err("%s: kfifo_in, error, len = %d, _osal_fifo_avail_size = %d, buf=%p\n",
+ __func__, len, _osal_fifo_avail_size(pFifo), buf);
+
+ ret = 0;
+ }
+
+ return ret;
+}
+
+int _osal_fifo_data_out(OSAL_FIFO *pFifo, void *buf, unsigned int len)
+{
+ struct kfifo *fifo = NULL;
+ int ret = 0;
+
+ if (!pFifo || !pFifo->pFifoBody) {
+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n"
+ , __func__);
+ return -1;
+ }
+
+ fifo = (struct kfifo *)pFifo->pFifoBody;
+
+ if (fifo && buf && (len <= _osal_fifo_len(pFifo))) {
+ ret = kfifo_out(fifo, buf, len);
+ } else {
+ pr_err("%s: kfifo_out, error, len = %d, osal_fifo_len = %d, buf=%p\n",
+ __func__, len, _osal_fifo_len(pFifo), buf);
+
+ ret = 0;
+ }
+
+ return ret;
+}
+
+int _osal_fifo_reset(OSAL_FIFO *pFifo)
+{
+ struct kfifo *fifo = NULL;
+
+ if (!pFifo || !pFifo->pFifoBody) {
+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n",
+ __func__);
+ return -1;
+ }
+
+ fifo = (struct kfifo *)pFifo->pFifoBody;
+
+ if (fifo)
+ kfifo_reset(fifo);
+
+ return 0;
+}
+
+int osal_fifo_init(P_OSAL_FIFO pFifo, unsigned char *buffer, unsigned int size)
+{
+ if (!pFifo) {
+ pr_err("%s:pFifo = NULL, error\n", __func__);
+ return -1;
+ }
+
+ pFifo->FifoInit = _osal_fifo_init;
+ pFifo->FifoDeInit = _osal_fifo_deinit;
+ pFifo->FifoSz = _osal_fifo_size;
+ pFifo->FifoAvailSz = _osal_fifo_avail_size;
+ pFifo->FifoLen = _osal_fifo_len;
+ pFifo->FifoIsEmpty = _osal_fifo_is_empty;
+ pFifo->FifoIsFull = _osal_fifo_is_full;
+ pFifo->FifoDataIn = _osal_fifo_data_in;
+ pFifo->FifoDataOut = _osal_fifo_data_out;
+ pFifo->FifoReset = _osal_fifo_reset;
+
+ if (pFifo->pFifoBody != NULL) {
+ pr_err("%s:Because pFifo room is avialable, we clear the room and allocate them again.\n", __func__);
+ pFifo->FifoDeInit(pFifo->pFifoBody);
+ pFifo->pFifoBody = NULL;
+ }
+
+ pFifo->FifoInit(pFifo, buffer, size);
+
+ return 0;
+}
+
+void osal_fifo_deinit(P_OSAL_FIFO pFifo)
+{
+ if (pFifo)
+ pFifo->FifoDeInit(pFifo);
+ else {
+ pr_err("%s:pFifo = NULL, error\n", __func__);
+ return;
+ }
+ kfree(pFifo->pFifoBody);
+}
+
+int osal_fifo_reset(P_OSAL_FIFO pFifo)
+{
+ int ret = -1;
+
+ if (pFifo) {
+ ret = pFifo->FifoReset(pFifo);
+ } else {
+ pr_err("%s:pFifo = NULL, error\n", __func__);
+ ret = -1;
+ }
+ return ret;
+}
+
+unsigned int osal_fifo_in(P_OSAL_FIFO pFifo,
+ unsigned char *buffer, unsigned int size)
+{
+ unsigned int ret = 0;
+
+ if (pFifo) {
+ ret = pFifo->FifoDataIn(pFifo, buffer, size);
+ } else {
+ pr_err("%s:pFifo = NULL, error\n", __func__);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+unsigned int osal_fifo_out(P_OSAL_FIFO pFifo,
+ unsigned char *buffer, unsigned int size)
+{
+ unsigned int ret = 0;
+
+ if (pFifo) {
+ ret = pFifo->FifoDataOut(pFifo, buffer, size);
+ } else {
+ pr_err("%s:pFifo = NULL, error\n", __func__);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+unsigned int osal_fifo_len(P_OSAL_FIFO pFifo)
+{
+ unsigned int ret = 0;
+
+ if (pFifo) {
+ ret = pFifo->FifoLen(pFifo);
+ } else {
+ pr_err("%s:pFifo = NULL, error\n", __func__);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+unsigned int osal_fifo_sz(P_OSAL_FIFO pFifo)
+{
+ unsigned int ret = 0;
+
+ if (pFifo) {
+ ret = pFifo->FifoSz(pFifo);
+ } else {
+ pr_err("%s:pFifo = NULL, error\n", __func__);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+unsigned int osal_fifo_avail(P_OSAL_FIFO pFifo)
+{
+ unsigned int ret = 0;
+
+ if (pFifo) {
+ ret = pFifo->FifoAvailSz(pFifo);
+ } else {
+ pr_err("%s:pFifo = NULL, error\n", __func__);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+unsigned int osal_fifo_is_empty(P_OSAL_FIFO pFifo)
+{
+ unsigned int ret = 0;
+
+ if (pFifo) {
+ ret = pFifo->FifoIsEmpty(pFifo);
+ } else {
+ pr_err("%s:pFifo = NULL, error\n", __func__);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+unsigned int osal_fifo_is_full(P_OSAL_FIFO pFifo)
+{
+ unsigned int ret = 0;
+
+ if (pFifo) {
+ ret = pFifo->FifoIsFull(pFifo);
+ } else {
+ pr_err("%s:pFifo = NULL, error\n", __func__);
+ ret = 0;
+ }
+ return ret;
+}
+
+/*
+ * sleepable lock operations APIs
+ * init
+ * lock
+ * unlock
+ * destroy
+ *
+ */
+#if !defined(CONFIG_PROVE_LOCKING)
+int osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK pUSL)
+{
+ spin_lock_init(&(pUSL->lock));
+ return 0;
+}
+#endif
+
+int osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL)
+{
+ spin_lock_irqsave(&(pUSL->lock), pUSL->flag);
+ return 0;
+}
+
+int osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL)
+{
+ spin_unlock_irqrestore(&(pUSL->lock), pUSL->flag);
+ return 0;
+}
+
+int osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK pUSL)
+{
+ return 0;
+}
+
+/*
+ * unsleepable operations APIs
+ * init
+ * lock
+ * unlock
+ * destroy
+ *
+ */
+
+#if !defined(CONFIG_PROVE_LOCKING)
+int osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK pSL)
+{
+ mutex_init(&pSL->lock);
+ return 0;
+}
+#endif
+
+int osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL)
+{
+ return mutex_lock_killable(&pSL->lock);
+}
+
+int osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL)
+{
+ mutex_unlock(&pSL->lock);
+ return 0;
+}
+
+int osal_trylock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL)
+{
+ return mutex_trylock(&pSL->lock);
+}
+
+int osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK pSL)
+{
+ mutex_destroy(&pSL->lock);
+ return 0;
+}
+
+int osal_sleep_ms(unsigned int ms)
+{
+ msleep(ms);
+ return 0;
+}
+
+int osal_udelay(unsigned int us)
+{
+ udelay(us);
+ return 0;
+}
+
+int osal_usleep_range(unsigned long min, unsigned long max)
+{
+ usleep_range(min, max);
+ return 0;
+}
+
+int osal_gettimeofday(int *sec, int *usec)
+{
+ int ret = 0;
+ struct timeval now;
+
+ do_gettimeofday(&now);
+
+ if (sec != NULL)
+ *sec = now.tv_sec;
+ else
+ ret = -1;
+
+ if (usec != NULL)
+ *usec = now.tv_usec;
+ else
+ ret = -1;
+
+ return ret;
+}
+
+void osal_get_local_time(unsigned long long *sec, unsigned long *nsec)
+{
+ if (sec != NULL && nsec != NULL) {
+ *sec = local_clock();
+ *nsec = do_div(*sec, 1000000000)/1000;
+ } else
+ pr_err("The input parameters error when get local time\n");
+}
+
+unsigned long long osal_elapsed_us(unsigned long long ts, unsigned long usec)
+{
+ unsigned long long current_ts = 0;
+ unsigned long current_usec = 0;
+
+ osal_get_local_time(¤t_ts, ¤t_usec);
+ return (current_ts*1000000 + current_usec) - (ts*1000000 + usec);
+}
+
+void osal_buffer_dump(const unsigned char *buf,
+ const unsigned char *title, const unsigned int len,
+ const unsigned int limit)
+{
+ int k;
+ unsigned int dump_len;
+ char str[DBG_LOG_STR_SIZE] = {""};
+ int strlen = 0;
+
+ pr_info("[%s] len=%d, limit=%d, start dump\n", title, len, limit);
+
+ dump_len = ((limit != 0) && (len > limit)) ? limit : len;
+ for (k = 0; k < dump_len; k++) {
+ if ((k+1) % 16 != 0) {
+ strlen += osal_snprintf(str + strlen, DBG_LOG_STR_SIZE - strlen,
+ "%02x ", buf[k]);
+ } else {
+ strlen += osal_snprintf(str + strlen, DBG_LOG_STR_SIZE - strlen,
+ "%02x ", buf[k]);
+
+ pr_info("%s", str);
+ strlen = 0;
+ }
+ }
+ if (k % 16 != 0)
+ pr_info("%s\n", str);
+
+ pr_info("end of dump\n");
+}
+
+void osal_buffer_dump_data(const unsigned int *buf,
+ const unsigned char *title, const unsigned int len,
+ const unsigned int limit,
+ const int flag)
+{
+ int k;
+ unsigned int dump_len;
+ char str[DBG_LOG_STR_SIZE] = {""};
+ int strlen = 0;
+
+ dump_len = ((limit != 0) && (len > limit)) ? limit : len;
+ for (k = 0; k < dump_len; k++) {
+ if (((k+1) % 8 != 0) && (k < (dump_len - 1))) {
+ strlen += osal_snprintf(str + strlen, DBG_LOG_STR_SIZE - strlen,
+ "0x%08x,", buf[k]);
+ } else {
+ strlen += osal_snprintf(str + strlen, DBG_LOG_STR_SIZE - strlen,
+ "0x%08x,", buf[k]);
+ if (flag)
+ osal_ftrace_print("%s%s", title, str);
+ else
+ pr_info("%s%s", title, str);
+ strlen = 0;
+ }
+ }
+ if (k % 8 != 0) {
+ if (flag)
+ osal_ftrace_print("%s%s", title, str);
+ else
+ pr_info("%s%s", title, str);
+ }
+}
+
+unsigned int osal_op_get_id(P_OSAL_OP pOp)
+{
+ return (pOp) ? pOp->op.opId : 0xFFFFFFFF;
+}
+
+MTK_CONN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp)
+{
+ return (pOp && pOp->signal.timeoutValue)
+ ? MTK_CONN_BOOL_TRUE : MTK_CONN_BOOL_FALSE;
+}
+
+void osal_op_raise_signal(P_OSAL_OP pOp, int result)
+{
+ if (pOp) {
+ pOp->result = result;
+ osal_raise_signal(&pOp->signal);
+ }
+}
+
+int osal_ftrace_print(const char *str, ...)
+{
+#ifdef CONFIG_TRACING
+ va_list args;
+ char tempString[DBG_LOG_STR_SIZE];
+
+ if (ftrace_flag) {
+ va_start(args, str);
+ vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args);
+ va_end(args);
+
+ trace_printk("%s\n", tempString);
+ }
+#endif
+ return 0;
+}
+
+int osal_ftrace_print_ctrl(int flag)
+{
+#ifdef CONFIG_TRACING
+ if (flag)
+ ftrace_flag = 1;
+ else
+ ftrace_flag = 0;
+#endif
+ return 0;
+}
+
+void osal_set_op_result(P_OSAL_OP pOp, int result)
+{
+ if (pOp)
+ pOp->result = result;
+
+}
+
+static void _osal_opq_dump(const char *qName, P_OSAL_OP_Q pOpQ)
+{
+ /* Line format:
+ * [LogicalIdx(PhysicalIdx)]Address:OpId(Ref)(Result)-Info-OpData0,OpData1,OpData2,OpData3,OpData5_
+ * [LogicalIdx] max 10+2=12 chars (decimal)
+ * (PhysicalIdx) max 10+2=12 chars (decimal)
+ * Address: max 16+1=17 chars (hex)
+ * OpId max 10 chars (decimal)
+ * (Ref) max 2+2=4 chars (should only be 1 digit, reserve 2 in case of negative number)
+ * (Result) max 11+2=13 chars (signed decimal)
+ * -Info- max 8+2=10 chars (hex)
+ * OpData, max 16+1=17 chars (hex)
+ */
+#define OPQ_DUMP_OP_PER_LINE 1
+#define OPQ_DUMP_OPDATA_PER_OP 6
+#define OPQ_DUMP_OP_BUF_SIZE (12 + 12 + 17 + 10 + 4 + 13 + 10 + (17 * (OPQ_DUMP_OPDATA_PER_OP)) + 1)
+#define OPQ_DUMP_LINE_BUF_SIZE ((OPQ_DUMP_OP_BUF_SIZE * OPQ_DUMP_OP_PER_LINE) + 1)
+ unsigned int rd;
+ unsigned int wt;
+ unsigned int idx = 0;
+ unsigned int opDataIdx;
+ unsigned int idxInBuf;
+ int printed;
+ P_OSAL_OP op;
+ char buf[OPQ_DUMP_LINE_BUF_SIZE];
+
+ rd = pOpQ->read;
+ wt = pOpQ->write;
+
+ pr_info("%s(%p), sz:%u/%u, rd:%u, wt:%u\n",
+ qName, pOpQ, RB_COUNT(pOpQ), RB_SIZE(pOpQ), rd, wt);
+ while (rd != wt && idx < RB_SIZE(pOpQ)) {
+ idxInBuf = idx % OPQ_DUMP_OP_PER_LINE;
+ op = pOpQ->queue[rd & RB_MASK(pOpQ)];
+
+ if (idxInBuf == 0) {
+ printed = 0;
+ buf[0] = 0;
+ }
+
+ if (op) {
+ printed += snprintf(buf + printed, OPQ_DUMP_LINE_BUF_SIZE - printed,
+ "[%u(%u)]%p:%u(%d)(%d)-%u-",
+ idx,
+ (rd & RB_MASK(pOpQ)),
+ op,
+ op->op.opId,
+ atomic_read(&op->ref_count),
+ op->result,
+ op->op.u4InfoBit);
+ for (opDataIdx = 0; opDataIdx < OPQ_DUMP_OPDATA_PER_OP; opDataIdx++)
+ printed += snprintf(buf + printed, OPQ_DUMP_LINE_BUF_SIZE - printed,
+ "%zx,", op->op.au4OpData[opDataIdx]);
+ buf[printed-1] = ' ';
+ } else {
+ printed += snprintf(buf + printed, OPQ_DUMP_LINE_BUF_SIZE - printed,
+ "[%u(%u)]%p ", idx, (rd & RB_MASK(pOpQ)), op);
+ }
+ buf[printed++] = ' ';
+
+ if (idxInBuf == OPQ_DUMP_OP_PER_LINE - 1 || rd == wt - 1) {
+ buf[printed - 1] = 0;
+ pr_info("%s\n", buf);
+ }
+ rd++;
+ idx++;
+ }
+}
+
+void osal_opq_dump(const char *qName, P_OSAL_OP_Q pOpQ)
+{
+ int err;
+
+ err = osal_lock_sleepable_lock(&pOpQ->sLock);
+ if (err) {
+ pr_info("Failed to lock queue (%d)\n", err);
+ return;
+ }
+
+ _osal_opq_dump(qName, pOpQ);
+
+ osal_unlock_sleepable_lock(&pOpQ->sLock);
+}
+
+void osal_opq_dump_locked(const char *qName, P_OSAL_OP_Q pOpQ)
+{
+ _osal_opq_dump(qName, pOpQ);
+}
+
+MTK_CONN_BOOL osal_opq_has_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp)
+{
+ unsigned int rd;
+ unsigned int wt;
+ P_OSAL_OP op;
+
+ rd = pOpQ->read;
+ wt = pOpQ->write;
+
+ while (rd != wt) {
+ op = pOpQ->queue[rd & RB_MASK(pOpQ)];
+ if (op == pOp)
+ return MTK_CONN_BOOL_TRUE;
+ rd++;
+ }
+ return MTK_CONN_BOOL_FALSE;
+}
+
+static void osal_op_history_print_work(struct work_struct *work)
+{
+ struct osal_op_history *log_history
+ = container_of(work, struct osal_op_history, dump_work);
+ struct ring *ring_buffer = &log_history->dump_ring_buffer;
+ struct ring_segment seg;
+ struct osal_op_history_entry *queue = ring_buffer->base;
+ struct osal_op_history_entry *entry;
+ int index = 0;
+
+ if (queue == NULL) {
+ pr_info("queue shouldn't be NULL, %s", log_history->name);
+ return;
+ }
+
+ if (RING_EMPTY(ring_buffer))
+ pr_info("History of %s is empty.\n", log_history->name);
+
+ RING_READ_FOR_EACH_ITEM(RING_SIZE(ring_buffer), seg, ring_buffer) {
+ index = seg.ring_pt - ring_buffer->base;
+ entry = &queue[index];
+ pr_info("(%llu.%06lu) %s: pOp(%p):%u(%d)-%x-%zx,%zx,%zx,%zx\n",
+ entry->ts,
+ entry->usec,
+ log_history->name,
+ entry->opbuf_address,
+ entry->op_id,
+ entry->opbuf_ref_count,
+ entry->op_info_bit,
+ entry->param_0,
+ entry->param_1,
+ entry->param_2,
+ entry->param_3);
+ }
+ kfree(queue);
+ ring_buffer->base = NULL;
+}
+
+void osal_op_history_init(struct osal_op_history *log_history, int queue_size)
+{
+ int size = queue_size * sizeof(struct osal_op_history_entry);
+
+ spin_lock_init(&(log_history->lock));
+
+ log_history->queue = kzalloc(size, GFP_ATOMIC);
+ if (log_history->queue == NULL)
+ return;
+
+ /* queue_size must be power of 2 */
+ ring_init(
+ &log_history->queue,
+ queue_size,
+ 0,
+ 0,
+ &log_history->ring_buffer);
+
+ INIT_WORK(&log_history->dump_work, osal_op_history_print_work);
+}
+
+void osal_op_history_print(struct osal_op_history *log_history, char *name)
+{
+ struct osal_op_history_entry *queue;
+ struct ring *ring_buffer, *dump_ring_buffer;
+ int queue_size;
+ unsigned long flags;
+ struct work_struct *work = &log_history->dump_work;
+ spinlock_t *lock = &(log_history->lock);
+
+ if (log_history->queue == NULL) {
+ pr_info("Queue is NULL, name: %s\n", name);
+ return;
+ }
+
+ ring_buffer = &log_history->ring_buffer;
+ queue_size = sizeof(struct osal_op_history_entry)
+ * RING_SIZE(ring_buffer);
+
+ /* Allocate memory before getting lock to save time of holding lock */
+ queue = kmalloc(queue_size, GFP_KERNEL);
+ if (queue == NULL)
+ return;
+
+ dump_ring_buffer = &log_history->dump_ring_buffer;
+
+ spin_lock_irqsave(lock, flags);
+ if (dump_ring_buffer->base != NULL) {
+ spin_unlock_irqrestore(lock, flags);
+ kfree(queue);
+ pr_info("print is ongoing: %s\n", name);
+ return;
+ }
+
+ osal_snprintf(log_history->name, sizeof(log_history->name), "%s", name);
+ osal_memcpy(queue, log_history->queue, queue_size);
+ osal_memcpy(dump_ring_buffer, ring_buffer, sizeof(struct ring));
+ /* assign value to base after memory copy */
+ dump_ring_buffer->base = queue;
+ spin_unlock_irqrestore(lock, flags);
+ schedule_work(work);
+}
+
+void osal_op_history_save(struct osal_op_history *log_history, P_OSAL_OP pOp)
+{
+ struct osal_op_history_entry *entry = NULL;
+ struct ring_segment seg;
+ int index;
+ unsigned long long sec = 0;
+ unsigned long usec = 0;
+ unsigned long flags;
+
+ if (log_history->queue == NULL)
+ return;
+
+ osal_get_local_time(&sec, &usec);
+
+ spin_lock_irqsave(&(log_history->lock), flags);
+ RING_OVERWRITE_FOR_EACH(1, seg, &log_history->ring_buffer) {
+ index = seg.ring_pt - log_history->ring_buffer.base;
+ entry = &log_history->queue[index];
+ }
+
+ if (entry == NULL) {
+ pr_info("Entry is null, size %d\n",
+ RING_SIZE(&log_history->ring_buffer));
+ spin_unlock_irqrestore(&(log_history->lock), flags);
+ return;
+ }
+
+ entry->opbuf_address = pOp;
+ entry->op_id = pOp->op.opId;
+ entry->opbuf_ref_count = atomic_read(&pOp->ref_count);
+ entry->op_info_bit = pOp->op.u4InfoBit;
+ entry->param_0 = pOp->op.au4OpData[0];
+ entry->param_1 = pOp->op.au4OpData[1];
+ entry->param_2 = pOp->op.au4OpData[2];
+ entry->param_3 = pOp->op.au4OpData[3];
+ entry->ts = sec;
+ entry->usec = usec;
+ spin_unlock_irqrestore(&(log_history->lock), flags);
+}
+
+static inline void osal_systrace_prepare(void)
+{
+ if (unlikely(mark_addr == 0))
+ mark_addr = kallsyms_lookup_name("tracing_mark_write");
+ if (unlikely(g_pid == 0))
+ g_pid = task_pid_nr(current);
+}
+
+static void osal_systrace_b(const char *log)
+{
+ osal_systrace_prepare();
+ preempt_disable();
+ KERNEL_event_trace_printk(mark_addr, "B|%d|%s\n", g_pid, log);
+ preempt_enable();
+}
+
+
+static void osal_systrace_e(void)
+{
+ preempt_disable();
+ KERNEL_event_trace_printk(mark_addr, "E\n");
+ preempt_enable();
+}
+
+static void osal_systrace_c(int val, const char *log)
+{
+ osal_systrace_prepare();
+ preempt_disable();
+ KERNEL_event_trace_printk(mark_addr, "C|%d|%s|%d\n", g_pid, log, val);
+ preempt_enable();
+}
+
+void osal_systrace_major_b(const char *fmt, ...)
+{
+ char log[DBG_LOG_STR_SIZE];
+ va_list args;
+
+ memset(log, ' ', sizeof(log));
+ va_start(args, fmt);
+ vsnprintf(log, sizeof(log), fmt, args);
+ va_end(args);
+ osal_systrace_b(log);
+}
+
+void osal_systrace_major_e(void)
+{
+ osal_systrace_e();
+}
+
+void osal_systrace_minor_b(const char *fmt, ...)
+{
+ char log[DBG_LOG_STR_SIZE];
+ va_list args;
+
+ if (!ftrace_flag)
+ return;
+
+ memset(log, ' ', sizeof(log));
+ va_start(args, fmt);
+ vsnprintf(log, sizeof(log), fmt, args);
+ va_end(args);
+ osal_systrace_b(log);
+
+}
+
+void osal_systrace_minor_e(void)
+{
+ if (!ftrace_flag)
+ return;
+ osal_systrace_e();
+}
+
+void osal_systrace_minor_c(int val, const char *fmt, ...)
+{
+ char log[DBG_LOG_STR_SIZE];
+ va_list args;
+
+ if (!ftrace_flag)
+ return;
+
+ memset(log, ' ', sizeof(log));
+ va_start(args, fmt);
+ vsnprintf(log, sizeof(log), fmt, args);
+ va_end(args);
+ osal_systrace_c(val, log);
+}
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/base/ring.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/base/ring.c
new file mode 100755
index 0000000..e563760
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/base/ring.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+#include "ring.h"
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/bug.h>
+
+
+
+void ring_init(void *base, unsigned int max_size, unsigned int read,
+ unsigned int write, struct ring *ring)
+{
+ WARN_ON(!base);
+
+ /* making sure max_size is power of 2 */
+ WARN_ON(!max_size || (max_size & (max_size - 1)));
+
+ /* making sure write largger than read */
+ WARN_ON(read > write);
+
+ ring->base = base;
+ ring->read = read;
+ ring->write = write;
+ ring->max_size = max_size;
+}
+
+void ring_dump(const char *title, struct ring *ring)
+{
+ pr_info("[%s] ring:{write=%d, read=%d, max_size=%d}\n",
+ title, ring->write, ring->read, ring->max_size);
+}
+
+void ring_dump_segment(const char *title, struct ring_segment *seg)
+{
+ pr_info("[%s] seg:{ring_pt=0x%p, data_pos=%d, sz=%d, remain=%d}\n",
+ title, seg->ring_pt, seg->data_pos,
+ seg->sz, seg->remain);
+}
+
+/*
+ * Function prepares the ring_segment and
+ * returns the number of valid bytes for read.
+ */
+unsigned int ring_read_prepare(unsigned int sz,
+ struct ring_segment *seg,
+ struct ring *ring)
+{
+ unsigned int wt = ring->write;
+ unsigned int rd = ring->read;
+
+ memset(seg, 0, sizeof(struct ring_segment));
+ if (sz > wt - rd)
+ sz = wt - rd;
+ seg->remain = sz;
+ /* ring_dump(__func__, ring); */
+ /* ring_dump_segment(__func__, seg); */
+ return seg->remain;
+}
+
+/*
+ * Function prepares the ring_segment and
+ * returns the number of bytes available for write.
+ */
+unsigned int ring_write_prepare(unsigned int sz,
+ struct ring_segment *seg,
+ struct ring *ring)
+{
+ unsigned int wt = ring->write;
+ unsigned int rd = ring->read;
+
+ memset(seg, 0, sizeof(struct ring_segment));
+ if (sz > ring->max_size - (wt - rd))
+ sz = ring->max_size - (wt - rd);
+ seg->remain = sz;
+ /* ring_dump(__func__, ring); */
+ /* ring_dump_segment(__func__, seg); */
+ return seg->remain;
+}
+
+unsigned int ring_overwrite_prepare(unsigned int sz, struct ring_segment *seg,
+ struct ring *ring)
+{
+ unsigned int wt = ring->write;
+ unsigned int rd = ring->read;
+
+ memset(seg, 0, sizeof(struct ring_segment));
+ if (sz > ring->max_size - (wt - rd))
+ ring->read += sz - (ring->max_size - (wt - rd));
+ seg->remain = sz;
+ /* ring_dump(__func__, ring); */
+ /* ring_dump_segment(__func__, seg); */
+ return seg->remain;
+}
+
+void __ring_segment_prepare(unsigned int from, unsigned int sz,
+ struct ring_segment *seg,
+ struct ring *ring)
+{
+ unsigned int ring_pos = from & (ring->max_size - 1);
+
+ seg->ring_pt = ring->base + ring_pos;
+ seg->data_pos = (seg->sz ? seg->data_pos + seg->sz : 0);
+ if (ring_pos + sz <= ring->max_size)
+ seg->sz = sz;
+ else
+ seg->sz = ring->max_size - ring_pos;
+ seg->remain -= seg->sz;
+ /* ring_dump(__func__, ring); */
+ /* ring_dump_segment(__func__, seg); */
+}
+
+void _ring_segment_prepare(unsigned int from,
+ struct ring_segment *seg,
+ struct ring *ring)
+{
+ __ring_segment_prepare(from, seg->remain, seg, ring);
+}
+
+void _ring_segment_prepare_item(unsigned int from,
+ struct ring_segment *seg,
+ struct ring *ring)
+{
+ unsigned int size;
+
+ size = (seg->remain ? 1 : 0);
+ __ring_segment_prepare(from, size, seg, ring);
+}
+
+void _ring_read_commit(struct ring_segment *seg, struct ring *ring)
+{
+ ring->read += seg->sz;
+ /* ring_dump(__func__, ring); */
+ /* ring_dump_segment(__func__, seg); */
+}
+void _ring_write_commit(struct ring_segment *seg, struct ring *ring)
+{
+ ring->write += seg->sz;
+ /* ring_dump(__func__, ring); */
+ /* ring_dump_segment(__func__, seg); */
+}
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/conf/conninfra_conf.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/conf/conninfra_conf.c
new file mode 100755
index 0000000..e333e98
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/conf/conninfra_conf.c
@@ -0,0 +1,634 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__
+
+#include <linux/firmware.h>
+#include "conninfra_conf.h"
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+struct parse_data {
+ char *name;
+ int (*parser)(const struct parse_data *data, const char *value);
+ char *(*writer)(const struct parse_data *data);
+ void (*relase_mem)(const struct parse_data *data);
+ /*PCHAR param1, *param2, *param3; */
+ /* TODO:[FixMe][George] CLARIFY WHAT SHOULD BE USED HERE!!! */
+ char *param1;
+ char *param2;
+ char *param3;
+};
+
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+struct conninfra_conf g_conninfra_conf;
+
+/******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+*******************************************************************************
+*/
+static int conf_parse_char(const struct parse_data *data, const char *pos);
+
+static char *conf_write_char(const struct parse_data *data);
+
+static int conf_parse_short(const struct parse_data *data, const char *pos);
+
+static char *conf_write_short(const struct parse_data *data);
+
+static int conf_parse_int(const struct parse_data *data, const char *pos);
+
+static char *conf_write_int(const struct parse_data *data);
+
+static int conf_parse_byte_array(const struct parse_data *data,
+ const char *pos);
+
+static char *conf_write_byte_array(const struct parse_data *data);
+
+static void conf_release_byte_array(const struct parse_data *data);
+
+static int conf_parse_pair(const char *key, const char *pVal);
+
+static int conf_parse(const char *pInBuf, unsigned int size);
+
+//#define OFFSET(v) ((void *) &((struct conninfra_conf*) 0)->v)
+
+#define CHAR(f) {#f, conf_parse_char, conf_write_char, NULL, (char *)&g_conninfra_conf.f, NULL, NULL}
+
+#define SHORT(f) {#f, conf_parse_short, conf_write_short, NULL, (char *)&g_conninfra_conf.f, NULL, NULL}
+
+#define INT(f) {#f, conf_parse_int, conf_write_int, NULL, (char *)&g_conninfra_conf.f, NULL, NULL}
+
+#define BYTE_ARRAY(f) {#f, conf_parse_byte_array, conf_write_byte_array, conf_release_byte_array,\
+ (char *)&g_conninfra_conf.f, NULL, NULL}
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+static const struct parse_data cfg_fields[] = {
+ CHAR(coex_wmt_ant_mode),
+ CHAR(coex_wmt_ant_mode_ex),
+ CHAR(coex_wmt_ext_component),
+ CHAR(coex_wmt_wifi_time_ctl),
+ CHAR(coex_wmt_ext_pta_dev_on),
+ CHAR(coex_wmt_filter_mode),
+
+ CHAR(coex_bt_rssi_upper_limit),
+ CHAR(coex_bt_rssi_mid_limit),
+ CHAR(coex_bt_rssi_lower_limit),
+ CHAR(coex_bt_pwr_high),
+ CHAR(coex_bt_pwr_mid),
+ CHAR(coex_bt_pwr_low),
+
+ CHAR(coex_wifi_rssi_upper_limit),
+ CHAR(coex_wifi_rssi_mid_limit),
+ CHAR(coex_wifi_rssi_lower_limit),
+ CHAR(coex_wifi_pwr_high),
+ CHAR(coex_wifi_pwr_mid),
+ CHAR(coex_wifi_pwr_low),
+
+ CHAR(coex_ext_pta_hi_tx_tag),
+ CHAR(coex_ext_pta_hi_rx_tag),
+ CHAR(coex_ext_pta_lo_tx_tag),
+ CHAR(coex_ext_pta_lo_rx_tag),
+ SHORT(coex_ext_pta_sample_t1),
+ SHORT(coex_ext_pta_sample_t2),
+ CHAR(coex_ext_pta_wifi_bt_con_trx),
+
+ INT(coex_misc_ext_pta_on),
+ INT(coex_misc_ext_feature_set),
+
+ CHAR(wmt_gps_lna_pin),
+ CHAR(wmt_gps_lna_enable),
+
+ CHAR(pwr_on_rtc_slot),
+ CHAR(pwr_on_ldo_slot),
+ CHAR(pwr_on_rst_slot),
+ CHAR(pwr_on_off_slot),
+ CHAR(pwr_on_on_slot),
+ CHAR(co_clock_flag),
+
+ CHAR(disable_deep_sleep_cfg),
+
+ INT(sdio_driving_cfg),
+
+ SHORT(coex_wmt_wifi_path),
+
+ CHAR(coex_wmt_ext_elna_gain_p1_support),
+ INT(coex_wmt_ext_elna_gain_p1_D0),
+ INT(coex_wmt_ext_elna_gain_p1_D1),
+ INT(coex_wmt_ext_elna_gain_p1_D2),
+ INT(coex_wmt_ext_elna_gain_p1_D3),
+
+ BYTE_ARRAY(coex_wmt_epa_elna),
+
+ CHAR(bt_tssi_from_wifi),
+ SHORT(bt_tssi_target),
+
+ CHAR(coex_config_bt_ctrl),
+ CHAR(coex_config_bt_ctrl_mode),
+ CHAR(coex_config_bt_ctrl_rw),
+
+ CHAR(coex_config_addjust_opp_time_ratio),
+ CHAR(coex_config_addjust_opp_time_ratio_bt_slot),
+ CHAR(coex_config_addjust_opp_time_ratio_wifi_slot),
+
+ CHAR(coex_config_addjust_ble_scan_time_ratio),
+ CHAR(coex_config_addjust_ble_scan_time_ratio_bt_slot),
+ CHAR(coex_config_addjust_ble_scan_time_ratio_wifi_slot),
+ CHAR(tcxo_gpio),
+};
+
+#define NUM_CFG_FIELDS (osal_sizeof(cfg_fields) / osal_sizeof(cfg_fields[0]))
+
+static int conf_parse_char(const struct parse_data *data, const char *pos)
+{
+ char *dst;
+ long res = 0;
+
+ dst = (char *)(data->param1);
+
+ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) {
+ osal_strtol(pos + 2, 16, &res);
+ *dst = (char)res;
+ pr_debug("cfg==> %s=0x%x\n", data->name, *dst);
+ } else {
+ osal_strtol(pos, 10, &res);
+ *dst = (char)res;
+ pr_debug("cfg==> %s=%d\n", data->name, *dst);
+ }
+ return 0;
+}
+
+static char *conf_write_char(const struct parse_data *data)
+{
+ char *src;
+ int res;
+ char *value;
+
+ src = data->param1;
+
+ value = osal_malloc(20);
+ if (value == NULL)
+ return NULL;
+ res = osal_snprintf(value, 20, "0x%x", *src);
+ if (res < 0 || res >= 20) {
+ osal_free(value);
+ return NULL;
+ }
+ value[20 - 1] = '\0';
+ return value;
+}
+
+static int conf_parse_short(const struct parse_data *data, const char *pos)
+{
+ unsigned short *dst;
+ long res = 0;
+
+ dst = (unsigned short *)data->param1;
+
+ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) {
+ osal_strtol(pos + 2, 16, &res);
+ *dst = (unsigned short)res;
+ pr_debug("cfg==> %s=0x%x\n", data->name, *dst);
+ } else {
+ osal_strtol(pos, 10, &res);
+ *dst = (unsigned short)res;
+ pr_debug("cfg==> %s=%d\n", data->name, *dst);
+ }
+
+ return 0;
+}
+
+static char *conf_write_short(const struct parse_data *data)
+{
+ short *src;
+ int res;
+ char *value;
+
+ /* TODO: [FixMe][George] FIX COMPILE WARNING HERE! */
+ src = (short *)data->param1;
+
+ value = osal_malloc(20);
+ if (value == NULL)
+ return NULL;
+ res = osal_snprintf(value, 20, "0x%x", *src);
+ if (res < 0 || res >= 20) {
+ osal_free(value);
+ return NULL;
+ }
+ value[20 - 1] = '\0';
+ return value;
+}
+
+static int conf_parse_int(const struct parse_data *data, const char *pos)
+{
+ int *dst;
+ long res = 0;
+
+ dst = (int *)data->param1;
+
+ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) {
+ osal_strtol(pos + 2, 16, &res);
+ *dst = (unsigned int)res;
+ pr_debug("cfg==> %s=0x%x\n", data->name, *dst);
+ } else {
+ osal_strtol(pos, 10, &res);
+ *dst = (unsigned int)res;
+ pr_debug("cfg==> %s=%d\n", data->name, *dst);
+ }
+
+ return 0;
+}
+
+static char *conf_write_int(const struct parse_data *data)
+{
+ int *src;
+ int res;
+ char *value;
+
+ src = (unsigned int *) data->param1;
+
+ value = osal_malloc(20);
+ if (value == NULL)
+ return NULL;
+ res = osal_snprintf(value, 20, "0x%x", *src);
+ if (res < 0 || res >= 20) {
+ osal_free(value);
+ return NULL;
+ }
+ value[20 - 1] = '\0';
+ return value;
+}
+
+static int conf_parse_byte_array(const struct parse_data *data,
+ const char *pos)
+{
+ unsigned char **dst;
+ struct conf_byte_ary *ba;
+ unsigned char *buffer;
+ int size = osal_strlen(pos) / 2;
+ unsigned char temp[3];
+ int i;
+ long value;
+
+ if (size <= 1) {
+ pr_err("cfg==> %s has no value assigned\n",
+ data->name);
+ return -1;
+ } else if (size & 0x1) {
+ pr_debug("cfg==> %s, length should be even\n", data->name);
+ return -1;
+ }
+
+ ba = (struct conf_byte_ary *)osal_malloc(sizeof(struct conf_byte_ary));
+ if (ba == NULL) {
+ pr_err("cfg==> %s malloc fail\n", data->name);
+ return -1;
+ }
+
+ buffer = osal_malloc(size);
+ if (buffer == NULL) {
+ osal_free(ba);
+ pr_err("cfg==> %s malloc fail, size %d\n", data->name, size);
+ return -1;
+ }
+
+ temp[2] = '\0';
+ for (i = 0; i < size; i++) {
+ osal_memcpy(temp, &pos[i * 2], 2);
+ if (osal_strtol(temp, 16, &value) < 0) {
+ pr_err("cfg==> %s should be hexadecimal format\n",
+ data->name);
+ osal_free(ba);
+ osal_free(buffer);
+ return -1;
+ }
+ buffer[i] = (char)value;
+ }
+ ba->data = buffer;
+ ba->size = size;
+
+ dst = (unsigned char **) data->param1;
+ *dst = (unsigned char *)ba;
+
+ return 0;
+}
+
+static char *conf_write_byte_array(const struct parse_data *data)
+{
+ unsigned char **src;
+ char *value;
+ struct conf_byte_ary *ba;
+ int i;
+
+ src = (unsigned char **) data->param1;
+ if (*src == NULL)
+ return NULL;
+
+ ba = (struct conf_byte_ary *)*src;
+
+ value = osal_malloc(ba->size * 2 + 1);
+ if (value == NULL)
+ return NULL;
+
+ for (i = 0; i < ba->size; i++)
+ osal_snprintf(&value[i * 2], 3, "%x", ba->data[i]);
+
+ return value;
+}
+
+
+static void conf_release_byte_array(const struct parse_data *data)
+{
+ //unsigned char *buffer;
+ struct conf_byte_ary *ba;
+ unsigned char **src;
+
+ if (data->param1 != NULL) {
+ src = (unsigned char **) data->param1;
+ ba = (struct conf_byte_ary *) *src;
+ if (ba->data != NULL) {
+ osal_free(ba->data);
+ ba->data = NULL;
+ }
+ osal_free(ba);
+ //data->param1 = NULL;
+ *src = NULL;
+ }
+}
+
+static int conf_parse_pair(const char *pKey, const char *pVal)
+{
+ int i = 0;
+ int ret = 0;
+
+
+ for (i = 0; i < NUM_CFG_FIELDS; i++) {
+ const struct parse_data *field = &cfg_fields[i];
+
+ if (osal_strcmp(pKey, field->name) != 0)
+ continue;
+ if (field->parser(field, pVal)) {
+ pr_err("failed to parse %s '%s'.\n", pKey, pVal);
+ ret = -1;
+ }
+ break;
+ }
+ if (i == NUM_CFG_FIELDS) {
+ pr_err("unknown field '%s'.\n", pKey);
+ ret = -1;
+ }
+
+ return ret;
+}
+
+static int conf_parse(const char *pInBuf, unsigned int size)
+{
+ char *pch;
+ char *pBuf;
+ char *pLine;
+ char *pKey;
+ char *pVal;
+ char *pPos;
+ int ret = 0;
+ int i = 0;
+ char *pa = NULL;
+
+ pBuf = osal_malloc(size+1);
+ if (!pBuf)
+ return -1;
+
+ osal_memcpy(pBuf, pInBuf, size);
+ pBuf[size] = '\0';
+
+ pch = pBuf;
+ /* pch is to be updated by strsep(). Keep pBuf unchanged!! */
+
+ while ((pLine = osal_strsep(&pch, "\r\n")) != NULL) {
+ /* pch is updated to the end of pLine by
+ * strsep() and updated to '\0'
+ */
+ /* parse each line */
+
+ if (!*pLine)
+ continue;
+
+ pVal = osal_strchr(pLine, '=');
+ if (!pVal) {
+ pr_warn("mal-format cfg string(%s)\n", pLine);
+ continue;
+ }
+
+ /* |<-pLine->|'='<-pVal->|'\n' ('\0')| */
+ *pVal = '\0'; /* replace '=' with '\0' to get key */
+ /* |<-pKey->|'\0'|<-pVal->|'\n' ('\0')| */
+ pKey = pLine;
+
+ if ((pVal - pBuf) < size)
+ pVal++;
+
+ /*key handling */
+ pPos = pKey;
+ /*skip space characeter */
+ while (((*pPos) == ' ') ||
+ ((*pPos) == '\t') || ((*pPos) == '\n')) {
+ if ((pPos - pBuf) >= size)
+ break;
+ pPos++;
+ }
+ /*key head */
+ pKey = pPos;
+ while (((*pPos) != ' ') &&
+ ((*pPos) != '\t') && ((*pPos) != '\0')
+ && ((*pPos) != '\n')) {
+ if ((pPos - pBuf) >= size)
+ break;
+ pPos++;
+ }
+ /*key tail */
+ (*pPos) = '\0';
+
+ /*value handling */
+ pPos = pVal;
+ /*skip space characeter */
+ while (((*pPos) == ' ') ||
+ ((*pPos) == '\t') || ((*pPos) == '\n')) {
+ if ((pPos - pBuf) >= size)
+ break;
+ pPos++;
+ }
+ /*value head */
+ pVal = pPos;
+ while (((*pPos) != ' ') &&
+ ((*pPos) != '\t') && ((*pPos) != '\0')
+ && ((*pPos) != '\n')) {
+ if ((pPos - pBuf) >= size)
+ break;
+ pPos++;
+ }
+ /*value tail */
+ (*pPos) = '\0';
+
+ ret = conf_parse_pair(pKey, pVal);
+ pr_debug("parse (%s, %s, %d)\n", pKey, pVal, ret);
+ if (ret)
+ pr_debug("parse fail (%s, %s, %d)\n", pKey, pVal, ret);
+ }
+
+ for (i = 0; i < NUM_CFG_FIELDS; i++) {
+ const struct parse_data *field = &cfg_fields[i];
+
+ pa = field->writer(field);
+ if (pa) {
+ pr_debug("#%d(%s)=>%s\n", i, field->name, pa);
+ osal_free(pa);
+ } else
+ pr_err("failed to parse '%s'.\n", field->name);
+ }
+ osal_free(pBuf);
+ return 0;
+}
+
+static int platform_request_firmware(char *patch_name, osal_firmware **ppPatch)
+{
+ int ret;
+ osal_firmware *fw = NULL;
+
+ if (!ppPatch) {
+ pr_err("invalid ppBufptr!\n");
+ return -1;
+ }
+
+ *ppPatch = NULL;
+ do {
+ ret = request_firmware((const struct firmware **)&fw,
+ patch_name, NULL);
+ if (ret == -EAGAIN) {
+ pr_err("failed to open or read!(%s), retry again!\n",
+ patch_name);
+ osal_sleep_ms(100);
+ }
+ } while (ret == -EAGAIN);
+ if (ret != 0) {
+ pr_err("failed to open or read!(%s)\n", patch_name);
+ release_firmware(fw);
+ return -1;
+ }
+ pr_debug("loader firmware %s ok!!\n", patch_name);
+ ret = 0;
+ *ppPatch = fw;
+
+ return ret;
+}
+
+static int platform_release_firmware(osal_firmware **ppPatch)
+{
+ if (*ppPatch != NULL) {
+ release_firmware((const struct firmware *)*ppPatch);
+ *ppPatch = NULL;
+ }
+ return 0;
+}
+
+int conninfra_conf_init(void)
+{
+ int ret = -1;
+ const osal_firmware *conf_inst;
+
+ osal_memset(&g_conninfra_conf, 0, osal_sizeof(struct conninfra_conf));
+ osal_strcpy(&(g_conninfra_conf.conf_name[0]), "conninfra.cfg");
+
+ pr_debug("config file:%s\n", &(g_conninfra_conf.conf_name[0]));
+ if (0 ==
+ platform_request_firmware(&g_conninfra_conf.conf_name[0],
+ (osal_firmware **) &conf_inst)) {
+ /*get full name patch success */
+ pr_debug("get full file name(%s) buf(0x%p) size(%zu)\n",
+ &g_conninfra_conf.conf_name[0], conf_inst->data,
+ conf_inst->size);
+ if (0 ==
+ conf_parse((const char *)conf_inst->data,
+ conf_inst->size)) {
+ /*config file exists */
+ g_conninfra_conf.cfg_exist = 1;
+ ret = 0;
+ } else {
+ pr_err("conf parsing fail\n");
+ ret = -1;
+ }
+ platform_release_firmware((osal_firmware **) &conf_inst);
+ return ret;
+ }
+ pr_err("read %s file fails\n", &(g_conninfra_conf.conf_name[0]));
+ g_conninfra_conf.cfg_exist = 0;
+ return ret;
+}
+
+int conninfra_conf_set_cfg_file(const char *name)
+{
+ if (name == NULL) {
+ pr_err("name is NULL\n");
+ return -1;
+ }
+ if (osal_strlen(name) >= osal_sizeof(g_conninfra_conf.conf_name)) {
+ pr_err("name is too long, length=%d, expect to < %zu\n",
+ osal_strlen(name),
+ osal_sizeof(g_conninfra_conf.conf_name));
+ return -2;
+ }
+ osal_memset(&g_conninfra_conf.conf_name[0], 0,
+ osal_sizeof(g_conninfra_conf.conf_name));
+ osal_strcpy(&(g_conninfra_conf.conf_name[0]), name);
+ pr_err("WMT config file is set to (%s)\n",
+ &(g_conninfra_conf.conf_name[0]));
+
+ return 0;
+}
+
+const struct conninfra_conf *conninfra_conf_get_cfg(void)
+{
+ if (g_conninfra_conf.cfg_exist == 0)
+ return NULL;
+
+ return &g_conninfra_conf;
+}
+
+int conninfra_conf_deinit(void)
+{
+ int i;
+
+ if (g_conninfra_conf.cfg_exist == 0)
+ return -1;
+
+ for (i = 0; i < NUM_CFG_FIELDS; i++) {
+ const struct parse_data *field = &cfg_fields[i];
+ field->relase_mem(field);
+ }
+ g_conninfra_conf.cfg_exist = 0;
+ return 0;
+}
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/conf/include/conninfra_conf.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/conf/include/conninfra_conf.h
new file mode 100755
index 0000000..4e49b3b
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/conf/include/conninfra_conf.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+
+
+#ifndef _CONNINFRA_CONF_H_
+#define _CONNINFRA_CONF_H_
+
+#include "osal.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+#define CUST_CFG_INFRA "WMT.cfg"
+#define CUST_CFG_INFRA_SOC "WMT_SOC.cfg"
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+struct conf_byte_ary {
+ unsigned int size;
+ char *data;
+};
+
+struct conninfra_conf {
+
+ char conf_name[NAME_MAX + 1];
+ //const osal_firmware *conf_inst;
+ unsigned char cfg_exist;
+
+ unsigned char coex_wmt_ant_mode;
+ unsigned char coex_wmt_ant_mode_ex;
+ unsigned char coex_wmt_ext_component;
+ unsigned char coex_wmt_wifi_time_ctl;
+ unsigned char coex_wmt_ext_pta_dev_on;
+ /*combo chip and LTE coex filter mode setting */
+ unsigned char coex_wmt_filter_mode;
+
+ unsigned char coex_bt_rssi_upper_limit;
+ unsigned char coex_bt_rssi_mid_limit;
+ unsigned char coex_bt_rssi_lower_limit;
+ unsigned char coex_bt_pwr_high;
+ unsigned char coex_bt_pwr_mid;
+ unsigned char coex_bt_pwr_low;
+
+ unsigned char coex_wifi_rssi_upper_limit;
+ unsigned char coex_wifi_rssi_mid_limit;
+ unsigned char coex_wifi_rssi_lower_limit;
+ unsigned char coex_wifi_pwr_high;
+ unsigned char coex_wifi_pwr_mid;
+ unsigned char coex_wifi_pwr_low;
+
+ unsigned char coex_ext_pta_hi_tx_tag;
+ unsigned char coex_ext_pta_hi_rx_tag;
+ unsigned char coex_ext_pta_lo_tx_tag;
+ unsigned char coex_ext_pta_lo_rx_tag;
+ unsigned short coex_ext_pta_sample_t1;
+ unsigned short coex_ext_pta_sample_t2;
+ unsigned char coex_ext_pta_wifi_bt_con_trx;
+
+ unsigned int coex_misc_ext_pta_on;
+ unsigned int coex_misc_ext_feature_set;
+ /*GPS LNA setting */
+ unsigned char wmt_gps_lna_pin;
+ unsigned char wmt_gps_lna_enable;
+ /*Power on sequence */
+ unsigned char pwr_on_rtc_slot;
+ unsigned char pwr_on_ldo_slot;
+ unsigned char pwr_on_rst_slot;
+ unsigned char pwr_on_off_slot;
+ unsigned char pwr_on_on_slot;
+ unsigned char co_clock_flag;
+
+ /*deep sleep feature flag*/
+ unsigned char disable_deep_sleep_cfg;
+
+ /* Combo chip side SDIO driving setting */
+ unsigned int sdio_driving_cfg;
+
+ /* Combo chip WiFi path setting */
+ unsigned short coex_wmt_wifi_path;
+ /* Combo chip WiFi eLAN gain setting */
+ unsigned char coex_wmt_ext_elna_gain_p1_support;
+ unsigned int coex_wmt_ext_elna_gain_p1_D0;
+ unsigned int coex_wmt_ext_elna_gain_p1_D1;
+ unsigned int coex_wmt_ext_elna_gain_p1_D2;
+ unsigned int coex_wmt_ext_elna_gain_p1_D3;
+
+ struct conf_byte_ary *coex_wmt_epa_elna;
+
+ unsigned char bt_tssi_from_wifi;
+ unsigned short bt_tssi_target;
+
+ unsigned char coex_config_bt_ctrl;
+ unsigned char coex_config_bt_ctrl_mode;
+ unsigned char coex_config_bt_ctrl_rw;
+
+ unsigned char coex_config_addjust_opp_time_ratio;
+ unsigned char coex_config_addjust_opp_time_ratio_bt_slot;
+ unsigned char coex_config_addjust_opp_time_ratio_wifi_slot;
+
+ unsigned char coex_config_addjust_ble_scan_time_ratio;
+ unsigned char coex_config_addjust_ble_scan_time_ratio_bt_slot;
+ unsigned char coex_config_addjust_ble_scan_time_ratio_wifi_slot;
+
+ /* POS. If set, means using ext TCXO */
+ unsigned char tcxo_gpio;
+
+};
+
+
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+
+
+
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+const struct conninfra_conf *conninfra_conf_get_cfg(void);
+int conninfra_conf_set_cfg_file(const char *name);
+
+int conninfra_conf_init(void);
+int conninfra_conf_deinit(void);
+
+#endif /* _CONNINFRA_CONF_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/core/conninfra_core.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/core/conninfra_core.c
new file mode 100755
index 0000000..ebbb359
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/core/conninfra_core.c
@@ -0,0 +1,1765 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__
+
+#include "consys_hw.h"
+#include "conninfra_core.h"
+#include "msg_thread.h"
+#include "consys_reg_mng.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+#define CONNINFRA_EVENT_TIMEOUT 3000
+#define CONNINFRA_RESET_TIMEOUT 500
+#define CONNINFRA_PRE_CAL_TIMEOUT 500
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/delay.h>
+#include <linux/thermal.h>
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+static int opfunc_power_on(struct msg_op_data *op);
+static int opfunc_power_off(struct msg_op_data *op);
+static int opfunc_chip_rst(struct msg_op_data *op);
+static int opfunc_pre_cal(struct msg_op_data *op);
+static int opfunc_therm_ctrl(struct msg_op_data *op);
+static int opfunc_rfspi_read(struct msg_op_data *op);
+static int opfunc_rfspi_write(struct msg_op_data *op);
+static int opfunc_adie_top_ck_en_on(struct msg_op_data *op);
+static int opfunc_adie_top_ck_en_off(struct msg_op_data *op);
+static int opfunc_spi_clock_switch(struct msg_op_data *op);
+static int opfunc_clock_fail_dump(struct msg_op_data *op);
+static int opfunc_pre_cal_prepare(struct msg_op_data *op);
+static int opfunc_pre_cal_check(struct msg_op_data *op);
+
+static int opfunc_force_conninfra_wakeup(struct msg_op_data *op);
+static int opfunc_force_conninfra_sleep(struct msg_op_data *op);
+
+static int opfunc_dump_power_state(struct msg_op_data *op);
+
+static int opfunc_subdrv_pre_reset(struct msg_op_data *op);
+static int opfunc_subdrv_post_reset(struct msg_op_data *op);
+static int opfunc_subdrv_cal_pwr_on(struct msg_op_data *op);
+static int opfunc_subdrv_cal_do_cal(struct msg_op_data *op);
+static int opfunc_subdrv_therm_ctrl(struct msg_op_data *op);
+
+static void _conninfra_core_update_rst_status(enum chip_rst_status status);
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+struct conninfra_ctx g_conninfra_ctx;
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+static const msg_opid_func conninfra_core_opfunc[] = {
+ [CONNINFRA_OPID_PWR_ON] = opfunc_power_on,
+ [CONNINFRA_OPID_PWR_OFF] = opfunc_power_off,
+ [CONNINFRA_OPID_THERM_CTRL] = opfunc_therm_ctrl,
+ [CONNINFRA_OPID_RFSPI_READ] = opfunc_rfspi_read,
+ [CONNINFRA_OPID_RFSPI_WRITE] = opfunc_rfspi_write,
+ [CONNINFRA_OPID_ADIE_TOP_CK_EN_ON] = opfunc_adie_top_ck_en_on,
+ [CONNINFRA_OPID_ADIE_TOP_CK_EN_OFF] = opfunc_adie_top_ck_en_off,
+ [CONNINFRA_OPID_SPI_CLOCK_SWITCH] = opfunc_spi_clock_switch,
+ [CONNINFRA_OPID_CLOCK_FAIL_DUMP] = opfunc_clock_fail_dump,
+ [CONNINFRA_OPID_PRE_CAL_PREPARE] = opfunc_pre_cal_prepare,
+ [CONNINFRA_OPID_PRE_CAL_CHECK] = opfunc_pre_cal_check,
+
+ [CONNINFRA_OPID_FORCE_CONNINFRA_WAKUP] = opfunc_force_conninfra_wakeup,
+ [CONNINFRA_OPID_FORCE_CONNINFRA_SLEEP] = opfunc_force_conninfra_sleep,
+
+ [CONNINFRA_OPID_DUMP_POWER_STATE] = opfunc_dump_power_state,
+};
+
+static const msg_opid_func conninfra_core_cb_opfunc[] = {
+ [CONNINFRA_CB_OPID_CHIP_RST] = opfunc_chip_rst,
+ [CONNINFRA_CB_OPID_PRE_CAL] = opfunc_pre_cal,
+};
+
+
+/* subsys ops */
+static char *drv_thread_name[] = {
+ [CONNDRV_TYPE_BT] = "sub_bt_thrd",
+ [CONNDRV_TYPE_FM] = "sub_fm_thrd",
+ [CONNDRV_TYPE_GPS] = "sub_gps_thrd",
+ [CONNDRV_TYPE_WIFI] = "sub_wifi_thrd",
+ [CONNDRV_TYPE_CONNINFRA] = "sub_conninfra_thrd",
+};
+
+static char *drv_name[] = {
+ [CONNDRV_TYPE_BT] = "BT",
+ [CONNDRV_TYPE_FM] = "FM",
+ [CONNDRV_TYPE_GPS] = "GPS",
+ [CONNDRV_TYPE_WIFI] = "WIFI",
+ [CONNDRV_TYPE_CONNINFRA] = "CONNINFRA",
+};
+
+typedef enum {
+ INFRA_SUBDRV_OPID_PRE_RESET = 0,
+ INFRA_SUBDRV_OPID_POST_RESET = 1,
+ INFRA_SUBDRV_OPID_CAL_PWR_ON = 2,
+ INFRA_SUBDRV_OPID_CAL_DO_CAL = 3,
+ INFRA_SUBDRV_OPID_THERM_CTRL = 4,
+
+ INFRA_SUBDRV_OPID_MAX
+} infra_subdrv_op;
+
+
+static const msg_opid_func infra_subdrv_opfunc[] = {
+ [INFRA_SUBDRV_OPID_PRE_RESET] = opfunc_subdrv_pre_reset,
+ [INFRA_SUBDRV_OPID_POST_RESET] = opfunc_subdrv_post_reset,
+ [INFRA_SUBDRV_OPID_CAL_PWR_ON] = opfunc_subdrv_cal_pwr_on,
+ [INFRA_SUBDRV_OPID_CAL_DO_CAL] = opfunc_subdrv_cal_do_cal,
+ [INFRA_SUBDRV_OPID_THERM_CTRL] = opfunc_subdrv_therm_ctrl,
+};
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+static void reset_chip_rst_trg_data(void)
+{
+ g_conninfra_ctx.trg_drv = CONNDRV_TYPE_MAX;
+ memset(g_conninfra_ctx.trg_reason, '\0', CHIP_RST_REASON_MAX_LEN);
+}
+
+static unsigned long timeval_to_ms(struct timeval *begin, struct timeval *end)
+{
+ unsigned long time_diff;
+
+ time_diff = (end->tv_sec - begin->tv_sec) * 1000;
+ time_diff += (end->tv_usec - begin->tv_usec) / 1000;
+
+ return time_diff;
+}
+
+static unsigned int opfunc_get_current_status(void)
+{
+ unsigned int ret = 0;
+ unsigned int i;
+
+ for (i = 0; i < CONNDRV_TYPE_MAX; i++) {
+ ret |= (g_conninfra_ctx.drv_inst[i].drv_status << i);
+ }
+
+ return ret;
+}
+
+static void opfunc_vcn_control_internal(unsigned int drv_type, bool on)
+{
+ /* VCNx enable */
+ switch (drv_type) {
+ case CONNDRV_TYPE_BT:
+ consys_hw_bt_power_ctl(on);
+ break;
+ case CONNDRV_TYPE_FM:
+ consys_hw_fm_power_ctl(on);
+ break;
+ case CONNDRV_TYPE_GPS:
+ consys_hw_gps_power_ctl(on);
+ break;
+ case CONNDRV_TYPE_WIFI:
+ consys_hw_wifi_power_ctl(on);
+ break;
+ default:
+ pr_err("Wrong parameter: drv_type(%d)\n", drv_type);
+ break;
+ }
+}
+
+static int opfunc_power_on_internal(unsigned int drv_type)
+{
+ int ret;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ /* Check abnormal type */
+ if (drv_type >= CONNDRV_TYPE_MAX) {
+ pr_err("abnormal Fun(%d)\n", drv_type);
+ return -EINVAL;
+ }
+
+ /* Check abnormal state */
+ if ((g_conninfra_ctx.drv_inst[drv_type].drv_status < DRV_STS_POWER_OFF)
+ || (g_conninfra_ctx.drv_inst[drv_type].drv_status >= DRV_STS_MAX)) {
+ pr_err("func(%d) status[0x%x] abnormal\n", drv_type,
+ g_conninfra_ctx.drv_inst[drv_type].drv_status);
+ return -EINVAL;
+ }
+
+ ret = osal_lock_sleepable_lock(&infra_ctx->core_lock);
+ if (ret) {
+ pr_err("core_lock fail!!");
+ return ret;
+ }
+
+ /* check if func already on */
+ if (g_conninfra_ctx.drv_inst[drv_type].drv_status == DRV_STS_POWER_ON) {
+ pr_warn("func(%d) already on\n", drv_type);
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+ return 0;
+ }
+
+ ret = consys_hw_pwr_on(opfunc_get_current_status(), drv_type);
+ if (ret) {
+ pr_err("Conninfra power on fail. drv(%d) ret=(%d)\n",
+ drv_type, ret);
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+ return -3;
+ }
+ /* POWER ON SEQUENCE */
+ g_conninfra_ctx.infra_drv_status = DRV_STS_POWER_ON;
+
+ g_conninfra_ctx.drv_inst[drv_type].drv_status = DRV_STS_POWER_ON;
+
+ /* VCNx enable */
+ opfunc_vcn_control_internal(drv_type, true);
+
+ pr_info("[Conninfra Pwr On] BT=[%d] FM=[%d] GPS=[%d] WF=[%d]",
+ infra_ctx->drv_inst[CONNDRV_TYPE_BT].drv_status,
+ infra_ctx->drv_inst[CONNDRV_TYPE_FM].drv_status,
+ infra_ctx->drv_inst[CONNDRV_TYPE_GPS].drv_status,
+ infra_ctx->drv_inst[CONNDRV_TYPE_WIFI].drv_status);
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+
+ return 0;
+}
+
+static int opfunc_power_on(struct msg_op_data *op)
+{
+ unsigned int drv_type = op->op_data[0];
+
+ return opfunc_power_on_internal(drv_type);
+}
+
+static int opfunc_power_off_internal(unsigned int drv_type)
+{
+ int i, ret;
+ bool try_power_off = true;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+ unsigned int curr_status = opfunc_get_current_status();
+
+ /* Check abnormal type */
+ if (drv_type >= CONNDRV_TYPE_MAX) {
+ pr_err("abnormal Fun(%d)\n", drv_type);
+ return -EINVAL;
+ }
+
+ ret = osal_lock_sleepable_lock(&infra_ctx->core_lock);
+ if (ret) {
+ pr_err("core_lock fail!!");
+ return ret;
+ }
+
+ /* Check abnormal state */
+ if ((g_conninfra_ctx.drv_inst[drv_type].drv_status < DRV_STS_POWER_OFF)
+ || (g_conninfra_ctx.drv_inst[drv_type].drv_status >= DRV_STS_MAX)) {
+ pr_err("func(%d) status[0x%x] abnormal\n", drv_type,
+ g_conninfra_ctx.drv_inst[drv_type].drv_status);
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+ return -2;
+ }
+
+ /* Special case for force power off */
+ if (drv_type == CONNDRV_TYPE_CONNINFRA) {
+ if (g_conninfra_ctx.infra_drv_status == DRV_STS_POWER_OFF) {
+ pr_warn("Connsys already off, do nothing for force off\n");
+ return 0;
+ }
+ /* Turn off subsys VCN and update record */
+ for (i = 0; i < CONNDRV_TYPE_MAX; i++) {
+ if (g_conninfra_ctx.drv_inst[i].drv_status == DRV_STS_POWER_ON) {
+ opfunc_vcn_control_internal(i, false);
+ g_conninfra_ctx.drv_inst[i].drv_status = DRV_STS_POWER_OFF;
+ }
+ }
+ /* POWER OFF SEQUENCE */
+ ret = consys_hw_pwr_off(0, drv_type);
+ /* For force power off operation, ignore err code */
+ if (ret)
+ pr_err("Force power off fail. ret=%d\n", ret);
+ try_power_off = true;
+ } else {
+ /* check if func already off */
+ if (g_conninfra_ctx.drv_inst[drv_type].drv_status
+ == DRV_STS_POWER_OFF) {
+ pr_warn("func(%d) already off\n", drv_type);
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+ return 0;
+ }
+ /* VCNx disable */
+ opfunc_vcn_control_internal(drv_type, false);
+ g_conninfra_ctx.drv_inst[drv_type].drv_status = DRV_STS_POWER_OFF;
+ /* is there subsys on ? */
+ for (i = 0; i < CONNDRV_TYPE_MAX; i++)
+ if (g_conninfra_ctx.drv_inst[i].drv_status == DRV_STS_POWER_ON)
+ try_power_off = false;
+
+ /* POWER OFF SEQUENCE */
+ ret = consys_hw_pwr_off(curr_status, drv_type);
+ if (ret) {
+ pr_err("Conninfra power on fail. drv(%d) ret=(%d)\n",
+ drv_type, ret);
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+ return -3;
+ }
+ }
+
+ if (try_power_off)
+ g_conninfra_ctx.infra_drv_status = DRV_STS_POWER_OFF;
+
+ pr_info("[Conninfra Pwr Off] Conninfra=[%d] BT=[%d] FM=[%d] GPS=[%d] WF=[%d]",
+ infra_ctx->infra_drv_status,
+ infra_ctx->drv_inst[CONNDRV_TYPE_BT].drv_status,
+ infra_ctx->drv_inst[CONNDRV_TYPE_FM].drv_status,
+ infra_ctx->drv_inst[CONNDRV_TYPE_GPS].drv_status,
+ infra_ctx->drv_inst[CONNDRV_TYPE_WIFI].drv_status);
+
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+ return 0;
+}
+
+static int opfunc_power_off(struct msg_op_data *op)
+{
+ unsigned int drv_type = op->op_data[0];
+
+ return opfunc_power_off_internal(drv_type);
+}
+
+static int opfunc_chip_rst(struct msg_op_data *op)
+{
+ int i, ret, cur_rst_state;
+ struct subsys_drv_inst *drv_inst;
+ unsigned int drv_pwr_state[CONNDRV_TYPE_MAX];
+ const unsigned int subdrv_all_done = (0x1 << CONNDRV_TYPE_MAX) - 1;
+ struct timeval pre_begin, pre_end, reset_end, done_end;
+
+ if (g_conninfra_ctx.infra_drv_status == DRV_STS_POWER_OFF) {
+ pr_info("No subsys on, just return");
+ _conninfra_core_update_rst_status(CHIP_RST_NONE);
+ return 0;
+ }
+
+ do_gettimeofday(&pre_begin);
+
+ atomic_set(&g_conninfra_ctx.rst_state, 0);
+ sema_init(&g_conninfra_ctx.rst_sema, 1);
+
+ _conninfra_core_update_rst_status(CHIP_RST_PRE_CB);
+
+ /* pre */
+ for (i = 0; i < CONNDRV_TYPE_MAX; i++) {
+ drv_inst = &g_conninfra_ctx.drv_inst[i];
+ drv_pwr_state[i] = drv_inst->drv_status;
+ pr_info("subsys %d is %d", i, drv_inst->drv_status);
+ ret = msg_thread_send_1(&drv_inst->msg_ctx,
+ INFRA_SUBDRV_OPID_PRE_RESET, i);
+ }
+
+ pr_info("[chip_rst] pre vvvvvvvvvvvvv");
+ while (atomic_read(&g_conninfra_ctx.rst_state) != subdrv_all_done) {
+ ret = down_timeout(&g_conninfra_ctx.rst_sema, msecs_to_jiffies(CONNINFRA_RESET_TIMEOUT));
+ pr_info("sema ret=[%d]", ret);
+ if (ret == 0)
+ continue;
+ cur_rst_state = atomic_read(&g_conninfra_ctx.rst_state);
+ pr_info("cur_rst state =[%d]", cur_rst_state);
+ for (i = 0; i < CONNDRV_TYPE_MAX; i++) {
+ if ((cur_rst_state & (0x1 << i)) == 0) {
+ pr_info("[chip_rst] [%s] pre-callback is not back", drv_thread_name[i]);
+ drv_inst = &g_conninfra_ctx.drv_inst[i];
+ osal_thread_show_stack(&drv_inst->msg_ctx.thread);
+ }
+ }
+ }
+
+ _conninfra_core_update_rst_status(CHIP_RST_RESET);
+
+ do_gettimeofday(&pre_end);
+
+ pr_info("[chip_rst] reset ++++++++++++");
+ /*******************************************************/
+ /* reset */
+ /* call consys_hw */
+ /*******************************************************/
+ /* Special power-off function, turn off connsys directly */
+ ret = opfunc_power_off_internal(CONNDRV_TYPE_CONNINFRA);
+ pr_info("Force conninfra power off, ret=%d\n", ret);
+ pr_info("conninfra status should be power off. Status=%d", g_conninfra_ctx.infra_drv_status);
+
+ /* Turn on subsys */
+ for (i = 0; i < CONNDRV_TYPE_MAX; i++) {
+ if (drv_pwr_state[i]) {
+ ret = opfunc_power_on_internal(i);
+ pr_info("Call subsys(%d) power on ret=%d", i, ret);
+ }
+ }
+ pr_info("conninfra status should be power on. Status=%d", g_conninfra_ctx.infra_drv_status);
+
+ pr_info("[chip_rst] reset --------------");
+
+ _conninfra_core_update_rst_status(CHIP_RST_POST_CB);
+
+ do_gettimeofday(&reset_end);
+
+ /* post */
+ atomic_set(&g_conninfra_ctx.rst_state, 0);
+ sema_init(&g_conninfra_ctx.rst_sema, 1);
+ for (i = 0; i < CONNDRV_TYPE_MAX; i++) {
+ drv_inst = &g_conninfra_ctx.drv_inst[i];
+ ret = msg_thread_send_1(&drv_inst->msg_ctx,
+ INFRA_SUBDRV_OPID_POST_RESET, i);
+ }
+
+ while (atomic_read(&g_conninfra_ctx.rst_state) != subdrv_all_done) {
+ ret = down_timeout(&g_conninfra_ctx.rst_sema, msecs_to_jiffies(CONNINFRA_RESET_TIMEOUT));
+ if (ret == 0)
+ continue;
+ cur_rst_state = atomic_read(&g_conninfra_ctx.rst_state);
+ for (i = 0; i < CONNDRV_TYPE_MAX; i++) {
+ if ((cur_rst_state & (0x1 << i)) == 0) {
+ pr_info("[chip_rst] [%s] post-callback is not back", drv_thread_name[i]);
+ drv_inst = &g_conninfra_ctx.drv_inst[i];
+ osal_thread_show_stack(&drv_inst->msg_ctx.thread);
+ }
+ }
+ }
+ pr_info("[chip_rst] post ^^^^^^^^^^^^^^");
+
+ reset_chip_rst_trg_data();
+ //_conninfra_core_update_rst_status(CHIP_RST_DONE);
+ _conninfra_core_update_rst_status(CHIP_RST_NONE);
+ do_gettimeofday(&done_end);
+
+ pr_info("[chip_rst] summary pre=[%lu] reset=[%lu] post=[%lu]",
+ timeval_to_ms(&pre_begin, &pre_end),
+ timeval_to_ms(&pre_end, &reset_end),
+ timeval_to_ms(&reset_end, &done_end));
+
+ return 0;
+}
+
+static int opfunc_pre_cal(struct msg_op_data *op)
+{
+#define CAL_DRV_COUNT 2
+ int cal_drvs[CAL_DRV_COUNT] = {CONNDRV_TYPE_BT, CONNDRV_TYPE_WIFI};
+ int i, ret, cur_state;
+ int bt_cal_ret, wf_cal_ret;
+ struct subsys_drv_inst *drv_inst;
+ int pre_cal_done_state = (0x1 << CONNDRV_TYPE_BT) | (0x1 << CONNDRV_TYPE_WIFI);
+ struct timeval begin, bt_cal_begin, wf_cal_begin, end;
+
+ /* Check BT/WIFI status again */
+ ret = osal_lock_sleepable_lock(&g_conninfra_ctx.core_lock);
+ if (ret) {
+ pr_err("[%s] core_lock fail!!", __func__);
+ return ret;
+ }
+ /* check if func already on */
+ for (i = 0; i < CAL_DRV_COUNT; i++) {
+ if (g_conninfra_ctx.drv_inst[cal_drvs[i]].drv_status == DRV_STS_POWER_ON) {
+ pr_warn("[%s] %s already on\n", __func__, drv_name[cal_drvs[i]]);
+ osal_unlock_sleepable_lock(&g_conninfra_ctx.core_lock);
+ return 0;
+ }
+ }
+ osal_unlock_sleepable_lock(&g_conninfra_ctx.core_lock);
+
+ ret = conninfra_core_power_on(CONNDRV_TYPE_BT);
+ if (ret) {
+ pr_err("BT power on fail during pre_cal");
+ return -1;
+ }
+ ret = conninfra_core_power_on(CONNDRV_TYPE_WIFI);
+ if (ret) {
+ pr_err("WIFI power on fail during pre_cal");
+ conninfra_core_power_off(CONNDRV_TYPE_BT);
+ return -2;
+ }
+
+ do_gettimeofday(&begin);
+
+ /* power on subsys */
+ atomic_set(&g_conninfra_ctx.pre_cal_state, 0);
+ sema_init(&g_conninfra_ctx.pre_cal_sema, 1);
+
+ for (i = 0; i < CAL_DRV_COUNT; i++) {
+ drv_inst = &g_conninfra_ctx.drv_inst[cal_drvs[i]];
+ ret = msg_thread_send_1(&drv_inst->msg_ctx,
+ INFRA_SUBDRV_OPID_CAL_PWR_ON, cal_drvs[i]);
+ if (ret)
+ pr_warn("driver [%d] power on fail\n", cal_drvs[i]);
+ }
+
+ while (atomic_read(&g_conninfra_ctx.pre_cal_state) != pre_cal_done_state) {
+ ret = down_timeout(&g_conninfra_ctx.pre_cal_sema, msecs_to_jiffies(CONNINFRA_PRE_CAL_TIMEOUT));
+ if (ret == 0)
+ continue;
+ cur_state = atomic_read(&g_conninfra_ctx.pre_cal_state);
+ pr_info("[pre_cal] cur state =[%d]", cur_state);
+ if ((cur_state & (0x1 << CONNDRV_TYPE_BT)) == 0) {
+ pr_info("[pre_cal] BT pwr_on callback is not back");
+ drv_inst = &g_conninfra_ctx.drv_inst[CONNDRV_TYPE_BT];
+ osal_thread_show_stack(&drv_inst->msg_ctx.thread);
+ }
+ if ((cur_state & (0x1 << CONNDRV_TYPE_WIFI)) == 0) {
+ pr_info("[pre_cal] WIFI pwr_on callback is not back");
+ drv_inst = &g_conninfra_ctx.drv_inst[CONNDRV_TYPE_WIFI];
+ osal_thread_show_stack(&drv_inst->msg_ctx.thread);
+ }
+ }
+ pr_info("[pre_cal] >>>>>>> power on DONE!!");
+
+ do_gettimeofday(&bt_cal_begin);
+
+ /* Do Calibration */
+ drv_inst = &g_conninfra_ctx.drv_inst[CONNDRV_TYPE_BT];
+ bt_cal_ret = msg_thread_send_wait_1(&drv_inst->msg_ctx,
+ INFRA_SUBDRV_OPID_CAL_DO_CAL, 0, CONNDRV_TYPE_BT);
+
+ pr_info("[pre_cal] driver [%s] calibration %s, ret=[%d]\n", drv_name[CONNDRV_TYPE_BT],
+ (bt_cal_ret == CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF ||
+ bt_cal_ret == CONNINFRA_CB_RET_CAL_FAIL_POWER_ON) ? "fail" : "success",
+ bt_cal_ret);
+
+ if (bt_cal_ret == CONNINFRA_CB_RET_CAL_PASS_POWER_OFF ||
+ bt_cal_ret == CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF)
+ conninfra_core_power_off(CONNDRV_TYPE_BT);
+
+ pr_info("[pre_cal] >>>>>>>> BT do cal done");
+
+ do_gettimeofday(&wf_cal_begin);
+
+ drv_inst = &g_conninfra_ctx.drv_inst[CONNDRV_TYPE_WIFI];
+ wf_cal_ret = msg_thread_send_wait_1(&drv_inst->msg_ctx,
+ INFRA_SUBDRV_OPID_CAL_DO_CAL, 0, CONNDRV_TYPE_WIFI);
+
+ pr_info("[pre_cal] driver [%s] calibration %s, ret=[%d]\n", drv_name[CONNDRV_TYPE_WIFI],
+ (wf_cal_ret == CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF ||
+ wf_cal_ret == CONNINFRA_CB_RET_CAL_FAIL_POWER_ON) ? "fail" : "success",
+ wf_cal_ret);
+
+ if (wf_cal_ret == CONNINFRA_CB_RET_CAL_PASS_POWER_OFF ||
+ wf_cal_ret == CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF)
+ conninfra_core_power_off(CONNDRV_TYPE_WIFI);
+
+ pr_info(">>>>>>>> WF do cal done");
+
+ do_gettimeofday(&end);
+
+ pr_info("[pre_cal] summary pwr=[%lu] bt_cal=[%d][%lu] wf_cal=[%d][%lu]",
+ timeval_to_ms(&begin, &bt_cal_begin),
+ bt_cal_ret, timeval_to_ms(&bt_cal_begin, &wf_cal_begin),
+ wf_cal_ret, timeval_to_ms(&wf_cal_begin, &end));
+
+ return 0;
+}
+
+
+static int opfunc_therm_ctrl(struct msg_op_data *op)
+{
+ static DEFINE_RATELIMIT_STATE(_rs, 10*HZ, 1);
+ int ret = -1;
+ int *data_ptr = (int*)op->op_data[0];
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) {
+ *data_ptr = THERMAL_TEMP_INVALID;
+ return 0;
+ } else {
+ if (__ratelimit(&_rs)) {
+ pr_info("[Conn status] Conninfra=[%d] BT=[%d] FM=[%d] GPS=[%d] WF=[%d]",
+ infra_ctx->infra_drv_status,
+ infra_ctx->drv_inst[CONNDRV_TYPE_BT].drv_status,
+ infra_ctx->drv_inst[CONNDRV_TYPE_FM].drv_status,
+ infra_ctx->drv_inst[CONNDRV_TYPE_GPS].drv_status,
+ infra_ctx->drv_inst[CONNDRV_TYPE_WIFI].drv_status);
+ }
+ }
+
+ if (data_ptr)
+ ret = consys_hw_therm_query(data_ptr);
+ return ret;
+}
+
+
+static int opfunc_rfspi_read(struct msg_op_data *op)
+{
+ int ret = 0;
+ unsigned int data = 0;
+ unsigned int* data_pt = (unsigned int*)op->op_data[2];
+
+ ret = osal_lock_sleepable_lock(&g_conninfra_ctx.core_lock);
+ if (ret) {
+ pr_err("core_lock fail!!\n");
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+
+ if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) {
+ pr_err("Connsys didn't power on\n");
+ ret = CONNINFRA_SPI_OP_FAIL;
+ goto err;
+ }
+ if (consys_hw_reg_readable() == 0) {
+ pr_err("connsys reg not readable\n");
+ ret = CONNINFRA_SPI_OP_FAIL;
+ goto err;
+ }
+ /* DO read spi */
+ ret = consys_hw_spi_read(op->op_data[0], op->op_data[1], &data);
+ if (data_pt)
+ *(data_pt) = data;
+err:
+ osal_unlock_sleepable_lock(&g_conninfra_ctx.core_lock);
+ return ret;
+}
+
+static int opfunc_rfspi_write(struct msg_op_data *op)
+{
+ int ret = 0;
+
+ ret = osal_lock_sleepable_lock(&g_conninfra_ctx.core_lock);
+ if (ret) {
+ pr_err("core_lock fail!!\n");
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+
+ if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) {
+ pr_err("Connsys didn't power on\n");
+ ret = CONNINFRA_SPI_OP_FAIL;
+ goto err;
+ }
+ if (consys_hw_reg_readable() == 0) {
+ pr_err("connsys reg not readable\n");
+ ret = CONNINFRA_SPI_OP_FAIL;
+ goto err;
+ }
+ /* DO spi write */
+ ret = consys_hw_spi_write(op->op_data[0], op->op_data[1], op->op_data[2]);
+err:
+ osal_unlock_sleepable_lock(&g_conninfra_ctx.core_lock);
+ return ret;
+}
+
+static int opfunc_adie_top_ck_en_on(struct msg_op_data *op)
+{
+ int ret = 0;
+ unsigned int type = op->op_data[0];
+
+ if (type >= CONNSYS_ADIE_CTL_MAX) {
+ pr_err("wrong parameter %d\n", type);
+ return -EINVAL;
+ }
+
+ ret = osal_lock_sleepable_lock(&g_conninfra_ctx.core_lock);
+ if (ret) {
+ pr_err("core_lock fail!!\n");
+ ret = -1;
+ goto err;
+ }
+
+ if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) {
+ pr_err("Connsys didn't power on\n");
+ ret = -2;
+ goto err;
+ }
+
+ ret = consys_hw_adie_top_ck_en_on(type);
+
+err:
+ osal_unlock_sleepable_lock(&g_conninfra_ctx.core_lock);
+ return ret;
+}
+
+
+static int opfunc_adie_top_ck_en_off(struct msg_op_data *op)
+{
+ int ret = 0;
+ unsigned int type = op->op_data[0];
+
+ if (type >= CONNSYS_ADIE_CTL_MAX) {
+ pr_err("wrong parameter %d\n", type);
+ return -EINVAL;
+ }
+
+ ret = osal_lock_sleepable_lock(&g_conninfra_ctx.core_lock);
+ if (ret) {
+ pr_err("core_lock fail!!\n");
+ ret = -1;
+ goto err;
+ }
+ if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) {
+ pr_err("Connsys didn't power on\n");
+ ret = -2;
+ goto err;
+ }
+
+ ret = consys_hw_adie_top_ck_en_off(type);
+err:
+ osal_unlock_sleepable_lock(&g_conninfra_ctx.core_lock);
+ return ret;
+}
+
+static int opfunc_spi_clock_switch(struct msg_op_data *op)
+{
+ int ret = 0;
+ unsigned int type = op->op_data[0];
+
+ if (type >= CONNSYS_SPI_SPEED_MAX) {
+ pr_err("wrong parameter %d\n", type);
+ return -EINVAL;
+ }
+
+ ret = osal_lock_sleepable_lock(&g_conninfra_ctx.core_lock);
+ if (ret) {
+ pr_err("core_lock fail!!\n");
+ ret = -2;
+ goto err;
+ }
+ if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) {
+ pr_err("Connsys didn't power on\n");
+ ret = -2;
+ goto err;
+ }
+
+ ret = consys_hw_spi_clock_switch(type);
+err:
+ osal_unlock_sleepable_lock(&g_conninfra_ctx.core_lock);
+ return ret;
+}
+
+
+static int opfunc_clock_fail_dump(struct msg_op_data *op)
+{
+ consys_hw_clock_fail_dump();
+ return 0;
+}
+
+
+static int opfunc_pre_cal_prepare(struct msg_op_data *op)
+{
+ int ret, rst_status;
+ unsigned long flag;
+ struct pre_cal_info *cal_info = &g_conninfra_ctx.cal_info;
+ struct subsys_drv_inst *bt_drv = &g_conninfra_ctx.drv_inst[CONNDRV_TYPE_BT];
+ struct subsys_drv_inst *wifi_drv = &g_conninfra_ctx.drv_inst[CONNDRV_TYPE_WIFI];
+ enum pre_cal_status cur_status;
+
+ spin_lock_irqsave(&g_conninfra_ctx.infra_lock, flag);
+
+ if (bt_drv->ops_cb.pre_cal_cb.do_cal_cb == NULL ||
+ wifi_drv->ops_cb.pre_cal_cb.do_cal_cb == NULL) {
+ pr_info("[%s] [pre_cal] [%p][%p]", __func__,
+ bt_drv->ops_cb.pre_cal_cb.do_cal_cb,
+ wifi_drv->ops_cb.pre_cal_cb.do_cal_cb);
+ spin_unlock_irqrestore(&g_conninfra_ctx.infra_lock, flag);
+ return 0;
+ }
+ spin_unlock_irqrestore(&g_conninfra_ctx.infra_lock, flag);
+
+ spin_lock_irqsave(&g_conninfra_ctx.rst_lock, flag);
+ rst_status = g_conninfra_ctx.rst_status;
+ spin_unlock_irqrestore(&g_conninfra_ctx.rst_lock, flag);
+
+ if (rst_status > CHIP_RST_NONE) {
+ pr_info("rst is ongoing, skip pre_cal");
+ return 0;
+ }
+
+ /* non-zero means lock got, zero means not */
+ ret = osal_trylock_sleepable_lock(&cal_info->pre_cal_lock);
+
+ if (ret) {
+ cur_status = cal_info->status;
+
+ if ((cur_status == PRE_CAL_NOT_INIT || cur_status == PRE_CAL_NEED_RESCHEDULE) &&
+ bt_drv->drv_status == DRV_STS_POWER_OFF &&
+ wifi_drv->drv_status == DRV_STS_POWER_OFF) {
+ cal_info->status = PRE_CAL_SCHEDULED;
+ pr_info("[pre_cal] BT&WIFI is off, schedule pre-cal from status=[%d] to new status[%d]\n",
+ cur_status, cal_info->status);
+ schedule_work(&cal_info->pre_cal_work);
+ } else {
+ pr_info("[%s] [pre_cal] bt=[%d] wf=[%d] status=[%d]", __func__,
+ bt_drv->drv_status, wifi_drv->drv_status, cur_status);
+ }
+ osal_unlock_sleepable_lock(&cal_info->pre_cal_lock);
+ }
+
+ return 0;
+}
+
+static int opfunc_pre_cal_check(struct msg_op_data *op)
+{
+ int ret;
+ struct pre_cal_info *cal_info = &g_conninfra_ctx.cal_info;
+ struct subsys_drv_inst *bt_drv = &g_conninfra_ctx.drv_inst[CONNDRV_TYPE_BT];
+ struct subsys_drv_inst *wifi_drv = &g_conninfra_ctx.drv_inst[CONNDRV_TYPE_WIFI];
+ enum pre_cal_status cur_status;
+
+ /* non-zero means lock got, zero means not */
+ ret = osal_trylock_sleepable_lock(&cal_info->pre_cal_lock);
+ if (ret) {
+ cur_status = cal_info->status;
+
+ pr_info("[%s] [pre_cal] bt=[%d] wf=[%d] status=[%d]", __func__,
+ bt_drv->drv_status, wifi_drv->drv_status,
+ cur_status);
+ if (cur_status == PRE_CAL_DONE &&
+ bt_drv->drv_status == DRV_STS_POWER_OFF &&
+ wifi_drv->drv_status == DRV_STS_POWER_OFF) {
+ pr_info("[pre_cal] reset pre-cal");
+ cal_info->status = PRE_CAL_NEED_RESCHEDULE;
+ }
+ osal_unlock_sleepable_lock(&cal_info->pre_cal_lock);
+ }
+ return 0;
+}
+
+
+static int opfunc_force_conninfra_wakeup(struct msg_op_data *op)
+{
+ int ret;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ ret = osal_lock_sleepable_lock(&infra_ctx->core_lock);
+ if (ret) {
+ pr_err("core_lock fail!!");
+ return ret;
+ }
+
+ /* check if conninfra already on */
+ if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) {
+ ret = -1;
+ goto err;
+ }
+
+ ret = consys_hw_force_conninfra_wakeup();
+ if (ret)
+ pr_err("force conninfra wakeup fail");
+
+err:
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+ return ret;
+}
+
+static int opfunc_force_conninfra_sleep(struct msg_op_data *op)
+{
+ int ret;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ ret = osal_lock_sleepable_lock(&infra_ctx->core_lock);
+ if (ret) {
+ pr_err("core_lock fail!!");
+ return ret;
+ }
+
+ /* check if conninfra already on */
+ if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) {
+ ret = -1;
+ goto err;
+ }
+
+ ret = consys_hw_force_conninfra_sleep();
+ if (ret)
+ pr_err("force conninfra sleep fail");
+
+err:
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+ return ret;
+}
+
+
+static int opfunc_dump_power_state(struct msg_op_data *op)
+{
+ int ret;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ ret = osal_lock_sleepable_lock(&infra_ctx->core_lock);
+ if (ret) {
+ pr_err("core_lock fail!!");
+ return ret;
+ }
+
+ /* check if conninfra already on */
+ if (g_conninfra_ctx.infra_drv_status != DRV_STS_POWER_ON) {
+ ret = -1;
+ goto err;
+ }
+
+ ret = consys_hw_dump_power_state();
+ if (ret)
+ pr_err("dump power state fail");
+
+err:
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+ return ret;
+
+}
+
+static int opfunc_subdrv_pre_reset(struct msg_op_data *op)
+{
+ int ret, cur_rst_state;
+ unsigned int drv_type = op->op_data[0];
+ struct subsys_drv_inst *drv_inst;
+
+
+ /* TODO: should be locked, to avoid cb was reset */
+ drv_inst = &g_conninfra_ctx.drv_inst[drv_type];
+ if (/*drv_inst->drv_status == DRV_ST_POWER_ON &&*/
+ drv_inst->ops_cb.rst_cb.pre_whole_chip_rst) {
+
+ ret = drv_inst->ops_cb.rst_cb.pre_whole_chip_rst(g_conninfra_ctx.trg_drv,
+ g_conninfra_ctx.trg_reason);
+ if (ret)
+ pr_err("[%s] fail [%d]", __func__, ret);
+ }
+
+ atomic_add(0x1 << drv_type, &g_conninfra_ctx.rst_state);
+ cur_rst_state = atomic_read(&g_conninfra_ctx.rst_state);
+
+ pr_info("[%s] rst_state=[%d]", drv_thread_name[drv_type], cur_rst_state);
+
+ up(&g_conninfra_ctx.rst_sema);
+ return 0;
+}
+
+static int opfunc_subdrv_post_reset(struct msg_op_data *op)
+{
+ int ret;
+ unsigned int drv_type = op->op_data[0];
+ struct subsys_drv_inst *drv_inst;
+
+ /* TODO: should be locked, to avoid cb was reset */
+ drv_inst = &g_conninfra_ctx.drv_inst[drv_type];
+ if (/*drv_inst->drv_status == DRV_ST_POWER_ON &&*/
+ drv_inst->ops_cb.rst_cb.post_whole_chip_rst) {
+ ret = drv_inst->ops_cb.rst_cb.post_whole_chip_rst();
+ if (ret)
+ pr_warn("[%s] fail [%d]", __func__, ret);
+ }
+
+ atomic_add(0x1 << drv_type, &g_conninfra_ctx.rst_state);
+ up(&g_conninfra_ctx.rst_sema);
+ return 0;
+}
+
+static int opfunc_subdrv_cal_pwr_on(struct msg_op_data *op)
+{
+ int ret;
+ unsigned int drv_type = op->op_data[0];
+ struct subsys_drv_inst *drv_inst;
+
+ pr_info("[%s] drv=[%s]", __func__, drv_thread_name[drv_type]);
+
+ /* TODO: should be locked, to avoid cb was reset */
+ drv_inst = &g_conninfra_ctx.drv_inst[drv_type];
+ if (/*drv_inst->drv_status == DRV_ST_POWER_ON &&*/
+ drv_inst->ops_cb.pre_cal_cb.pwr_on_cb) {
+ ret = drv_inst->ops_cb.pre_cal_cb.pwr_on_cb();
+ if (ret)
+ pr_warn("[%s] fail [%d]", __func__, ret);
+ }
+
+ atomic_add(0x1 << drv_type, &g_conninfra_ctx.pre_cal_state);
+ up(&g_conninfra_ctx.pre_cal_sema);
+
+ pr_info("[pre_cal][%s] [%s] DONE", __func__, drv_thread_name[drv_type]);
+ return 0;
+}
+
+static int opfunc_subdrv_cal_do_cal(struct msg_op_data *op)
+{
+ int ret;
+ unsigned int drv_type = op->op_data[0];
+ struct subsys_drv_inst *drv_inst;
+
+ pr_info("[%s] drv=[%s]", __func__, drv_thread_name[drv_type]);
+
+ drv_inst = &g_conninfra_ctx.drv_inst[drv_type];
+ if (/*drv_inst->drv_status == DRV_ST_POWER_ON &&*/
+ drv_inst->ops_cb.pre_cal_cb.do_cal_cb) {
+ ret = drv_inst->ops_cb.pre_cal_cb.do_cal_cb();
+ if (ret)
+ pr_warn("[%s] fail [%d]", __func__, ret);
+ }
+
+ pr_info("[pre_cal][%s] [%s] DONE", __func__, drv_thread_name[drv_type]);
+ return 0;
+}
+
+static int opfunc_subdrv_therm_ctrl(struct msg_op_data *op)
+{
+ return 0;
+}
+
+
+/*
+ * CONNINFRA API
+ */
+int conninfra_core_power_on(enum consys_drv_type type)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ ret = msg_thread_send_wait_1(&infra_ctx->msg_ctx,
+ CONNINFRA_OPID_PWR_ON, 0, type);
+ if (ret) {
+ pr_err("[%s] fail, ret = %d\n", __func__, ret);
+ return -1;
+ }
+ return 0;
+}
+
+int conninfra_core_power_off(enum consys_drv_type type)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ ret = msg_thread_send_wait_1(&infra_ctx->msg_ctx,
+ CONNINFRA_OPID_PWR_OFF, 0, type);
+ if (ret) {
+ pr_err("[%s] send msg fail, ret = %d\n", __func__, ret);
+ return -1;
+ }
+ return 0;
+}
+
+int conninfra_core_pre_cal_start(void)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+ struct pre_cal_info *cal_info = &infra_ctx->cal_info;
+
+ ret = osal_lock_sleepable_lock(&cal_info->pre_cal_lock);
+ if (ret) {
+ pr_err("[%s] get lock fail, ret = %d\n",
+ __func__, ret);
+ return -1;
+ }
+ cal_info->status = PRE_CAL_EXECUTING;
+ ret = msg_thread_send_wait(&infra_ctx->cb_ctx,
+ CONNINFRA_CB_OPID_PRE_CAL, 0);
+ if (ret) {
+ pr_err("[%s] send msg fail, ret = %d\n", __func__, ret);
+ }
+
+ cal_info->status = PRE_CAL_DONE;
+ osal_unlock_sleepable_lock(&cal_info->pre_cal_lock);
+ return 0;
+}
+
+int conninfra_core_screen_on(void)
+{
+#if CFG_CONNINFRA_PRE_CAL_SUPPORT
+ int ret = 0, rst_status;
+ unsigned long flag;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ spin_lock_irqsave(&infra_ctx->rst_lock, flag);
+ rst_status = g_conninfra_ctx.rst_status;
+ spin_unlock_irqrestore(&infra_ctx->rst_lock, flag);
+
+ if (rst_status > CHIP_RST_NONE) {
+ pr_info("rst is ongoing, skip pre_cal");
+ return 0;
+ }
+
+ ret = msg_thread_send(&infra_ctx->msg_ctx,
+ CONNINFRA_OPID_PRE_CAL_PREPARE);
+ if (ret) {
+ pr_err("[%s] send msg fail, ret = %d\n", __func__, ret);
+ return -1;
+ }
+#endif /* CFG_CONNINFRA_PRE_CAL_SUPPORT */
+ return 0;
+}
+
+int conninfra_core_screen_off(void)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ ret = msg_thread_send(&infra_ctx->msg_ctx,
+ CONNINFRA_OPID_PRE_CAL_CHECK);
+ if (ret) {
+ pr_err("[%s] send msg fail, ret = %d\n", __func__, ret);
+ return -1;
+ }
+
+ return 0;
+}
+
+int conninfra_core_reg_readable(void)
+{
+ int ret = 0, rst_status;
+ unsigned long flag;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+
+ /* check if in reseting, can not read */
+ spin_lock_irqsave(&g_conninfra_ctx.rst_lock, flag);
+ rst_status = g_conninfra_ctx.rst_status;
+ spin_unlock_irqrestore(&g_conninfra_ctx.rst_lock, flag);
+
+ if (rst_status >= CHIP_RST_RESET &&
+ rst_status < CHIP_RST_POST_CB)
+ return 0;
+
+ ret = osal_lock_sleepable_lock(&infra_ctx->core_lock);
+ if (ret) {
+ pr_err("core_lock fail!!");
+ return 0;
+ }
+
+ if (infra_ctx->infra_drv_status == DRV_STS_POWER_ON)
+ ret = consys_hw_reg_readable();
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+
+ return ret;
+}
+
+int conninfra_core_reg_readable_no_lock(void)
+{
+ int rst_status;
+ unsigned long flag;
+
+ /* check if in reseting, can not read */
+ spin_lock_irqsave(&g_conninfra_ctx.rst_lock, flag);
+ rst_status = g_conninfra_ctx.rst_status;
+ spin_unlock_irqrestore(&g_conninfra_ctx.rst_lock, flag);
+
+ if (rst_status >= CHIP_RST_RESET &&
+ rst_status < CHIP_RST_POST_CB)
+ return 0;
+
+ return consys_hw_reg_readable();
+}
+
+int conninfra_core_is_bus_hang(void)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ ret = osal_lock_sleepable_lock(&infra_ctx->core_lock);
+ if (ret) {
+ pr_err("core_lock fail!!");
+ return 0;
+ }
+
+ if (infra_ctx->infra_drv_status == DRV_STS_POWER_ON)
+ ret = consys_hw_is_bus_hang();
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+
+ return ret;
+
+}
+
+int conninfra_core_is_consys_reg(phys_addr_t addr)
+{
+ return consys_hw_is_connsys_reg(addr);
+}
+
+int conninfra_core_reg_read(unsigned long address, unsigned int *value, unsigned int mask)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ ret = osal_lock_sleepable_lock(&infra_ctx->core_lock);
+ if (ret) {
+ pr_err("core_lock fail!!");
+ return 0;
+ }
+
+ if (infra_ctx->infra_drv_status == DRV_STS_POWER_ON) {
+ if (consys_reg_mng_is_host_csr(address))
+ ret = consys_reg_mng_reg_read(address, value, mask);
+ else if (consys_hw_reg_readable())
+ ret = consys_reg_mng_reg_read(address, value, mask);
+ else
+ pr_info("CR (%lx) is not readable\n", address);
+ } else
+ pr_info("CR (%lx) cannot read. conninfra is off\n", address);
+
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+ return ret;
+}
+
+int conninfra_core_reg_write(unsigned long address, unsigned int value, unsigned int mask)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ ret = osal_lock_sleepable_lock(&infra_ctx->core_lock);
+ if (ret) {
+ pr_err("core_lock fail!!");
+ return 0;
+ }
+
+ if (infra_ctx->infra_drv_status == DRV_STS_POWER_ON) {
+ if (consys_reg_mng_is_host_csr(address))
+ ret = consys_reg_mng_reg_write(address, value, mask);
+ else if (consys_hw_reg_readable())
+ ret = consys_reg_mng_reg_write(address, value, mask);
+ else
+ pr_info("CR (%p) is not readable\n", (void*)address);
+ } else
+ pr_info("CR (%p) cannot read. conninfra is off\n", (void*)address);
+
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+ return ret;
+
+}
+
+int conninfra_core_lock_rst(void)
+{
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+ int ret = 0;
+ unsigned long flag;
+
+ spin_lock_irqsave(&infra_ctx->rst_lock, flag);
+
+ ret = infra_ctx->rst_status;
+ if (infra_ctx->rst_status > CHIP_RST_NONE &&
+ infra_ctx->rst_status < CHIP_RST_DONE) {
+ /* do nothing */
+ } else {
+ infra_ctx->rst_status = CHIP_RST_START;
+ }
+ spin_unlock_irqrestore(&infra_ctx->rst_lock, flag);
+
+ pr_info("[%s] ret=[%d]", __func__, ret);
+ return ret;
+}
+
+int conninfra_core_unlock_rst(void)
+{
+ unsigned long flag;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ spin_lock_irqsave(&infra_ctx->rst_lock, flag);
+ infra_ctx->rst_status = CHIP_RST_NONE;
+ spin_unlock_irqrestore(&infra_ctx->rst_lock, flag);
+ return 0;
+}
+
+int conninfra_core_trg_chip_rst(enum consys_drv_type drv, char *reason)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ infra_ctx->trg_drv = drv;
+ snprintf(infra_ctx->trg_reason, CHIP_RST_REASON_MAX_LEN, "%s", reason);
+ ret = msg_thread_send_1(&infra_ctx->cb_ctx,
+ CONNINFRA_CB_OPID_CHIP_RST, drv);
+ if (ret) {
+ pr_err("[%s] send msg fail, ret = %d", __func__, ret);
+ return -1;
+ }
+ pr_info("trg_reset DONE!");
+ return 0;
+}
+
+int conninfra_core_thermal_query(int *temp_val)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ ret = msg_thread_send_wait_1(&infra_ctx->msg_ctx,
+ CONNINFRA_OPID_THERM_CTRL, 0,
+ (size_t) temp_val);
+ if (ret) {
+ pr_err("send msg fail ret=%d\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+void conninfra_core_clock_fail_dump_cb(void)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ ret = msg_thread_send(&infra_ctx->msg_ctx,
+ CONNINFRA_OPID_CLOCK_FAIL_DUMP);
+ if (ret)
+ pr_err("failed (ret = %d)", ret);
+}
+
+static inline char* conninfra_core_spi_subsys_string(enum sys_spi_subsystem subsystem)
+{
+ static char* subsys_name[] = {
+ "SYS_SPI_WF1",
+ "SYS_SPI_WF",
+ "SYS_SPI_BT",
+ "SYS_SPI_FM",
+ "SYS_SPI_GPS",
+ "SYS_SPI_TOP",
+ "SYS_SPI_WF2",
+ "SYS_SPI_WF3",
+ "SYS_SPI_MAX"
+ };
+ return subsys_name[subsystem];
+}
+
+int conninfra_core_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+ size_t data_ptr = (size_t)data;
+
+ ret = msg_thread_send_wait_3(&infra_ctx->msg_ctx,
+ CONNINFRA_OPID_RFSPI_READ, 0,
+ subsystem, addr, data_ptr);
+ if (ret) {
+ pr_err("[%s] failed (ret = %d). subsystem=%s addr=%x\n",
+ __func__, ret, conninfra_core_spi_subsys_string(subsystem), addr);
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+ return 0;
+}
+
+int conninfra_core_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data)
+{
+ int ret;
+ ret = msg_thread_send_wait_3(&(g_conninfra_ctx.msg_ctx), CONNINFRA_OPID_RFSPI_WRITE, 0,
+ subsystem, addr, data);
+ if (ret) {
+ pr_err("[%s] failed (ret = %d). subsystem=%s addr=0x%x data=%d\n",
+ __func__, ret, conninfra_core_spi_subsys_string(subsystem), addr, data);
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+ return 0;
+}
+
+int conninfra_core_adie_top_ck_en_on(enum consys_adie_ctl_type type)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ ret = msg_thread_send_wait_1(&infra_ctx->msg_ctx,
+ CONNINFRA_OPID_ADIE_TOP_CK_EN_ON, 0, type);
+ if (ret) {
+ pr_err("[%s] fail, ret = %d\n", __func__, ret);
+ return -1;
+ }
+ return 0;
+}
+
+int conninfra_core_adie_top_ck_en_off(enum consys_adie_ctl_type type)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ ret = msg_thread_send_wait_1(&infra_ctx->msg_ctx,
+ CONNINFRA_OPID_ADIE_TOP_CK_EN_OFF, 0, type);
+ if (ret) {
+ pr_err("[%s] fail, ret = %d\n", __func__, ret);
+ return -1;
+ }
+ return 0;
+}
+
+int conninfra_core_force_conninfra_wakeup(void)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ /* if in conninfra_cored thread */
+ if (current == infra_ctx->msg_ctx.thread.pThread)
+ return opfunc_force_conninfra_wakeup(NULL);
+
+ ret = msg_thread_send_wait(&infra_ctx->msg_ctx,
+ CONNINFRA_OPID_FORCE_CONNINFRA_WAKUP, 0);
+ if (ret) {
+ pr_err("[%s] fail, ret = %d\n", __func__, ret);
+ return -1;
+ }
+ return 0;
+}
+
+int conninfra_core_force_conninfra_sleep(void)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ /* if in conninfra_cored thread */
+ if (current == infra_ctx->msg_ctx.thread.pThread)
+ return opfunc_force_conninfra_sleep(NULL);
+
+ ret = msg_thread_send_wait(&infra_ctx->msg_ctx,
+ CONNINFRA_OPID_FORCE_CONNINFRA_SLEEP, 0);
+ if (ret) {
+ pr_err("[%s] fail, ret = %d\n", __func__, ret);
+ return -1;
+ }
+ return 0;
+}
+
+int conninfra_core_spi_clock_switch(enum connsys_spi_speed_type type)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ ret = msg_thread_send_wait_1(&infra_ctx->msg_ctx,
+ CONNINFRA_OPID_SPI_CLOCK_SWITCH, 0, type);
+ if (ret) {
+ pr_err("[%s] fail, ret = %d\n", __func__, ret);
+ return -1;
+ }
+ return 0;
+}
+
+int conninfra_core_subsys_ops_reg(enum consys_drv_type type,
+ struct sub_drv_ops_cb *cb)
+{
+ unsigned long flag;
+ struct subsys_drv_inst *drv_inst;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+ int ret, trigger_pre_cal = 0;
+
+
+ spin_lock_irqsave(&g_conninfra_ctx.infra_lock, flag);
+ drv_inst = &g_conninfra_ctx.drv_inst[type];
+ memcpy(&g_conninfra_ctx.drv_inst[type].ops_cb, cb,
+ sizeof(struct sub_drv_ops_cb));
+
+ pr_info("[%s] [pre_cal] type=[%s] cb rst=[%p][%p] pre_cal=[%p][%p], therm=[%p]",
+ __func__, drv_name[type],
+ cb->rst_cb.pre_whole_chip_rst, cb->rst_cb.post_whole_chip_rst,
+ cb->pre_cal_cb.pwr_on_cb, cb->pre_cal_cb.do_cal_cb, cb->thermal_qry);
+
+#if CFG_CONNINFRA_PRE_CAL_SUPPORT
+ pr_info("[%s] [pre_cal] type=[%d] bt=[%p] wf=[%p]", __func__, type,
+ infra_ctx->drv_inst[CONNDRV_TYPE_BT].ops_cb.pre_cal_cb.pwr_on_cb,
+ infra_ctx->drv_inst[CONNDRV_TYPE_WIFI].ops_cb.pre_cal_cb.pwr_on_cb);
+
+ /* trigger pre-cal if BT and WIFI are registered */
+ if (infra_ctx->drv_inst[CONNDRV_TYPE_BT].ops_cb.pre_cal_cb.do_cal_cb != NULL &&
+ infra_ctx->drv_inst[CONNDRV_TYPE_WIFI].ops_cb.pre_cal_cb.do_cal_cb != NULL)
+ trigger_pre_cal = 1;
+#endif /* CFG_CONNINFRA_PRE_CAL_SUPPORT */
+
+ spin_unlock_irqrestore(&g_conninfra_ctx.infra_lock, flag);
+
+ if (trigger_pre_cal) {
+ pr_info("[%s] [pre_cal] trigger pre-cal BT/WF are registered", __func__);
+ ret = msg_thread_send(&infra_ctx->msg_ctx,
+ CONNINFRA_OPID_PRE_CAL_PREPARE);
+ if (ret)
+ pr_err("send pre_cal_prepare msg fail, ret = %d\n", ret);
+ }
+
+ return 0;
+}
+
+int conninfra_core_subsys_ops_unreg(enum consys_drv_type type)
+{
+ unsigned long flag;
+
+ spin_lock_irqsave(&g_conninfra_ctx.infra_lock, flag);
+ memset(&g_conninfra_ctx.drv_inst[type].ops_cb, 0,
+ sizeof(struct sub_drv_ops_cb));
+ spin_unlock_irqrestore(&g_conninfra_ctx.infra_lock, flag);
+
+ return 0;
+}
+
+#if CFG_CONNINFRA_PRE_CAL_BLOCKING
+void conninfra_core_pre_cal_blocking(void)
+{
+#define BLOCKING_CHECK_MONITOR_THREAD 100
+ int ret;
+ struct pre_cal_info *cal_info = &g_conninfra_ctx.cal_info;
+ struct timeval start, end;
+ unsigned long diff;
+
+ do_gettimeofday(&start);
+
+ /* non-zero means lock got, zero means not */
+ while (true) {
+ ret = osal_trylock_sleepable_lock(&cal_info->pre_cal_lock);
+ if (ret) {
+ if (cal_info->status == PRE_CAL_NOT_INIT ||
+ cal_info->status == PRE_CAL_SCHEDULED) {
+ pr_info("[%s] [pre_cal] ret=[%d] status=[%d]", __func__, ret, cal_info->status);
+ osal_unlock_sleepable_lock(&cal_info->pre_cal_lock);
+ osal_sleep_ms(100);
+ continue;
+ }
+ osal_unlock_sleepable_lock(&cal_info->pre_cal_lock);
+ break;
+ } else {
+ pr_info("[%s] [pre_cal] ret=[%d] status=[%d]", __func__, ret, cal_info->status);
+ osal_sleep_ms(100);
+ }
+ }
+ do_gettimeofday(&end);
+
+ diff = timeval_to_ms(&start, &end);
+ if (diff > BLOCKING_CHECK_MONITOR_THREAD)
+ pr_info("blocking spent [%lu]", diff);
+}
+#endif /* CFG_CONNINFRA_PRE_CAL_BLOCKING */
+
+
+static void _conninfra_core_update_rst_status(enum chip_rst_status status)
+{
+ unsigned long flag;
+
+ spin_lock_irqsave(&g_conninfra_ctx.rst_lock, flag);
+ g_conninfra_ctx.rst_status = status;
+ spin_unlock_irqrestore(&g_conninfra_ctx.rst_lock, flag);
+}
+
+
+int conninfra_core_is_rst_locking(void)
+{
+ unsigned long flag;
+ int ret = 0;
+
+ spin_lock_irqsave(&g_conninfra_ctx.rst_lock, flag);
+
+ if (g_conninfra_ctx.rst_status > CHIP_RST_NONE &&
+ g_conninfra_ctx.rst_status < CHIP_RST_POST_CB)
+ ret = 1;
+ spin_unlock_irqrestore(&g_conninfra_ctx.rst_lock, flag);
+ return ret;
+}
+
+static void conninfra_core_pre_cal_work_handler(struct work_struct *work)
+{
+ int ret;
+
+ /* if fail, do we need re-try? */
+ ret = conninfra_core_pre_cal_start();
+ pr_info("[%s] [pre_cal][ret=%d] -----------", __func__, ret);
+}
+
+
+int conninfra_core_dump_power_state(void)
+{
+ int ret = 0;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ ret = msg_thread_send(&infra_ctx->msg_ctx,
+ CONNINFRA_OPID_DUMP_POWER_STATE);
+ if (ret) {
+ pr_err("[%s] fail, ret = %d\n", __func__, ret);
+ return -1;
+ }
+ return 0;
+
+}
+
+void conninfra_core_config_setup(void)
+{
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+ int ret;
+
+ ret = osal_lock_sleepable_lock(&infra_ctx->core_lock);
+ if (ret) {
+ pr_err("[%s] core_lock fail!!\n", __func__);
+ return;
+ }
+
+ if (infra_ctx->infra_drv_status == DRV_STS_POWER_ON)
+ consys_hw_config_setup();
+
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+}
+
+int conninfra_core_pmic_event_cb(unsigned int id, unsigned int event)
+{
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+ int ret;
+
+ if (conninfra_core_is_rst_locking()) {
+ return 0;
+ }
+
+ ret = osal_lock_sleepable_lock(&infra_ctx->core_lock);
+ if (ret) {
+ pr_err("[%s] core_lock fail!!\n", __func__);
+ return 0;
+ }
+
+ if (infra_ctx->infra_drv_status == DRV_STS_POWER_ON)
+ consys_hw_pmic_event_cb(id, event);
+
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+
+ return 0;
+}
+
+int conninfra_core_bus_clock_ctrl(enum consys_drv_type drv_type, unsigned int bus_clock, int status)
+{
+ int ret = -1, rst_status;
+ unsigned long flag;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ /* check if in reseting, can not read */
+ spin_lock_irqsave(&g_conninfra_ctx.rst_lock, flag);
+ rst_status = g_conninfra_ctx.rst_status;
+ spin_unlock_irqrestore(&g_conninfra_ctx.rst_lock, flag);
+
+ if (rst_status >= CHIP_RST_RESET &&
+ rst_status < CHIP_RST_POST_CB)
+ return -1;
+
+ ret = osal_lock_sleepable_lock(&infra_ctx->core_lock);
+ if (ret) {
+ pr_err("[%s] core_lock fail!!", __func__);
+ return -1;
+ }
+
+ if (infra_ctx->infra_drv_status == DRV_STS_POWER_ON)
+ ret = consys_hw_bus_clock_ctrl(drv_type, bus_clock, status);
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+
+ return ret;
+}
+
+int conninfra_core_debug_dump(void)
+{
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+ int ret = -1;
+ unsigned int i;
+
+ ret = osal_lock_sleepable_lock(&infra_ctx->core_lock);
+ if (ret) {
+ pr_err("[%s] core_lock fail, ret=%d", __func__, ret);
+ return -1;
+ }
+
+ pr_info("%s\n", __func__);
+ msg_thread_dump(&infra_ctx->msg_ctx);
+ msg_thread_dump(&infra_ctx->cb_ctx);
+ for (i = 0; i < CONNDRV_TYPE_MAX; i++) {
+ msg_thread_dump(&(infra_ctx->drv_inst[i].msg_ctx));
+ }
+
+ osal_unlock_sleepable_lock(&infra_ctx->core_lock);
+
+ return ret;
+}
+
+int conninfra_core_init(void)
+{
+ int ret = 0, i;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ osal_memset(&g_conninfra_ctx, 0, sizeof(g_conninfra_ctx));
+
+ reset_chip_rst_trg_data();
+
+ spin_lock_init(&infra_ctx->infra_lock);
+ osal_sleepable_lock_init(&infra_ctx->core_lock);
+ spin_lock_init(&infra_ctx->rst_lock);
+
+
+ ret = msg_thread_init(&infra_ctx->msg_ctx, "conninfra_cored",
+ conninfra_core_opfunc, CONNINFRA_OPID_MAX);
+ if (ret) {
+ pr_err("msg_thread init fail(%d)\n", ret);
+ return -1;
+ }
+
+ ret = msg_thread_init(&infra_ctx->cb_ctx, "conninfra_cb",
+ conninfra_core_cb_opfunc, CONNINFRA_CB_OPID_MAX);
+ if (ret) {
+ pr_err("callback msg thread init fail(%d)\n", ret);
+ return -1;
+ }
+ /* init subsys drv state */
+ for (i = 0; i < CONNDRV_TYPE_MAX; i++) {
+ ret += msg_thread_init(&infra_ctx->drv_inst[i].msg_ctx,
+ drv_thread_name[i], infra_subdrv_opfunc,
+ INFRA_SUBDRV_OPID_MAX);
+ }
+
+ if (ret) {
+ pr_err("subsys callback thread init fail.\n");
+ return -1;
+ }
+
+ INIT_WORK(&infra_ctx->cal_info.pre_cal_work, conninfra_core_pre_cal_work_handler);
+ osal_sleepable_lock_init(&infra_ctx->cal_info.pre_cal_lock);
+
+ return ret;
+}
+
+
+int conninfra_core_deinit(void)
+{
+ int ret, i;
+ struct conninfra_ctx *infra_ctx = &g_conninfra_ctx;
+
+ osal_sleepable_lock_deinit(&infra_ctx->cal_info.pre_cal_lock);
+
+ for (i = 0; i < CONNDRV_TYPE_MAX; i++) {
+ ret = msg_thread_deinit(&infra_ctx->drv_inst[i].msg_ctx);
+ if (ret)
+ pr_warn("subdrv [%d] msg_thread deinit fail (%d)\n",
+ i, ret);
+ }
+
+ ret = msg_thread_deinit(&infra_ctx->msg_ctx);
+ if (ret) {
+ pr_err("msg_thread_deinit fail(%d)\n", ret);
+ return -1;
+ }
+
+ osal_sleepable_lock_deinit(&infra_ctx->core_lock);
+ //osal_sleepable_lock_deinit(&infra_ctx->rst_lock);
+
+ return 0;
+}
+
+
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/core/include/conninfra_core.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/core/include/conninfra_core.h
new file mode 100755
index 0000000..2c1e3e2
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/core/include/conninfra_core.h
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _CONNINFRA_CORE_H_
+#define _CONNINFRA_CORE_H_
+
+#include <linux/semaphore.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/time.h>
+
+#include "osal.h"
+#include "msg_thread.h"
+#include "conninfra.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+#define CHIP_RST_REASON_MAX_LEN 128
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+typedef enum _ENUM_DRV_STS_ {
+ DRV_STS_POWER_OFF = 0, /* initial state */
+ DRV_STS_POWER_ON = 1, /* powered on */
+ DRV_STS_RESET = 2,
+ DRV_STS_MAX
+} ENUM_DRV_STS, *P_ENUM_DRV_STS;
+
+enum pre_cal_status {
+ PRE_CAL_NOT_INIT = 0,
+ PRE_CAL_NEED_RESCHEDULE = 1,
+ PRE_CAL_SCHEDULED = 2,
+ PRE_CAL_EXECUTING = 3,
+ PRE_CAL_DONE = 4
+};
+
+enum chip_rst_status {
+ CHIP_RST_NONE = 0,
+ CHIP_RST_START = 1,
+ CHIP_RST_PRE_CB = 2,
+ CHIP_RST_RESET = 3,
+ CHIP_RST_POST_CB = 4,
+ CHIP_RST_DONE = 5
+};
+
+struct subsys_drv_inst {
+ ENUM_DRV_STS drv_status; /* Controlled driver status */
+ unsigned int rst_state;
+ struct sub_drv_ops_cb ops_cb;
+ struct msg_thread_ctx msg_ctx;
+};
+
+struct pre_cal_info {
+ enum pre_cal_status status;
+ struct work_struct pre_cal_work;
+ OSAL_SLEEPABLE_LOCK pre_cal_lock;
+};
+
+
+/*
+ * state of conninfra
+ *
+ */
+struct conninfra_ctx {
+ ENUM_DRV_STS infra_drv_status;
+
+ struct subsys_drv_inst drv_inst[CONNDRV_TYPE_MAX];
+ /*struct spinlock infra_lock;*/
+ spinlock_t infra_lock;
+
+ OSAL_SLEEPABLE_LOCK core_lock;
+
+ /* chip reset */
+ enum chip_rst_status rst_status;
+ spinlock_t rst_lock;
+
+ struct semaphore rst_sema;
+ atomic_t rst_state;
+ enum consys_drv_type trg_drv;
+ char trg_reason[CHIP_RST_REASON_MAX_LEN];
+
+ /* pre_cal */
+ struct semaphore pre_cal_sema;
+ atomic_t pre_cal_state;
+
+ struct msg_thread_ctx msg_ctx;
+ struct msg_thread_ctx cb_ctx;
+
+ unsigned int hw_ver;
+ unsigned int fw_ver;
+ unsigned int ip_ver;
+
+ struct pre_cal_info cal_info;
+
+};
+
+//typedef enum _ENUM_CONNINFRA_CORE_OPID_T {
+typedef enum {
+ CONNINFRA_OPID_PWR_ON = 0,
+ CONNINFRA_OPID_PWR_OFF = 1,
+ CONNINFRA_OPID_THERM_CTRL = 2,
+ CONNINFRA_OPID_RFSPI_READ = 5,
+ CONNINFRA_OPID_RFSPI_WRITE = 6,
+ CONNINFRA_OPID_ADIE_TOP_CK_EN_ON = 7,
+ CONNINFRA_OPID_ADIE_TOP_CK_EN_OFF = 8,
+ CONNINFRA_OPID_SPI_CLOCK_SWITCH = 9,
+ CONNINFRA_OPID_CLOCK_FAIL_DUMP = 10,
+ CONNINFRA_OPID_PRE_CAL_PREPARE = 11,
+ CONNINFRA_OPID_PRE_CAL_CHECK = 12,
+ CONNINFRA_OPID_FORCE_CONNINFRA_WAKUP = 13,
+ CONNINFRA_OPID_FORCE_CONNINFRA_SLEEP = 14,
+ CONNINFRA_OPID_DUMP_POWER_STATE = 15,
+ CONNINFRA_OPID_MAX
+} conninfra_core_opid;
+
+/* For the operation which may callback subsys driver */
+typedef enum {
+ CONNINFRA_CB_OPID_CHIP_RST = 0,
+ CONNINFRA_CB_OPID_PRE_CAL = 1,
+ CONNINFRA_CB_OPID_MAX
+} conninfra_core_cb_opid;
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+extern int conninfra_core_init(void);
+extern int conninfra_core_deinit(void);
+
+int conninfra_core_power_on(enum consys_drv_type type);
+int conninfra_core_power_off(enum consys_drv_type type);
+
+int conninfra_core_lock_rst(void);
+int conninfra_core_unlock_rst(void);
+int conninfra_core_trg_chip_rst(enum consys_drv_type drv, char *reason);
+
+int conninfra_core_subsys_ops_reg(enum consys_drv_type type,
+ struct sub_drv_ops_cb *cb);
+int conninfra_core_subsys_ops_unreg(enum consys_drv_type type);
+
+
+int conninfra_core_screen_on(void);
+int conninfra_core_screen_off(void);
+
+/* pre_cal */
+int conninfra_core_pre_cal_start(void);
+#if CFG_CONNINFRA_PRE_CAL_BLOCKING
+void conninfra_core_pre_cal_blocking(void);
+#endif
+
+/* reg control */
+/* NOTE: NOT thread-safe
+ * return value
+ * 1 : Yes, 0: NO
+ */
+int conninfra_core_reg_readable(void);
+int conninfra_core_reg_readable_no_lock(void);
+int conninfra_core_is_bus_hang(void);
+
+int conninfra_core_is_consys_reg(phys_addr_t addr);
+int conninfra_core_reg_read(unsigned long address, unsigned int *value, unsigned int mask);
+int conninfra_core_reg_write(unsigned long address, unsigned int value, unsigned int mask);
+
+int conninfra_core_is_rst_locking(void);
+
+int conninfra_core_thermal_query(int *temp_val);
+void conninfra_core_clock_fail_dump_cb(void);
+
+int conninfra_core_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data);
+int conninfra_core_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data);
+
+int conninfra_core_adie_top_ck_en_on(enum consys_adie_ctl_type type);
+int conninfra_core_adie_top_ck_en_off(enum consys_adie_ctl_type type);
+
+int conninfra_core_force_conninfra_wakeup(void);
+int conninfra_core_force_conninfra_sleep(void);
+
+int conninfra_core_spi_clock_switch(enum connsys_spi_speed_type type);
+
+int conninfra_core_dump_power_state(void);
+int conninfra_core_pmic_event_cb(unsigned int, unsigned int);
+
+void conninfra_core_config_setup(void);
+
+int conninfra_core_bus_clock_ctrl(enum consys_drv_type drv_type, unsigned int bus_clock, int status);
+
+int conninfra_core_debug_dump(void);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _CONNINFRA_CORE_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/conninfra_dbg.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/conninfra_dbg.c
new file mode 100644
index 0000000..83df214
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/conninfra_dbg.c
@@ -0,0 +1,600 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/proc_fs.h>
+#include "osal.h"
+#include "conninfra_dbg.h"
+#include "conninfra.h"
+#include "conninfra_core.h"
+#include "emi_mng.h"
+#if CFG_CONNINFRA_COREDUMP_SUPPORT
+#include "connsys_debug_utility.h"
+#endif
+
+#define CONNINFRA_DBG_PROCNAME "driver/conninfra_dbg"
+
+#define BUF_LEN_MAX 384
+
+static struct proc_dir_entry *g_conninfra_dbg_entry;
+
+static ssize_t conninfra_dbg_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos);
+static ssize_t conninfra_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos);
+
+static int conninfra_dbg_hwver_get(int par1, int par2, int par3);
+
+static int conninfra_dbg_chip_rst(int par1, int par2, int par3);
+
+static int conninfra_dbg_read_chipid(int par1, int par2, int par3);
+
+static int conninfra_dbg_force_conninfra_wakeup(int par1, int par2, int par3);
+static int conninfra_dbg_force_conninfra_sleep(int par1, int par2, int par3);
+
+static int conninfra_dbg_reg_read(int par1, int par2, int par3);
+static int conninfra_dbg_reg_write(int par1, int par2, int par3);
+
+static int conninfra_dbg_efuse_read(int par1, int par2, int par3);
+static int conninfra_dbg_efuse_write(int par1, int par2, int par3);
+
+static int conninfra_dbg_ap_reg_read(int par1, int par2, int par3);
+static int conninfra_dbg_ap_reg_write(int par1, int par2, int par3);
+
+
+#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH
+/* consys log, need this ?? */
+static int conninfra_dbg_set_fw_log_mode(int par1, int par2, int par3);
+static int conninfra_dbg_fw_log_dump_emi(int par1, int offset, int size);
+#endif
+
+static int conninfra_dbg_suspend_debug(int par1, int offset, int size);
+static int conninfra_dbg_fw_log_ctrl(int par1, int onoff, int level);
+
+static int conninfra_dbg_thermal_query(int par1, int count, int interval);
+static int conninfra_dbg_thermal_ctrl(int par1, int par2, int par3);
+static int conninfra_dbg_step_ctrl(int par1, int par2, int par3);
+
+static int conninfra_dbg_connsys_emi_dump(int par1, int par2, int par3);
+
+static int conninfra_dbg_connsys_coredump_ctrl(int par1, int par2, int par3);
+static int conninfra_dbg_connsys_coredump_mode_query(int par1, int par2, int par3);
+
+static int conninfra_dbg_thread_status_dump(int par1, int par2, int par3);
+
+static const CONNINFRA_DEV_DBG_FUNC conninfra_dev_dbg_func[] = {
+ [0x0] = conninfra_dbg_hwver_get,
+ [0x1] = conninfra_dbg_chip_rst,
+ [0x2] = conninfra_dbg_read_chipid,
+
+ [0x3] = conninfra_dbg_force_conninfra_wakeup,
+ [0x4] = conninfra_dbg_force_conninfra_sleep,
+ [0x5] = conninfra_dbg_reg_read,
+ [0x6] = conninfra_dbg_reg_write,
+
+ [0x7] = conninfra_dbg_efuse_read,
+ [0x8] = conninfra_dbg_efuse_write,
+ [0x9] = conninfra_dbg_ap_reg_read,
+ [0xa] = conninfra_dbg_ap_reg_write,
+
+ [0xb] = conninfra_dbg_fw_log_ctrl,
+ [0xc] = conninfra_dbg_thermal_query,
+ [0xd] = conninfra_dbg_thermal_ctrl,
+ [0xe] = conninfra_dbg_step_ctrl,
+
+ [0xf] = conninfra_dbg_suspend_debug,
+#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH
+ [0x10] = conninfra_dbg_set_fw_log_mode,
+ [0x11] = conninfra_dbg_fw_log_dump_emi,
+#endif
+ [0x12] = conninfra_dbg_connsys_emi_dump,
+ [0x13] = conninfra_dbg_connsys_coredump_ctrl,
+ [0x14] = conninfra_dbg_connsys_coredump_mode_query,
+ [0x15] = conninfra_dbg_thread_status_dump,
+};
+
+#define CONNINFRA_DBG_DUMP_BUF_SIZE 1024
+char g_dump_buf[CONNINFRA_DBG_DUMP_BUF_SIZE];
+char *g_dump_buf_ptr;
+int g_dump_buf_len;
+static OSAL_SLEEPABLE_LOCK g_dump_lock;
+
+int conninfra_dbg_hwver_get(int par1, int par2, int par3)
+{
+ pr_info("query chip version\n");
+ /* TODO: */
+ return 0;
+}
+
+int conninfra_dbg_chip_rst(int par1, int par2, int par3)
+{
+ /* TODO: */
+ conninfra_trigger_whole_chip_rst(CONNDRV_TYPE_BT, "Conninfra_dbg");
+ return 0;
+}
+
+
+int conninfra_dbg_read_chipid(int par1, int par2, int par3)
+{
+ //pr_info("chip id = %d\n", wmt_lib_get_icinfo(WMTCHIN_CHIPID));
+
+ return 0;
+}
+
+int conninfra_dbg_reg_read(int par1, int par2, int par3)
+{
+ int ret = 0, sz;
+ char buf[CONNINFRA_DBG_DUMP_BUF_SIZE];
+
+ /* par2-->register address */
+ /* par3-->register mask */
+ unsigned int value = 0x0;
+ int iRet;
+
+ iRet = conninfra_core_reg_read(par2, &value, par3);
+ snprintf(buf, CONNINFRA_DBG_DUMP_BUF_SIZE,
+ "read chip register (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n",
+ par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value);
+
+ pr_info("%s", buf);
+ ret = osal_lock_sleepable_lock(&g_dump_lock);
+ if (ret) {
+ pr_err("dump_lock fail!!");
+ return ret;
+ }
+
+ if (g_dump_buf_len < CONNINFRA_DBG_DUMP_BUF_SIZE) {
+ sz = strlen(buf);
+ sz = (sz < CONNINFRA_DBG_DUMP_BUF_SIZE - g_dump_buf_len) ?
+ sz : CONNINFRA_DBG_DUMP_BUF_SIZE - g_dump_buf_len;
+ strncpy(g_dump_buf + g_dump_buf_len, buf, sz);
+ g_dump_buf_len += sz;
+ }
+
+ osal_unlock_sleepable_lock(&g_dump_lock);
+
+ return 0;
+}
+
+int conninfra_dbg_reg_write(int par1, int par2, int par3)
+{
+ /* par2-->register address */
+ /* par3-->value to set */
+ int ret;
+
+ ret = conninfra_core_reg_write(par2, par3, 0xffffffff);
+ pr_info("write chip register (0x%08x) with value (0x%08x) %s\n",
+ par2, par3, ret != 0 ? "failed" : "succeed");
+ return 0;
+}
+
+
+int conninfra_dbg_force_conninfra_wakeup(int par1, int par2, int par3)
+{
+ int ret;
+
+ ret = conninfra_core_force_conninfra_wakeup();
+ if (ret)
+ pr_info("conninfra wakup fail\n");
+ else
+ pr_info("conninfra wakup success\n");
+
+ return 0;
+}
+
+int conninfra_dbg_force_conninfra_sleep(int par1, int par2, int par3)
+{
+ int ret;
+
+ ret = conninfra_core_force_conninfra_sleep();
+ if (ret)
+ pr_info("conninfra sleep fail\n");
+ else
+ pr_info("conninfra sleep success\n");
+
+ return 0;
+}
+
+int conninfra_dbg_efuse_read(int par1, int par2, int par3)
+{
+#if 0
+ /* par2-->efuse address */
+ /* par3-->register mask */
+ Uint value = 0x0;
+ Uint iRet = -1;
+
+ iRet = wmt_lib_efuse_rw(0, par2, &value, par3);
+ pr_info("read combo chip efuse (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n",
+ par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value);
+#endif
+ return 0;
+}
+
+int conninfra_dbg_efuse_write(int par1, int par2, int par3)
+{
+#if 0
+ /* par2-->efuse address */
+ /* par3-->value to set */
+ Uint iRet = -1;
+
+ iRet = wmt_lib_efuse_rw(1, par2, &par3, 0xffffffff);
+ pr_info("write combo chip efuse (0x%08x) with value (0x%08x) %s\n",
+ par2, par3, iRet != 0 ? "failed" : "succeed");
+#endif
+ return 0;
+}
+
+
+static int conninfra_dbg_ap_reg_read(int par1, int par2, int par3)
+{
+ int value = 0x0;
+ unsigned char *ap_reg_base = NULL;
+
+ pr_info("AP register read, reg address:0x%x\n", par2);
+ ap_reg_base = ioremap_nocache(par2, 0x4);
+ if (ap_reg_base) {
+ value = readl(ap_reg_base);
+ pr_info("AP register read, reg address:0x%x, value:0x%x\n", par2, value);
+ iounmap(ap_reg_base);
+ } else
+ pr_err("AP register ioremap fail!\n");
+
+ return 0;
+}
+
+static int conninfra_dbg_ap_reg_write(int par1, int par2, int par3)
+{
+ int value = 0x0;
+ unsigned char *ap_reg_base = NULL;
+
+ pr_info("AP register write, reg address:0x%x, value:0x%x\n", par2, par3);
+
+ ap_reg_base = ioremap_nocache(par2, 0x4);
+ if (ap_reg_base) {
+ writel(par3, ap_reg_base);
+ value = readl(ap_reg_base);
+ pr_info("AP register write done, value after write:0x%x\n", value);
+ iounmap(ap_reg_base);
+ } else
+ pr_err("AP register ioremap fail!\n");
+
+ return 0;
+}
+
+#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH
+static int conninfra_dbg_set_fw_log_mode(int par1, int par2, int par3)
+{
+ //connsys_dedicated_log_set_log_mode(par2);
+ return 0;
+}
+
+static int conninfra_dbg_fw_log_dump_emi(int par1, int offset, int size)
+{
+ //connsys_dedicated_log_dump_emi(offset, size);
+ return 0;
+}
+#endif
+
+/********************************************************/
+/* par2: */
+/* 0: Off */
+/* others: alarm time (seconds) */
+/********************************************************/
+static int conninfra_dbg_suspend_debug(int par1, int par2, int par3)
+{
+#if 0
+ if (par2 > 0)
+ connsys_log_alarm_enable(par2);
+ else
+ connsys_log_alarm_disable();
+#endif
+ return 0;
+}
+
+
+static int conninfra_dbg_fw_log_ctrl(int par1, int onoff, int level)
+{
+ /* Parameter format
+ * onoff:
+ * - bit 24~31: unused
+ * - bit 16~23: subsys type
+ * - bit 8~15 : unused
+ * - bit 0~7 : on/off setting
+ * level: only lowest 8 bites will be used.
+ * - bit 8~31 : unused
+ * - bit 0~7 : log level setting
+ * Example:
+ * 1. To turn on MCU log
+ * onoff = 0x0001
+ * 2. To turn on Subsys Z log
+ * onoff = 0x0z01 (z = subsys)
+ * 3. To turn off Subsys Z log
+ * onoff = 0x0z00 (z = subsys)
+ */
+#if 0
+ UINT8 type = (unsigned char)(onoff >> 16);
+
+ pr_info("Configuring firmware log: type:%d, on/off:%d, level:%d\n",
+ type, (unsigned char)onoff, (unsigned char)level);
+ //wmt_lib_fw_log_ctrl(type, (unsigned char)onoff, (unsigned char)level);
+#endif
+ return 0;
+}
+
+int conninfra_dbg_thermal_query(int par1, int count, int interval)
+{
+ int temp, ret;
+
+ ret = conninfra_core_thermal_query(&temp);
+
+ pr_info("[Conninfra_Thermal_Query] ret=[%d] temp=[%d]", ret, temp);
+
+ return 0;
+}
+
+int conninfra_dbg_thermal_ctrl(int par1, int par2, int par3)
+{
+#if 0
+ if (par2 == 0) {
+ if (par3 >= 99) {
+ pr_info("Can`t set temp threshold greater or queal 99\n");
+ return -1;
+ }
+ wmt_dev_set_temp_threshold(par3);
+ }
+#endif
+ return 0;
+}
+
+static int conninfra_dbg_step_ctrl(int par1, int par2, int par3)
+{
+#if 0
+ if (par2 == 0)
+ wmt_step_print_version();
+ else if (par2 == 1) {
+ pr_info("STEP show: Start to change config\n");
+ wmt_step_deinit();
+ wmt_step_init();
+ pr_info("STEP show: End to change config\n");
+ }
+#endif
+ return 0;
+}
+
+static int conninfra_dbg_connsys_emi_dump(int par1, int par2, int par3)
+{
+ unsigned int start;
+ // make size 16-byte alignment
+ int size = (((par3 + 15) >> 4) << 4);
+ void __iomem *vir_addr = NULL;
+ char* buf = NULL;
+ struct consys_emi_addr_info* addr_info = emi_mng_get_phy_addr();
+ int i;
+
+ if (par2 & 0xf) {
+ pr_err("EMI dump fail: wrong offset(0x%x), should be 16-byte alignment\n", par2);
+ return -1;
+ }
+
+ start = (unsigned int)(par2 + addr_info->emi_ap_phy_addr);
+
+ buf = (char*)osal_malloc(sizeof(char)*size);
+ if (buf == NULL) {
+ pr_err("[%s] allocate buffer fail\n", __func__);
+ return -1;
+ }
+
+ pr_info("EMI dump, offset=0x%x(physical addr=0x%x), size=0x%x\n", par2, start, size);
+ vir_addr = ioremap_nocache(start, size);
+ if (!vir_addr) {
+ pr_err("ioremap fail");
+ osal_free(buf);
+ return -1;
+ }
+ memcpy_fromio(buf, vir_addr, size);
+ for (i = 0; i < size; i+= 16) {
+ pr_info(
+ "EMI[0x%x]: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ par2 + i,
+ buf[i + 0], buf[i + 1], buf[i + 2], buf[i + 3],
+ buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7],
+ buf[i + 8], buf[i + 9], buf[i + 0xa], buf[i + 0xb],
+ buf[i + 0xc], buf[i + 0xd], buf[i + 0xe], buf[i + 0xf]);
+ }
+
+ iounmap(vir_addr);
+ osal_free(buf);
+ return 0;
+}
+
+static int conninfra_dbg_connsys_coredump_ctrl(int par1, int par2, int par3)
+{
+#if CFG_CONNINFRA_COREDUMP_SUPPORT
+ unsigned int orig_mode = connsys_coredump_get_mode();
+
+ pr_info("Setup coredump mode from %d to %d\n", orig_mode, par2);
+ connsys_coredump_set_dump_mode(par2);
+#else
+ pr_info("Connsys coredump is not support");
+#endif
+ return 0;
+}
+
+static int conninfra_dbg_connsys_coredump_mode_query(int par1, int par2, int par3)
+{
+#if CFG_CONNINFRA_COREDUMP_SUPPORT
+ unsigned int orig_mode = connsys_coredump_get_mode();
+
+ pr_info("Connsys coredump mode is [%d]\n", orig_mode);
+ return orig_mode;
+#else
+ pr_info("Connsys coredump is not support");
+ return 0;
+#endif
+}
+
+static int conninfra_dbg_thread_status_dump(int par1, int par2, int par3)
+{
+ conninfra_debug_dump();
+ return 0;
+}
+
+ssize_t conninfra_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
+{
+ int ret = 0;
+ int dump_len;
+
+ ret = osal_lock_sleepable_lock(&g_dump_lock);
+ if (ret) {
+ pr_err("dump_lock fail!!");
+ return ret;
+ }
+
+ if (g_dump_buf_len == 0)
+ goto exit;
+
+ if (*f_pos == 0)
+ g_dump_buf_ptr = g_dump_buf;
+
+ dump_len = g_dump_buf_len >= count ? count : g_dump_buf_len;
+ ret = copy_to_user(buf, g_dump_buf_ptr, dump_len);
+ if (ret) {
+ pr_err("copy to dump info buffer failed, ret:%d\n", ret);
+ ret = -EFAULT;
+ goto exit;
+ }
+
+ *f_pos += dump_len;
+ g_dump_buf_len -= dump_len;
+ g_dump_buf_ptr += dump_len;
+ pr_info("conninfra_dbg:after read,wmt for dump info buffer len(%d)\n", g_dump_buf_len);
+
+ ret = dump_len;
+exit:
+
+ osal_unlock_sleepable_lock(&g_dump_lock);
+ return ret;
+}
+
+ssize_t conninfra_dbg_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos)
+{
+ size_t len = count;
+ char buf[256];
+ char* pBuf;
+ int x = 0, y = 0, z = 0;
+ char* pToken = NULL;
+ char* pDelimiter = " \t";
+ long res = 0;
+ static char dbg_enabled;
+
+ pr_info("write parameter len = %d\n\r", (int) len);
+ if (len >= osal_sizeof(buf)) {
+ pr_err("input handling fail!\n");
+ len = osal_sizeof(buf) - 1;
+ return -1;
+ }
+
+ if (copy_from_user(buf, buffer, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ pr_info("write parameter data = %s\n\r", buf);
+
+ pBuf = buf;
+ pToken = osal_strsep(&pBuf, pDelimiter);
+ if (pToken != NULL) {
+ osal_strtol(pToken, 16, &res);
+ x = (int)res;
+ } else {
+ x = 0;
+ }
+
+ pToken = osal_strsep(&pBuf, "\t\n ");
+ if (pToken != NULL) {
+ osal_strtol(pToken, 16, &res);
+ y = (int)res;
+ pr_info("y = 0x%08x\n\r", y);
+ } else {
+ y = 3000;
+ /*efuse, register read write default value */
+ if (0x5 == x || 0x6 == x)
+ y = 0x80000000;
+ }
+
+ pToken = osal_strsep(&pBuf, "\t\n ");
+ if (pToken != NULL) {
+ osal_strtol(pToken, 16, &res);
+ z = (int)res;
+ } else {
+ z = 10;
+ /*efuse, register read write default value */
+ if (0x5 == x || 0x6 == x)
+ z = 0xffffffff;
+ }
+
+ pr_info("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z);
+
+ /* For eng and userdebug load, have to enable wmt_dbg by writing 0xDB9DB9 to
+ * "/proc/driver/wmt_dbg" to avoid some malicious use
+ */
+#if CFG_CONNINFRA_DBG_SUPPORT
+ if (0xDB9DB9 == x) {
+ dbg_enabled = 1;
+ return len;
+ }
+#endif
+ /* For user load, only 0x13/0x14 is allowed to execute */
+ if (0 == dbg_enabled && ((x != 0x13) && (x != 0x14))) {
+ pr_info("please enable conninfra debug first\n\r");
+ return len;
+ }
+
+ if (osal_array_size(conninfra_dev_dbg_func) > x && NULL != conninfra_dev_dbg_func[x])
+ (*conninfra_dev_dbg_func[x]) (x, y, z);
+ else
+ pr_warn("no handler defined for command id(0x%08x)\n\r", x);
+
+ return len;
+}
+
+int conninfra_dev_dbg_init(void)
+{
+ static const struct file_operations conninfra_dbg_fops = {
+ .owner = THIS_MODULE,
+ .read = conninfra_dbg_read,
+ .write = conninfra_dbg_write,
+ };
+ int i_ret = 0;
+
+ g_conninfra_dbg_entry = proc_create(CONNINFRA_DBG_PROCNAME, 0664, NULL, &conninfra_dbg_fops);
+ if (g_conninfra_dbg_entry == NULL) {
+ pr_err("Unable to create / wmt_aee proc entry\n\r");
+ i_ret = -1;
+ }
+
+ osal_sleepable_lock_init(&g_dump_lock);
+
+ return i_ret;
+}
+
+int conninfra_dev_dbg_deinit(void)
+{
+ osal_sleepable_lock_deinit(&g_dump_lock);
+
+ if (g_conninfra_dbg_entry != NULL) {
+ proc_remove(g_conninfra_dbg_entry);
+ g_conninfra_dbg_entry = NULL;
+ }
+
+ return 0;
+}
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/conninfra_dbg.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/conninfra_dbg.h
new file mode 100644
index 0000000..c06b8c6
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/conninfra_dbg.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#ifndef _CONNINFRA_DBG_H_
+#define _CONNINFRA_DBG_H_
+#include "osal.h"
+
+typedef int(*CONNINFRA_DEV_DBG_FUNC) (int par1, int par2, int par3);
+int conninfra_dev_dbg_init(void);
+int conninfra_dev_dbg_deinit(void);
+
+#endif /* _CONNINFRA_DBG_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/connsyslog.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/connsyslog.c
new file mode 100644
index 0000000..b373a52
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/connsyslog.c
@@ -0,0 +1,1271 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/workqueue.h>
+#include <linux/ratelimit.h>
+#include <linux/alarmtimer.h>
+#include <linux/suspend.h>
+
+#include "connsyslog.h"
+#include "connsyslog_emi.h"
+#include "connsyslog_hw_config.h"
+#include "ring.h"
+#include "ring_emi.h"
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/* Close debug log */
+//#define DEBUG_RING 1
+
+#define CONNLOG_ALARM_STATE_DISABLE 0x0
+#define CONNLOG_ALARM_STATE_ENABLE 0x01
+#define CONNLOG_ALARM_STATE_RUNNING 0x03
+
+#define BYETES_PER_LINE 16
+#define LOG_LINE_SIZE (3*BYETES_PER_LINE + BYETES_PER_LINE + 1)
+#define IS_VISIBLE_CHAR(c) ((c) >= 32 && (c) <= 126)
+
+#define LOG_MAX_LEN 1024
+#define LOG_HEAD_LENG 16
+#define TIMESYNC_LENG 40
+
+static const char log_head[] = {0x55, 0x00, 0x00, 0x62};
+static const char timesync_head[] = {0x55, 0x00, 0x25, 0x62};
+
+struct connlog_alarm {
+ struct alarm alarm_timer;
+ unsigned int alarm_state;
+ unsigned int blank_state;
+ unsigned int alarm_sec;
+ spinlock_t alarm_lock;
+ unsigned long flags;
+};
+
+struct connlog_offset {
+ unsigned int emi_base_offset;
+ unsigned int emi_size;
+ unsigned int emi_read;
+ unsigned int emi_write;
+ unsigned int emi_buf;
+ unsigned int emi_guard_pattern_offset;
+};
+
+struct connlog_buffer {
+ struct ring_emi ring_emi;
+ struct ring ring_cache;
+ void *cache_base;
+};
+
+struct connlog_event_cb {
+ CONNLOG_EVENT_CB log_data_handler;
+};
+
+struct connlog_dev {
+ int conn_type;
+ phys_addr_t phyAddrEmiBase;
+ unsigned int emi_size;
+ void __iomem *virAddrEmiLogBase;
+ struct connlog_offset log_offset;
+ struct connlog_buffer log_buffer;
+ bool eirqOn;
+ spinlock_t irq_lock;
+ unsigned long flags;
+ unsigned int irq_counter;
+ struct timer_list workTimer;
+ struct work_struct logDataWorker;
+ void *log_data;
+ char log_line[LOG_MAX_LEN];
+ struct connlog_event_cb callback;
+};
+
+static char *type_to_title[CONN_DEBUG_TYPE_END] = {
+ "wifi_fw", "bt_fw"
+};
+
+static struct connlog_dev* gLogDev[CONN_DEBUG_TYPE_END];
+
+#ifdef CONFIG_MTK_CONNSYS_DEDICATED_LOG_PATH
+static atomic_t g_log_mode = ATOMIC_INIT(LOG_TO_FILE);
+#else
+static atomic_t g_log_mode = ATOMIC_INIT(PRINT_TO_KERNEL_LOG);
+#endif
+
+static phys_addr_t gPhyEmiBase;
+
+/* alarm timer for suspend */
+struct connlog_alarm gLogAlarm;
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+static void connlog_do_schedule_work(struct connlog_dev* handler, bool count);
+static void work_timer_handler(unsigned long data);
+static void connlog_event_set(struct connlog_dev* handler);
+static struct connlog_dev* connlog_subsys_init(
+ int conn_type,
+ phys_addr_t emiaddr,
+ unsigned int emi_size);
+static void connlog_subsys_deinit(struct connlog_dev* handler);
+static ssize_t connlog_read_internal(
+ struct connlog_dev* handler, int conn_type,
+ char *buf, char __user *userbuf, size_t count, bool to_user);
+static void connlog_dump_emi(struct connlog_dev* handler, int offset, int size);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+struct connlog_emi_config* __weak get_connsyslog_platform_config(int conn_type)
+{
+ pr_err("Miss platform ops !!\n");
+ return NULL;
+}
+
+void *connlog_cache_allocate(size_t size)
+{
+ void *pBuffer = NULL;
+
+ pBuffer = kmalloc(size, GFP_KERNEL);
+ if (!pBuffer)
+ return NULL;
+ return pBuffer;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * connlog_event_set
+ * DESCRIPTION
+ * Trigger event call back to wakeup waitqueue
+ * PARAMETERS
+ * conn_type [IN] subsys type
+ * RETURNS
+ * void
+ *****************************************************************************/
+static void connlog_event_set(struct connlog_dev* handler)
+{
+ if (handler->callback.log_data_handler)
+ handler->callback.log_data_handler();
+}
+
+
+/*****************************************************************************
+* FUNCTION
+* connlog_set_ring_ready
+* DESCRIPTION
+* set reserved bit be EMIFWLOG to indicate that init is ready.
+* PARAMETERS
+* void
+* RETURNS
+* void
+*****************************************************************************/
+static void connlog_set_ring_ready(struct connlog_dev* handler)
+{
+ const char ready_str[] = "EMIFWLOG";
+
+ memcpy_toio(handler->virAddrEmiLogBase + CONNLOG_READY_PATTERN_BASE,
+ ready_str, CONNLOG_READY_PATTERN_BASE_SIZE);
+}
+
+static unsigned int connlog_cal_log_size(unsigned int emi_size)
+{
+ int position;
+ int i;
+
+ if (emi_size > 0) {
+ for (i = (emi_size >> 1), position = 0; i != 0; ++position)
+ i >>= 1;
+ } else {
+ return 0;
+ }
+
+ return (1UL << position);
+}
+
+static int connlog_emi_init(struct connlog_dev* handler, phys_addr_t emiaddr, unsigned int emi_size)
+{
+ int conn_type = handler->conn_type;
+ unsigned int cal_log_size = connlog_cal_log_size(
+ emi_size - CONNLOG_EMI_BASE_OFFSET - CONNLOG_EMI_END_PATTERN_SIZE);
+
+ if (emiaddr == 0 || cal_log_size == 0) {
+ pr_err("[%s] consys emi memory address invalid emi_addr=%p emi_size=%d\n",
+ type_to_title[conn_type], emiaddr, emi_size);
+ return -1;
+ }
+ pr_info("input size = %d cal_size = %d\n", emi_size, cal_log_size);
+
+ handler->phyAddrEmiBase = emiaddr;
+ handler->emi_size = emi_size;
+ handler->virAddrEmiLogBase = ioremap_nocache(handler->phyAddrEmiBase, emi_size);
+ handler->log_offset.emi_base_offset = CONNLOG_EMI_BASE_OFFSET;
+ handler->log_offset.emi_size = cal_log_size;
+ handler->log_offset.emi_read = CONNLOG_EMI_READ;
+ handler->log_offset.emi_write = CONNLOG_EMI_WRITE;
+ handler->log_offset.emi_buf = CONNLOG_EMI_BUF;
+ handler->log_offset.emi_guard_pattern_offset = handler->log_offset.emi_buf + handler->log_offset.emi_size;
+
+ if (handler->virAddrEmiLogBase) {
+ pr_info("[%s] EMI mapping OK virtual(0x%p) physical(0x%x) size=%d\n",
+ type_to_title[conn_type],
+ handler->virAddrEmiLogBase,
+ (unsigned int)handler->phyAddrEmiBase,
+ handler->emi_size);
+ /* Clean it */
+ memset_io(handler->virAddrEmiLogBase, 0xff, handler->emi_size);
+ /* Clean control block as 0 */
+ memset_io(handler->virAddrEmiLogBase + CONNLOG_EMI_BASE_OFFSET, 0x0, CONNLOG_EMI_32_BYTE_ALIGNED);
+ /* Setup henader */
+ EMI_WRITE32(handler->virAddrEmiLogBase + 0, handler->log_offset.emi_base_offset);
+ EMI_WRITE32(handler->virAddrEmiLogBase + 4, handler->log_offset.emi_size);
+ /* Setup end pattern */
+ memcpy_toio(
+ handler->virAddrEmiLogBase + handler->log_offset.emi_guard_pattern_offset,
+ CONNLOG_EMI_END_PATTERN, CONNLOG_EMI_END_PATTERN_SIZE);
+ } else {
+ pr_err("[%s] EMI mapping fail\n", type_to_title[conn_type]);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* FUNCTION
+* connlog_emi_deinit
+* DESCRIPTION
+* Do iounmap for log buffer on EMI
+* PARAMETERS
+* void
+* RETURNS
+* void
+*****************************************************************************/
+static void connlog_emi_deinit(struct connlog_dev* handler)
+{
+ iounmap(handler->virAddrEmiLogBase);
+}
+
+static int connlog_buffer_init(struct connlog_dev* handler)
+{
+ /* Init ring emi */
+ ring_emi_init(
+ handler->virAddrEmiLogBase + handler->log_offset.emi_buf,
+ handler->log_offset.emi_size,
+ handler->virAddrEmiLogBase + handler->log_offset.emi_read,
+ handler->virAddrEmiLogBase + handler->log_offset.emi_write,
+ &handler->log_buffer.ring_emi);
+
+ /* init ring cache */
+ /* TODO: use emi size. Need confirm */
+ handler->log_buffer.cache_base = connlog_cache_allocate(handler->emi_size);
+ memset(handler->log_buffer.cache_base, 0, handler->emi_size);
+ ring_init(
+ handler->log_buffer.cache_base,
+ handler->log_offset.emi_size,
+ 0,
+ 0,
+ &handler->log_buffer.ring_cache);
+
+ return 0;
+}
+
+static int connlog_ring_buffer_init(struct connlog_dev* handler)
+{
+ if (!handler->virAddrEmiLogBase) {
+ pr_err("[%s] consys emi memory address phyAddrEmiBase invalid\n",
+ type_to_title[handler->conn_type]);
+ return -1;
+ }
+ connlog_buffer_init(handler);
+ /* TODO: use emi size. Need confirm */
+ handler->log_data = connlog_cache_allocate(handler->emi_size);
+ connlog_set_ring_ready(handler);
+ return 0;
+}
+
+/*****************************************************************************
+* FUNCTION
+* connlog_ring_buffer_deinit
+* DESCRIPTION
+* Initialize ring buffer setting for subsys
+* PARAMETERS
+* void
+* RETURNS
+* void
+*****************************************************************************/
+static void connlog_ring_buffer_deinit(struct connlog_dev* handler)
+{
+ kfree(handler->log_buffer.cache_base);
+ handler->log_buffer.cache_base = NULL;
+
+ kfree(handler->log_data);
+ handler->log_data = NULL;
+}
+
+/*****************************************************************************
+* FUNCTION
+* work_timer_handler
+* DESCRIPTION
+* IRQ is still on, do schedule_work again
+* PARAMETERS
+* data [IN] input data
+* RETURNS
+* void
+*****************************************************************************/
+static void work_timer_handler(unsigned long data)
+{
+ struct connlog_dev* handler = (struct connlog_dev*)data;
+ connlog_do_schedule_work(handler, false);
+}
+
+/*****************************************************************************
+* FUNCTION
+* connlog_dump_buf
+* DESCRIPTION
+* Dump EMI content. Output format:
+* xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ................
+* 3 digits hex * 16 + 16 single char + 1 NULL terminate = 64+1 bytes
+* PARAMETERS
+*
+* RETURNS
+* void
+*****************************************************************************/
+void connsys_log_dump_buf(const char *title, const char *buf, ssize_t sz)
+{
+ int i;
+ char line[LOG_LINE_SIZE];
+
+ i = 0;
+ line[LOG_LINE_SIZE-1] = 0;
+ while (sz--) {
+ snprintf(line + i*3, 3, "%02x", *buf);
+ line[i*3 + 2] = ' ';
+
+ if (IS_VISIBLE_CHAR(*buf))
+ line[3*BYETES_PER_LINE + i] = *buf;
+ else
+ line[3*BYETES_PER_LINE + i] = '`';
+
+ i++;
+ buf++;
+
+ if (i >= BYETES_PER_LINE || !sz) {
+ if (i < BYETES_PER_LINE) {
+ memset(line+i*3, ' ', (BYETES_PER_LINE-i)*3);
+ memset(line+3*BYETES_PER_LINE+i, '.', BYETES_PER_LINE-i);
+ }
+ pr_info("%s: %s\n", title, line);
+ i = 0;
+ }
+ }
+}
+EXPORT_SYMBOL(connsys_log_dump_buf);
+
+/*****************************************************************************
+* FUNCTION
+* connlog_dump_emi
+* DESCRIPTION
+* dump EMI buffer for debug.
+* PARAMETERS
+* offset [IN] buffer offset
+* size [IN] dump buffer size
+* RETURNS
+* void
+*****************************************************************************/
+void connlog_dump_emi(struct connlog_dev* handler, int offset, int size)
+{
+ char title[100];
+ memset(title, 0, 100);
+ sprintf(title, "%s(%p)", "emi", handler->virAddrEmiLogBase + offset);
+ connsys_log_dump_buf(title, handler->virAddrEmiLogBase + offset, size);
+}
+
+/*****************************************************************************
+* FUNCTION
+* connlog_ring_emi_check
+* DESCRIPTION
+*
+* PARAMETERS
+*
+* RETURNS
+* void
+*****************************************************************************/
+static bool connlog_ring_emi_check(struct connlog_dev* handler)
+{
+ struct ring_emi *ring_emi = &handler->log_buffer.ring_emi;
+ char line[CONNLOG_EMI_END_PATTERN_SIZE + 1];
+
+ memcpy_fromio(
+ line,
+ handler->virAddrEmiLogBase + handler->log_offset.emi_guard_pattern_offset,
+ CONNLOG_EMI_END_PATTERN_SIZE);
+ line[CONNLOG_EMI_END_PATTERN_SIZE] = '\0';
+
+ /* Check ring_emi buffer memory. Dump EMI data if it is corruption. */
+ if (EMI_READ32(ring_emi->read) > handler->log_offset.emi_size ||
+ EMI_READ32(ring_emi->write) > handler->log_offset.emi_size ||
+ strncmp(line, CONNLOG_EMI_END_PATTERN, CONNLOG_EMI_END_PATTERN_SIZE) != 0) {
+ pr_err("[connlog] %s out of bound or guard pattern overwrited. Read(pos=%p)=[0x%x] write(pos=%p)=[0x%x] size=[0x%x]\n",
+ type_to_title[handler->conn_type],
+ ring_emi->read, EMI_READ32(ring_emi->read),
+ ring_emi->write, EMI_READ32(ring_emi->write),
+ handler->log_offset.emi_size);
+ connlog_dump_emi(handler, 0x0, 0x60);
+ connlog_dump_emi(handler, CONNLOG_EMI_BASE_OFFSET, 0x20);
+ connlog_dump_emi(
+ handler,
+ handler->log_offset.emi_guard_pattern_offset,
+ CONNLOG_EMI_END_PATTERN_SIZE);
+ return false;
+ }
+
+ return true;
+}
+
+/*****************************************************************************
+* FUNCTION
+* connlog_ring_emi_to_cache
+* DESCRIPTION
+*
+* PARAMETERS
+*
+* RETURNS
+* void
+*****************************************************************************/
+static void connlog_ring_emi_to_cache(struct connlog_dev* handler)
+{
+ struct ring_emi_segment ring_emi_seg;
+ struct ring_emi *ring_emi = &handler->log_buffer.ring_emi;
+ struct ring *ring_cache = &handler->log_buffer.ring_cache;
+ int total_size = 0;
+ int count = 0;
+ unsigned int cache_max_size = 0;
+#ifndef DEBUG_LOG_ON
+ static DEFINE_RATELIMIT_STATE(_rs, 10 * HZ, 1);
+ static DEFINE_RATELIMIT_STATE(_rs2, HZ, 1);
+#endif
+
+ if (RING_FULL(ring_cache)) {
+ #ifndef DEBUG_LOG_ON
+ if (__ratelimit(&_rs))
+ #endif
+ pr_warn("[connlog] %s cache is full.\n", type_to_title[handler->conn_type]);
+ return;
+ }
+
+ cache_max_size = RING_WRITE_REMAIN_SIZE(ring_cache);
+ if (RING_EMI_EMPTY(ring_emi) || !ring_emi_read_prepare(cache_max_size, &ring_emi_seg, ring_emi)) {
+ #ifndef DEBUG_LOG_ON
+ if(__ratelimit(&_rs))
+ #endif
+ pr_err("[connlog] %s no data.\n", type_to_title[handler->conn_type]);
+ return;
+ }
+
+ /* Check ring_emi buffer memory. Dump EMI data if it is corruption. */
+ if (connlog_ring_emi_check(handler) == false) {
+ pr_err("[connlog] %s emi check fail\n", type_to_title[handler->conn_type]);
+ /* TODO: trigger assert by callback? */
+ return;
+ }
+
+ RING_EMI_READ_ALL_FOR_EACH(ring_emi_seg, ring_emi) {
+ struct ring_segment ring_cache_seg;
+ unsigned int emi_buf_size = ring_emi_seg.sz;
+ unsigned int written = 0;
+
+#ifdef DEBUG_RING
+ ring_emi_dump(__func__, ring_emi);
+ ring_emi_dump_segment(__func__, &ring_emi_seg);
+#endif
+ RING_WRITE_FOR_EACH(ring_emi_seg.sz, ring_cache_seg, &handler->log_buffer.ring_cache) {
+#ifdef DEBUG_RING
+ ring_dump(__func__, &handler->log_buffer.ring_cache);
+ ring_dump_segment(__func__, &ring_cache_seg);
+#endif
+ #ifndef DEBUG_LOG_ON
+ if (__ratelimit(&_rs2))
+ #endif
+ pr_info("%s: ring_emi_seg.sz=%d, ring_cache_pt=%p, ring_cache_seg.sz=%d\n",
+ type_to_title[handler->conn_type], ring_emi_seg.sz, ring_cache_seg.ring_pt,
+ ring_cache_seg.sz);
+ memcpy_fromio(ring_cache_seg.ring_pt, ring_emi_seg.ring_emi_pt + ring_cache_seg.data_pos,
+ ring_cache_seg.sz);
+ emi_buf_size -= ring_cache_seg.sz;
+ written += ring_cache_seg.sz;
+ }
+
+ total_size += ring_emi_seg.sz;
+ count++;
+ }
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ * connlog_fw_log_parser
+ * DESCRIPTION
+ * Parse fw log and print to kernel
+ * PARAMETERS
+ * conn_type [IN] log type
+ * buf [IN] buffer to prase
+ * sz [IN] buffer size
+ * RETURNS
+ * void
+ *****************************************************************************/
+static void connlog_fw_log_parser(struct connlog_dev* handler, ssize_t sz)
+{
+ unsigned int systime = 0;
+ unsigned int utc_s = 0;
+ unsigned int utc_us = 0;
+ unsigned int buf_len = 0;
+ unsigned int print_len = 0;
+ char* log_line = handler->log_line;
+ const char* buf = handler->log_data;
+ int conn_type = handler->conn_type;
+
+ while (sz > LOG_HEAD_LENG) {
+ if (*buf == log_head[0]) {
+ if (!memcmp(buf, log_head, sizeof(log_head))) {
+ buf_len = buf[14] + (buf[15] << 8);
+ print_len = buf_len >= LOG_MAX_LEN ? LOG_MAX_LEN - 1 : buf_len;
+ memcpy(log_line, buf + LOG_HEAD_LENG, print_len);
+ log_line[print_len] = 0;
+ pr_info("%s: %s\n", type_to_title[conn_type], log_line);
+ sz -= (LOG_HEAD_LENG + buf_len);
+ buf += (LOG_HEAD_LENG + buf_len);
+ continue;
+ } else if (sz >= TIMESYNC_LENG &&
+ !memcmp(buf, timesync_head, sizeof(timesync_head))) {
+ memcpy(&systime, buf + 28, sizeof(systime));
+ memcpy(&utc_s, buf + 32, sizeof(utc_s));
+ memcpy(&utc_us, buf + 36, sizeof(utc_us));
+ pr_info("%s: timesync : (%u) %u.%06u\n",
+ type_to_title[conn_type], systime, utc_s, utc_us);
+ sz -= TIMESYNC_LENG;
+ buf += TIMESYNC_LENG;
+ continue;
+ }
+ }
+ sz--;
+ buf++;
+ }
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * connlog_ring_print
+ * DESCRIPTION
+ * print log data on kernel log
+ * PARAMETERS
+ * handler [IN] log handler
+ * RETURNS
+ * void
+ *****************************************************************************/
+static void connlog_ring_print(struct connlog_dev* handler)
+{
+ unsigned int written = 0;
+ unsigned int buf_size;
+ struct ring_emi_segment ring_emi_seg;
+ struct ring_emi *ring_emi = &handler->log_buffer.ring_emi;
+ int conn_type = handler->conn_type;
+
+ if (RING_EMI_EMPTY(ring_emi) || !ring_emi_read_all_prepare(&ring_emi_seg, ring_emi)) {
+ pr_err("type(%s) no data, possibly taken by concurrent reader.\n", type_to_title[conn_type]);
+ return;
+ }
+ buf_size = ring_emi_seg.remain;
+ memset(handler->log_data, 0, handler->emi_size);
+
+ /* Check ring_emi buffer memory. Dump EMI data if it is corruption. */
+ if (connlog_ring_emi_check(handler) == false) {
+ pr_err("[connlog] %s emi check fail\n", type_to_title[handler->conn_type]);
+ /* TODO: trigger assert by callback? */
+ return;
+ }
+
+ RING_EMI_READ_ALL_FOR_EACH(ring_emi_seg, ring_emi) {
+ memcpy_fromio(handler->log_data + written, ring_emi_seg.ring_emi_pt, ring_emi_seg.sz);
+ buf_size -= ring_emi_seg.sz;
+ written += ring_emi_seg.sz;
+ }
+
+ if (conn_type != CONN_DEBUG_TYPE_BT)
+ connlog_fw_log_parser(handler, written);
+}
+
+/*****************************************************************************
+* FUNCTION
+* connlog_log_data_handler
+* DESCRIPTION
+*
+* PARAMETERS
+*
+* RETURNS
+* void
+*****************************************************************************/
+static void connlog_log_data_handler(struct work_struct *work)
+{
+ struct connlog_dev* handler =
+ container_of(work, struct connlog_dev, logDataWorker);
+#ifndef DEBUG_LOG_ON
+ static DEFINE_RATELIMIT_STATE(_rs, 10 * HZ, 1);
+ static DEFINE_RATELIMIT_STATE(_rs2, 2 * HZ, 1);
+#endif
+
+ if (!RING_EMI_EMPTY(&handler->log_buffer.ring_emi)) {
+ if (atomic_read(&g_log_mode) == LOG_TO_FILE)
+ connlog_ring_emi_to_cache(handler);
+ else
+ connlog_ring_print(handler);
+ connlog_event_set(handler);
+ } else {
+#ifndef DEBUG_LOG_ON
+ if (__ratelimit(&_rs))
+#endif
+ pr_info("[connlog] %s emi ring is empty!\n",
+ type_to_title[handler->conn_type]);
+ }
+
+#ifndef DEBUG_LOG_ON
+ if (__ratelimit(&_rs2))
+#endif
+ pr_info("[connlog] %s irq counter = %d\n",
+ type_to_title[handler->conn_type],
+ EMI_READ32(handler->virAddrEmiLogBase + CONNLOG_IRQ_COUNTER_BASE));
+
+ spin_lock_irqsave(&handler->irq_lock, handler->flags);
+ if (handler->eirqOn)
+ mod_timer(&handler->workTimer, jiffies + 1);
+ spin_unlock_irqrestore(&handler->irq_lock, handler->flags);
+}
+
+static void connlog_do_schedule_work(struct connlog_dev* handler, bool count)
+{
+ spin_lock_irqsave(&handler->irq_lock, handler->flags);
+ if (count) {
+ handler->irq_counter++;
+ EMI_WRITE32(
+ handler->virAddrEmiLogBase + CONNLOG_IRQ_COUNTER_BASE,
+ handler->irq_counter);
+ }
+ handler->eirqOn = !schedule_work(&handler->logDataWorker);
+ spin_unlock_irqrestore(&handler->irq_lock, handler->flags);
+}
+
+/*****************************************************************************
+* FUNCTION
+* connsys_log_get_buf_size
+* DESCRIPTION
+* Get ring buffer unread size on EMI.
+* PARAMETERS
+* conn_type [IN] subsys type
+* RETURNS
+* unsigned int Ring buffer unread size
+*****************************************************************************/
+unsigned int connsys_log_get_buf_size(int conn_type)
+{
+ struct connlog_dev* handler;
+ if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type >= CONN_DEBUG_TYPE_END)
+ return 0;
+
+ handler = gLogDev[conn_type];
+ if (handler == NULL) {
+ pr_err("[%s][%s] didn't init\n", __func__, type_to_title[conn_type]);
+ return 0;
+ }
+
+ return RING_SIZE(&handler->log_buffer.ring_cache);
+}
+EXPORT_SYMBOL(connsys_log_get_buf_size);
+
+/*****************************************************************************
+ * FUNCTION
+ * connsys_log_read_internal
+ * DESCRIPTION
+ * Read log in ring_cache to buf
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+static ssize_t connlog_read_internal(
+ struct connlog_dev* handler, int conn_type,
+ char *buf, char __user *userbuf, size_t count, bool to_user)
+{
+ unsigned int written = 0;
+ unsigned int cache_buf_size;
+ struct ring_segment ring_seg;
+ struct ring *ring = &handler->log_buffer.ring_cache;
+ unsigned int size = 0;
+ int retval;
+ static DEFINE_RATELIMIT_STATE(_rs, 10 * HZ, 1);
+ static DEFINE_RATELIMIT_STATE(_rs2, 1 * HZ, 1);
+
+ size = count < RING_SIZE(ring) ? count : RING_SIZE(ring);
+ if (RING_EMPTY(ring) || !ring_read_prepare(size, &ring_seg, ring)) {
+ pr_err("type(%d) no data, possibly taken by concurrent reader.\n", conn_type);
+ goto done;
+ }
+ cache_buf_size = ring_seg.remain;
+
+ RING_READ_FOR_EACH(size, ring_seg, ring) {
+ if (to_user) {
+ retval = copy_to_user(userbuf + written, ring_seg.ring_pt, ring_seg.sz);
+ if (retval) {
+ if (__ratelimit(&_rs))
+ pr_err("copy to user buffer failed, ret:%d\n", retval);
+ goto done;
+ }
+ } else {
+ memcpy(buf + written, ring_seg.ring_pt, ring_seg.sz);
+ }
+ cache_buf_size -= ring_seg.sz;
+ written += ring_seg.sz;
+ if (__ratelimit(&_rs2))
+ pr_info("[%s] copy %d to %s\n",
+ type_to_title[conn_type],
+ ring_seg.sz,
+ (to_user? "user space" : "buffer"));
+ }
+done:
+ return written;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * connsys_log_read_to_user
+ * DESCRIPTION
+ * Read log in ring_cache to user space buf
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+ssize_t connsys_log_read_to_user(int conn_type, char __user *buf, size_t count)
+{
+ struct connlog_dev* handler;
+ unsigned int written = 0;
+
+ if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type >= CONN_DEBUG_TYPE_END)
+ goto done;
+ if (atomic_read(&g_log_mode) != LOG_TO_FILE)
+ goto done;
+
+ handler = gLogDev[conn_type];
+ if (handler == NULL) {
+ pr_err("[%s][%s] not init\n", __func__, type_to_title[conn_type]);
+ goto done;
+ }
+ written = connlog_read_internal(handler, conn_type, NULL, buf, count, true);
+done:
+ return written;
+}
+EXPORT_SYMBOL(connsys_log_read_to_user);
+
+/*****************************************************************************
+ * FUNCTION
+ * connsys_log_read
+ * DESCRIPTION
+ * Read log in ring_cache to buf
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+ssize_t connsys_log_read(int conn_type, char *buf, size_t count)
+{
+ unsigned int ret = 0;
+ struct connlog_dev* handler;
+
+ if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type >= CONN_DEBUG_TYPE_END)
+ goto done;
+ if (atomic_read(&g_log_mode) != LOG_TO_FILE)
+ goto done;
+
+ handler = gLogDev[conn_type];
+ ret = connlog_read_internal(handler, conn_type, buf, NULL, count, false);
+done:
+ return ret;
+}
+EXPORT_SYMBOL(connsys_log_read);
+
+
+/*****************************************************************************
+ * FUNCTION
+ * connsys_dedicated_log_set_log_mode
+ * DESCRIPTION
+ * set log mode.
+ * PARAMETERS
+ * mode [IN] log mode
+ * RETURNS
+ * void
+ *****************************************************************************/
+void connsys_dedicated_log_set_log_mode(int mode)
+{
+ atomic_set(&g_log_mode, (mode > 0 ? LOG_TO_FILE : PRINT_TO_KERNEL_LOG));
+}
+EXPORT_SYMBOL(connsys_dedicated_log_set_log_mode);
+
+/*****************************************************************************
+* FUNCTION
+* connsys_dedicated_log_get_log_mode
+* DESCRIPTION
+* get log mode.
+* PARAMETERS
+* void
+* RETURNS
+* int log mode
+*****************************************************************************/
+int connsys_dedicated_log_get_log_mode(void)
+{
+ return atomic_read(&g_log_mode);
+}
+EXPORT_SYMBOL(connsys_dedicated_log_get_log_mode);
+
+/*****************************************************************************
+* FUNCTION
+* connsys_log_irq_handler
+* DESCRIPTION
+*
+* PARAMETERS
+* void
+* RETURNS
+* int
+*****************************************************************************/
+int connsys_log_irq_handler(int conn_type)
+{
+ struct connlog_dev* handler;
+ if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type >= CONN_DEBUG_TYPE_END)
+ return -1;
+
+ handler = gLogDev[conn_type];
+ if (handler == NULL) {
+ pr_err("[%s][%s] didn't init\n", __func__, type_to_title[conn_type]);
+ return -1;
+ }
+
+ connlog_do_schedule_work(handler, true);
+ return 0;
+}
+EXPORT_SYMBOL(connsys_log_irq_handler);
+
+/*****************************************************************************
+* FUNCTION
+* connsys_log_register_event_cb
+* DESCRIPTION
+*·
+* PARAMETERS
+* void
+* RETURNS
+*
+*****************************************************************************/
+int connsys_log_register_event_cb(int conn_type, CONNLOG_EVENT_CB func)
+{
+ struct connlog_dev* handler;
+ if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type >= CONN_DEBUG_TYPE_END)
+ return -1;
+
+ handler = gLogDev[conn_type];
+ if (handler == NULL) {
+ pr_err("[%s][%s] didn't init\n", __func__, type_to_title[conn_type]);
+ return -1;
+ }
+
+ handler->callback.log_data_handler = func;
+ return 0;
+}
+EXPORT_SYMBOL(connsys_log_register_event_cb);
+
+/*****************************************************************************
+* FUNCTION
+* connlog_subsys_init
+* DESCRIPTION
+*
+* PARAMETERS
+* conn_type [IN] subsys type
+* emi_addr [IN] physical emi
+* emi_size [IN] emi size
+* RETURNS
+* struct connlog_dev* the handler
+*****************************************************************************/
+static struct connlog_dev* connlog_subsys_init(
+ int conn_type,
+ phys_addr_t emi_addr,
+ unsigned int emi_size)
+{
+ struct connlog_dev* handler = 0;
+
+ if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type >= CONN_DEBUG_TYPE_END)
+ return 0;
+
+ handler = (struct connlog_dev*)kmalloc(sizeof(struct connlog_dev), GFP_KERNEL);
+ if (!handler)
+ return 0;
+
+ handler->conn_type = conn_type;
+ if (connlog_emi_init(handler, emi_addr, emi_size)) {
+ pr_err("[%s] EMI init failed\n", type_to_title[conn_type]);
+ goto error_exit;
+ }
+
+ if (connlog_ring_buffer_init(handler)) {
+ pr_err("[%s] Ring buffer init failed\n", type_to_title[conn_type]);
+ goto error_exit;
+ }
+
+ init_timer(&handler->workTimer);
+ handler->workTimer.data = (unsigned long)handler;
+ handler->workTimer.function = work_timer_handler;
+ handler->irq_counter = 0;
+ spin_lock_init(&handler->irq_lock);
+ INIT_WORK(&handler->logDataWorker, connlog_log_data_handler);
+
+ /* alarm timer */
+ return handler;
+
+error_exit:
+ if (handler)
+ connlog_subsys_deinit(handler);
+ return 0;
+
+}
+
+/*****************************************************************************
+* FUNCTION
+* connsys_log_init
+* DESCRIPTION
+*
+* PARAMETERS
+* void
+* RETURNS
+* int
+*****************************************************************************/
+int connsys_log_init(int conn_type)
+{
+ struct connlog_dev* handler;
+ phys_addr_t log_start_addr;
+ unsigned int log_size;
+ struct connlog_emi_config* emi_config;
+
+ if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type >= CONN_DEBUG_TYPE_END) {
+ pr_err("[%s] invalid type:%d\n", __func__, conn_type);
+ return -1;
+ }
+ if (gLogDev[conn_type] != NULL) {
+ pr_err("[%s][%s] double init.\n", __func__, type_to_title[conn_type]);
+ return 0;
+ }
+
+ emi_config = get_connsyslog_platform_config(conn_type);
+ if (!emi_config) {
+ pr_err("[%s] get emi config fail.\n", __func__);
+ return -1;
+ }
+
+ log_start_addr = emi_config->log_offset + gPhyEmiBase;
+ log_size = emi_config->log_size;
+ pr_info("%s init. Base=%p size=%d\n",
+ type_to_title[conn_type], log_start_addr, log_size);
+
+ handler = connlog_subsys_init(conn_type, log_start_addr, log_size);
+ if (handler == NULL) {
+ pr_err("[%s][%s] failed.\n", __func__, type_to_title[conn_type]);
+ return -1;
+ }
+
+ gLogDev[conn_type] = handler;
+ return 0;
+}
+EXPORT_SYMBOL(connsys_log_init);
+
+/*****************************************************************************
+* Function
+* connlog_subsys_deinit
+* DESCRIPTION
+*
+* PARAMETERS
+*
+* RETURNS
+*
+*****************************************************************************/
+static void connlog_subsys_deinit(struct connlog_dev* handler)
+{
+ if (handler == NULL)
+ return;
+
+ connlog_emi_deinit(handler);
+ connlog_ring_buffer_deinit(handler);
+ kfree(handler);
+}
+
+/*****************************************************************************
+* Function
+* connsys_log_deinit
+* DESCRIPTION
+*
+* PARAMETERS
+*
+* RETURNS
+*
+*****************************************************************************/
+int connsys_log_deinit(int conn_type)
+{
+ struct connlog_dev* handler;
+ if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type >= CONN_DEBUG_TYPE_END)
+ return -1;
+
+ handler = gLogDev[conn_type];
+ if (handler == NULL) {
+ pr_err("[%s][%s] didn't init\n", __func__, type_to_title[conn_type]);
+ return -1;
+ }
+
+ connlog_subsys_deinit(gLogDev[conn_type]);
+ gLogDev[conn_type] = NULL;
+ return 0;
+}
+EXPORT_SYMBOL(connsys_log_deinit);
+
+/*****************************************************************************
+* FUNCTION
+* connsys_log_get_utc_time
+* DESCRIPTION
+* Return UTC time
+* PARAMETERS
+* second [IN] UTC seconds
+* usecond [IN] UTC usecons
+* RETURNS
+* void
+*****************************************************************************/
+void connsys_log_get_utc_time(
+ unsigned int *second, unsigned int *usecond)
+{
+ struct timeval time;
+
+ do_gettimeofday(&time);
+ *second = (unsigned int)time.tv_sec; /* UTC time second unit */
+ *usecond = (unsigned int)time.tv_usec; /* UTC time microsecond unit */
+}
+EXPORT_SYMBOL(connsys_log_get_utc_time);
+
+static inline bool connlog_is_alarm_enable(void)
+{
+ if ((gLogAlarm.alarm_state & CONNLOG_ALARM_STATE_ENABLE) > 0)
+ return true;
+ return false;
+}
+
+static int connlog_set_alarm_timer(void)
+{
+ ktime_t kt;
+
+ kt = ktime_set(gLogAlarm.alarm_sec, 0);
+ alarm_start_relative(&gLogAlarm.alarm_timer, kt);
+
+ pr_info("[connsys_log_alarm] alarm timer enabled timeout=[%d]", gLogAlarm.alarm_sec);
+ return 0;
+}
+
+static int connlog_cancel_alarm_timer(void)
+{
+ pr_info("[connsys_log_alarm] alarm timer cancel");
+ return alarm_cancel(&gLogAlarm.alarm_timer);
+}
+
+
+static enum alarmtimer_restart connlog_alarm_timer_handler(struct alarm *alarm,
+ ktime_t now)
+{
+ ktime_t kt;
+ struct rtc_time tm;
+ unsigned int tsec, tusec;
+ int i;
+
+ connsys_log_get_utc_time(&tsec, &tusec);
+ rtc_time_to_tm(tsec, &tm);
+ pr_info("[connsys_log_alarm] alarm_timer triggered [%d-%02d-%02d %02d:%02d:%02d.%09u]"
+ , tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday
+ , tm.tm_hour, tm.tm_min, tm.tm_sec, tusec);
+
+ for (i = 0; i < CONN_DEBUG_TYPE_END; i++) {
+ if (gLogDev[i]) {
+ connlog_do_schedule_work(gLogDev[i], false);
+ }
+ }
+
+ spin_lock_irqsave(&gLogAlarm.alarm_lock, gLogAlarm.flags);
+ kt = ktime_set(gLogAlarm.alarm_sec, 0);
+ alarm_start_relative(&gLogAlarm.alarm_timer, kt);
+ spin_unlock_irqrestore(&gLogAlarm.alarm_lock, gLogAlarm.flags);
+
+ return ALARMTIMER_NORESTART;
+}
+
+static int connlog_alarm_init(void)
+{
+ alarm_init(&gLogAlarm.alarm_timer, ALARM_REALTIME, connlog_alarm_timer_handler);
+ gLogAlarm.alarm_state = CONNLOG_ALARM_STATE_DISABLE;
+ spin_lock_init(&gLogAlarm.alarm_lock);
+
+ return 0;
+}
+
+/*****************************************************************************
+* FUNCTION
+* connsys_dedicated_log_path_alarm_enable
+* DESCRIPTION
+* Enable log timer.
+* When log timer is enable, it starts every sec seconds to fetch log from EMI
+* to file.
+* Usually enable log timer for debug.
+* PARAMETERS
+* sec [IN] timer config
+* RETURNS
+* int
+*****************************************************************************/
+int connsys_dedicated_log_path_alarm_enable(unsigned int sec)
+{
+ if (!gPhyEmiBase)
+ return -1;
+
+ spin_lock_irqsave(&gLogAlarm.alarm_lock, gLogAlarm.flags);
+
+ gLogAlarm.alarm_sec = sec;
+ if (!connlog_is_alarm_enable()) {
+ gLogAlarm.alarm_state = CONNLOG_ALARM_STATE_ENABLE;
+ pr_info("[connsys_log_alarm] alarm timer enabled timeout=[%d]", sec);
+ }
+ if (gLogAlarm.blank_state == 0)
+ connlog_set_alarm_timer();
+
+ spin_unlock_irqrestore(&gLogAlarm.alarm_lock, gLogAlarm.flags);
+ return 0;
+}
+EXPORT_SYMBOL(connsys_dedicated_log_path_alarm_enable);
+
+/*****************************************************************************
+* FUNCTION
+* connsys_dedicated_log_path_alarm_disable
+* DESCRIPTION
+* Disable log timer
+* PARAMETERS
+*
+* RETURNS
+* int
+*****************************************************************************/
+int connsys_dedicated_log_path_alarm_disable(void)
+{
+ int ret;
+
+ if (!gPhyEmiBase)
+ return -1;
+
+ spin_lock_irqsave(&gLogAlarm.alarm_lock, gLogAlarm.flags);
+
+ if (connlog_is_alarm_enable()) {
+ ret = connlog_cancel_alarm_timer();
+ gLogAlarm.alarm_state = CONNLOG_ALARM_STATE_ENABLE;
+ pr_info("[connsys_log_alarm] alarm timer disable ret=%d", ret);
+ }
+ spin_unlock_irqrestore(&gLogAlarm.alarm_lock, gLogAlarm.flags);
+ return 0;
+}
+EXPORT_SYMBOL(connsys_dedicated_log_path_alarm_disable);
+
+/****************************************************************************
+* FUNCTION
+* connsys_dedicated_log_path_blank_state_changed
+* DESCRIPTION
+*
+* PARAMETERS
+*
+* RETURNS
+* int
+*****************************************************************************/
+int connsys_dedicated_log_path_blank_state_changed(int blank_state)
+{
+ int ret = 0;
+
+ if (!gPhyEmiBase)
+ return -1;
+ spin_lock_irqsave(&gLogAlarm.alarm_lock, gLogAlarm.flags);
+ gLogAlarm.blank_state = blank_state;
+ if (connlog_is_alarm_enable()) {
+ if (blank_state == 0)
+ ret = connlog_set_alarm_timer();
+ else
+ ret = connlog_cancel_alarm_timer();
+ }
+
+ spin_unlock_irqrestore(&gLogAlarm.alarm_lock, gLogAlarm.flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(connsys_dedicated_log_path_blank_state_changed);
+
+/*****************************************************************************
+* FUNCTION
+* connsys_dedicated_log_path_apsoc_init
+* DESCRIPTION
+* Initialize API for common driver to initialize connsys dedicated log
+* for APSOC platform
+* PARAMETERS
+* emiaddr [IN] EMI physical base address
+* RETURNS
+* void
+****************************************************************************/
+int connsys_dedicated_log_path_apsoc_init(phys_addr_t emiaddr)
+{
+ if (gPhyEmiBase != 0 || emiaddr == 0) {
+ pr_err("Connsys log double init or invalid parameter(emiaddr=%p)\n", emiaddr);
+ return -1;
+ }
+
+ gPhyEmiBase = emiaddr;
+
+ connlog_alarm_init();
+ return 0;
+}
+EXPORT_SYMBOL(connsys_dedicated_log_path_apsoc_init);
+
+/*****************************************************************************
+* FUNCTION
+* connsys_dedicated_log_path_apsoc_deinit
+* DESCRIPTION
+* De-Initialize API for common driver to release cache, un-remap emi and free
+* irq for APSOC platform
+* PARAMETERS
+* void
+* RETURNS
+* void
+*****************************************************************************/
+int connsys_dedicated_log_path_apsoc_deinit(void)
+{
+ int i;
+
+ /* Check subsys */
+ for (i = 0; i < CONN_DEBUG_TYPE_END; i++) {
+ if (gLogDev[i] != NULL) {
+ pr_err("[%s] subsys %s should be deinit first.\n",
+ __func__, type_to_title[i]);
+ return -1;
+ }
+ }
+
+ gPhyEmiBase = 0;
+ return 0;
+}
+EXPORT_SYMBOL(connsys_dedicated_log_path_apsoc_deinit);
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/connsyslog.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/connsyslog.h
new file mode 100644
index 0000000..6e410ec
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/connsyslog.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#ifndef _CONNSYSLOG_H_
+#define _CONNSYSLOG_H_
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+#include "connsys_debug_utility.h"
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+/* Close debug log */
+//#define DEBUG_LOG_ON 1
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+enum FW_LOG_MODE {
+ PRINT_TO_KERNEL_LOG = 0,
+ LOG_TO_FILE = 1,
+};
+
+typedef void (*CONNLOG_EVENT_CB) (void);
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/* utility */
+void connsys_log_dump_buf(const char *title, const char *buf, ssize_t sz);
+void connsys_log_get_utc_time(
+ unsigned int *second, unsigned int *usecond);
+
+/* Global config */
+int connsys_dedicated_log_path_apsoc_init(phys_addr_t emiaddr);
+int connsys_dedicated_log_path_apsoc_deinit(void);
+void connsys_dedicated_log_set_log_mode(int mode);
+int connsys_dedicated_log_get_log_mode(void);
+int connsys_dedicated_log_path_alarm_enable(unsigned int sec);
+int connsys_dedicated_log_path_alarm_disable(void);
+int connsys_dedicated_log_path_blank_state_changed(int blank_state);
+
+/* For subsys */
+int connsys_log_init(int conn_type);
+int connsys_log_deinit(int conn_type);
+unsigned int connsys_log_get_buf_size(int conn_type);
+int connsys_log_register_event_cb(int conn_type, CONNLOG_EVENT_CB func);
+ssize_t connsys_log_read_to_user(int conn_type, char __user *buf, size_t count);
+ssize_t connsys_log_read(int conn_type, char *buf, size_t count);
+int connsys_log_irq_handler(int conn_type);
+
+#endif /*_CONNSYSLOG_H_*/
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/connsyslog_emi.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/connsyslog_emi.h
new file mode 100644
index 0000000..d2d823b
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/connsyslog_emi.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+#ifndef _CONNSYSLOG_EMI_H_
+#define _CONNSYSLOG_EMI_H_
+
+#define CONNLOG_EMI_32_BYTE_ALIGNED 32 /* connsys EMI cache is 32-byte aligned */
+#define CONNLOG_CONTROL_RING_BUFFER_BASE_SIZE 64 /* Reserve for setup ring buffer base address */
+#define CONNLOG_CONTROL_RING_BUFFER_RESERVE_SIZE 32
+#define CONNLOG_IRQ_COUNTER_BASE 48
+#define CONNLOG_READY_PATTERN_BASE 56
+#define CONNLOG_READY_PATTERN_BASE_SIZE 8
+#define CONNLOG_EMI_END_PATTERN_SIZE CONNLOG_EMI_32_BYTE_ALIGNED
+#define CONNLOG_EMI_END_PATTERN "FWLOGENDFWLOGENDFWLOGENDFWLOGEND"
+
+#define CONNLOG_EMI_BASE_OFFSET CONNLOG_CONTROL_RING_BUFFER_BASE_SIZE
+#define CONNLOG_EMI_READ (CONNLOG_EMI_BASE_OFFSET + 0)
+#define CONNLOG_EMI_WRITE (CONNLOG_EMI_BASE_OFFSET + 4)
+#define CONNLOG_EMI_BUF (CONNLOG_EMI_BASE_OFFSET + \
+ CONNLOG_EMI_32_BYTE_ALIGNED)
+
+#endif /* _CONNSYSLOG_EMI_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/platform/include/connsyslog_hw_config.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/platform/include/connsyslog_hw_config.h
new file mode 100644
index 0000000..df226ec
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/platform/include/connsyslog_hw_config.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#ifndef __CONNSYSLOG_HW_CONFIG_H__
+#define __CONNSYSLOG_HW_CONFIG_H__
+
+struct connlog_emi_config {
+ phys_addr_t log_offset;
+ unsigned int log_size;
+};
+
+#endif /* __CONNSYSLOG_HW_CONFIG_H__ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/platform/mt6885/mt6885.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/platform/mt6885/mt6885.c
new file mode 100644
index 0000000..e58b5b6
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/platform/mt6885/mt6885.c
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+#include <linux/printk.h>
+
+#include "connsys_debug_utility.h"
+#include "connsyslog_hw_config.h"
+
+#ifdef CONFIG_FPGA_EARLY_PORTING
+#define CONNLOG_EMI_OFFSET_WIFI 0x0001F000
+#define CONNLOG_EMI_OFFSET_BT 0x0002F000
+#else
+#define CONNLOG_EMI_OFFSET_WIFI 0x0024F000
+#define CONNLOG_EMI_OFFSET_BT 0x0004b000
+#endif
+
+#define CONNLOG_EMI_SIZE_WIFI (192*1024)
+#define CONNLOG_EMI_SIZE_BT (64*1024)
+
+struct connlog_emi_config g_connsyslog_config[CONN_DEBUG_TYPE_END] = {
+ /* Wi-Fi config */
+ {CONNLOG_EMI_OFFSET_WIFI, CONNLOG_EMI_SIZE_WIFI},
+ {CONNLOG_EMI_OFFSET_BT, CONNLOG_EMI_SIZE_BT},
+};
+
+struct connlog_emi_config* get_connsyslog_platform_config(int conn_type)
+{
+ if (conn_type < 0 || conn_type >= CONN_DEBUG_TYPE_END) {
+ pr_err("Incorrect type: %d\n", conn_type);
+ return NULL;
+ }
+ return &g_connsyslog_config[conn_type];
+}
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/ring.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/ring.c
new file mode 100644
index 0000000..240f538
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/ring.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#include "ring.h"
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/bug.h>
+
+
+
+void ring_init(void *base, unsigned int max_size, unsigned int read,
+ unsigned int write, struct ring *ring)
+{
+ WARN_ON(!base);
+
+ /* making sure max_size is power of 2 */
+ WARN_ON(!max_size || (max_size & (max_size - 1)));
+
+ /* making sure write largger than read */
+ WARN_ON(read > write);
+
+ ring->base = base;
+ ring->read = read;
+ ring->write = write;
+ ring->max_size = max_size;
+}
+
+void ring_dump(const char *title, struct ring *ring)
+{
+ pr_info("[%s] ring:{write=%d, read=%d, max_size=%d}\n",
+ title, ring->write, ring->read, ring->max_size);
+}
+
+void ring_dump_segment(const char *title, struct ring_segment *seg)
+{
+ pr_info("[%s] seg:{ring_pt=0x%p, data_pos=%d, sz=%d, remain=%d}\n",
+ title, seg->ring_pt, seg->data_pos, seg->sz, seg->remain);
+}
+
+/*
+ * Function prepares the ring_segment and returns the number of valid bytes for read.
+ */
+unsigned int ring_read_prepare(unsigned int sz, struct ring_segment *seg, struct ring *ring)
+{
+ unsigned int wt = ring->write;
+ unsigned int rd = ring->read;
+
+ memset(seg, 0, sizeof(struct ring_segment));
+ if (sz > wt - rd)
+ sz = wt - rd;
+ seg->remain = sz;
+ /* ring_dump(__func__, ring); */
+ /* ring_dump_segment(__func__, seg); */
+ return seg->remain;
+}
+
+/*
+ * Function prepares the ring_segment and returns the number of bytes available for write.
+ */
+unsigned int ring_write_prepare(unsigned int sz, struct ring_segment *seg, struct ring *ring)
+{
+ unsigned int wt = ring->write;
+ unsigned int rd = ring->read;
+
+ memset(seg, 0, sizeof(struct ring_segment));
+ if (sz > ring->max_size - (wt - rd))
+ sz = ring->max_size - (wt - rd);
+ seg->remain = sz;
+ /* ring_dump(__func__, ring); */
+ /* ring_dump_segment(__func__, seg); */
+ return seg->remain;
+}
+
+unsigned int ring_overwrite_prepare(unsigned int sz, struct ring_segment *seg,
+ struct ring *ring)
+{
+ unsigned int wt = ring->write;
+ unsigned int rd = ring->read;
+
+ memset(seg, 0, sizeof(struct ring_segment));
+ if (sz > ring->max_size - (wt - rd))
+ ring->read += sz - (ring->max_size - (wt - rd));
+ seg->remain = sz;
+ /* ring_dump(__func__, ring); */
+ /* ring_dump_segment(__func__, seg); */
+ return seg->remain;
+}
+
+void __ring_segment_prepare(unsigned int from, unsigned int sz, struct ring_segment *seg,
+ struct ring *ring)
+{
+ unsigned int ring_pos = from & (ring->max_size - 1);
+
+ seg->ring_pt = ring->base + ring_pos;
+ seg->data_pos = (seg->sz ? seg->data_pos + seg->sz : 0);
+ if (ring_pos + sz <= ring->max_size)
+ seg->sz = sz;
+ else
+ seg->sz = ring->max_size - ring_pos;
+ seg->remain -= seg->sz;
+ /* ring_dump(__func__, ring); */
+ /* ring_dump_segment(__func__, seg); */
+}
+
+void _ring_segment_prepare(unsigned int from, struct ring_segment *seg, struct ring *ring)
+{
+ __ring_segment_prepare(from, seg->remain, seg, ring);
+}
+
+void _ring_segment_prepare_item(unsigned int from, struct ring_segment *seg, struct ring *ring)
+{
+ unsigned int size;
+
+ size = (seg->remain ? 1 : 0);
+ __ring_segment_prepare(from, size, seg, ring);
+}
+
+void _ring_read_commit(struct ring_segment *seg, struct ring *ring)
+{
+ ring->read += seg->sz;
+ /* ring_dump(__func__, ring); */
+ /* ring_dump_segment(__func__, seg); */
+}
+void _ring_write_commit(struct ring_segment *seg, struct ring *ring)
+{
+ ring->write += seg->sz;
+ /* ring_dump(__func__, ring); */
+ /* ring_dump_segment(__func__, seg); */
+}
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/ring_emi.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/ring_emi.c
new file mode 100644
index 0000000..03115ad
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/ring_emi.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+#include "ring_emi.h"
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/bug.h>
+
+void ring_emi_init(void *base, unsigned int max_size, void *read, void *write, struct ring_emi *ring_emi)
+{
+ WARN_ON(!base || !read || !write);
+
+ /* making sure max_size is power of 2 */
+ WARN_ON(!max_size || (max_size & (max_size - 1)));
+
+ /* making sure read & write pointers are 4 bytes aligned */
+ WARN_ON(((long)read & 0x3) != 0 || ((long)write & 0x3) != 0);
+
+ ring_emi->base = base;
+ ring_emi->read = read;
+ ring_emi->write = write;
+ EMI_WRITE32(ring_emi->write, 0);
+ EMI_WRITE32(ring_emi->read, 0);
+ ring_emi->max_size = max_size;
+ pr_info("write(%p) as 0, read(%p) as 0\n", ring_emi->write, ring_emi->read);
+ pr_info("base: %p, read: %p, write: %p, max_size: %d\n", base, read, write, max_size);
+}
+
+void ring_emi_dump(const char *title, struct ring_emi *ring_emi)
+{
+ pr_info("[%s] ring_emi:{base=0x%p, write=%d, read=%d, max_size=%d}\n",
+ title, ring_emi->base, EMI_READ32(ring_emi->write),
+ EMI_READ32(ring_emi->read), ring_emi->max_size);
+}
+
+void ring_emi_dump_segment(const char *title, struct ring_emi_segment *seg)
+{
+ pr_info("[%s] seg:{ring_emi_pt=0x%p, data_pos=%d, sz=%d, remain=%d}\n",
+ title, seg->ring_emi_pt, seg->data_pos, seg->sz, seg->remain);
+}
+
+/*
+ * Function prepares the ring_emi_segment and returns the number of valid bytes for read.
+ */
+unsigned int ring_emi_read_prepare(unsigned int sz, struct ring_emi_segment *seg, struct ring_emi *ring_emi)
+{
+ unsigned int wt = EMI_READ32(ring_emi->write);
+ unsigned int rd = EMI_READ32(ring_emi->read);
+
+ memset(seg, 0, sizeof(struct ring_emi_segment));
+#ifdef ROUND_REPEAT
+ if (wt >= rd) {
+ if (sz > wt - rd)
+ sz = wt - rd;
+ seg->remain = sz;
+ } else {
+ if (sz > ring_emi->max_size - (rd - wt))
+ sz = ring_emi->max_size - (rd - wt);
+ seg->remain = sz;
+ }
+#else
+ if (sz > wt - rd)
+ sz = wt - rd;
+ seg->remain = sz;
+#endif
+ /* ring_emi_dump(__func__, ring_emi); */
+ /* ring_emi_dump_segment(__func__, seg); */
+ return seg->remain;
+}
+
+/*
+ * Function prepares the ring_emi_segment and returns the number of bytes available for write.
+ */
+unsigned int ring_emi_write_prepare(unsigned int sz, struct ring_emi_segment *seg, struct ring_emi *ring_emi)
+{
+ unsigned int wt = EMI_READ32(ring_emi->write);
+ unsigned int rd = EMI_READ32(ring_emi->read);
+
+ memset(seg, 0, sizeof(struct ring_emi_segment));
+#ifdef ROUND_REPEAT
+ if (wt >= rd)
+ seg->remain = ring_emi->max_size - (wt - rd + 1);
+ else
+ seg->remain = ring_emi->max_size - (rd - wt + 1);
+
+ if (sz <= seg->remain)
+ seg->remain = sz;
+#else
+ if (sz > ring_emi->max_size - (wt - rd))
+ sz = ring_emi->max_size - (wt - rd);
+ seg->remain = sz;
+#endif
+ /* ring_emi_dump(__func__, ring_emi); */
+ /* ring_emi_dump_segment(__func__, seg); */
+ return seg->remain;
+}
+
+void _ring_emi_segment_prepare(unsigned int from, struct ring_emi_segment *seg, struct ring_emi *ring_emi)
+{
+#ifndef ROUND_REPEAT
+ unsigned int ring_emi_pos = from & (ring_emi->max_size - 1);
+
+ seg->ring_emi_pt = ring_emi->base + ring_emi_pos;
+#else
+ seg->ring_emi_pt = ring_emi->base + from;
+#endif
+ seg->data_pos = (seg->sz ? seg->data_pos + seg->sz : 0);
+ if (from + seg->remain <= ring_emi->max_size)
+ seg->sz = seg->remain;
+ else
+ seg->sz = ring_emi->max_size - from;
+ seg->remain -= seg->sz;
+ /* ring_emi_dump(__func__, ring_emi); */
+ /* ring_emi_dump_segment(__func__, seg); */
+}
+
+void _ring_emi_read_commit(struct ring_emi_segment *seg, struct ring_emi *ring_emi)
+{
+#ifdef ROUND_REPEAT
+#ifdef DEBUG_LOG_ON
+ pr_info("[%s] write %p as %d\n", __func__, ring_emi->read, (EMI_READ32(ring_emi->read) + seg->sz) & (ring_emi->max_size - 1));
+#endif
+ EMI_WRITE32(ring_emi->read, (EMI_READ32(ring_emi->read) + seg->sz) & (ring_emi->max_size - 1));
+#else
+#ifdef DEBUG_LOG_ON
+ pr_info("[%s] write %p as %d\n", __func__, ring_emi->read, EMI_READ32(ring_emi->read) + seg->sz);
+#endif
+ EMI_WRITE32(ring_emi->read, EMI_READ32(ring_emi->read) + seg->sz);
+#endif
+ /* *(ring_emi->read) += seg->sz; */
+ /* ring_emi_dump(__func__, ring_emi); */
+ /* ring_emi_dump_segment(__func__, seg); */
+}
+void _ring_emi_write_commit(struct ring_emi_segment *seg, struct ring_emi *ring_emi)
+{
+#ifdef ROUND_REPEAT
+#ifdef DEBUG_LOG_ON
+ pr_info("[%s] write %p as %d\n", __func__, (EMI_READ32(ring_emi->write) + seg->sz) & (ring_emi->max_size - 1));
+#endif
+ EMI_WRITE32(ring_emi->write, (EMI_READ32(ring_emi->write) + seg->sz) & (ring_emi->max_size - 1));
+#else
+#ifdef DEBUG_LOG_ON
+ pr_info("[%s] write %p as %d\n", __func__, ring_emi->write, EMI_READ32(ring_emi->write) + seg->sz);
+#endif
+ EMI_WRITE32(ring_emi->write, EMI_READ32(ring_emi->write) + seg->sz);
+#endif
+ /* ring_emi_dump(__func__, ring_emi); */
+ /* ring_emi_dump_segment(__func__, seg); */
+}
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/ring_emi.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/ring_emi.h
new file mode 100644
index 0000000..5969fd9
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/connsyslog/ring_emi.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+#ifndef _RING_EMI_H_
+#define _RING_EMI_H_
+
+#include <linux/io.h>
+#define ROUND_REPEAT
+#define EMI_READ32(addr) (readl(addr))
+#define EMI_WRITE32(addr, data) (writel(data, addr))
+
+struct ring_emi {
+ /* addr where ring buffer starts */
+ void *base;
+ /* addr storing the next writable pos, guaranteed to be >= read except when write overflow, but it's ok. */
+ void *write;
+ /* addr storing the next readable pos, except when read == write as buffer empty */
+ void *read;
+ /* must be power of 2 */
+ unsigned int max_size;
+};
+
+struct ring_emi_segment {
+ /* addr points into ring buffer for read/write */
+ void *ring_emi_pt;
+ /* size to read/write */
+ unsigned int sz;
+ /* pos in external data buffer to read/write */
+ unsigned int data_pos;
+ /* the size to be read/write after this segment completed */
+ unsigned int remain;
+};
+
+void ring_emi_init(void *base, unsigned int max_size, void *read, void *write, struct ring_emi *ring_emi);
+unsigned int ring_emi_read_prepare(unsigned int sz, struct ring_emi_segment *seg, struct ring_emi *ring_emi);
+#define ring_emi_read_all_prepare(seg, ring_emi) ring_emi_read_prepare((ring_emi)->max_size, seg, ring_emi)
+unsigned int ring_emi_write_prepare(unsigned int sz, struct ring_emi_segment *seg, struct ring_emi *ring_emi);
+
+/* making sure max_size is power of 2 */
+#define RING_EMI_VALIDATE_SIZE(max_size) WARN_ON(!max_size || (max_size & (max_size - 1)))
+
+#define RING_EMI_EMPTY(ring_emi) (EMI_READ32((ring_emi)->read) == EMI_READ32((ring_emi)->write))
+/* equation works even when write overflow */
+#define RING_EMI_SIZE(ring_emi) (EMI_READ32((ring_emi)->write) - EMI_READ32((ring_emi)->read))
+#ifdef ROUND_REPEAT
+#define RING_EMI_FULL(ring_emi) (((EMI_READ32((ring_emi)->write) + 1) & ((ring_emi)->max_size - 1)) \
+ == EMI_READ32((ring_emi)->read))
+#else
+#define RING_EMI_FULL(ring_emi) (RING_EMI_SIZE(ring_emi) == (ring_emi)->max_size)
+#endif
+
+#define RING_EMI_READ_FOR_EACH(_sz, _seg, _ring_emi) \
+ for (_ring_emi_segment_prepare(EMI_READ32((_ring_emi)->read), &(_seg), (_ring_emi)); \
+ (_seg).sz > 0; \
+ _ring_emi_read_commit(&(_seg), (_ring_emi)), \
+ _ring_emi_segment_prepare(EMI_READ32((_ring_emi)->read), &(_seg), (_ring_emi)))
+
+#define RING_EMI_READ_ALL_FOR_EACH(seg, ring_emi) RING_EMI_READ_FOR_EACH((ring_emi)->max_size, seg, ring_emi)
+
+#define RING_EMI_WRITE_FOR_EACH(_sz, _seg, _ring_emi) \
+ for (_ring_emi_segment_prepare(EMI_READ32((_ring_emi)->write), &(_seg), (_ring_emi)); \
+ (_seg).sz > 0; \
+ _ring_emi_write_commit(&(_seg), (_ring_emi)), \
+ _ring_emi_segment_prepare(EMI_READ32((_ring_emi)->write), &(_seg), (_ring_emi)))
+
+void ring_emi_dump(const char *title, struct ring_emi *ring_emi);
+void ring_emi_dump_segment(const char *title, struct ring_emi_segment *seg);
+
+
+/* Ring Buffer Internal API */
+void _ring_emi_segment_prepare(unsigned int from, struct ring_emi_segment *seg, struct ring_emi *ring_emi);
+void _ring_emi_read_commit(struct ring_emi_segment *seg, struct ring_emi *ring_emi);
+void _ring_emi_write_commit(struct ring_emi_segment *seg, struct ring_emi *ring_emi);
+
+#endif
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/conndump_netlink.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/conndump_netlink.c
new file mode 100755
index 0000000..7c96564
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/conndump_netlink.c
@@ -0,0 +1,535 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <net/sock.h>
+#include <net/netlink.h>
+#include <linux/skbuff.h>
+#include <net/genetlink.h>
+
+#include "connsys_debug_utility.h"
+#include "conndump_netlink.h"
+
+
+/*******************************************************************************
+* MACROS
+********************************************************************************
+*/
+#define MAX_BIND_PROCESS (4)
+
+#define CONNSYS_DUMP_NETLINK_FAMILY_NAME_WIFI "CONNDUMP_WIFI"
+#define CONNSYS_DUMP_NETLINK_FAMILY_NAME_BT "CONNDUMP_BT"
+
+#ifndef GENL_ID_GENERATE
+#define GENL_ID_GENERATE 0
+#endif
+
+#define CONNSYS_DUMP_PKT_SIZE NLMSG_DEFAULT_SIZE
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+enum {
+ __CONNDUMP_ATTR_INVALID,
+ CONNDUMP_ATTR_MSG,
+ CONNDUMP_ATTR_PORT,
+ CONNDUMP_ATTR_HEADER,
+ CONNDUMP_ATTR_MSG_SIZE,
+ CONNDUMP_ATTR_LAST,
+ __CONNDUMP_ATTR_MAX,
+};
+#define CONNDUMP_ATTR_MAX (__CONNDUMP_ATTR_MAX - 1)
+
+enum {
+ __CONNDUMP_COMMAND_INVALID,
+ CONNDUMP_COMMAND_BIND,
+ CONNDUMP_COMMAND_DUMP,
+ CONNDUMP_COMMAND_END,
+ CONNDUMP_COMMAND_RESET,
+ __CONNDUMP_COMMAND_MAX,
+};
+
+enum LINK_STATUS {
+ LINK_STATUS_INIT,
+ LINK_STATUS_INIT_DONE,
+ LINK_STATUS_MAX,
+};
+
+struct dump_netlink_ctx {
+ int conn_type;
+ pid_t bind_pid[MAX_BIND_PROCESS];
+ unsigned int num_bind_process;
+ struct genl_family gnl_family;
+ unsigned int seqnum;
+ struct mutex nl_lock;
+ enum LINK_STATUS status;
+ void* coredump_ctx;
+ struct netlink_event_cb cb;
+};
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+static int conndump_nl_bind_wifi(struct sk_buff *skb, struct genl_info *info);
+static int conndump_nl_dump_wifi(struct sk_buff *skb, struct genl_info *info);
+static int conndump_nl_dump_end_wifi(struct sk_buff *skb, struct genl_info *info);
+static int conndump_nl_reset_wifi(struct sk_buff *skb, struct genl_info *info);
+static int conndump_nl_bind_bt(struct sk_buff *skb, struct genl_info *info);
+static int conndump_nl_dump_bt(struct sk_buff *skb, struct genl_info *info);
+static int conndump_nl_dump_end_bt(struct sk_buff *skb, struct genl_info *info);
+static int conndump_nl_reset_bt(struct sk_buff *skb, struct genl_info *info);
+
+/*******************************************************************************
+* G L O B A L V A R I A B L E
+********************************************************************************
+*/
+
+/* attribute policy */
+static struct nla_policy conndump_genl_policy[CONNDUMP_ATTR_MAX + 1] = {
+ [CONNDUMP_ATTR_MSG] = {.type = NLA_NUL_STRING},
+ [CONNDUMP_ATTR_PORT] = {.type = NLA_U32},
+ [CONNDUMP_ATTR_HEADER] = {.type = NLA_NUL_STRING},
+ [CONNDUMP_ATTR_MSG_SIZE] = {.type = NLA_U32},
+ [CONNDUMP_ATTR_LAST] = {.type = NLA_U32},
+};
+
+
+/* operation definition */
+static struct genl_ops conndump_gnl_ops_array_wifi[] = {
+ {
+ .cmd = CONNDUMP_COMMAND_BIND,
+ .flags = 0,
+ .policy = conndump_genl_policy,
+ .doit = conndump_nl_bind_wifi,
+ .dumpit = NULL,
+ },
+ {
+ .cmd = CONNDUMP_COMMAND_DUMP,
+ .flags = 0,
+ .policy = conndump_genl_policy,
+ .doit = conndump_nl_dump_wifi,
+ .dumpit = NULL,
+ },
+ {
+ .cmd = CONNDUMP_COMMAND_END,
+ .flags = 0,
+ .policy = conndump_genl_policy,
+ .doit = conndump_nl_dump_end_wifi,
+ .dumpit = NULL,
+ },
+ {
+ .cmd = CONNDUMP_COMMAND_RESET,
+ .flags = 0,
+ .policy = conndump_genl_policy,
+ .doit = conndump_nl_reset_wifi,
+ .dumpit = NULL,
+ },
+};
+
+static struct genl_ops conndump_gnl_ops_array_bt[] = {
+ {
+ .cmd = CONNDUMP_COMMAND_BIND,
+ .flags = 0,
+ .policy = conndump_genl_policy,
+ .doit = conndump_nl_bind_bt,
+ .dumpit = NULL,
+ },
+ {
+ .cmd = CONNDUMP_COMMAND_DUMP,
+ .flags = 0,
+ .policy = conndump_genl_policy,
+ .doit = conndump_nl_dump_bt,
+ .dumpit = NULL,
+ },
+ {
+ .cmd = CONNDUMP_COMMAND_END,
+ .flags = 0,
+ .policy = conndump_genl_policy,
+ .doit = conndump_nl_dump_end_bt,
+ .dumpit = NULL,
+ },
+ {
+ .cmd = CONNDUMP_COMMAND_RESET,
+ .flags = 0,
+ .policy = conndump_genl_policy,
+ .doit = conndump_nl_reset_bt,
+ .dumpit = NULL,
+ },
+};
+
+struct dump_netlink_ctx g_netlink_ctx[2] = {
+ /* WIFI */
+ {
+ .conn_type = CONN_DEBUG_TYPE_WIFI,
+ .gnl_family = {
+ .id = GENL_ID_GENERATE,
+ .hdrsize = 0,
+ .name = CONNSYS_DUMP_NETLINK_FAMILY_NAME_WIFI,
+ .version = 1,
+ .maxattr = CONNDUMP_ATTR_MAX,
+ .ops = conndump_gnl_ops_array_wifi,
+ .n_ops = ARRAY_SIZE(conndump_gnl_ops_array_wifi),
+ },
+ .status = LINK_STATUS_INIT,
+ .num_bind_process = 0,
+ .seqnum = 0,
+ },
+ /* BT */
+ {
+ .conn_type = CONN_DEBUG_TYPE_BT,
+ .gnl_family = {
+ .id = GENL_ID_GENERATE,
+ .hdrsize = 0,
+ .name = CONNSYS_DUMP_NETLINK_FAMILY_NAME_BT,
+ .version = 1,
+ .maxattr = CONNDUMP_ATTR_MAX,
+ .ops = conndump_gnl_ops_array_bt,
+ .n_ops = ARRAY_SIZE(conndump_gnl_ops_array_bt),
+ },
+ .status = LINK_STATUS_INIT,
+ .num_bind_process = 0,
+ .seqnum = 0,
+ },
+};
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+static int conndump_nl_bind_internal(struct dump_netlink_ctx* ctx, struct sk_buff *skb, struct genl_info *info)
+{
+ int i;
+ struct nlattr *port_na;
+ unsigned int port;
+
+ if (info == NULL)
+ goto out;
+
+ if (mutex_lock_killable(&ctx->nl_lock))
+ return -1;
+
+ port_na = info->attrs[CONNDUMP_ATTR_PORT];
+ if (port_na) {
+ port = (unsigned int)nla_get_u32(port_na);
+ } else {
+ pr_err("%s:-> no port_na found\n");
+ return -1;
+ }
+
+ for (i = 0; i < MAX_BIND_PROCESS; i ++) {
+ if (ctx->bind_pid[i] == 0) {
+ ctx->bind_pid[i] = port;
+ ctx->num_bind_process++;
+ pr_info("%s():-> pid = %d\n", __func__, port);
+ break;
+ }
+ }
+ if (i == MAX_BIND_PROCESS) {
+ pr_err("%s(): exceeding binding limit %d\n", __func__, MAX_BIND_PROCESS);
+ }
+ mutex_unlock(&ctx->nl_lock);
+
+out:
+ return 0;
+}
+
+static int conndump_nl_dump_end_internal(struct dump_netlink_ctx* ctx, struct sk_buff *skb, struct genl_info *info)
+{
+ if (ctx && ctx->cb.coredump_end) {
+ pr_info("Get coredump end command, type=%d", ctx->conn_type);
+ ctx->cb.coredump_end(ctx->coredump_ctx);
+ }
+ return 0;
+}
+
+static int conndump_nl_bind_wifi(struct sk_buff *skb, struct genl_info *info)
+{
+ int ret = 0;
+
+ ret = conndump_nl_bind_internal(&g_netlink_ctx[CONN_DEBUG_TYPE_WIFI], skb, info);
+ return ret;
+}
+
+static int conndump_nl_dump_wifi(struct sk_buff *skb, struct genl_info *info)
+{
+ pr_err("%s(): should not be invoked\n", __func__);
+
+ return 0;
+}
+
+static int conndump_nl_dump_end_wifi(struct sk_buff *skb, struct genl_info *info)
+{
+ int ret = 0;
+
+ ret = conndump_nl_dump_end_internal(&g_netlink_ctx[CONN_DEBUG_TYPE_WIFI], skb, info);
+
+ return ret;
+}
+
+static int conndump_nl_reset_wifi(struct sk_buff *skb, struct genl_info *info)
+{
+ pr_err("%s(): should not be invoked\n", __func__);
+
+ return 0;
+}
+
+static int conndump_nl_bind_bt(struct sk_buff *skb, struct genl_info *info)
+{
+ int ret = 0;
+
+ ret = conndump_nl_bind_internal(&g_netlink_ctx[CONN_DEBUG_TYPE_BT], skb, info);
+ return ret;
+}
+
+static int conndump_nl_dump_bt(struct sk_buff *skb, struct genl_info *info)
+{
+ pr_err("%s(): should not be invoked\n", __func__);
+
+ return 0;
+}
+
+static int conndump_nl_dump_end_bt(struct sk_buff *skb, struct genl_info *info)
+{
+ int ret = 0;
+
+ ret = conndump_nl_dump_end_internal(&g_netlink_ctx[CONN_DEBUG_TYPE_BT], skb, info);
+
+ return ret;
+
+}
+
+static int conndump_nl_reset_bt(struct sk_buff *skb, struct genl_info *info)
+{
+ pr_err("%s(): should not be invoked\n", __func__);
+
+ return 0;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * conndump_netlink_init
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+int conndump_netlink_init(int conn_type, void* dump_ctx, struct netlink_event_cb* cb)
+{
+ int ret = 0;
+ struct dump_netlink_ctx* ctx;
+
+ if (conn_type < CONN_DEBUG_TYPE_WIFI || conn_type > CONN_DEBUG_TYPE_BT) {
+ pr_err("Incorrect type (%d)\n", conn_type);
+ return -1;
+ }
+
+ ctx = &g_netlink_ctx[conn_type];
+ mutex_init(&ctx->nl_lock);
+ ret = genl_register_family(&ctx->gnl_family);
+ if (ret != 0) {
+ pr_err("%s(): GE_NELINK family registration fail (ret=%d)\n", __func__, ret);
+ return -2;
+ }
+ ctx->status = LINK_STATUS_INIT_DONE;
+ memset(ctx->bind_pid, 0, sizeof(ctx->bind_pid));
+ ctx->coredump_ctx = dump_ctx;
+ memcpy(&(ctx->cb), cb, sizeof(struct netlink_event_cb));
+
+ return ret;
+}
+
+int conndump_netlink_msg_send(struct dump_netlink_ctx* ctx, char* tag, char* buf, unsigned int length, pid_t pid, unsigned int seq)
+{
+ struct sk_buff *skb;
+ void* msg_head = NULL;
+ int ret = 0;
+ int conn_type = ctx->conn_type;
+
+ /* Allocating a Generic Netlink message buffer */
+ skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (skb != NULL) {
+ /* Create message header */
+ msg_head = genlmsg_put(skb, 0, seq, &ctx->gnl_family, 0, CONNDUMP_COMMAND_DUMP);
+ if (msg_head == NULL) {
+ pr_err("%s(): genlmsg_put fail(conn_type=%d).\n", __func__, conn_type);
+ nlmsg_free(skb);
+ return -EMSGSIZE;
+ }
+ /* Add message attribute and content */
+ ret = nla_put_string(skb, CONNDUMP_ATTR_HEADER, tag);
+ if (ret != 0) {
+ pr_err("%s(): nla_put_string header fail(conn_type=%d): %d\n", __func__, conn_type, ret);
+ genlmsg_cancel(skb, msg_head);
+ nlmsg_free(skb);
+ return ret;
+ }
+ if (length) {
+ ret = nla_put(skb, CONNDUMP_ATTR_MSG, length, buf);
+ if (ret != 0) {
+ pr_err("%s(): nla_put fail(conn_type=%d): %d\n", __func__, conn_type, ret);
+ genlmsg_cancel(skb, msg_head);
+ nlmsg_free(skb);
+ return ret;
+ }
+ ret = nla_put_u32(skb, CONNDUMP_ATTR_MSG_SIZE, length);
+ if (ret != 0) {
+ pr_err("%s(): nal_put_u32 fail(conn_type=%d): %d\n", __func__, conn_type, ret);
+ genlmsg_cancel(skb, msg_head);
+ nlmsg_free(skb);
+ return ret;
+ }
+ }
+ /* finalize the message */
+ genlmsg_end(skb, msg_head);
+
+ /* sending message */
+ ret = genlmsg_unicast(&init_net, skb, pid);
+ } else {
+ pr_err("Allocate message error\n");
+ ret = -ENOMEM;
+ }
+
+ return ret;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * conndump_send_to_native
+ * DESCRIPTION
+ * Send dump content to native layer (AEE or dump service)
+ * PARAMETERS
+ * conn_type [IN] subsys type
+ * tag [IN] the tag for the content (null end string)
+ * [M] for coredump
+ * buf [IN] the content to dump (a buffer may not have end character)
+ * length [IN] dump length
+ * RETURNS
+ *
+ *****************************************************************************/
+int conndump_netlink_send_to_native_internal(struct dump_netlink_ctx* ctx, char* tag, char* buf, unsigned int length)
+{
+ int killed_num = 0;
+ int i, j, ret = 0;
+ unsigned int retry;
+
+ for (i = 0; i < ctx->num_bind_process; i++) {
+ ret =conndump_netlink_msg_send(ctx, tag, buf, length, ctx->bind_pid[i], ctx->seqnum);
+ if (ret != 0) {
+ pr_err("%s(): genlmsg_unicast fail (ret=%d): pid = %d seq=%d tag=%s\n",
+ __func__, ret, ctx->bind_pid[i], ctx->seqnum, tag);
+ if (ret == -EAGAIN) {
+ retry = 0;
+ while (retry < 100 && ret == -EAGAIN) {
+ msleep(10);
+ ret =conndump_netlink_msg_send(ctx, tag, buf, length, ctx->bind_pid[i], ctx->seqnum);
+ retry ++;
+ pr_err("%s(): genlmsg_unicast retry (%d)...: ret = %d pid = %d seq=%d tag=%s\n",
+ __func__, retry, ret, ctx->bind_pid[i], ctx->seqnum, tag);
+ }
+ if (ret) {
+ pr_err("%s(): genlmsg_unicast fail (ret=%d) after retry %d times: pid = %d seq=%d tag=%s\n",
+ __func__, ret, retry, ctx->bind_pid[i], ctx->seqnum, tag);
+ }
+ }
+ if (ret == -ECONNREFUSED) {
+ ctx->bind_pid[i] = 0;
+ killed_num++;
+ }
+ }
+ }
+
+ ctx->seqnum ++;
+
+ /* Clean up invalid bind_pid */
+ if (killed_num > 0) {
+ if (mutex_lock_killable(&ctx->nl_lock)) {
+ /* if fail to get lock, it is fine to update bind_pid[] later */
+ return ret;
+ }
+ for (i = 0; i < ctx->num_bind_process - killed_num; i++) {
+ if (ctx->bind_pid[i] == 0) {
+ for (j = ctx->num_bind_process - 1; j > i; j--) {
+ if (ctx->bind_pid[j] > 0) {
+ ctx->bind_pid[i] = ctx->bind_pid[j];
+ ctx->bind_pid[j] = 0;
+ }
+ }
+ }
+ }
+ ctx->num_bind_process -= killed_num;
+ mutex_unlock(&ctx->nl_lock);
+ }
+
+ return ret;
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ * conndump_send_to_native
+ * DESCRIPTION
+ * Send dump content to native layer (AEE or dump service)
+ * PARAMETERS
+ * conn_type [IN] subsys type
+ * tag [IN] the tag for the content (null end string)
+ * [M] for coredump
+ * buf [IN] the content to dump (a buffer may not have end character)
+ * length [IN] dump length
+ * RETURNS
+ *
+ *****************************************************************************/
+int conndump_netlink_send_to_native(int conn_type, char* tag, char* buf, unsigned int length)
+{
+ struct dump_netlink_ctx* ctx;
+ int idx = 0;
+ unsigned int send_len;
+ unsigned int remain_len = length;
+ int ret;
+
+ pr_info("[%s] conn_type=%d tag=%s buf=0x%x length=%d\n",
+ __func__, conn_type, tag, buf, length);
+ if ((conn_type < CONN_DEBUG_TYPE_WIFI || conn_type > CONN_DEBUG_TYPE_BT) || tag == NULL) {
+ pr_err("Incorrect type (%d), tag = %s\n", conn_type, tag);
+ return -1;
+ }
+
+ ctx = &g_netlink_ctx[conn_type];
+ if (ctx->status != LINK_STATUS_INIT_DONE) {
+ pr_err("%s(): netlink should be init (type=%d).\n", __func__, conn_type);
+ return -2;
+ }
+
+ if (ctx->num_bind_process == 0) {
+ pr_err("No bind service\n");
+ return -3;
+ }
+
+ while (remain_len) {
+ send_len = (remain_len > CONNSYS_DUMP_PKT_SIZE? CONNSYS_DUMP_PKT_SIZE : remain_len);
+ ret = conndump_netlink_send_to_native_internal(ctx, tag, &buf[idx], send_len);
+ if (ret) {
+ pr_err("[%s] from %d with len=%d fail, ret=%d\n", __func__, idx, send_len, ret);
+ break;
+ }
+ remain_len -= send_len;
+ idx += send_len;
+ }
+ return idx;
+}
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/conndump_netlink.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/conndump_netlink.h
new file mode 100755
index 0000000..70f3517
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/conndump_netlink.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+#ifndef _CONNDUMP_NETLINK_H_
+#define _CONNDUMP_NETLINK_H_
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+#include "coredump/connsys_coredump.h"
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+struct netlink_event_cb {
+ void (*coredump_end)(void*);
+};
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+int conndump_netlink_init(int conn_type, void* dump_ctx, struct netlink_event_cb* cb);
+int conndump_netlink_send_to_native(int conn_type, char* tag, char* buf, unsigned int length);
+
+
+#endif /*_CONNDUMP_NETLINK_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/connsys_coredump.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/connsys_coredump.c
new file mode 100755
index 0000000..98d36b4
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/connsys_coredump.c
@@ -0,0 +1,1707 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/ratelimit.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#if defined(CONNINFRA_PLAT_ALPS) && CONNINFRA_PLAT_ALPS
+#include <aee.h>
+#endif
+#include "conninfra.h"
+#include "connsys_debug_utility.h"
+#include "connsys_coredump.h"
+#include "connsys_coredump_emi.h"
+#include "connsys_coredump_hw_config.h"
+#include "conndump_netlink.h"
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+#define DEBUG_MODE 1
+
+#define CONNSYS_DUMP_INFO_SIZE 180
+#define CONNSYS_ASSERT_INFO_SIZE 164
+#define CONNSYS_ASSERT_TYPE_SIZE 64
+#define CONNSYS_ASSERT_KEYWORD_SIZE 64
+#define CONNSYS_ASSERT_REASON_SIZE 128
+#define CONNSYS_AEE_INFO_SIZE 240
+
+#define INFO_HEAD ";CONSYS FW CORE,"
+#define WDT_INFO_HEAD "Watch Dog Timeout"
+
+enum fw_coredump_status {
+ FW_DUMP_STATE_NOT_START = 0,
+ FW_DUMP_STATE_PUTTING = 1,
+ FW_DUMP_STATE_PUT_DONE = 2,
+ FW_DUMP_STATE_END,
+};
+
+enum core_dump_state {
+ CORE_DUMP_INIT = 0,
+ CORE_DUMP_START,
+ CORE_DUMP_DOING,
+ CORE_DUMP_TIMEOUT, /* Coredump timeout */
+ CORE_DUMP_EMI_TIMEOUT, /* EMI dump timeout */
+ CORE_DUMP_EMI, /* start for EMI dump */
+ CORE_DUMP_DONE,
+ CORE_DUMP_INVALID,
+ CORE_DUMP_MAX,
+};
+
+enum connsys_issue_type {
+ CONNSYS_ISSUE_FW_ASSERT = 0,
+ CONNSYS_ISSUE_FW_EXCEPTION,
+ CONNSYS_ISSUE_DRIVER_ASSERT,
+ CONNSYS_ISSUE_MAX,
+};
+
+struct connsys_dump_info {
+ enum connsys_issue_type issue_type;
+ char dump_info[CONNSYS_DUMP_INFO_SIZE];
+ char assert_info[CONNSYS_ASSERT_INFO_SIZE];
+ unsigned int fw_task_id;
+ unsigned int fw_isr;
+ unsigned int fw_irq;
+ unsigned int exp_ipc;
+ unsigned int exp_eva;
+ char etype[CONNSYS_ASSERT_INFO_SIZE];
+ char assert_type[CONNSYS_ASSERT_TYPE_SIZE];
+ char exception_log[CONNSYS_AEE_INFO_SIZE];
+ int drv_type;
+ char reason[CONNSYS_ASSERT_REASON_SIZE];
+ char keyword[CONNSYS_ASSERT_KEYWORD_SIZE];
+};
+
+struct connsys_dump_ctx {
+ int conn_type;
+ phys_addr_t emi_phy_addr_base;
+ void __iomem *emi_virt_addr_base;
+ unsigned int emi_size;
+ unsigned int mcif_emi_size;
+ struct coredump_event_cb callback;
+ struct timer_list dmp_timer;
+ struct completion emi_dump;
+ enum core_dump_state sm;
+ char* page_dump_buf;
+ struct dump_region* dump_regions;
+ int dump_regions_num;
+ unsigned int dynamic_map_cr;
+ struct coredump_hw_config hw_config;
+ struct connsys_dump_info info;
+ unsigned int full_emi_size;
+};
+
+#define DUMP_REGION_NAME_LENGTH 10
+/* TODO: Need check */
+#define DUMP_REGION_DEFAULT_NUM 50
+
+enum dump_region_type {
+ DUMP_TYPE_CR = 0,
+ DUMP_TYPE_ROM,
+ DUMP_TYPE_ILM,
+ DUMP_TYPE_DLM,
+ DUMP_TYPE_SRAM,
+ DUMP_TYPE_SYS1,
+ DUMP_TYPE_SYS2,
+ DUMP_TYPE_MAX,
+};
+
+struct dump_region {
+ int dump_type;
+ char name[DUMP_REGION_NAME_LENGTH];
+ unsigned int base;
+ unsigned int length;
+};
+
+static atomic_t g_dump_mode = ATOMIC_INIT(DUMP_MODE_DAEMON);
+
+static const char* g_type_name[] = {
+ "Wi-Fi",
+ "BT",
+};
+
+/*******************************************************************************
+* MACROS
+********************************************************************************
+*/
+
+#if DEBUG_MODE
+#if defined(CONFIG_FPGA_EARLY_PORTING)
+/* For FPGA shorten the timer */
+#define CONNSYS_COREDUMP_TIMEOUT (1*10*1000)
+#define CONNSYS_EMIDUMP_TIMEOUT (10*1000)
+#else
+#define CONNSYS_COREDUMP_TIMEOUT (1*10*1000)
+#define CONNSYS_EMIDUMP_TIMEOUT (60*1000)
+#endif
+#else
+#define CONNSYS_COREDUMP_TIMEOUT (10*1000)
+#define CONNSYS_EMIDUMP_TIMEOUT (60*1000)
+#endif
+
+#define CONNSYS_DUMP_BUFF_SIZE (32*1024*sizeof(char))
+
+#define EMI_READ32(addr) (readl(addr))
+#define EMI_READ8(addr) (readb(addr))
+#define DUMP_LOG_BYTES_PER_LINE (128)
+#define IS_VISIBLE_CHAR(c) ((c) >= 32 && (c) <= 126)
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+static void conndump_set_dump_state(struct connsys_dump_ctx* ctx, enum core_dump_state state);
+static enum core_dump_state conndump_get_dump_state(struct connsys_dump_ctx* ctx);
+static void conndump_timeout_handler(unsigned long data);
+static inline int conndump_get_dmp_info(struct connsys_dump_ctx* ctx, unsigned int offset, bool log);
+/* Dynamic remap relative function */
+static unsigned int conndump_setup_dynamic_remap(struct connsys_dump_ctx* ctx, unsigned int base, unsigned int length);
+static void __iomem* conndump_remap(struct connsys_dump_ctx* ctx, unsigned int base, unsigned int length);
+static void conndump_unmap(struct connsys_dump_ctx* ctx, void __iomem* vir_addr);
+/* To dump different partition */
+static void conndump_dump_log(char* buf, int size);
+static int conndump_dump_print_buff(struct connsys_dump_ctx* ctx);
+static int conndump_dump_dump_buff(struct connsys_dump_ctx* ctx);
+static int conndump_dump_cr_regions(struct connsys_dump_ctx* ctx);
+static int conndump_dump_mem_regions(struct connsys_dump_ctx* ctx);
+static int conndump_dump_emi(struct connsys_dump_ctx* ctx);
+static int conndump_send_fake_coredump(struct connsys_dump_ctx* ctx);
+/* Utility */
+static bool conndump_check_cr_readable(struct connsys_dump_ctx* ctx);
+static int conndump_info_format(
+ struct connsys_dump_ctx* ctx,
+ char* buf, unsigned int max_len,
+ bool full_dump);
+static void conndump_exception_show(struct connsys_dump_ctx* ctx, bool full_dump);
+/* memory allocate/free */
+static void* conndump_malloc(unsigned int size);
+static void conndump_free(const void* dst);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+/* Platform relative function */
+/* ------------------------------------------------------------------------------*/
+struct coredump_hw_config* __weak get_coredump_platform_config(int conn_type)
+{
+ pr_err("[%s] Miss platform ops!\n", __func__);
+ return NULL;
+}
+
+unsigned int __weak get_coredump_platform_chipid(void)
+{
+ pr_err("[%s] Miss platform ops!\n", __func__);
+ return 0;
+}
+
+char* __weak get_task_string(int conn_type, int task_id)
+{
+ pr_err("[%s] Miss platform ops!\n", __func__);
+ return "ERROR";
+}
+
+char* __weak get_sys_name(int conn_type)
+{
+ pr_err("[%s] Miss platform ops!\n", __func__);
+ return "ERROR";
+}
+
+bool __weak is_host_view_cr(unsigned int addr, unsigned int* host_view)
+{
+ pr_err("[%s] Miss platform ops!\n", __func__);
+ return false;
+}
+
+/*----------------------------------------------------------------------------*/
+
+
+static unsigned long timeval_to_ms(struct timeval *begin, struct timeval *end)
+{
+ unsigned long time_diff;
+
+ time_diff = (end->tv_sec - begin->tv_sec) * 1000;
+ time_diff += (end->tv_usec - begin->tv_usec) / 1000;
+
+ return time_diff;
+}
+
+static void* conndump_malloc(unsigned int size)
+{
+ void* p = NULL;
+
+ if (size > (PAGE_SIZE << 1))
+ p = vmalloc(size);
+ else
+ p = kmalloc(size, GFP_KERNEL);
+
+ /* If there is fragment, kmalloc may not get memory when size > one page.
+ * For this case, use vmalloc instead.
+ */
+ if (p == NULL && size > PAGE_SIZE)
+ p = vmalloc(size);
+ return p;
+}
+
+static void conndump_free(const void* dst)
+{
+ kvfree(dst);
+}
+
+
+static bool conndump_check_cr_readable(struct connsys_dump_ctx* ctx)
+{
+ int cb_ret = 0;
+
+ /* Check reg readable */
+ if (ctx->callback.reg_readable) {
+ cb_ret = ctx->callback.reg_readable();
+ if (cb_ret == 1) {
+ return true;
+ }
+ pr_err("[%s] reg_readable callback ret = %d\n",
+ g_type_name[ctx->conn_type], cb_ret);
+ return false;
+ }
+
+ pr_err("[%s] reg_readable callback is not implement! Return false\n", g_type_name[ctx->conn_type]);
+ return false;
+}
+
+static void conndump_set_dump_state(
+ struct connsys_dump_ctx* ctx, enum core_dump_state state)
+{
+ if (ctx)
+ ctx->sm = state;
+}
+
+static enum core_dump_state conndump_get_dump_state(struct connsys_dump_ctx* ctx)
+{
+ if (ctx)
+ return ctx->sm;
+ pr_err("%s ctx is null\n", __func__);
+ return CORE_DUMP_INVALID;
+}
+
+static void conndump_timeout_handler(unsigned long data)
+{
+ struct connsys_dump_ctx* ctx = (struct connsys_dump_ctx*)data;
+
+ pr_info("[%s] coredump timeout\n", ctx->conn_type);
+ conndump_set_dump_state(ctx, CORE_DUMP_TIMEOUT);
+}
+
+static inline void conndump_get_dmp_char(struct connsys_dump_ctx* ctx, unsigned int offset, unsigned int byte_num, char* dest)
+{
+ int i;
+ char ret;
+
+ if (!dest)
+ return;
+
+ for (i = 0; i < byte_num; i++) {
+ ret = EMI_READ8(ctx->emi_virt_addr_base + offset + i);
+ dest[i] = ret;
+ }
+}
+
+static inline int conndump_get_dmp_info(struct connsys_dump_ctx* ctx, unsigned int offset, bool log)
+{
+ int ret;
+
+ ret = EMI_READ32(ctx->emi_virt_addr_base + offset);
+ if (log)
+ pr_info("EMI[0x%x] = 0x%08x\n", offset, ret);
+
+ return ret;
+}
+
+static void conndump_dump_log(char* buf, int size)
+{
+ int i = 0;
+ char line[DUMP_LOG_BYTES_PER_LINE + 1];
+
+ while (size--) {
+ if (IS_VISIBLE_CHAR(*buf))
+ line[i] = *buf;
+ else
+ line[i] = '.';
+ i++;
+ buf++;
+
+ if (i >= DUMP_LOG_BYTES_PER_LINE || !size) {
+ line[i] = 0;
+ pr_info("page_trace: %s\n", line);
+ i = 0;
+ }
+ }
+}
+
+static int conndump_info_format(
+ struct connsys_dump_ctx* ctx,
+ char* buf,
+ unsigned int max_len,
+ bool full_dump)
+{
+#define FORMAT_STRING(buf, len, max_len, sec_len, fmt, arg...) \
+do { \
+ sec_len = snprintf(buf + len, max_len, fmt, ##arg); \
+ max_len -= sec_len; \
+ len += sec_len; \
+ if (max_len <= 0) \
+ goto format_finish; \
+} while (0)
+
+ int len = 0;
+ int ret;
+ int idx;
+ int sec_len;
+ char* drv_name[CONNDRV_TYPE_MAX] = {
+ "DRV_BT",
+ "DRV_FM",
+ "DRV_GPS",
+ "DRV_WIFI",
+ "DRV_CONNINFRA",
+ };
+ /* Align with connac1.x and previous version */
+ char* task_drv_name[CONNDRV_TYPE_MAX] = {
+ "Task_DrvBT",
+ "Task_DrvFM",
+ "Task_DrvGPS",
+ "Task_DrvWifi",
+ "Task_DrvConninfra",
+ };
+ char* task_drv_name2[CONN_DEBUG_TYPE_END] = {
+ "Task_DrvWifi",
+ "Task_DrvBT",
+ };
+
+ if (!buf) {
+ pr_err("Invalid input, buf = %p", buf);
+ return 0;
+ }
+
+ /* Init buffer */
+ memset(buf, '\0', max_len);
+ FORMAT_STRING(buf, len, max_len, sec_len, "<main>\n");
+ FORMAT_STRING(buf, len, max_len, sec_len, "\t<chipid>MT%x</chipid>\n", get_coredump_platform_chipid());
+
+ /* <issue> section */
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t<issue>\n\t\t<classification>\n\t\t\t%s\n\t\t</classification>\n",
+ ctx->info.assert_info);
+ if (ctx->info.issue_type == CONNSYS_ISSUE_FW_EXCEPTION) {
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t<rc>\n\t\t\tFW Exception: %s\n\t\t</rc>\n", ctx->info.etype);
+ } else if (ctx->info.issue_type == CONNSYS_ISSUE_FW_ASSERT) {
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t<rc>\n\t\t\t%s\n\t\t</rc>\n", ctx->info.assert_type);
+ } else if (ctx->info.issue_type == CONNSYS_ISSUE_DRIVER_ASSERT) {
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t<rc>\n\t\t\t%s trigger assert\n\t\t</rc>\n", drv_name[ctx->info.drv_type]);
+ } else {
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t<rc>\n\t\t\tUnknown\n\t\t</rc>\n");
+ }
+ /* <hint><client> section @{*/
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t</issue>\n\t<hint>\n\t\t<client>\n");
+
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t\t<subsys>%s</subsys>\n", ctx->hw_config.name);
+ if (ctx->info.issue_type == CONNSYS_ISSUE_DRIVER_ASSERT) {
+ /* Driver trigger assert */
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t\t<task>%s</task>\n",
+ task_drv_name[ctx->info.drv_type]);
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t\t<irqx>NULL</irqx>\n");
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t\t<isr>NULL</isr>\n");
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t\t<drv_type>%s</drv_type>\n",
+ drv_name[ctx->info.drv_type]);
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t\t<reason>%s</reason>\n",
+ ctx->info.reason);
+ } else {
+ /* FW assert */
+ if (full_dump) {
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t\t<task>%s</task>\n",
+ get_task_string(ctx->conn_type, ctx->info.fw_task_id));
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t\t<irqx>IRQ_0x%x_%s</irqx>\n",
+ ctx->info.fw_irq,
+ get_sys_name(ctx->conn_type));
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t\t<isr>0x%x</isr>\n",
+ ctx->info.fw_isr);
+ } else {
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t\t<task>%s</task>\n",
+ task_drv_name2[ctx->conn_type]);
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t\t<irqx>NULL</irqx>\n");
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t\t<isr>NULL</isr>\n");
+ }
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t\t<drv_type>%s</drv_type>\n",
+ "NULL");
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t\t<reason>%s</reason>\n",
+ "NULL");
+ }
+ if (strlen(ctx->info.keyword) != 0) {
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t\t<keyword>%s</keyword>\n",
+ ctx->info.keyword);
+ } else {
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t\t<keyword>NULL</keyword>\n");
+
+ }
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t</client>\n\t</hint>\n");
+ /*<hint><client> section @}*/
+ /* <map> section start @{ */
+ FORMAT_STRING(buf, len, max_len, sec_len, "\t<map>\n");
+ for (idx = 0; idx < ctx->dump_regions_num; idx++) {
+ /* Non-empty name means memory regions */
+ if (ctx->dump_regions[idx].name[0] != 0) {
+ FORMAT_STRING(buf, len, max_len, sec_len,
+ "\t\t<%s>\n\t\t\t<offset>0x%x</offset>\n\t\t\t<size>0x%x</size>\n\t\t</%s>\n",
+ ctx->dump_regions[idx].name,
+ ctx->dump_regions[idx].base,
+ ctx->dump_regions[idx].length,
+ ctx->dump_regions[idx].name);
+ }
+ }
+ FORMAT_STRING(buf, len, max_len, sec_len, "\t</map>\n");
+ /* <map> section end @} */
+ FORMAT_STRING(buf, len, max_len, sec_len, "</main>\n");
+
+format_finish:
+ pr_info("== Issue info ==\n", buf);
+ pr_info("%s\n", buf);
+ pr_info("===== END =====\n");
+ ret = conndump_netlink_send_to_native(ctx->conn_type, "INFO", buf, len);
+ if (ret < 0)
+ pr_err("Send issue info to native fail, ret=%d\n", ret);
+ return len;
+}
+
+static void conndump_info_analysis(
+ struct connsys_dump_ctx* ctx,
+ unsigned int buf_len)
+{
+ const char* parser_sub_string[] = {
+ "<ASSERT> ",
+ "id=",
+ "isr=",
+ "irq=",
+ "rc=",
+ };
+ const char* exception_sub_string[] = {
+ "<EXCEPTION> ",
+ "ipc=",
+ "eva=",
+ "etype:",
+ };
+ char* pStr = ctx->page_dump_buf;
+ char* pDtr = NULL;
+ char* pTemp = NULL;
+ char* pTemp2 = NULL;
+ unsigned int len;
+ int remain_array_len = 0, sec_len = 0, idx = 0;
+ char tempBuf[CONNSYS_ASSERT_TYPE_SIZE] = { 0 };
+ int ret, res;
+ char* type_str;
+
+ /* Check <ASSERT> */
+ memset(&ctx->info.assert_info[0], '\0', CONNSYS_ASSERT_INFO_SIZE);
+ type_str = (char*)parser_sub_string[0];
+ pDtr = strstr(pStr, type_str);
+ if (pDtr != NULL) {
+ if (ctx->info.issue_type != CONNSYS_ISSUE_DRIVER_ASSERT)
+ ctx->info.issue_type = CONNSYS_ISSUE_FW_ASSERT;
+ pDtr += strlen(type_str);
+ pTemp = strchr(pDtr, ' ');
+
+ if (pTemp != NULL) {
+ idx = 0;
+ remain_array_len = CONNSYS_ASSERT_INFO_SIZE -1;
+ sec_len = strlen("assert@");
+ memcpy(&ctx->info.assert_info[0], "assert@", sec_len);
+ idx += sec_len;
+ remain_array_len -= sec_len;
+
+ len = pTemp - pDtr;
+ sec_len = (len < remain_array_len ? len : remain_array_len);
+ if (sec_len > remain_array_len)
+ goto check_task_id;
+ memcpy(&ctx->info.assert_info[idx], pDtr, sec_len);
+ remain_array_len -= sec_len;
+ idx += sec_len;
+
+ sec_len = strlen("_");
+ if (sec_len > remain_array_len)
+ goto check_task_id;
+ ctx->info.assert_info[idx] = '_';
+ remain_array_len -= sec_len;
+ idx += sec_len;
+
+ pTemp = strchr(pDtr, '#');
+ if (pTemp != NULL) {
+ pTemp += 1;
+ pTemp2 = strchr(pTemp, ' ');
+ if (pTemp2 == NULL) {
+ pr_err("parser ' ' is not find\n");
+ pTemp2 = pTemp + 1;
+ }
+ pr_info("(pTemp2 - pTemp)=%d\n", (pTemp2 - pTemp));
+ if ((remain_array_len) > (pTemp2 - pTemp)) {
+ pr_info("Copy %d\n", pTemp2 - pTemp);
+ memcpy(
+ &ctx->info.assert_info[idx],
+ pTemp,
+ pTemp2 - pTemp);
+ } else {
+ pr_info("copy %d\n", (remain_array_len - 1));
+ memcpy(
+ &ctx->info.assert_info[idx],
+ pTemp,
+ remain_array_len);
+ }
+ }
+ pr_info("assert info:%s\n", ctx->info.assert_info);
+ }
+ } else {
+ /* FW exception */
+ type_str = (char*)exception_sub_string[0];
+ pDtr = strstr(pStr, type_str);
+ if (pDtr == NULL)
+ goto check_task_id;
+
+ if (ctx->info.issue_type != CONNSYS_ISSUE_DRIVER_ASSERT)
+ ctx->info.issue_type = CONNSYS_ISSUE_FW_EXCEPTION;
+ idx = 0;
+ remain_array_len = CONNSYS_ASSERT_INFO_SIZE;
+ sec_len = snprintf(&ctx->info.assert_info[idx], remain_array_len,
+ "%s", "Exception:");
+ remain_array_len -= sec_len;
+ idx += sec_len;
+
+ /* Check ipc */
+ type_str = (char*)exception_sub_string[1];
+ pDtr = strstr(pDtr, type_str);
+ if (pDtr == NULL) {
+ pr_err("Exception substring (%s) not found\n", type_str);
+ goto check_task_id;
+ }
+ pDtr += strlen(type_str);
+ pTemp = strchr(pDtr, ',');
+ if (pTemp != NULL) {
+ len = pTemp - pDtr;
+ len = (len >= CONNSYS_ASSERT_TYPE_SIZE) ? CONNSYS_ASSERT_TYPE_SIZE - 1 : len;
+ memcpy(&tempBuf[0], pDtr, len);
+ tempBuf[len] = '\0';
+ ret = kstrtouint(tempBuf, 16, &res);
+ if (ret) {
+ pr_err("Convert to uint fail, ret=%d, buf=%s\n",
+ ret, tempBuf);
+ } else {
+ ctx->info.exp_ipc = res;
+ pr_info("exp_ipc=0x%x\n", ctx->info.exp_ipc);
+ }
+ if (remain_array_len > 0) {
+ sec_len = snprintf(&ctx->info.assert_info[idx], remain_array_len,
+ " ipc=0x%x", ctx->info.exp_ipc);
+ remain_array_len -= sec_len;
+ idx += sec_len;
+ }
+ }
+
+ /* Check eva */
+ type_str = (char*)exception_sub_string[2];
+ pDtr = strstr(pDtr, type_str);
+ if (pDtr == NULL) {
+ pr_err("substring (%s) not found\n", type_str);
+ goto check_task_id;
+ }
+ pDtr += strlen(type_str);
+ pTemp = strchr(pDtr, ',');
+ if (pTemp != NULL) {
+ len = pTemp - pDtr;
+ len = (len >= CONNSYS_ASSERT_TYPE_SIZE) ? CONNSYS_ASSERT_TYPE_SIZE - 1 : len;
+ memcpy(&tempBuf[0], pDtr, len);
+ tempBuf[len] = '\0';
+ ret = kstrtouint(tempBuf, 16, &res);
+ if (ret) {
+ pr_err("Convert to uint fail, ret=%d, buf=%s\n",
+ ret, tempBuf);
+ } else {
+ ctx->info.exp_eva = res;
+ pr_info("eva addr=0x%x\n", ctx->info.exp_eva);
+ }
+ if (remain_array_len > 0) {
+ sec_len = snprintf(
+ &ctx->info.assert_info[idx], remain_array_len,
+ " eva=0x%x", ctx->info.exp_eva);
+ remain_array_len -= sec_len;
+ idx += sec_len;
+ }
+ }
+
+ /* Check etype */
+ type_str = (char*)exception_sub_string[3];
+ pDtr = strstr(pDtr, type_str);
+ if (pDtr == NULL) {
+ pr_err("Substring(%s) not found\n", type_str);
+ goto check_task_id;
+ }
+ pDtr += strlen(type_str);
+ pTemp = strchr(pDtr, ',');
+ if (pTemp != NULL) {
+ len = pTemp - pDtr;
+ len = (len >= CONNSYS_ASSERT_TYPE_SIZE) ? CONNSYS_ASSERT_TYPE_SIZE - 1 : len;
+ memcpy(ctx->info.etype, pDtr, len);
+ ctx->info.etype[len] = '\0';
+ pr_info("etype=%s\n", ctx->info.etype);
+ if (remain_array_len > 0) {
+ sec_len = snprintf(
+ &ctx->info.assert_info[idx], remain_array_len,
+ " etype=%s", ctx->info.etype);
+ remain_array_len -= sec_len;
+ idx += sec_len;
+ }
+ }
+ }
+
+check_task_id:
+ /* Check id */
+ ctx->info.fw_task_id = 0;
+ type_str = (char*)parser_sub_string[1];
+ pDtr = strstr(pStr, type_str);
+ if (pDtr == NULL) {
+ pr_err("parser str is NULL,substring(%s)\n", type_str);
+
+ } else {
+ pDtr += strlen(type_str);
+ pTemp = strchr(pDtr, ' ');
+
+ if (pTemp == NULL) {
+ pr_err("delimiter( ) is not found,substring(%s)\n",
+ type_str);
+ } else {
+ len = pTemp - pDtr;
+ len = (len >= CONNSYS_ASSERT_TYPE_SIZE) ? CONNSYS_ASSERT_TYPE_SIZE - 1 : len;
+ memcpy(&tempBuf[0], pDtr, len);
+ tempBuf[len] = '\0';
+ ret = kstrtouint(tempBuf, 16, &res);
+ if (ret) {
+ pr_err("Convert to uint fail, ret=%d\n, buf=%s\n",
+ ret, tempBuf);
+ } else {
+ ctx->info.fw_task_id = res;
+ pr_info("fw task id: %x\n", ctx->info.fw_task_id);
+ }
+ }
+ }
+
+ /* Check ISR */
+ ctx->info.fw_isr = 0;
+ type_str = (char*)parser_sub_string[2];
+ pDtr = strstr(pStr, type_str);
+ if (pDtr == NULL) {
+ pr_err("parser str is NULL,substring(%s)\n", type_str);
+ } else {
+ pDtr += strlen(type_str);
+ pTemp = strchr(pDtr, ',');
+
+ if (pTemp == NULL) {
+ pr_err("delimiter(,) is not found,substring(%s)\n", type_str);
+ } else {
+ len = pTemp - pDtr;
+ len = (len >= CONNSYS_ASSERT_TYPE_SIZE) ? CONNSYS_ASSERT_TYPE_SIZE - 1 : len;
+ memcpy(&tempBuf[0], pDtr, len);
+ tempBuf[len] = '\0';
+
+ ret = kstrtouint(tempBuf, 16, &res);
+ if (ret) {
+ pr_err("Get fw isr id fail, ret=%d, buf=%s\n", ret, tempBuf);
+ } else {
+ ctx->info.fw_isr = res;
+ pr_info("fw isr str:%x\n", ctx->info.fw_isr);
+ }
+ }
+ }
+
+ /* Check IRQ */
+ ctx->info.fw_irq = 0;
+ type_str = (char*)parser_sub_string[3];
+ pDtr = strstr(pStr, type_str);
+ if (pDtr == NULL) {
+ pr_err("parser str is NULL,substring(%s)\n", type_str);
+ } else {
+ pDtr += strlen(type_str);
+ pTemp = strchr(pDtr, ',');
+ if (pTemp == NULL) {
+ pr_err("delimiter(,) is not found,substring(%s)\n", type_str);
+ } else {
+ len = pTemp - pDtr;
+ len = (len >= CONNSYS_ASSERT_TYPE_SIZE) ? CONNSYS_ASSERT_TYPE_SIZE - 1 : len;
+ memcpy(&tempBuf[0], pDtr, len);
+ tempBuf[len] = '\0';
+ ret = kstrtouint(tempBuf, 16, &res);
+ if (ret) {
+ pr_err("get fw irq id fail ret=%d, buf=%s\n", ret, tempBuf);
+ } else {
+ ctx->info.fw_irq = res;
+ pr_info("fw irq value:%x\n", ctx->info.fw_irq);
+ }
+ }
+ }
+
+ /* Check assert type */
+ memset(&ctx->info.assert_type[0], '\0', CONNSYS_ASSERT_TYPE_SIZE);
+ type_str = (char*)parser_sub_string[4];
+ pDtr = strstr(pStr, type_str);
+ if (pDtr == NULL) {
+ pr_err("parser str is NULL,substring(%s)\n", type_str);
+ } else {
+ pDtr += strlen(type_str);
+ pTemp = strchr(pDtr, ',');
+
+ if (pTemp == NULL) {
+ pr_err("delimiter(,) is not found,substring(%s)\n", type_str);
+ } else {
+ len = pTemp - pDtr;
+ len = (len >= CONNSYS_ASSERT_TYPE_SIZE) ? CONNSYS_ASSERT_TYPE_SIZE - 1 : len;
+ memcpy(&tempBuf[0], pDtr, len);
+ tempBuf[len] = '\0';
+
+ if (memcmp(tempBuf, "*", strlen("*")) == 0)
+ memcpy(
+ &ctx->info.assert_type[0],
+ "general assert",
+ strlen("general assert"));
+ if (memcmp(tempBuf, WDT_INFO_HEAD, strlen(WDT_INFO_HEAD)) == 0)
+ memcpy(
+ &ctx->info.assert_type[0], "wdt", strlen("wdt"));
+ if (memcmp(tempBuf, "RB_FULL", strlen("RB_FULL")) == 0) {
+ memcpy(&ctx->info.assert_type[0], tempBuf, len);
+ pDtr = strstr(&ctx->info.assert_type[0], "RB_FULL(");
+ if (pDtr == NULL) {
+ pr_err("parser str is NULL,substring(RB_FULL()\n");
+ } else {
+ pDtr += strlen("RB_FULL(");
+ pTemp = strchr(pDtr, ')');
+ len = pTemp - pDtr;
+ len = (len >= CONNSYS_ASSERT_TYPE_SIZE) ? CONNSYS_ASSERT_TYPE_SIZE - 1 : len;
+ memcpy(&tempBuf[0], pDtr, len);
+ tempBuf[len] = '\0';
+ ret = kstrtouint(tempBuf, 16, &res);
+ if (ret) {
+ pr_err("get fw task id fail(%d)\n", ret);
+ } else {
+ snprintf(
+ ctx->info.keyword,
+ CONNSYS_ASSERT_KEYWORD_SIZE,
+ "RB_FULL_%d_%s", res,
+ ctx->hw_config.name);
+ }
+ }
+ }
+ }
+ pr_info("fw asert type:%s\n", ctx->info.assert_type);
+ }
+
+ /* Store first several characters */
+ len = strlen(ctx->page_dump_buf);
+ len = (len >= CONNSYS_DUMP_INFO_SIZE) ? CONNSYS_DUMP_INFO_SIZE - 1 : len;
+ strncpy(ctx->info.dump_info, ctx->page_dump_buf, CONNSYS_DUMP_INFO_SIZE);
+ ctx->info.dump_info[len] = '\0';
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * conndump_dump_print_buff
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+static int conndump_dump_print_buff(struct connsys_dump_ctx* ctx)
+{
+ int ret = 0;
+ unsigned int buff_start, buff_len;
+ int section_len;
+
+ buff_start = CONNSYS_DUMP_PRINT_BUFF_OFFSET;
+ buff_len = conndump_get_dmp_info(ctx, CONNSYS_DUMP_CTRL_BLOCK_OFFSET + EXP_CTRL_PRINT_BUFF_IDX, true);
+
+ if (buff_len > CONNSYS_DUMP_PRINT_BUFF_SIZE) {
+ pr_err("Get print buff idx = %d, but the length is %d\n", buff_len, CONNSYS_DUMP_PRINT_BUFF_SIZE);
+ buff_len = CONNSYS_DUMP_PRINT_BUFF_SIZE;
+ }
+
+ pr_info("-- paged trace ascii output start --\n");
+ while (buff_len > 0) {
+ memset(ctx->page_dump_buf, '\0', CONNSYS_DUMP_BUFF_SIZE);
+ section_len = (buff_len > (CONNSYS_DUMP_BUFF_SIZE - 1)) ? (CONNSYS_DUMP_BUFF_SIZE - 1) : buff_len;
+ memcpy_fromio(ctx->page_dump_buf, ctx->emi_virt_addr_base + buff_start, section_len);
+
+ pr_info("-- paged trace ascii output --\n");
+ conndump_dump_log(ctx->page_dump_buf, section_len);
+
+ buff_len -= section_len;
+ buff_start += section_len;
+ }
+ pr_info("-- paged trace ascii output end --\n");
+ return ret;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * conndump_dump_dump_buff
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+static int conndump_dump_dump_buff(struct connsys_dump_ctx* ctx)
+{
+ int ret = 0;
+ unsigned int buff_start, buff_len;
+ int section_len;
+ bool first = true;
+
+ buff_start = CONNSYS_DUMP_DUMP_BUFF_OFFSET;
+ buff_len = conndump_get_dmp_info(ctx, CONNSYS_DUMP_CTRL_BLOCK_OFFSET + EXP_CTRL_DUMP_BUFF_IDX, true);
+
+ if (buff_len > CONNSYS_DUMP_DUMP_BUFF_SIZE) {
+ pr_err("Get dump buff idx = %d, but the size is %d\n", buff_len, CONNSYS_DUMP_DUMP_BUFF_SIZE);
+ buff_len = CONNSYS_DUMP_DUMP_BUFF_SIZE;
+ }
+
+ if (buff_len == 0) {
+ ret = conndump_send_fake_coredump(ctx);
+ return ret;
+ }
+
+ while (buff_len > 0) {
+ memset(ctx->page_dump_buf, '\0', CONNSYS_DUMP_BUFF_SIZE);
+ section_len = (buff_len > (CONNSYS_DUMP_BUFF_SIZE - 1)) ? (CONNSYS_DUMP_BUFF_SIZE - 1): buff_len;
+ memcpy_fromio(ctx->page_dump_buf, ctx->emi_virt_addr_base + buff_start, section_len);
+
+ /* pack it */
+ ret = conndump_netlink_send_to_native(ctx->conn_type, "[M]", ctx->page_dump_buf, section_len);
+ /* For 1st package, analysis it */
+ if (first) {
+ conndump_info_analysis(ctx, section_len);
+ first = false;
+ }
+
+ buff_len -= section_len;
+ buff_start += section_len;
+ }
+ return ret;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * conndump_setup_dynamic_remap
+ * DESCRIPTION
+ * Setup dynamic remap region
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+static unsigned int conndump_setup_dynamic_remap(struct connsys_dump_ctx* ctx, unsigned int base, unsigned int length)
+{
+
+#define DYNAMIC_MAP_MAX_SIZE 0x300000
+ unsigned int map_len = (length > DYNAMIC_MAP_MAX_SIZE? DYNAMIC_MAP_MAX_SIZE : length);
+ void __iomem* vir_addr = 0;
+
+ if (is_host_view_cr(base, NULL)) {
+ pr_info("Host view CR: 0x%x, skip dynamic remap\n", base);
+ return length;
+ }
+
+ /* Expand to request size */
+ vir_addr = ioremap_nocache(ctx->hw_config.seg1_cr, 4);
+ if (vir_addr) {
+ iowrite32(ctx->hw_config.seg1_phy_addr + map_len, vir_addr);
+ iounmap(vir_addr);
+ } else {
+ return 0;
+ }
+ /* Setup map base */
+ vir_addr = ioremap_nocache(ctx->hw_config.seg1_start_addr, 4);
+ if (vir_addr) {
+ iowrite32(base, vir_addr);
+ iounmap(vir_addr);
+ } else {
+ return 0;
+ }
+ return map_len;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * conndump_remap
+ * DESCRIPTION
+ * Map dynamic remap CR region to virtual address
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+static void __iomem* conndump_remap(struct connsys_dump_ctx* ctx, unsigned int base, unsigned int length)
+{
+ void __iomem* vir_addr = 0;
+ unsigned int host_cr;
+
+ if (is_host_view_cr(base, &host_cr)) {
+ pr_info("Map 0x%x to 0x%x\n", base, host_cr);
+ vir_addr = ioremap_nocache(host_cr, length);
+ } else {
+ vir_addr = ioremap_nocache(ctx->hw_config.seg1_phy_addr, length);
+ }
+ return vir_addr;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * conndump_unmap
+ * DESCRIPTION
+ * Unmap virtual address
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+static void conndump_unmap(struct connsys_dump_ctx* ctx, void __iomem* vir_addr)
+{
+ iounmap(vir_addr);
+}
+
+
+/*****************************************************************************
+ * FUNCTION
+ * conndump_dump_cr_regions
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+static int conndump_dump_cr_regions(struct connsys_dump_ctx* ctx)
+{
+#define CR_PER_LINE 11
+ int ret = 0;
+ int idx;
+ unsigned int map_length;
+ void __iomem *map_base;
+ unsigned int buff_size = CONNSYS_DUMP_BUFF_SIZE;
+ /* format is [addr,valu] */
+ char per_cr[CR_PER_LINE];
+ int i;
+ int addr, value;
+ unsigned int buff_idx = 0;
+
+ if (!conndump_check_cr_readable(ctx)) {
+ pr_err("CR not readable, skip cr dump\n");
+ return -1;
+ }
+
+ for (idx = 0; idx < ctx->dump_regions_num; idx++) {
+ /* empty name means cr regions */
+ if (ctx->dump_regions[idx].name[0] == 0 &&
+ (ctx->dump_regions[idx].base > 0) &&
+ (ctx->dump_regions[idx].base & 0x3) == 0 &&
+ (ctx->dump_regions[idx].length & 0x3) == 0) {
+ pr_info("[%s][Region %d] base=0x%x size=0x%x\n", __func__, idx, ctx->dump_regions[idx].base, ctx->dump_regions[idx].length);
+ map_length = conndump_setup_dynamic_remap(
+ ctx, ctx->dump_regions[idx].base, ctx->dump_regions[idx].length);
+ /* For CR region, we assume region size should < dynamic remap region. */
+ if (map_length != ctx->dump_regions[idx].length) {
+ pr_err("Expect_size=0x%x map_length=0x%x\n", ctx->dump_regions[idx].length, map_length);
+ } else {
+ map_base = conndump_remap(ctx, ctx->dump_regions[idx].base, map_length);
+ if (!map_base) {
+ pr_err("[%s][Region %d] remap fail, break\n", __func__, idx);
+ break;
+ }
+ for (i = 0, addr = ctx->dump_regions[idx].base; i < map_length; i+=4, addr+=4) {
+ value = (*((volatile unsigned int *)(map_base + i)));
+ per_cr[0] = '[';
+ memcpy(&per_cr[1], &addr, 4);
+ per_cr[5] = ',';
+ memcpy(&per_cr[6], &value, 4);
+ per_cr[10] = ']';
+ if (buff_size < CR_PER_LINE) {
+ pr_info("[%s] Dump buffer full (%d-th cr), flush to native space.\n", __func__, i);
+ /* pack it! */
+ conndump_netlink_send_to_native(ctx->conn_type, "[M]", ctx->page_dump_buf, buff_idx);
+
+ /* start from buffer start */
+ buff_size = CONNSYS_DUMP_BUFF_SIZE;
+ buff_idx = 0;
+ memset(ctx->page_dump_buf, 0, CONNSYS_DUMP_BUFF_SIZE);
+ }
+ memcpy(&ctx->page_dump_buf[buff_idx], per_cr, CR_PER_LINE);
+ buff_size -= CR_PER_LINE;
+ buff_idx += CR_PER_LINE;
+ }
+ conndump_unmap(ctx, map_base);
+ }
+ }
+ }
+
+ /* pack remaining item */
+ if (buff_idx) {
+ pr_info("[%s] send remain %d bytes\n", __func__, buff_idx);
+ conndump_netlink_send_to_native(ctx->conn_type, "[M]", ctx->page_dump_buf, buff_idx);
+ }
+
+ return ret;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * conndump_nfra_get_phy_addr(&emi_addr, &emi_size);
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+static int conndump_dump_mem_regions(struct connsys_dump_ctx* ctx)
+{
+#define MEM_REGION_TAG_LENGTH 32
+#define MEM_REGION_MAX_COPY_LENGTH (CONNSYS_DUMP_BUFF_SIZE - MEM_REGION_TAG_LENGTH)
+ int ret = 0;
+ int idx;
+ unsigned int map_length;
+ void __iomem *map_base;
+ unsigned int* dump_buff = NULL;
+ unsigned int copy_idx;
+
+ pr_info("[%s] dump_regions_num=%d\n", __func__, ctx->dump_regions_num);
+ /* Check reg readable */
+ if (!conndump_check_cr_readable(ctx)) {
+ pr_err("CR not readable, skip memory region dump\n");
+ return -1;
+ }
+ for (idx = 0; idx < ctx->dump_regions_num; idx++) {
+ /* Non-empty name means memory regions */
+ if (ctx->dump_regions[idx].name[0] != 0 &&
+ (ctx->dump_regions[idx].length > 0) &&
+ (ctx->dump_regions[idx].length & 0x3) == 0 &&
+ (ctx->dump_regions[idx].base & 0x3) == 0) {
+ pr_info("[%s][Region %d][%s] base=0x%x size=0x%x\n",
+ __func__, idx, ctx->dump_regions[idx].name,
+ ctx->dump_regions[idx].base, ctx->dump_regions[idx].length);
+ /* variable init */
+ ret = 0;
+ dump_buff = (unsigned int*)conndump_malloc(ctx->dump_regions[idx].length);
+ if (!dump_buff) {
+ pr_err("Allocate buffer for %s fail.\n",
+ ctx->dump_regions[idx].name);
+ goto next_mem_region;
+ }
+ /* Change dynamic window */
+ map_length = conndump_setup_dynamic_remap(
+ ctx, ctx->dump_regions[idx].base, ctx->dump_regions[idx].length);
+ if (map_length != ctx->dump_regions[idx].length) {
+ pr_err("Setup dynamic remap for %s fail. Expect 0x%x but 0x%x",
+ ctx->dump_regions[idx].name,
+ ctx->dump_regions[idx].length,
+ map_length);
+ goto next_mem_region;
+ }
+ map_base = conndump_remap(ctx, ctx->dump_regions[idx].base, map_length);
+ if (!map_base) {
+ pr_err("Remap %s fail.\n", ctx->dump_regions[idx].name);
+ goto next_mem_region;
+ }
+ for (copy_idx = 0; copy_idx < map_length; copy_idx += 4) {
+ dump_buff[(copy_idx >> 2)] = (*((volatile unsigned int *)(map_base + copy_idx)));
+ }
+ conndump_unmap(ctx, map_base);
+ ret = conndump_netlink_send_to_native(
+ ctx->conn_type,
+ ctx->dump_regions[idx].name,
+ (char*)dump_buff,
+ ctx->dump_regions[idx].length);
+ if (ret != ctx->dump_regions[idx].length) {
+ pr_err("[%s][%s] Send fail, length = 0x%x but only 0x%x send\n",
+ __func__, ctx->dump_regions[idx].name,
+ ctx->dump_regions[idx].length, ret);
+ }
+ }
+next_mem_region:
+ if (dump_buff) {
+ conndump_free((void*)dump_buff);
+ dump_buff = NULL;
+ }
+ }
+ return ret;
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * conndump_dump_emi
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+static int conndump_dump_emi(struct connsys_dump_ctx* ctx)
+{
+#define EMI_COMMAND_LENGTH 64
+ int ret;
+ unsigned long comp_ret;
+ // format: emi_size=aaaaaaaa, mcif_emi_size=bbbbbbbb
+ char emi_dump_command[EMI_COMMAND_LENGTH];
+
+ snprintf(emi_dump_command, EMI_COMMAND_LENGTH, "emi_size=%d,mcif_emi_size=%d", ctx->full_emi_size, ctx->mcif_emi_size);
+ pr_info("[%s] dump command: %s\n", __func__, emi_dump_command);
+ conndump_set_dump_state(ctx, CORE_DUMP_EMI);
+ ret = conndump_netlink_send_to_native(ctx->conn_type, "[EMI]", emi_dump_command, strlen(emi_dump_command));
+
+ if (ret < 0) {
+ pr_err("Start EMI dump fail, ret = %d\n", ret);
+ return -1;
+ }
+
+ comp_ret = wait_for_completion_timeout(
+ &ctx->emi_dump,
+ msecs_to_jiffies(CONNSYS_EMIDUMP_TIMEOUT));
+
+ if (comp_ret == 0) {
+ pr_err("EMI dump timeout\n");
+ conndump_set_dump_state(ctx, CORE_DUMP_EMI_TIMEOUT);
+ } else {
+ pr_info("EMI dump end");
+ conndump_set_dump_state(ctx, CORE_DUMP_DONE);
+ }
+
+ return 0;
+}
+
+static int connsys_coredump_init_dump_regions(struct connsys_dump_ctx* ctx, int num)
+{
+ int size = sizeof(struct dump_region)*num;
+
+ ctx->dump_regions = (struct dump_region*)conndump_malloc(size);
+ if (!ctx->dump_regions) {
+ ctx->dump_regions_num = 0;
+ pr_err("ctx->dump_regions create fail!\n");
+ return 0;
+ }
+ memset(ctx->dump_regions, 0, size);
+ ctx->dump_regions_num = num;
+ return num;
+}
+
+static void connsys_coredump_deinit_dump_regions(struct connsys_dump_ctx* ctx)
+{
+ conndump_free(ctx->dump_regions);
+ ctx->dump_regions = 0;
+ ctx->dump_regions_num = 0;
+}
+
+static void conndump_coredump_end(void* handler)
+{
+ struct connsys_dump_ctx* ctx = (struct connsys_dump_ctx*)handler;
+
+ if (conndump_get_dump_state(ctx) == CORE_DUMP_EMI) {
+ pr_info("Wake up emi_dump\n");
+ complete(&ctx->emi_dump);
+ }
+}
+
+static int conndump_send_fake_coredump(struct connsys_dump_ctx* ctx)
+{
+ pr_info("Send fake coredump\n");
+ return conndump_netlink_send_to_native(ctx->conn_type, "[M]", "FORCE_COREDUMP", 13);
+}
+
+static void conndump_exception_show(struct connsys_dump_ctx* ctx, bool full_dump)
+{
+ if (full_dump) {
+ snprintf(
+ ctx->info.exception_log, CONNSYS_AEE_INFO_SIZE,
+ "%s %s %s %s",
+ INFO_HEAD, ctx->hw_config.name,
+ ctx->info.assert_type, ctx->info.dump_info);
+ } else {
+ snprintf(
+ ctx->info.exception_log, CONNSYS_AEE_INFO_SIZE,
+ "%s %s",
+ INFO_HEAD, ctx->hw_config.name);
+ }
+
+#if defined(CONNINFRA_PLAT_ALPS) && CONNINFRA_PLAT_ALPS
+ pr_info("par1: [%s] pars: [%s] par3: [%d]\n",
+ ctx->hw_config.exception_tag_name,
+ ctx->info.exception_log,
+ strlen(ctx->info.exception_log));
+ /* Call AEE API */
+ aed_common_exception_api(
+ ctx->hw_config.exception_tag_name,
+ NULL, 0,
+ (const int*)ctx->info.exception_log, strlen(ctx->info.exception_log),
+ ctx->info.exception_log, 0);
+#endif
+}
+
+/*****************************************************************************
+ * FUNCTION
+ * connsys_coredump_clean
+ * DESCRIPTION
+ * To clean coredump EMI region
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+void connsys_coredump_clean(void* handler)
+{
+ struct connsys_dump_ctx* ctx = (struct connsys_dump_ctx*)handler;
+
+ if (ctx == NULL)
+ return;
+
+ pr_info("[%s] Clear %p size=%d as zero\n", __func__, ctx->emi_virt_addr_base, ctx->emi_size);
+ memset_io(ctx->emi_virt_addr_base, 0, ctx->emi_size);
+
+ conndump_set_dump_state(ctx, CORE_DUMP_INIT);
+}
+EXPORT_SYMBOL(connsys_coredump_clean);
+
+
+/*****************************************************************************
+ * FUNCTION
+ * connsys_coredump_setup_dump_region
+ * DESCRIPTION
+ * Parse dump region in EMI (including CR regions, IDLM, SYSRAM, ...)
+ * The number would be record in ctx->dump_regions_num
+ * The data would be stored in ctx->dump_regions
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+int connsys_coredump_setup_dump_region(void* handler)
+{
+ int ret = 0;
+ int cr_regions_idx = 0;
+ int total_mem_region;
+ int total_count;
+ int i, idx = 0, offset;
+ struct connsys_dump_ctx* ctx = (struct connsys_dump_ctx*)handler;
+ struct dump_region* curr_region = 0;
+
+ total_mem_region = conndump_get_dmp_info(
+ ctx, CONNSYS_DUMP_CTRL_BLOCK_OFFSET + EXP_CTRL_TOTAL_MEM_REGION, false);
+
+ /* Get idx first. The number is idx/8 */
+ cr_regions_idx = conndump_get_dmp_info(
+ ctx, CONNSYS_DUMP_CTRL_BLOCK_OFFSET + EXP_CTRL_CR_REGION_IDX, false);
+ if (cr_regions_idx & 0x7) {
+ pr_err("cr_regions_idx should be multiple of 8. But it is %d.\n", cr_regions_idx);
+ }
+ cr_regions_idx = (cr_regions_idx >> 3);
+ total_count = total_mem_region + cr_regions_idx;
+ pr_info("CR region=%d. Memory region=%d total dump regions is %d.\n",
+ cr_regions_idx, total_mem_region, total_count);
+
+ if (ctx->dump_regions) {
+ connsys_coredump_deinit_dump_regions(ctx);
+ }
+ if (total_count == 0) {
+ pr_info("Total dump regions is %d.\n", total_count);
+ return 0;
+ }
+
+ ret = connsys_coredump_init_dump_regions(ctx, total_count);
+ if (ret != total_count) {
+ pr_err("[%s] allocate %d dump regions failed\n", __func__, total_count);
+ return 0;
+ }
+
+ /* Setup memory region */
+ offset = CONNSYS_DUMP_CTRL_BLOCK_OFFSET + EXP_CTRL_MEM_REGION_NAME_1;
+ for (i = 0, curr_region = ctx->dump_regions; i < total_mem_region && idx < total_count; i++, idx++, offset += 12, curr_region++) {
+ conndump_get_dmp_char(ctx, offset, 4, curr_region->name);
+ curr_region->base = conndump_get_dmp_info(ctx, offset + 4, false);
+ curr_region->length = conndump_get_dmp_info(ctx, offset + 8, false);
+ pr_info("[%d][Memory region] name: %s, base: %x, length: %x\n",
+ idx,
+ curr_region->name,
+ curr_region->base,
+ curr_region->length);
+ }
+
+ offset = CONNSYS_DUMP_CR_REGION_OFFSET;
+ for (i = 0; i < cr_regions_idx && idx < total_count; i++, idx++, offset+=8) {
+ ctx->dump_regions[idx].base = conndump_get_dmp_info(ctx, offset, false);
+ ctx->dump_regions[idx].length = conndump_get_dmp_info(ctx, offset + 4, false);
+ pr_info("[%d][CR region] base: 0x%x, length: %d\n",
+ idx, ctx->dump_regions[idx].base, ctx->dump_regions[idx].length);
+ }
+ return ctx->dump_regions_num;
+}
+EXPORT_SYMBOL(connsys_coredump_setup_dump_region);
+
+/*****************************************************************************
+ * FUNCTION
+ * connsys_coredump_start
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+int connsys_coredump_start(
+ void* handler,
+ unsigned int dump_property,
+ int drv,
+ char* reason)
+{
+ struct connsys_dump_ctx* ctx = (struct connsys_dump_ctx*)handler;
+ int ret = 0;
+ bool full_dump = false;
+ struct timeval begin, end, put_done;
+ struct timeval mem_start, mem_end, cr_start, cr_end, emi_dump_start, emi_dump_end;
+
+ static DEFINE_RATELIMIT_STATE(_rs, HZ, 1);
+
+ if (ctx == NULL)
+ return 0;
+
+ /* TODO: Check coredump mode */
+ if (connsys_coredump_get_mode() == DUMP_MODE_RESET_ONLY) {
+ pr_info("Chip reset only, skip coredump\n");
+ return 0;
+ }
+
+ pr_info("[COREDUMP] dump_property=[0x%x] drv=[%d] reason=[%s]\n", dump_property, drv, reason);
+ do_gettimeofday(&begin);
+ conndump_set_dump_state(ctx, CORE_DUMP_START);
+ /* Reset assert info */
+ memset(&ctx->info, 0, sizeof(struct connsys_dump_info));
+ if (drv >= CONNDRV_TYPE_BT && drv < CONNDRV_TYPE_MAX) {
+ ctx->info.issue_type = CONNSYS_ISSUE_DRIVER_ASSERT;
+ ctx->info.drv_type = drv;
+ snprintf(ctx->info.reason, CONNSYS_ASSERT_REASON_SIZE, "%s", reason);
+ }
+
+ /* Start coredump timer */
+ mod_timer(&ctx->dmp_timer, jiffies + (CONNSYS_COREDUMP_TIMEOUT) / (1000 / HZ));
+
+ /* Check coredump status */
+ while (1) {
+ if (conndump_get_dmp_info(ctx, CONNSYS_DUMP_CTRL_BLOCK_OFFSET + EXP_CTRL_DUMP_STATE, false) == FW_DUMP_STATE_PUT_DONE) {
+ pr_info("coredump put done\n");
+ del_timer(&ctx->dmp_timer);
+ full_dump = true;
+ break;
+ } else if (conndump_get_dump_state(ctx) == CORE_DUMP_TIMEOUT) {
+ pr_err("Coredump timeout\n");
+ if (ctx->callback.poll_cpupcr) {
+ pr_info("Debug dump:\n");
+ ctx->callback.poll_cpupcr(5, 1);
+ }
+ conndump_send_fake_coredump(ctx);
+ goto partial_dump;
+ }
+ if (__ratelimit(&_rs)) {
+ pr_info("Wait coredump state, EMI[0]=0x%x EMI[4]=0x%x\n",
+ conndump_get_dmp_info(ctx, 0, false),
+ conndump_get_dmp_info(ctx, 4, false));
+ }
+ if (dump_property & CONNSYS_DUMP_PROPERTY_NO_WAIT) {
+ pr_info("Don't wait dump status, go to partial dump\n");
+ if (ctx->callback.poll_cpupcr) {
+ pr_info("Debug dump:\n");
+ ctx->callback.poll_cpupcr(5, 1);
+ }
+ conndump_send_fake_coredump(ctx);
+ goto partial_dump;
+ }
+ msleep(1);
+ }
+ do_gettimeofday(&put_done);
+ conndump_set_dump_state(ctx, CORE_DUMP_DOING);
+
+ /* Get print_buff */
+ conndump_dump_print_buff(ctx);
+
+ /* Get dump_buff and send to pack it */
+ conndump_dump_dump_buff(ctx);
+
+partial_dump:
+ /* TODO: move to init or other suitable place */
+ ret = connsys_coredump_setup_dump_region(ctx);
+ if (!ret)
+ pr_err("No dump region found\n");
+
+ conndump_set_dump_state(ctx, CORE_DUMP_DOING);
+ /* Memory region and CR region should be setup when MCU init */
+ /* Parse CR region and send to pack it */
+ do_gettimeofday(&cr_start);
+ conndump_dump_cr_regions(ctx);
+ do_gettimeofday(&cr_end);
+
+ /* Construct assert info and send to native */
+ conndump_info_format(ctx, ctx->page_dump_buf, CONNSYS_DUMP_BUFF_SIZE, full_dump);
+
+ /* Read memory region on ctrl block */
+ do_gettimeofday(&mem_start);
+ conndump_dump_mem_regions(ctx);
+ do_gettimeofday(&mem_end);
+
+
+ /* Start EMI dump */
+ do_gettimeofday(&emi_dump_start);
+ conndump_dump_emi(ctx);
+ do_gettimeofday(&emi_dump_end);
+
+ /* All process finished, set to init status */
+ conndump_set_dump_state(ctx, CORE_DUMP_INIT);
+
+ conndump_exception_show(ctx, full_dump);
+ do_gettimeofday(&end);
+ pr_info("Coredump end\n");
+ if (full_dump) {
+ pr_info("%s coredump summary: full dump total=[%lu] put_done=[%lu] cr=[%lu] mem=[%lu] emi=[%lu]\n",
+ g_type_name[ctx->conn_type],
+ timeval_to_ms(&begin, &end),
+ timeval_to_ms(&begin, &put_done),
+ timeval_to_ms(&cr_start, &cr_end),
+ timeval_to_ms(&mem_start, &mem_end),
+ timeval_to_ms(&emi_dump_start, &emi_dump_end));
+ } else {
+ pr_info("%s coredump summary: partial dump total=[%lu] cr=[%lu] mem=[%lu] emi=[%lu]\n",
+ g_type_name[ctx->conn_type],
+ timeval_to_ms(&begin, &end),
+ timeval_to_ms(&cr_start, &cr_end),
+ timeval_to_ms(&mem_start, &mem_end),
+ timeval_to_ms(&emi_dump_start, &emi_dump_end));
+ }
+ return 0;
+}
+EXPORT_SYMBOL(connsys_coredump_start);
+
+/*****************************************************************************
+ * FUNCTION
+ * connsys_coredump_get_start_offset
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+phys_addr_t connsys_coredump_get_start_offset(int conn_type)
+{
+ struct coredump_hw_config *config = get_coredump_platform_config(conn_type);
+
+ if (config)
+ return config->start_offset;
+ return 0;
+}
+EXPORT_SYMBOL(connsys_coredump_get_start_offset);
+
+/*****************************************************************************
+ * FUNCTION
+ * connsys_coredump_init
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+void* connsys_coredump_init(
+ int conn_type,
+ struct coredump_event_cb* cb)
+{
+ struct connsys_dump_ctx* ctx = 0;
+ struct netlink_event_cb nl_cb;
+ struct coredump_hw_config *config = get_coredump_platform_config(conn_type);
+ phys_addr_t emi_base;
+ unsigned int emi_size, mcif_emi_size;
+
+ /* Get EMI config */
+ if (config == NULL) {
+ pr_err("Get coredump EMI config fail\n");
+ goto error_exit;
+ }
+
+ ctx = (struct connsys_dump_ctx*)conndump_malloc(sizeof(struct connsys_dump_ctx));
+ if (!ctx) {
+ pr_err("Allocate connsys_dump_ctx fail");
+ goto error_exit;
+ }
+
+ /* clean it */
+ memset(ctx, 0, sizeof(struct connsys_dump_ctx));
+ memcpy(&ctx->hw_config, config, sizeof(struct coredump_hw_config));
+
+ ctx->page_dump_buf = (char*)conndump_malloc(CONNSYS_DUMP_BUFF_SIZE);
+ if (!ctx->page_dump_buf) {
+ pr_err("Create dump buffer fail.\n");
+ goto error_exit;
+ }
+
+ ctx->conn_type = conn_type;
+ if (cb)
+ memcpy(&ctx->callback, cb, sizeof(struct coredump_event_cb));
+ else
+ pr_info("[%s][%d] callback is null\n", __func__, conn_type);
+
+ /* EMI init */
+ conninfra_get_emi_phy_addr(CONNSYS_EMI_FW, &emi_base, &emi_size);
+ conninfra_get_emi_phy_addr(CONNSYS_EMI_MCIF, NULL, &mcif_emi_size);
+ pr_info("Get emi_base=0x%x emi_size=%d\n", emi_base, emi_size);
+ ctx->full_emi_size = emi_size;
+ ctx->emi_phy_addr_base = config->start_offset + emi_base;
+ ctx->emi_size = config->size;
+ ctx->mcif_emi_size = mcif_emi_size;
+
+ ctx->emi_virt_addr_base =
+ ioremap_nocache(ctx->emi_phy_addr_base, ctx->emi_size);
+ if (ctx->emi_virt_addr_base == 0) {
+ pr_err("Remap emi fail (0x%08x) size=%d",
+ ctx->emi_phy_addr_base, ctx->emi_size);
+ goto error_exit;
+ }
+
+ pr_info("Clear %p size=%d as zero\n", ctx->emi_virt_addr_base, ctx->emi_size);
+ memset_io(ctx->emi_virt_addr_base, 0, ctx->emi_size);
+
+ /* Setup timer */
+ init_timer(&ctx->dmp_timer);
+ ctx->dmp_timer.function = conndump_timeout_handler;
+ ctx->dmp_timer.data = (unsigned long)ctx;
+ init_completion(&ctx->emi_dump);
+
+ conndump_set_dump_state(ctx, CORE_DUMP_INIT);
+
+ /* Init netlink */
+ nl_cb.coredump_end = conndump_coredump_end;
+ conndump_netlink_init(ctx->conn_type, ctx, &nl_cb);
+ return ctx;
+
+error_exit:
+ if (ctx)
+ connsys_coredump_deinit(ctx);
+
+ return 0;
+}
+EXPORT_SYMBOL(connsys_coredump_init);
+
+/*****************************************************************************
+ * FUNCTION
+ * connsys_coredump_deinit
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+void connsys_coredump_deinit(void* handler)
+{
+ struct connsys_dump_ctx* ctx = (struct connsys_dump_ctx*)handler;
+
+ if (handler == NULL)
+ return;
+
+ if (ctx->emi_virt_addr_base) {
+ iounmap(ctx->emi_virt_addr_base);
+ ctx->emi_virt_addr_base = NULL;
+ }
+
+ if (ctx->page_dump_buf) {
+ conndump_free(ctx->page_dump_buf);
+ ctx->page_dump_buf = NULL;
+ }
+
+ if (ctx->dump_regions) {
+ connsys_coredump_deinit_dump_regions(ctx);
+ ctx->dump_regions = NULL;
+ }
+
+ conndump_free(ctx);
+}
+EXPORT_SYMBOL(connsys_coredump_deinit);
+
+
+/*****************************************************************************
+ * FUNCTION
+ * connsys_coredump_get_mode
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+enum connsys_coredump_mode connsys_coredump_get_mode(void)
+{
+ return atomic_read(&g_dump_mode);
+}
+EXPORT_SYMBOL(connsys_coredump_get_mode);
+
+/*****************************************************************************
+ * FUNCTION
+ * connsys_coredump_set_dump_mode
+ * DESCRIPTION
+ *
+ * PARAMETERS
+ *
+ * RETURNS
+ *
+ *****************************************************************************/
+void connsys_coredump_set_dump_mode(enum connsys_coredump_mode mode)
+{
+ if (mode < DUMP_MODE_MAX)
+ atomic_set(&g_dump_mode, mode);
+}
+EXPORT_SYMBOL(connsys_coredump_set_dump_mode);
+
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/connsys_coredump.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/connsys_coredump.h
new file mode 100755
index 0000000..609f60b
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/connsys_coredump.h
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+#ifndef _CONNSYS_COREDUMP_H_
+#define _CONNSYS_COREDUMP_H_
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+/* Coredump property */
+#define CONNSYS_DUMP_PROPERTY_NO_WAIT 0x1
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+enum connsys_coredump_mode {
+ DUMP_MODE_RESET_ONLY = 0,
+ DUMP_MODE_AEE = 1,
+ DUMP_MODE_DAEMON = 2,
+ DUMP_MODE_MAX,
+};
+
+struct coredump_event_cb {
+ int (*reg_readable)(void);
+ void (*poll_cpupcr)(unsigned int times, unsigned int sleep);
+};
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/* subsys usage */
+void* connsys_coredump_init(
+ int conn_type,
+ struct coredump_event_cb* cb);
+void connsys_coredump_deinit(void* handler);
+
+phys_addr_t connsys_coredump_get_start_offset(int conn_type);
+
+int connsys_coredump_setup_dump_region(void* handler);
+int connsys_coredump_start(
+ void* handler,
+ unsigned int dump_property,
+ int drv,
+ char *reason);
+void connsys_coredump_clean(void* handler);
+
+
+/* config relative */
+enum connsys_coredump_mode connsys_coredump_get_mode(void);
+void connsys_coredump_set_dump_mode(enum connsys_coredump_mode mode);
+
+#endif
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/connsys_coredump_emi.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/connsys_coredump_emi.h
new file mode 100755
index 0000000..b521404
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/connsys_coredump_emi.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#ifndef _CONNSYS_COREDUMP_EMI_H_
+#define _CONNSYS_COREDUMP_EMI_H_
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+
+/* Block and size definition */
+#define CONNSYS_DUMP_CTRL_BLOCK_SIZE 0x80
+#define CONNSYS_DUMP_DEBUG_BLOCK_SIZE 0x80
+#define CONNSYS_DUMP_PRINT_BUFF_SIZE 0x7f00
+#define CONNSYS_DUMP_DUMP_BUFF_SIZE 0x8000
+#define CONNSYS_DUMP_CR_REGION_SIZE 0x8000
+
+#define CONNSYS_DUMP_CTRL_BLOCK_OFFSET 0x0
+#define CONNSYS_DUMP_DEBUG_BLOCK_OFFSET (CONNSYS_DUMP_CTRL_BLOCK_OFFSET + CONNSYS_DUMP_CTRL_BLOCK_SIZE)
+#define CONNSYS_DUMP_PRINT_BUFF_OFFSET (CONNSYS_DUMP_DEBUG_BLOCK_OFFSET + CONNSYS_DUMP_DEBUG_BLOCK_SIZE)
+#define CONNSYS_DUMP_DUMP_BUFF_OFFSET (CONNSYS_DUMP_PRINT_BUFF_OFFSET + CONNSYS_DUMP_PRINT_BUFF_SIZE)
+#define CONNSYS_DUMP_CR_REGION_OFFSET (CONNSYS_DUMP_DUMP_BUFF_OFFSET + CONNSYS_DUMP_DUMP_BUFF_SIZE)
+
+/* Control block definition */
+enum connsys_dump_ctrl_block_offset {
+ EXP_CTRL_DUMP_STATE = 0x4,
+ EXP_CTRL_OUTBAND_ASSERT_W1 = 0x8,
+ EXP_CTRL_PRINT_BUFF_IDX = 0xC,
+ EXP_CTRL_DUMP_BUFF_IDX = 0x10,
+ EXP_CTRL_CR_REGION_IDX = 0x14,
+ EXP_CTRL_TOTAL_MEM_REGION = 0x18,
+ EXP_CTRL_MEM_REGION_NAME_1 = 0x1C,
+ EXP_CTRL_MEM_REGION_START_1 = 0x20,
+ EXP_CTRL_MEM_REGION_LEN_1 = 0x24,
+ EXP_CTRL_MEM_REGION_NAME_2 = 0x28,
+ EXP_CTRL_MEM_REGION_START_2 = 0x2c,
+ EXP_CTRL_MEM_REGION_LEN_2 = 0x30,
+ EXP_CTRL_MEM_REGION_NAME_3 = 0x34,
+ EXP_CTRL_MEM_REGION_START_3 = 0x38,
+ EXP_CTRL_MEM_REGION_LEN_3 = 0x3c,
+ EXP_CTRL_MEM_REGION_NAME_4 = 0x40,
+ EXP_CTRL_MEM_REGION_START_4 = 0x44,
+ EXP_CTRL_MEM_REGION_LEN_4 = 0x48,
+ EXP_CTRL_MEM_REGION_NAME_5 = 0x4C,
+ EXP_CTRL_MEM_REGION_START_5 = 0x50,
+ EXP_CTRL_MEM_REGION_LEN_5 = 0x54,
+};
+
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+#endif /*_CONNSYS_COREDUMP_EMI_H_*/
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/platform/include/connsys_coredump_hw_config.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/platform/include/connsys_coredump_hw_config.h
new file mode 100755
index 0000000..d150804
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/platform/include/connsys_coredump_hw_config.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#ifndef _CONNSYS_COREDUMP_HW_CONFIG_H_
+#define _CONNSYS_COREDUMP_HW_CONFIG_H_
+
+
+struct coredump_hw_config {
+ char* name;
+ phys_addr_t start_offset;
+ unsigned int size;
+ unsigned int seg1_cr;
+ unsigned int seg1_value_end;
+ unsigned int seg1_start_addr;
+ unsigned int seg1_phy_addr;
+ unsigned int task_table_size;
+ char** task_map_table;
+ char* exception_tag_name;
+};
+
+#endif
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/platform/mt6885/mt6885.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/platform/mt6885/mt6885.c
new file mode 100755
index 0000000..3ebcf97
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/coredump/platform/mt6885/mt6885.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#include <linux/printk.h>
+
+#include "connsys_debug_utility.h"
+#include "connsys_coredump_hw_config.h"
+
+static char* wifi_task_str[] = {
+ "Task_WIFI",
+ "Task_TST_WFSYS",
+ "Task_Idle_WFSYS",
+};
+
+static char* bt_task_str[] = {
+ "Task_WMT",
+ "Task_BT",
+ "Task_TST_BTSYS",
+ "Task_BT2",
+ "Task_Idle_BTSYS",
+};
+
+struct coredump_hw_config g_coredump_config[CONN_DEBUG_TYPE_END] = {
+ /* Wi-Fi config */
+ {
+ .name = "WFSYS",
+#ifdef CONFIG_FPGA_EARLY_PORTING
+ .start_offset = 0x0004f000,
+#else
+ .start_offset = 0x027f000,
+#endif
+ .size = 0x18000,
+ .seg1_cr = 0x1800112c,
+ .seg1_value_end = 0x187fffff,
+ .seg1_start_addr = 0x18001120,
+ .seg1_phy_addr = 0x18500000,
+ .task_table_size = sizeof(wifi_task_str)/sizeof(char*),
+ .task_map_table = wifi_task_str,
+ .exception_tag_name = "combo_wifi",
+ },
+ /* BT config */
+ {
+ .name = "BTSYS",
+ .start_offset = 0x33000,
+ .size = 0x18000,
+ .seg1_cr = 0x18001110,
+ .seg1_value_end = 0x18bfffff,
+ .seg1_start_addr = 0x18001104,
+ .seg1_phy_addr = 0x18900000,
+ .task_table_size = sizeof(bt_task_str)/sizeof(char*),
+ .task_map_table = bt_task_str,
+ .exception_tag_name = "combo_bt",
+ },
+};
+
+struct coredump_hw_config* get_coredump_platform_config(int conn_type)
+{
+ if (conn_type < 0 || conn_type >= CONN_DEBUG_TYPE_END) {
+ pr_err("Incorrect type: %d\n", conn_type);
+ return NULL;
+ }
+ return &g_coredump_config[conn_type];
+}
+
+unsigned int get_coredump_platform_chipid(void)
+{
+ return 0x6885;
+}
+
+char* get_task_string(int conn_type, unsigned int task_id)
+{
+ if (conn_type < 0 || conn_type >= CONN_DEBUG_TYPE_END) {
+ pr_err("Incorrect type: %d\n", conn_type);
+ return NULL;
+ }
+
+ if (task_id > g_coredump_config[conn_type].task_table_size) {
+ pr_err("[%s] Incorrect task: %d\n",
+ g_coredump_config[conn_type].name, task_id);
+ return NULL;
+ }
+
+ return g_coredump_config[conn_type].task_map_table[task_id];
+}
+
+char* get_sys_name(int conn_type)
+{
+ if (conn_type < 0 || conn_type >= CONN_DEBUG_TYPE_END) {
+ pr_err("Incorrect type: %d\n", conn_type);
+ return NULL;
+ }
+ return g_coredump_config[conn_type].name;
+}
+
+bool is_host_view_cr(unsigned int addr, unsigned int* host_view)
+{
+ if (addr >= 0x7C000000 && addr <= 0x7Cffffff) {
+ if (host_view) {
+ *host_view = ((addr - 0x7c000000) + 0x18000000);
+ }
+ return true;
+ } else if (addr >= 0x18000000 && addr <= 0x18ffffff) {
+ if (host_view) {
+ *host_view = addr;
+ }
+ return true;
+ }
+ return false;
+}
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/include/connsys_debug_utility.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/include/connsys_debug_utility.h
new file mode 100644
index 0000000..897bda5
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/include/connsys_debug_utility.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+#ifndef _CONNSYS_DEBUG_UTILITY_H_
+#define _CONNSYS_DEBUG_UTILITY_H_
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+#include "coredump/connsys_coredump.h"
+#include "connsyslog/connsyslog.h"
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+enum CONN_DEBUG_TYPE {
+ CONN_DEBUG_TYPE_WIFI = 0,
+ CONN_DEBUG_TYPE_BT = 1,
+ CONN_DEBUG_TYPE_END,
+};
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+#endif /*_CONNSYS_DEBUG_UTILITY_H_*/
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/CONNINFRA_STEP.cfg b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/CONNINFRA_STEP.cfg
new file mode 100755
index 0000000..ab2beca
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/CONNINFRA_STEP.cfg
@@ -0,0 +1,112 @@
+// Action | symbol | Param1 | Param2 | Param3 | Param4 | Param5
+// Read EMI | _EMI | R(0) | Begin offset | End offset
+// Read EMI to temp register | _EMI | R(0) | offset | Temp Reg ID($)
+// Read EMI to temp register | _EMI | R(0) | offset | mask | Temp Reg ID ($)
+// Read CR | _REG | R(0) | Pre-define base-addr ID | offset | times | delay time(ms)
+// Read CR | _REG | R(0) | AP Physical address | offset | times | delay time(ms)
+// Read CR to temp register | _REG | R(0) | Pre-define base-addr ID | offset | Temp Reg ID($)
+// Read CR to temp register | _REG | R(0) | AP Physical address | offset | Temp Reg ID($)
+// Read CR to temp register | _REG | R(0) | Pre-define base-addr ID | offset | mask | Temp Reg ID($)
+// Read CR to temp register | _REG | R(0) | AP Physical address | offset | mask | Temp Reg ID($)
+// Write CR | _REG | W(1) | Pre-define base-addr ID | offset | value
+// Write CR | _REG | W(1) | AP Physical address | offset | value
+// Write CR some bit | _REG | W(1) | Pre-define base-addr ID | offset | value | mask
+// Write CR some bit | _REG | W(1) | AP Physical address | offset | value | mask
+// Read GPIO | GPIO | R(0) | Pin number
+
+// Show message | SHOW | String(No space)
+
+// Check condition to result temp register | COND | Result Temp Reg ID($) | Left Temp Reg ID($) | Operator | Right Temp Reg ID($)
+// Check condition to result temp register | COND | Result Temp Reg ID($) | Left Temp Reg ID($) | Operator | Value(Dec or Hex)
+// Save value to temp register | _VAL | Temp Reg ID($) | Value
+//
+// Condition Action | symbol | Param1 | Param2 | Param3 | Param4 | Param5 | Param6
+// Read EMI with Condition | CEMI | Condition Temp Reg ID($) | R(0) | Begin offset | End offset
+// Read EMI to temp register with Condition | CEMI | Condition Temp Reg ID($) | R(0) | Begin offset | Temp Reg ID($)
+// Read EMI to temp register with Condition | CEMI | Condition Temp Reg ID($) | R(0) | Begin offset | mask | Temp Reg ID($)
+// Read CR with Condition | CREG | Condition Temp Reg ID($) | R(0) | Pre-define base-addr ID | offset | times | delay time(ms)
+// Read CR with Condition | CREG | Condition Temp Reg ID($) | R(0) | AP Physical address | offset | times | delay time(ms)
+// Read CR to temp register with Condition | CREG | Condition Temp Reg ID($) | R(0) | Pre-define base-addr ID | offset | Temp Reg ID($)
+// Read CR to temp register with Condition | CREG | Condition Temp Reg ID($) | R(0) | AP Physical address | offset | Temp Reg ID($)
+// Read CR to temp register with Condition | CREG | Condition Temp Reg ID($) | R(0) | Pre-define base-addr ID | offset | mask | Temp Reg ID($)
+// Read CR to temp register with Condition | CREG | Condition Temp Reg ID($) | R(0) | AP Physical address | offset | mask | Temp Reg ID($)
+// Write CR with Condition | CREG | Condition Temp Reg ID($) | W(1) | Pre-define base-addr ID | offset | value
+// Write CR with Condition | CREG | Condition Temp Reg ID($) | W(1) | AP Physical address | offset | value
+// Write CR some bit with Condition | CREG | Condition Temp Reg ID($) | W(1) | Pre-define base-addr ID | offset | value | mask
+// Write CR some bit with Condition | CREG | Condition Temp Reg ID($) | W(1) | AP Physical address | offset | value | mask
+//
+// Periodic dump: Add PD in trigger point
+// [TP x] Trigger point
+// [PD+] ms
+// [AT] xxxx
+// [AT] xxxx
+// [PD-]
+//
+// Temp Reg ID: ($0 ~ $9)
+//
+// Operator: ==, !=, >, >=, <, <=, &&, ||
+//
+// Pre-define base-addr ID: (You can find address and size in DTS file)
+// alps/kernel-4.9/arch/arm64/boot/dts/mediatek/mt6885.dts
+// base / size
+// #1 ==> conn_infra_rgu 0x18000000 / 0x1000
+// #2 ==> conn_infra_cfg 0x18001000 / 0x1000
+// #3 ==> conn_host_csr_top 0x18060000 / 0x10000
+// #4 ==> infracfg_ao 0x10001000 / 0x1000
+// #5 ==> TOP RGU 0x10007000 / 0x1000
+// #6 ==> SPM 0x10006000 / 0x1000
+// #7 ==> INFRACFG 0x1020e000 / 0x1000
+// #8 ==> conn_wt_slp_ctl_reg 0x18005000 / 0x1000
+// #9 ==> conn_afe_ctl 0x18003000 / 0x1000
+// #10 ==> conn_infra_sysram 0x18050000 / 0x10000
+// #11 ==> GPIO 0x10005000 / 0x1000
+// #12 ==> conn_rf_spi_mst_reg 0x18004000 / 0x1000
+// #13 ==> conn_semaphore 0x18070000 / 0x10000
+// #14 ==> conn_top_therm_ctl 0x18002000 / 0x1000
+// #15 ==> IOCFG_RT 0x11ea0000 / 0x1000
+
+// ********************** CONNINFRA ************************* //
+[TP CONNINFRA 1] Before Chip reset
+ [AT] _REG 0 #2 0x000 1 0
+
+[TP CONNINFRA 2] After Chip reset
+
+[TP CONNINFRA 3] Before read consys thermal
+ [AT] _REG 0 #2 0x000 1 0
+
+[TP CONNINFRA 4] Power on sequence(0): Start power on
+
+[TP CONNINFRA 5] Power on sequence(1): Before can get connsys id
+
+[TP CONNINFRA 6] Power on sequence(6): End power on
+
+[TP CONNINFRA 7] Before CONNINFRA power off
+
+[TP CONNINFRA 8] When AP suspend
+
+[TP CONNINFRA 9] When AP resume
+ [AT] _REG 0 #2 0x000 1 0
+
+
+// ********************** WF ************************* //
+[TP WF 1] Command timeout
+[TP WF 2] Before Chip reset
+[TP WF 3] After Chip reset
+
+
+// ********************** BT ************************* //
+[TP BT 1] Command timeout
+[TP BT 2] Before Chip reset
+[TP BT 3] After Chip reset
+
+
+// ********************** GPS ************************ //
+[TP GPS 1] Command timeout
+[TP GPS 2] Before Chip reset
+[TP GPS 3] After Chip reset
+
+
+// ********************** FM ************************* //
+[TP FM 1] Command timeout
+[TP FM 2] Before Chip reset
+[TP FM 3] After Chip reset
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/conninfra_step.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/conninfra_step.c
new file mode 100755
index 0000000..e0beee7
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/conninfra_step.c
@@ -0,0 +1,1145 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#include <connectivity_build_in_adapter.h>
+
+#include <linux/firmware.h>
+#include <asm/delay.h>
+#include <linux/slab.h>
+
+#include "osal.h"
+#include "conninfra_step.h"
+#include "conninfra_step_parse_act.h"
+#include "conninfra_core.h"
+#include "consys_hw.h"
+#include "emi_mng.h"
+#include "consys_reg_mng.h"
+#include "consys_reg_util.h"
+
+/*******************************************************************************
+ * F U N C T I O N D E C L A R A T I O N S
+********************************************************************************/
+
+static void conninfra_step_remove_emi_action(struct step_action *p_act);
+static void conninfra_step_remove_register_action(struct step_action *p_act);
+static void conninfra_step_remove_gpio_action(struct step_action *p_act);
+static void conninfra_step_remove_periodic_dump_action(struct step_action *p_act);
+static void conninfra_step_remove_show_string_action(struct step_action *p_act);
+static void conninfra_step_remove_sleep_action(struct step_action *p_act);
+static void conninfra_step_remove_condition_action(struct step_action *p_act);
+static void conninfra_step_remove_value_action(struct step_action *p_act);
+static void conninfra_step_remove_condition_emi_action(struct step_action *p_act);
+static void conninfra_step_remove_condition_register_action(struct step_action *p_act);
+
+
+static int conninfra_step_operator_result_greater(int l_val, int r_val);
+static int conninfra_step_operator_result_greater_equal(int l_val, int r_val);
+static int conninfra_step_operator_result_less(int l_val, int r_val);
+static int conninfra_step_operator_result_less_equal(int l_val, int r_val);
+static int conninfra_step_operator_result_equal(int l_val, int r_val);
+static int conninfra_step_operator_result_not_equal(int l_val, int r_val);
+static int conninfra_step_operator_result_and(int l_val, int r_val);
+static int conninfra_step_operator_result_or(int l_val, int r_val);
+
+
+/*******************************************************************************
+ * D E F I N E
+********************************************************************************/
+
+/*******************************************************************************
+ * P R I V A T E D A T A
+********************************************************************************/
+struct step_env_struct g_infra_step_env;
+
+struct step_drv_type_def g_step_drv_type_def[STEP_DRV_TYPE_MAX] = {
+ [STEP_DRV_TYPE_NO_DEFINE] = {"NoDefine", -1, NULL, NULL},
+ [STEP_DRV_TYPE_CONNINFRA] = {"CONNINFRA", STEP_CONNINFRA_TP_MAX, NULL, &g_infra_step_env.conninfra_actions[0]},
+ [STEP_DRV_TYPE_BT] = {"BT", STEP_BT_TP_MAX, NULL, &g_infra_step_env.bt_actions[0]},
+ [STEP_DRV_TYPE_FM] = {"FM", STEP_FM_TP_MAX, NULL, &g_infra_step_env.fm_actions[0]},
+ [STEP_DRV_TYPE_GPS] = {"GPS", STEP_GPS_TP_MAX, NULL, &g_infra_step_env.gps_actions[0]},
+ [STEP_DRV_TYPE_WIFI] = {"WF", STEP_WF_TP_MAX, NULL, &g_infra_step_env.wf_actions[0]},
+};
+
+
+
+static const struct step_action_contrl conninfra_step_action_map[] = {
+ [STEP_ACTION_INDEX_EMI] = {
+ conninfra_step_create_emi_action,
+ conninfra_step_do_emi_action,
+ conninfra_step_remove_emi_action
+ },
+ [STEP_ACTION_INDEX_REGISTER] = {
+ conninfra_step_create_register_action,
+ conninfra_step_do_register_action,
+ conninfra_step_remove_register_action
+ },
+ [STEP_ACTION_INDEX_GPIO] = {
+ conninfra_step_create_gpio_action,
+ conninfra_step_do_gpio_action,
+ conninfra_step_remove_gpio_action
+ },
+ [STEP_ACTION_INDEX_PERIODIC_DUMP] = {
+ conninfra_step_create_periodic_dump_action,
+ conninfra_step_do_periodic_dump_action,
+ conninfra_step_remove_periodic_dump_action,
+ },
+ [STEP_ACTION_INDEX_SHOW_STRING] = {
+ conninfra_step_create_show_string_action,
+ conninfra_step_do_show_string_action,
+ conninfra_step_remove_show_string_action
+ },
+ [STEP_ACTION_INDEX_SLEEP] = {
+ conninfra_step_create_sleep_action,
+ conninfra_step_do_sleep_action,
+ conninfra_step_remove_sleep_action
+ },
+ [STEP_ACTION_INDEX_CONDITION] = {
+ conninfra_step_create_condition_action,
+ conninfra_step_do_condition_action,
+ conninfra_step_remove_condition_action
+ },
+ [STEP_ACTION_INDEX_VALUE] = {
+ conninfra_step_create_value_action,
+ conninfra_step_do_value_action,
+ conninfra_step_remove_value_action
+ },
+ [STEP_ACTION_INDEX_CONDITION_EMI] = {
+ conninfra_step_create_condition_emi_action,
+ conninfra_step_do_condition_emi_action,
+ conninfra_step_remove_condition_emi_action
+ },
+ [STEP_ACTION_INDEX_CONDITION_REGISTER] = {
+ conninfra_step_create_condition_register_action,
+ conninfra_step_do_condition_register_action,
+ conninfra_step_remove_condition_register_action
+ },
+};
+
+typedef int (*STEP_OPERATOR_RESULT) (int, int);
+static const STEP_OPERATOR_RESULT conninfra_step_operator_result_map[] = {
+ [STEP_OPERATOR_GREATER] = conninfra_step_operator_result_greater,
+ [STEP_OPERATOR_GREATER_EQUAL] = conninfra_step_operator_result_greater_equal,
+ [STEP_OPERATOR_LESS] = conninfra_step_operator_result_less,
+ [STEP_OPERATOR_LESS_EQUAL] = conninfra_step_operator_result_less_equal,
+ [STEP_OPERATOR_EQUAL] = conninfra_step_operator_result_equal,
+ [STEP_OPERATOR_NOT_EQUAL] = conninfra_step_operator_result_not_equal,
+ [STEP_OPERATOR_AND] = conninfra_step_operator_result_and,
+ [STEP_OPERATOR_OR] = conninfra_step_operator_result_or,
+};
+
+/*******************************************************************************
+ * I N T E R N A L F U N C T I O N S
+********************************************************************************/
+
+static void conninfra_step_init_list(void)
+{
+ unsigned int i = 0;
+
+ for (i = 0; i < STEP_CONNINFRA_TP_MAX; i++)
+ INIT_LIST_HEAD(&(g_infra_step_env.conninfra_actions[i].list));
+
+ for (i = 0; i < STEP_WF_TP_MAX; i++)
+ INIT_LIST_HEAD(&(g_infra_step_env.wf_actions[i].list));
+
+ for (i = 0; i < STEP_BT_TP_MAX; i++)
+ INIT_LIST_HEAD(&(g_infra_step_env.bt_actions[i].list));
+
+ for (i = 0; i < STEP_GPS_TP_MAX; i++)
+ INIT_LIST_HEAD(&(g_infra_step_env.gps_actions[i].list));
+
+ for (i = 0; i < STEP_FM_TP_MAX; i++)
+ INIT_LIST_HEAD(&(g_infra_step_env.fm_actions[i].list));
+
+}
+
+static unsigned char __iomem *conninfra_step_get_emi_base_address(void)
+{
+ struct consys_emi_addr_info* emi_addr_info = NULL;
+
+ if (g_infra_step_env.emi_base_addr == NULL) {
+ emi_addr_info = emi_mng_get_phy_addr();
+ if (emi_addr_info != NULL) {
+ g_infra_step_env.emi_base_addr = ioremap_nocache(emi_addr_info->emi_ap_phy_addr,
+ emi_addr_info->emi_size);
+ g_infra_step_env.emi_size = emi_addr_info->emi_size;
+ }
+ }
+
+ return g_infra_step_env.emi_base_addr;
+}
+
+static void conninfra_step_clear_action_list(struct step_action_list *action_list)
+{
+ struct step_action *p_act, *p_act_next;
+
+ list_for_each_entry_safe(p_act, p_act_next, &(action_list->list), list) {
+ list_del_init(&p_act->list);
+ conninfra_step_remove_action(p_act);
+ }
+}
+
+static void conninfra_step_clear_list(void)
+{
+ unsigned int i = 0;
+
+ for (i = 0; i < STEP_CONNINFRA_TP_MAX; i++)
+ conninfra_step_clear_action_list(&g_infra_step_env.conninfra_actions[i]);
+
+ for (i = 0; i < STEP_WF_TP_MAX; i++)
+ conninfra_step_clear_action_list(&g_infra_step_env.wf_actions[i]);
+
+ for (i = 0; i < STEP_BT_TP_MAX; i++)
+ conninfra_step_clear_action_list(&g_infra_step_env.bt_actions[i]);
+
+ for (i = 0; i < STEP_GPS_TP_MAX; i++)
+ conninfra_step_clear_action_list(&g_infra_step_env.gps_actions[i]);
+
+ for (i = 0; i < STEP_FM_TP_MAX; i++)
+ conninfra_step_clear_action_list(&g_infra_step_env.fm_actions[i]);
+
+#if 0
+ for (i = 0; i < STEP_DRV_TYPE_MAX; i++)
+ for (j = 0; j < STEP_TRIGGER_POINT_MAX; j++)
+ conninfra_step_clear_action_list(&g_infra_step_env.actions[i][j]);
+#endif
+}
+
+static void conninfra_step_unioremap_emi(void)
+{
+ if (g_infra_step_env.emi_base_addr != NULL) {
+ iounmap(g_infra_step_env.emi_base_addr);
+ g_infra_step_env.emi_base_addr = NULL;
+ }
+}
+
+static unsigned char *conninfra_step_get_emi_virt_addr(unsigned char *emi_base_addr, unsigned int offset)
+{
+ unsigned char *p_virtual_addr = NULL;
+
+ if (offset > g_infra_step_env.emi_size) {
+ pr_err("STEP failed: offset size %d over MAX size(%d)\n", offset,
+ g_infra_step_env.emi_size);
+ return NULL;
+ }
+ p_virtual_addr = emi_base_addr + offset;
+
+ return p_virtual_addr;
+}
+
+static int conninfra_step_get_cfg(const char *p_patch_name, osal_firmware **pp_patch)
+{
+ osal_firmware *fw = NULL;
+
+ *pp_patch = NULL;
+ if (request_firmware((const struct firmware **)&fw, p_patch_name, NULL) != 0)
+ return -1;
+
+ pr_debug("Load step cfg %s ok!!\n", p_patch_name);
+ *pp_patch = fw;
+
+ return 0;
+}
+
+static int conninfra_step_release_cfg(osal_firmware ** ppPatch)
+{
+ if (ppPatch != NULL) {
+ release_firmware((const struct firmware *)*ppPatch);
+ *ppPatch = NULL;
+ }
+ return 0;
+}
+
+static void conninfra_step_sleep_or_delay(int ms)
+{
+ /* msleep < 20ms can sleep for up to 20ms */
+ if (ms < 20)
+ udelay(ms * 1000);
+ else
+ osal_sleep_ms(ms);
+}
+
+struct step_action_list *conninfra_step_get_tp_list(enum step_drv_type drv_type, int tp_id)
+{
+ if (drv_type <= STEP_DRV_TYPE_NO_DEFINE || drv_type >= STEP_DRV_TYPE_MAX) {
+ pr_err("STEP failed: incorrect drv type: %d\n", drv_type);
+ return NULL;
+ }
+
+ if (tp_id <= STEP_TP_NO_DEFINE || tp_id >= g_step_drv_type_def[drv_type].tp_max) {
+ pr_err("STEP failed: Write action to drv_type [%d] tp_id: [%d]\n",
+ drv_type, tp_id);
+ return NULL;
+ }
+
+ return &g_step_drv_type_def[drv_type].action_list[tp_id];
+}
+
+static void _conninfra_step_do_actions(struct step_action_list *action_list)
+{
+ struct step_action *p_act, *p_act_next;
+
+ list_for_each_entry_safe(p_act, p_act_next, &action_list->list, list) {
+ if (p_act->action_id <= STEP_ACTION_INDEX_NO_DEFINE || p_act->action_id >= STEP_ACTION_INDEX_MAX) {
+ pr_err("STEP failed: Wrong action id %d\n", (int)p_act->action_id);
+ continue;
+ }
+
+ if (conninfra_step_action_map[p_act->action_id].func_do_action != NULL)
+ conninfra_step_action_map[p_act->action_id].func_do_action(p_act, NULL);
+ else
+ pr_err("STEP failed: Action is NULL\n");
+ }
+}
+
+static void conninfra_step_start_work(struct step_pd_entry *p_entry)
+{
+ unsigned int timeout;
+ int result = 0;
+
+ if (!g_infra_step_env.pd_struct.step_pd_wq) {
+ pr_err("STEP failed: step wq doesn't run\n");
+ result = -1;
+ }
+
+ if (p_entry == NULL) {
+ pr_err("STEP failed: entry is null\n");
+ result = -1;
+ }
+
+ if (result == 0) {
+ timeout = p_entry->expires_ms;
+ queue_delayed_work(g_infra_step_env.pd_struct.step_pd_wq, &p_entry->pd_work, timeout);
+ }
+}
+
+static void conninfra_step_pd_work(struct work_struct *work)
+{
+ struct step_pd_entry *p_entry;
+ struct delayed_work *delayed_work;
+ int result = 0;
+
+ if (down_read_trylock(&g_infra_step_env.init_rwsem)) {
+ if (!g_infra_step_env.is_enable) {
+ pr_err("STEP failed: step doesn`t enable\n");
+ result = -1;
+ }
+
+ delayed_work = to_delayed_work(work);
+ if (delayed_work == NULL) {
+ pr_err("STEP failed: work is NULL\n");
+ result = -1;
+ }
+
+ if (result == 0) {
+ p_entry = container_of(delayed_work, struct step_pd_entry, pd_work);
+
+ pr_info("STEP show: Periodic dump: %d ms\n", p_entry->expires_ms);
+ _conninfra_step_do_actions(&p_entry->action_list);
+ conninfra_step_start_work(p_entry);
+ }
+
+ up_read(&g_infra_step_env.init_rwsem);
+ }
+}
+
+static struct step_pd_entry *conninfra_step_create_periodic_dump_entry(unsigned int expires)
+{
+ struct step_pd_entry *p_pd_entry = NULL;
+
+ p_pd_entry = kzalloc(sizeof(struct step_pd_entry), GFP_KERNEL);
+ if (p_pd_entry == NULL) {
+ pr_err("STEP failed: kzalloc fail\n");
+ return NULL;
+ }
+ p_pd_entry->expires_ms = expires;
+
+ INIT_DELAYED_WORK(&p_pd_entry->pd_work, conninfra_step_pd_work);
+ INIT_LIST_HEAD(&(p_pd_entry->action_list.list));
+
+ return p_pd_entry;
+}
+
+static void conninfra_step_print_trigger_time(enum consys_conninfra_step_trigger_point tp_id, char *reason)
+{
+ const char *p_trigger_name = NULL;
+
+ /* TODO: print trigger point name */
+ //p_trigger_name = STEP_TRIGGER_TIME_NAME[tp_id];
+ p_trigger_name = "";
+ if (reason != NULL)
+ pr_info("STEP show: Trigger point: %s reason: %s\n", p_trigger_name, reason);
+ else
+ pr_info("STEP show: Trigger point: %s\n", p_trigger_name);
+}
+
+void conninfra_step_do_actions_from_tp(enum step_drv_type drv_type,
+ unsigned int tp_id, char *reason)
+{
+ int result = 0;
+
+ if (down_read_trylock(&g_infra_step_env.init_rwsem)) {
+ if (g_infra_step_env.is_enable == 0)
+ result = -1;
+
+
+ if (tp_id <= STEP_TP_NO_DEFINE || tp_id >= g_step_drv_type_def[drv_type].tp_max) {
+ pr_err("STEP failed: Do actions from tp_id: %d\n", tp_id);
+ result = -1;
+ //} else if (list_empty(&g_infra_step_env.actions[tp_id].list)) {
+ } else if (list_empty(&g_step_drv_type_def[drv_type].action_list[tp_id].list)) {
+ result = -1;
+ }
+
+ if (result == 0) {
+ conninfra_step_print_trigger_time(tp_id, reason);
+ _conninfra_step_do_actions(&g_step_drv_type_def[drv_type].action_list[tp_id]);
+ }
+
+ up_read(&g_infra_step_env.init_rwsem);
+ }
+}
+
+static int conninfra_step_write_action(struct step_action_list *p_list, enum step_drv_type drv_type,
+ enum step_action_id act_id, int param_num, char *params[])
+{
+ struct step_action *p_action;
+
+ if (p_list == NULL) {
+ pr_err("STEP failed: p_list is null\n");
+ return -1;
+ }
+
+ p_action = conninfra_step_create_action(drv_type, act_id, param_num, params);
+ if (p_action != NULL) {
+ list_add_tail(&(p_action->list), &(p_list->list));
+ return 0;
+ }
+
+ return -1;
+}
+
+static int conninfra_step_operator_result_greater(int l_val, int r_val)
+{
+ return (l_val > r_val);
+}
+
+static int conninfra_step_operator_result_greater_equal(int l_val, int r_val)
+{
+ return (l_val >= r_val);
+}
+
+static int conninfra_step_operator_result_less(int l_val, int r_val)
+{
+ return (l_val < r_val);
+}
+
+static int conninfra_step_operator_result_less_equal(int l_val, int r_val)
+{
+ return (l_val <= r_val);
+}
+
+static int conninfra_step_operator_result_equal(int l_val, int r_val)
+{
+ return (l_val == r_val);
+}
+
+static int conninfra_step_operator_result_not_equal(int l_val, int r_val)
+{
+ return (l_val != r_val);
+}
+
+static int conninfra_step_operator_result_and(int l_val, int r_val)
+{
+ return (l_val && r_val);
+}
+
+static int conninfra_step_operator_result_or(int l_val, int r_val)
+{
+ return (l_val || r_val);
+}
+
+
+void conninfra_step_create_emi_cb(int mode, int write,
+ unsigned int begin, unsigned int mask, unsigned int reg_id) {
+}
+
+static int conninfra_step_do_write_register_action(struct step_register_info *p_reg_info,
+ STEP_DO_EXTRA func_do_extra)
+{
+ phys_addr_t phy_addr;
+ void __iomem *p_addr = NULL;
+
+ phy_addr = p_reg_info->address + p_reg_info->offset;
+
+ if (phy_addr & 0x3) {
+ pr_err("STEP failed: phy_addr(0x%08x) page failed\n", phy_addr);
+ return -1;
+ }
+
+ p_addr = ioremap_nocache(phy_addr, 0x4);
+ if (p_addr) {
+ CONSYS_REG_WRITE_MASK((unsigned int *)p_addr, p_reg_info->value, p_reg_info->mask);
+ pr_info(
+ "STEP show: reg write Phy addr(0x%08x): 0x%08x\n",
+ (unsigned int)phy_addr, CONSYS_REG_READ(p_addr));
+ if (func_do_extra != NULL)
+ func_do_extra(1, CONSYS_REG_READ(p_addr));
+ iounmap(p_addr);
+ } else {
+ pr_err("STEP failed: ioremap(0x%08x) is NULL\n", phy_addr);
+ return -1;
+ }
+ return 0;
+}
+
+static void _conninfra_step_do_read_register_action(struct step_register_info *p_reg_info,
+ STEP_DO_EXTRA func_do_extra, char *info, int value)
+{
+ int i;
+
+ for (i = 0; i < p_reg_info->times; i++) {
+ if (i > 0)
+ conninfra_step_sleep_or_delay(p_reg_info->delay_time);
+
+ if (p_reg_info->output_mode == STEP_OUTPUT_REGISTER) {
+ g_infra_step_env.temp_register[p_reg_info->temp_reg_id] = value & p_reg_info->mask;
+
+ pr_info("[%s] value=[%d] mask=[%d]", __func__, value, p_reg_info->mask);
+ } else
+ pr_info("%s", info);
+
+ if (func_do_extra != NULL)
+ func_do_extra(1, value);
+ }
+}
+
+static int conninfra_step_do_read_register_action(struct step_register_info *p_reg_info,
+ STEP_DO_EXTRA func_do_extra)
+{
+ phys_addr_t phy_addr;
+ void __iomem *p_addr = NULL;
+ char buf[128];
+
+ phy_addr = p_reg_info->address + p_reg_info->offset;
+
+ if (phy_addr & 0x3) {
+ pr_err("STEP failed: phy_addr(0x%08x) page failed\n", phy_addr);
+ return -1;
+ }
+
+ p_addr = ioremap_nocache(phy_addr, 0x4);
+ if (p_addr) {
+ sprintf(buf, "STEP show: reg read Phy addr(0x%08x): 0x%08x\n",
+ (unsigned int)phy_addr, CONSYS_REG_READ(p_addr));
+ _conninfra_step_do_read_register_action(p_reg_info, func_do_extra, buf,
+ CONSYS_REG_READ(p_addr));
+ iounmap(p_addr);
+ } else {
+ pr_err("STEP failed: ioremap(0x%08x) is NULL\n", phy_addr);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void conninfra_step_remove_emi_action(struct step_action *p_act)
+{
+ struct step_emi_action *p_emi_act = NULL;
+
+ p_emi_act = clist_entry_action(emi, p_act);
+ kfree(p_emi_act);
+}
+
+static void conninfra_step_remove_register_action(struct step_action *p_act)
+{
+ struct step_register_action *p_reg_act = NULL;
+
+ p_reg_act = clist_entry_action(register, p_act);
+ kfree(p_reg_act);
+}
+
+static void conninfra_step_remove_gpio_action(struct step_action *p_act)
+{
+ struct step_gpio_action *p_gpio_act = NULL;
+
+ p_gpio_act = clist_entry_action(gpio, p_act);
+ kfree(p_gpio_act);
+}
+
+static void conninfra_step_remove_periodic_dump_action(struct step_action *p_act)
+{
+ struct step_periodic_dump_action *p_pd = NULL;
+
+ p_pd = clist_entry_action(periodic_dump, p_act);
+ kfree(p_pd);
+}
+
+static void conninfra_step_remove_show_string_action(struct step_action *p_act)
+{
+ struct step_show_string_action *p_show = NULL;
+
+ p_show = clist_entry_action(show_string, p_act);
+ if (p_show->content != NULL)
+ kfree(p_show->content);
+
+ kfree(p_show);
+}
+
+static void conninfra_step_remove_sleep_action(struct step_action *p_act)
+{
+ struct step_sleep_action *p_sleep = NULL;
+
+ p_sleep = clist_entry_action(sleep, p_act);
+ kfree(p_sleep);
+}
+
+static void conninfra_step_remove_condition_action(struct step_action *p_act)
+{
+ struct step_condition_action *p_cond = NULL;
+
+ p_cond = clist_entry_action(condition, p_act);
+ kfree(p_cond);
+}
+
+static void conninfra_step_remove_value_action(struct step_action *p_act)
+{
+ struct step_value_action *p_val = NULL;
+
+ p_val = clist_entry_action(value, p_act);
+ kfree(p_val);
+}
+
+static void conninfra_step_remove_condition_emi_action(struct step_action *p_act)
+{
+ struct step_condition_emi_action *p_cond_emi_act = NULL;
+
+ p_cond_emi_act = clist_entry_action(condition_emi, p_act);
+ kfree(p_cond_emi_act);
+}
+
+static void conninfra_step_remove_condition_register_action(struct step_action *p_act)
+{
+ struct step_condition_register_action *p_cond_reg_act = NULL;
+
+ p_cond_reg_act = clist_entry_action(condition_register, p_act);
+ kfree(p_cond_reg_act);
+}
+
+static int _conninfra_step_do_emi_action(struct step_emi_info *p_emi_info, STEP_DO_EXTRA func_do_extra)
+{
+ unsigned char *p_emi_begin_addr = NULL, *p_emi_end_addr = NULL;
+ unsigned char __iomem *emi_base_addr = NULL;
+ unsigned int dis = 0, temp = 0, i = 0;
+ struct consys_emi_addr_info *emi_addr_info = NULL;
+
+ if (p_emi_info->is_write != 0) {
+ pr_err("STEP failed: Only support dump EMI region\n");
+ return -1;
+ }
+
+ if (p_emi_info->begin_offset > p_emi_info->end_offset) {
+ temp = p_emi_info->begin_offset;
+ p_emi_info->begin_offset = p_emi_info->end_offset;
+ p_emi_info->end_offset = temp;
+ }
+ dis = p_emi_info->end_offset - p_emi_info->begin_offset;
+
+ emi_base_addr = conninfra_step_get_emi_base_address();
+ if (emi_base_addr == NULL) {
+ pr_err("STEP failed: EMI base address is NULL\n");
+ return -1;
+ }
+
+ if (p_emi_info->begin_offset & 0x3) {
+ pr_err("STEP failed: begin offset(0x%08x) page failed\n",
+ p_emi_info->begin_offset);
+ return -1;
+ }
+
+ p_emi_begin_addr = conninfra_step_get_emi_virt_addr(emi_base_addr, p_emi_info->begin_offset);
+ p_emi_end_addr = conninfra_step_get_emi_virt_addr(emi_base_addr, p_emi_info->end_offset);
+ if (!p_emi_begin_addr) {
+ pr_err("STEP failed: Get NULL begin virtual address 0x%08x\n",
+ p_emi_info->begin_offset);
+ return -1;
+ }
+
+ if (!p_emi_end_addr) {
+ pr_err("STEP failed: Get NULL end virtual address 0x%08x\n",
+ p_emi_info->end_offset);
+ return -1;
+ }
+
+ for (i = 0; i < dis; i += 0x4) {
+ if (p_emi_info->output_mode == STEP_OUTPUT_REGISTER) {
+ g_infra_step_env.temp_register[p_emi_info->temp_reg_id] =
+ (CONSYS_REG_READ(p_emi_begin_addr + i) & p_emi_info->mask);
+ } else {
+ emi_addr_info = emi_mng_get_phy_addr();
+ //if (emi_mng_get_phy_addr(&phy_addr, &phy_size) != 0)
+ if (emi_addr_info == NULL)
+ pr_warn("STEP show: get phy addr fail");
+
+ pr_info("STEP show: EMI action, Phy address(0x%08x): 0x%08x\n",
+ (unsigned int) (emi_addr_info->emi_ap_phy_addr + p_emi_info->begin_offset + i),
+ CONSYS_REG_READ(p_emi_begin_addr + i));
+ }
+
+ if (func_do_extra != NULL)
+ func_do_extra(1, CONSYS_REG_READ(p_emi_begin_addr + i));
+ }
+
+ return 0;
+}
+
+static bool conninfra_step_reg_readable(struct step_register_info *p_reg_info)
+{
+ phys_addr_t phy_addr;
+ enum step_drv_type drv_type = p_reg_info->drv_type;
+
+ if (p_reg_info->address_type == 0) {
+ phy_addr = p_reg_info->address + p_reg_info->offset;
+ switch (drv_type) {
+ case STEP_DRV_TYPE_CONNINFRA:
+ return consys_reg_mng_reg_readable();
+ case STEP_DRV_TYPE_BT:
+ case STEP_DRV_TYPE_FM:
+ case STEP_DRV_TYPE_GPS:
+ case STEP_DRV_TYPE_WIFI:
+ if (g_step_drv_type_def[drv_type].drv_cb == NULL)
+ return 0;
+ return g_step_drv_type_def[drv_type].drv_cb->readable_cb(phy_addr);
+ default:
+ pr_err("STEP: reg readable drv type(%d) incorrect", drv_type);
+ };
+ } else {
+ return consys_reg_mng_reg_readable();
+ }
+ return 0;
+}
+
+int _conninfra_step_do_register_action(struct step_register_info *p_reg_info, STEP_DO_EXTRA func_do_extra)
+{
+ int ret = 0, r;
+
+ ret = conninfra_core_force_conninfra_wakeup();
+ if (ret) {
+ pr_err("STEP failed: wakeup conninfra fail\n");
+ return -3;
+ }
+
+ if (!conninfra_step_reg_readable(p_reg_info)) {
+ pr_err("STEP failed: register cannot read\n");
+ ret = -1;
+ goto err;
+ }
+
+ if (p_reg_info->is_write == 1)
+ ret = conninfra_step_do_write_register_action(p_reg_info, func_do_extra);
+ else
+ ret = conninfra_step_do_read_register_action(p_reg_info, func_do_extra);
+
+err:
+ r = conninfra_core_force_conninfra_sleep();
+ if (r)
+ pr_err("STEP failed: sleep conninfra fail\n");
+
+ return ret;
+}
+
+void conninfra_step_setup(void)
+{
+ if (!g_infra_step_env.is_setup) {
+ g_infra_step_env.is_setup = true;
+ init_rwsem(&g_infra_step_env.init_rwsem);
+ }
+}
+
+/*******************************************************************************
+ * I N T E R N A L F U N C T I O N S W I T H U T
+********************************************************************************/
+int conninfra_step_do_emi_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra)
+{
+ struct step_emi_action *p_emi_act = NULL;
+ struct step_emi_info *p_emi_info = NULL;
+
+ p_emi_act = clist_entry_action(emi, p_act);
+ p_emi_info = &p_emi_act->info;
+ return _conninfra_step_do_emi_action(p_emi_info, func_do_extra);
+}
+
+int conninfra_step_do_condition_emi_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra)
+{
+ struct step_condition_emi_action *p_cond_emi_act = NULL;
+ struct step_emi_info *p_emi_info = NULL;
+
+ p_cond_emi_act = clist_entry_action(condition_emi, p_act);
+ p_emi_info = &p_cond_emi_act->info;
+
+ if (g_infra_step_env.temp_register[p_cond_emi_act->cond_reg_id] == 0) {
+ pr_info("STEP show: Dont do emi, condition %c%d is %d\n",
+ STEP_TEMP_REGISTER_SYMBOL, p_emi_info->temp_reg_id,
+ g_infra_step_env.temp_register[p_cond_emi_act->cond_reg_id]);
+ return -1;
+ }
+
+ return _conninfra_step_do_emi_action(p_emi_info, func_do_extra);
+}
+
+int conninfra_step_do_register_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra)
+{
+ struct step_register_action *p_reg_act = NULL;
+ struct step_register_info *p_reg_info = NULL;
+
+ p_reg_act = clist_entry_action(register, p_act);
+ p_reg_info = &p_reg_act->info;
+
+ return _conninfra_step_do_register_action(p_reg_info, func_do_extra);
+}
+
+int conninfra_step_do_condition_register_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra)
+{
+ struct step_condition_register_action *p_cond_reg_act = NULL;
+ struct step_register_info *p_reg_info = NULL;
+
+ p_cond_reg_act = clist_entry_action(condition_register, p_act);
+ p_reg_info = &p_cond_reg_act->info;
+
+ if (g_infra_step_env.temp_register[p_cond_reg_act->cond_reg_id] == 0) {
+ pr_info("STEP show: Dont do register, condition %c%d is %d\n",
+ STEP_TEMP_REGISTER_SYMBOL, p_reg_info->temp_reg_id,
+ g_infra_step_env.temp_register[p_cond_reg_act->cond_reg_id]);
+ return -1;
+ }
+
+ return _conninfra_step_do_register_action(p_reg_info, func_do_extra);
+}
+
+int conninfra_step_do_gpio_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra)
+{
+ struct step_gpio_action *p_gpio_act = NULL;
+
+ p_gpio_act = clist_entry_action(gpio, p_act);
+ if (p_gpio_act->is_write == 1) {
+ pr_err("STEP failed: Only support dump GPIO\n");
+ return -1;
+ }
+
+#ifdef KERNEL_gpio_dump_regs_range
+ KERNEL_gpio_dump_regs_range(p_gpio_act->pin_symbol, p_gpio_act->pin_symbol);
+#else
+ pr_info("STEP show: No support gpio dump\n");
+#endif
+ if (func_do_extra != NULL)
+ func_do_extra(0);
+
+ return 0;
+}
+
+int conninfra_step_do_periodic_dump_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra)
+{
+ struct step_periodic_dump_action *p_pd_act = NULL;
+
+ p_pd_act = clist_entry_action(periodic_dump, p_act);
+ if (p_pd_act->pd_entry->is_enable == 0) {
+ pr_info("STEP show: Start periodic dump(%d ms)\n",
+ p_pd_act->pd_entry->expires_ms);
+ conninfra_step_start_work(p_pd_act->pd_entry);
+ p_pd_act->pd_entry->is_enable = 1;
+ }
+
+ if (func_do_extra != NULL)
+ func_do_extra(0);
+
+ return 0;
+}
+
+int conninfra_step_do_show_string_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra)
+{
+ struct step_show_string_action *p_show_act = NULL;
+
+ p_show_act = clist_entry_action(show_string, p_act);
+
+ pr_info("STEP show: %s\n", p_show_act->content);
+
+ if (func_do_extra != NULL)
+ func_do_extra(1, p_show_act->content);
+
+ return 0;
+}
+
+int conninfra_step_do_sleep_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra)
+{
+ struct step_sleep_action *p_sleep_act = NULL;
+
+ p_sleep_act = clist_entry_action(sleep, p_act);
+
+ conninfra_step_sleep_or_delay(p_sleep_act->ms);
+
+ if (func_do_extra != NULL)
+ func_do_extra(0);
+
+ return 0;
+}
+
+int conninfra_step_do_condition_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra)
+{
+ struct step_condition_action *p_cond_act = NULL;
+ int result, l_val, r_val;
+
+ p_cond_act = clist_entry_action(condition, p_act);
+
+ l_val = g_infra_step_env.temp_register[p_cond_act->l_temp_reg_id];
+
+ if (p_cond_act->mode == STEP_CONDITION_RIGHT_REGISTER)
+ r_val = g_infra_step_env.temp_register[p_cond_act->r_temp_reg_id];
+ else
+ r_val = p_cond_act->value;
+
+ if (conninfra_step_operator_result_map[p_cond_act->operator_id]) {
+ result = conninfra_step_operator_result_map[p_cond_act->operator_id] (l_val, r_val);
+ g_infra_step_env.temp_register[p_cond_act->result_temp_reg_id] = result;
+
+ pr_info("STEP show: Condition %d(%c%d) op %d(%c%d) => %d(%c%d)\n",
+ l_val, STEP_TEMP_REGISTER_SYMBOL, p_cond_act->l_temp_reg_id,
+ r_val, STEP_TEMP_REGISTER_SYMBOL, p_cond_act->r_temp_reg_id,
+ result, STEP_TEMP_REGISTER_SYMBOL, p_cond_act->result_temp_reg_id);
+ } else {
+ pr_err("STEP failed: operator no define id: %d\n", p_cond_act->operator_id);
+ }
+
+ if (func_do_extra != NULL)
+ func_do_extra(1, g_infra_step_env.temp_register[p_cond_act->result_temp_reg_id]);
+
+ return 0;
+}
+
+int conninfra_step_do_value_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra)
+{
+ struct step_value_action *p_val_act = NULL;
+
+ p_val_act = clist_entry_action(value, p_act);
+
+ g_infra_step_env.temp_register[p_val_act->temp_reg_id] = p_val_act->value;
+
+ if (func_do_extra != NULL)
+ func_do_extra(1, g_infra_step_env.temp_register[p_val_act->temp_reg_id]);
+
+ return 0;
+}
+
+struct step_action *conninfra_step_create_action(enum step_drv_type drv_type, enum step_action_id act_id,
+ int param_num, char *params[])
+{
+ struct step_action *p_act = NULL;
+
+ if (act_id <= STEP_ACTION_INDEX_NO_DEFINE || act_id >= STEP_ACTION_INDEX_MAX) {
+ pr_err("STEP failed: Create action id: %d\n", act_id);
+ return NULL;
+ }
+
+ if (conninfra_step_action_map[act_id].func_create_action != NULL)
+ p_act = conninfra_step_action_map[act_id].func_create_action(drv_type, param_num, params);
+ else
+ pr_err("STEP failed: Create no define id: %d\n", act_id);
+
+ if (p_act != NULL)
+ p_act->action_id = act_id;
+
+ return p_act;
+}
+
+int conninfra_step_init_pd_env(void)
+{
+ g_infra_step_env.pd_struct.step_pd_wq = create_workqueue(STEP_PERIODIC_DUMP_WORK_QUEUE);
+ if (!g_infra_step_env.pd_struct.step_pd_wq) {
+ pr_err("create_workqueue fail\n");
+ return -1;
+ }
+ pr_info("[%s] step_pd_wq [%p]", __func__, g_infra_step_env.pd_struct.step_pd_wq);
+ INIT_LIST_HEAD(&g_infra_step_env.pd_struct.pd_list);
+
+ return 0;
+}
+
+int conninfra_step_deinit_pd_env(void)
+{
+ struct step_pd_entry *p_current;
+ struct step_pd_entry *p_next;
+
+ if (!g_infra_step_env.pd_struct.step_pd_wq)
+ return -1;
+
+ list_for_each_entry_safe(p_current, p_next, &g_infra_step_env.pd_struct.pd_list, list) {
+ cancel_delayed_work(&p_current->pd_work);
+ conninfra_step_clear_action_list(&p_current->action_list);
+ }
+ pr_info("[%s] step_pd_wq [%p]", __func__, g_infra_step_env.pd_struct.step_pd_wq);
+
+ destroy_workqueue(g_infra_step_env.pd_struct.step_pd_wq);
+ g_infra_step_env.pd_struct.step_pd_wq = NULL;
+
+ return 0;
+}
+
+struct step_pd_entry *conninfra_step_get_periodic_dump_entry(unsigned int expires)
+{
+ struct step_pd_entry *p_current;
+
+ if (expires <= 0)
+ return NULL;
+
+ if (!g_infra_step_env.pd_struct.step_pd_wq) {
+ if (conninfra_step_init_pd_env() != 0)
+ return NULL;
+ }
+
+ p_current = conninfra_step_create_periodic_dump_entry(expires);
+ if (p_current == NULL)
+ return NULL;
+ list_add_tail(&(p_current->list), &(g_infra_step_env.pd_struct.pd_list));
+
+ return p_current;
+}
+
+int conninfra_step_read_file(const char *file_name)
+{
+ int ret = -1;
+ const osal_firmware *p_step_cfg = NULL;
+
+ if (g_infra_step_env.is_enable == 1)
+ return 0;
+
+ if (0 == conninfra_step_get_cfg(file_name, (osal_firmware **) &p_step_cfg)) {
+ if (0 == conninfra_step_parse_data((const char *)p_step_cfg->data, p_step_cfg->size,
+ conninfra_step_write_action)) {
+ ret = 0;
+ } else {
+ ret = -1;
+ }
+
+ conninfra_step_release_cfg((osal_firmware **) &p_step_cfg);
+
+ return ret;
+ }
+
+ pr_info("STEP read file, %s is not exist\n", file_name);
+
+ return ret;
+}
+
+void conninfra_step_remove_action(struct step_action *p_act)
+{
+ if (p_act != NULL) {
+ if (p_act->action_id <= STEP_ACTION_INDEX_NO_DEFINE || p_act->action_id >= STEP_ACTION_INDEX_MAX) {
+ pr_err("STEP failed: Wrong action id %d\n", (int)p_act->action_id);
+ return;
+ }
+
+ if (conninfra_step_action_map[p_act->action_id].func_remove_action != NULL)
+ conninfra_step_action_map[p_act->action_id].func_remove_action(p_act);
+ } else {
+ pr_err("STEP failed: Action is NULL\n");
+ }
+}
+
+void conninfra_step_print_version(void)
+{
+ pr_info("STEP version: %d\n", STEP_VERSION);
+}
+
+/*******************************************************************************
+ * E X T E R N A L F U N C T I O N S
+********************************************************************************/
+
+void conninfra_step_init(void)
+{
+ if (g_infra_step_env.is_enable)
+ return;
+
+ conninfra_step_setup();
+ conninfra_step_init_list();
+ if (conninfra_step_read_file(STEP_CONFIG_NAME) == 0) {
+ conninfra_step_print_version();
+ down_write(&g_infra_step_env.init_rwsem);
+ g_infra_step_env.is_enable = 1;
+ up_write(&g_infra_step_env.init_rwsem);
+ }
+}
+
+void conninfra_step_deinit(void)
+{
+ down_write(&g_infra_step_env.init_rwsem);
+ g_infra_step_env.is_enable = 0;
+ up_write(&g_infra_step_env.init_rwsem);
+ conninfra_step_clear_list();
+ conninfra_step_unioremap_emi();
+ conninfra_step_deinit_pd_env();
+}
+
+void conninfra_step_do_actions(enum consys_conninfra_step_trigger_point tp_id)
+{
+#ifdef CFG_CONNINFRA_STEP
+ conninfra_step_do_actions_from_tp(STEP_DRV_TYPE_CONNINFRA, tp_id, NULL);
+#endif
+}
+
+void consys_step_bt_register(struct consys_step_register_cb *cb)
+{
+#ifdef CFG_CONNINFRA_STEP
+ g_step_drv_type_def[STEP_DRV_TYPE_BT].drv_cb = cb;
+#endif
+}
+
+void consys_step_bt_do_action(enum consys_bt_step_trigger_point tp_id)
+{
+#ifdef CFG_CONNINFRA_STEP
+ conninfra_step_do_actions_from_tp(STEP_DRV_TYPE_BT, tp_id, NULL);
+#endif
+}
+
+void consys_step_wf_register(struct consys_step_register_cb *cb)
+{
+#ifdef CFG_CONNINFRA_STEP
+ g_step_drv_type_def[STEP_DRV_TYPE_WIFI].drv_cb = cb;
+#endif
+}
+
+void consys_step_wf_do_action(enum consys_wf_step_trigger_point tp_id)
+{
+#ifdef CFG_CONNINFRA_STEP
+ conninfra_step_do_actions_from_tp(STEP_DRV_TYPE_WIFI, tp_id, NULL);
+#endif
+}
+
+void consys_step_gps_register(struct consys_step_register_cb *cb)
+{
+#ifdef CFG_CONNINFRA_STEP
+ g_step_drv_type_def[STEP_DRV_TYPE_GPS].drv_cb = cb;
+#endif
+}
+
+void consys_step_gps_do_action(enum consys_gps_step_trigger_point tp_id)
+{
+#ifdef CFG_CONNINFRA_STEP
+ conninfra_step_do_actions_from_tp(STEP_DRV_TYPE_GPS, tp_id, NULL);
+#endif
+}
+
+void consys_step_fm_register(struct consys_step_register_cb *cb)
+{
+#ifdef CFG_CONNINFRA_STEP
+ g_step_drv_type_def[STEP_DRV_TYPE_FM].drv_cb = cb;
+#endif
+}
+
+void consys_step_fm_do_action(enum consys_fm_step_trigger_point tp_id)
+{
+#ifdef CFG_CONNINFRA_STEP
+ conninfra_step_do_actions_from_tp(STEP_DRV_TYPE_FM, tp_id, NULL);
+#endif
+}
+
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/conninfra_step_parse.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/conninfra_step_parse.c
new file mode 100755
index 0000000..fd4d62f
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/conninfra_step_parse.c
@@ -0,0 +1,417 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#include <connectivity_build_in_adapter.h>
+
+#include <linux/firmware.h>
+#include <asm/delay.h>
+#include <linux/slab.h>
+
+#include "osal.h"
+#include "conninfra_step.h"
+#include "conninfra_step_parse_act.h"
+
+/*******************************************************************************
+ * F U N C T I O N D E C L A R A T I O N S
+********************************************************************************/
+
+static int conninfra_step_access_line_state_init(char *tok,
+ struct step_target_act_list_info *p_parse_info,
+ struct step_parse_line_data_param_info *p_parse_line_info);
+static int conninfra_step_access_line_state_tp(char *tok,
+ struct step_target_act_list_info *p_parse_info,
+ struct step_parse_line_data_param_info *p_parse_line_info);
+
+static int conninfra_step_access_line_state_tp_id(char *tok,
+ struct step_target_act_list_info *p_parse_info,
+ struct step_parse_line_data_param_info *p_parse_line_info);
+static int conninfra_step_access_line_state_at(char *tok,
+ struct step_target_act_list_info *p_parse_info,
+ struct step_parse_line_data_param_info *p_parse_line_info);
+static int conninfra_step_access_line_state_at_op(char *tok,
+ struct step_target_act_list_info *p_parse_info,
+ struct step_parse_line_data_param_info *p_parse_line_info);
+static int conninfra_step_access_line_state_pd(char *tok,
+ struct step_target_act_list_info *p_parse_info,
+ struct step_parse_line_data_param_info *p_parse_line_info);
+
+
+/*******************************************************************************
+ * D E F I N E
+********************************************************************************/
+#define STEP_EMI_ACT_INT (int)(*(int *)STEP_ACTION_NAME_EMI)
+#define STEP_REG_ACT_INT (int)(*(int *)STEP_ACTION_NAME_REGISTER)
+#define STEP_GPIO_ACT_INT (int)(*(int *)STEP_ACTION_NAME_GPIO)
+#define STEP_DISABLE_RESET_ACT_INT (int)(*(int *)STEP_ACTION_NAME_DISABLE_RESET)
+#define STEP_CHIP_RESET_ACT_INT (int)(*(int *)STEP_ACTION_NAME_CHIP_RESET)
+#define STEP_KEEP_WAKEUP_ACT_INT (int)(*(int *)STEP_ACTION_NAME_KEEP_WAKEUP)
+#define STEP_CANCEL_KEEP_WAKEUP_ACT_INT (int)(*(int *)STEP_ACTION_NAME_CANCEL_WAKEUP)
+#define STEP_SHOW_STRING_ACT_INT (int)(*(int *)STEP_ACTION_NAME_SHOW_STRING)
+#define STEP_SLEEP_ACT_INT (int)(*(int *)STEP_ACTION_NAME_SLEEP)
+#define STEP_CONDITION_ACT_INT (int)(*(int *)STEP_ACTION_NAME_CONDITION)
+#define STEP_VALUE_ACT_INT (int)(*(int *)STEP_ACTION_NAME_VALUE)
+#define STEP_CONDITION_EMI_ACT_INT (int)(*(int *)STEP_ACTION_NAME_CONDITION_EMI)
+#define STEP_CONDITION_REG_ACT_INT (int)(*(int *)STEP_ACTION_NAME_CONDITION_REGISTER)
+
+#define STEP_PARSE_LINE_STATE_INIT 0
+#define STEP_PARSE_LINE_STATE_TP 1
+#define STEP_PARSE_LINE_STATE_TP_ID 2
+#define STEP_PARSE_LINE_STATE_AT 3
+#define STEP_PARSE_LINE_STATE_AT_OP 4
+#define STEP_PARSE_LINE_STATE_PD_START 5
+#define STEP_PARSE_LINE_STATE_PD_END 6
+
+/*******************************************************************************
+ * P R I V A T E D A T A
+********************************************************************************/
+
+
+typedef int (*STEP_LINE_STATE) (char *,
+ struct step_target_act_list_info *, struct step_parse_line_data_param_info *);
+
+static const STEP_LINE_STATE conninfra_step_line_state_action_map[] = {
+ [STEP_PARSE_LINE_STATE_INIT] = conninfra_step_access_line_state_init,
+ [STEP_PARSE_LINE_STATE_TP] = conninfra_step_access_line_state_tp,
+ [STEP_PARSE_LINE_STATE_TP_ID] = conninfra_step_access_line_state_tp_id,
+ [STEP_PARSE_LINE_STATE_AT] = conninfra_step_access_line_state_at,
+ [STEP_PARSE_LINE_STATE_AT_OP] = conninfra_step_access_line_state_at_op,
+ [STEP_PARSE_LINE_STATE_PD_START] = conninfra_step_access_line_state_pd,
+};
+
+/*******************************************************************************
+ * I N T E R N A L F U N C T I O N S
+********************************************************************************/
+
+#define STEP_PARSE_LINE_RET_CONTINUE 0
+#define STEP_PARSE_LINE_RET_BREAK 1
+
+static void conninfra_step_set_line_state(int *p_state, int value)
+{
+ *p_state = value;
+}
+
+static unsigned char conninfra_step_to_upper(char str)
+{
+ if ((str >= 'a') && (str <= 'z'))
+ return str + ('A' - 'a');
+ else
+ return str;
+}
+
+static void conninfra_step_string_to_upper(char *tok)
+{
+ for (; *tok != '\0'; tok++)
+ *tok = conninfra_step_to_upper(*tok);
+}
+
+static int conninfra_step_get_int_from_four_char(char *str)
+{
+ unsigned char char_array[4];
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (*(str + i) == '\0')
+ return -1;
+
+ char_array[i] = conninfra_step_to_upper(*(str + i));
+ }
+
+ return *(int *)char_array;
+}
+
+
+
+static unsigned int conninfra_step_parse_tp_id(enum step_drv_type drv_type, char *str)
+{
+ long tp_id = STEP_TP_NO_DEFINE;
+
+ if (osal_strtol(str, 10, &tp_id)) {
+ pr_err("STEP failed: str to value %s\n", str);
+ return STEP_TP_NO_DEFINE;
+ }
+ if (tp_id <= STEP_TP_NO_DEFINE || tp_id >= g_step_drv_type_def[drv_type].tp_max)
+ return STEP_TP_NO_DEFINE;
+
+ return tp_id;
+}
+
+
+static int conninfra_step_parse_pd_expires(char *ptr)
+{
+ long expires_ms;
+
+ if (osal_strtol(ptr, 0, &expires_ms))
+ return -1;
+
+ return (int)expires_ms;
+}
+
+static int conninfra_step_parse_act_id(char *str)
+{
+ int str_to_int = STEP_ACTION_INDEX_NO_DEFINE;
+
+ if (str == NULL || str == '\0')
+ return STEP_ACTION_INDEX_NO_DEFINE;
+
+ str_to_int = conninfra_step_get_int_from_four_char(str);
+ if (str_to_int == STEP_EMI_ACT_INT)
+ return STEP_ACTION_INDEX_EMI;
+ else if (str_to_int == STEP_REG_ACT_INT)
+ return STEP_ACTION_INDEX_REGISTER;
+ else if (str_to_int == STEP_GPIO_ACT_INT)
+ return STEP_ACTION_INDEX_GPIO;
+ else if (str_to_int == STEP_SHOW_STRING_ACT_INT)
+ return STEP_ACTION_INDEX_SHOW_STRING;
+ else if (str_to_int == STEP_SLEEP_ACT_INT)
+ return STEP_ACTION_INDEX_SLEEP;
+ else if (str_to_int == STEP_CONDITION_ACT_INT)
+ return STEP_ACTION_INDEX_CONDITION;
+ else if (str_to_int == STEP_VALUE_ACT_INT)
+ return STEP_ACTION_INDEX_VALUE;
+ else if (str_to_int == STEP_CONDITION_EMI_ACT_INT)
+ return STEP_ACTION_INDEX_CONDITION_EMI;
+ else if (str_to_int == STEP_CONDITION_REG_ACT_INT)
+ return STEP_ACTION_INDEX_CONDITION_REGISTER;
+ else
+ return STEP_ACTION_INDEX_NO_DEFINE;
+
+}
+
+
+static int conninfra_step_access_line_state_init(char *tok,
+ struct step_target_act_list_info *p_parse_info,
+ struct step_parse_line_data_param_info *p_parse_line_info)
+{
+ conninfra_step_string_to_upper(tok);
+ if (osal_strcmp(tok, "[TP") == 0) {
+ conninfra_step_set_line_state(&p_parse_line_info->state, STEP_PARSE_LINE_STATE_TP);
+ return STEP_PARSE_LINE_RET_CONTINUE;
+ }
+
+ if (p_parse_info->tp_id == STEP_TP_NO_DEFINE) {
+ pr_err("STEP failed: Set trigger point first: %s\n", tok);
+ return STEP_PARSE_LINE_RET_BREAK;
+ }
+
+ if (osal_strcmp(tok, "[PD+]") == 0) {
+ conninfra_step_set_line_state(&p_parse_line_info->state, STEP_PARSE_LINE_STATE_PD_START);
+ return STEP_PARSE_LINE_RET_CONTINUE;
+ }
+
+ if (osal_strcmp(tok, "[PD-]") == 0) {
+ conninfra_step_set_line_state(&p_parse_line_info->state, STEP_PARSE_LINE_STATE_PD_END);
+ return STEP_PARSE_LINE_RET_BREAK;
+ }
+
+ if (osal_strcmp(tok, "[AT]") == 0) {
+ conninfra_step_set_line_state(&p_parse_line_info->state, STEP_PARSE_LINE_STATE_AT);
+ return STEP_PARSE_LINE_RET_CONTINUE;
+ }
+
+ return STEP_PARSE_LINE_RET_BREAK;
+}
+
+static int conninfra_step_drv_type(char *tok, enum step_drv_type *drv_type)
+{
+ int i;
+ const char *p;
+
+ for (i = 0; i < STEP_DRV_TYPE_MAX; i++) {
+ p = g_step_drv_type_def[i].drv_type_str;
+ if (!strncmp(tok, p, strlen(p))) {
+ *drv_type = (enum step_drv_type)i;
+ return strlen(p);
+ }
+ }
+ return -1;
+}
+
+static int conninfra_step_access_line_state_tp(char *tok,
+ struct step_target_act_list_info *p_parse_info,
+ struct step_parse_line_data_param_info *p_parse_line_info)
+{
+ int ret = 0;
+ enum step_drv_type drv_type = STEP_DRV_TYPE_NO_DEFINE;
+
+ conninfra_step_string_to_upper(tok);
+ if (p_parse_info->p_pd_entry != NULL) {
+ pr_err("STEP failed: Please add [PD-] after [PD+], tok = %s\n", tok);
+ p_parse_info->p_pd_entry = NULL;
+ }
+
+ ret = conninfra_step_drv_type(tok, &drv_type);
+ if (ret <= 0) {
+ pr_err("STEP failed: Trigger point format is wrong: %s\n", tok);
+ return STEP_PARSE_LINE_RET_BREAK;
+ }
+
+ p_parse_info->drv_type = drv_type;
+ conninfra_step_set_line_state(&p_parse_line_info->state, STEP_PARSE_LINE_STATE_TP_ID);
+
+ return STEP_PARSE_LINE_RET_CONTINUE;
+}
+
+static int conninfra_step_access_line_state_tp_id(char *tok,
+ struct step_target_act_list_info *p_parse_info,
+ struct step_parse_line_data_param_info *p_parse_line_info)
+{
+ char *pch;
+ enum step_drv_type drv_type = p_parse_info->drv_type;
+
+ if (p_parse_info->p_pd_entry != NULL) {
+ pr_err("STEP failed: Please add [PD-] after [PD+], tok = %s\n", tok);
+ p_parse_info->p_pd_entry = NULL;
+ }
+
+ pch = osal_strchr(tok, ']');
+ if (pch == NULL) {
+ pr_err("STEP failed: Trigger point format is wrong: %s\n", tok);
+ } else {
+ *pch = '\0';
+ p_parse_info->tp_id = conninfra_step_parse_tp_id(drv_type, tok);
+ p_parse_info->p_target_list = conninfra_step_get_tp_list(drv_type, p_parse_info->tp_id);
+
+ if (p_parse_info->tp_id == STEP_TP_NO_DEFINE)
+ pr_err("STEP failed: Trigger point no define: %s\n", tok);
+ }
+
+ return STEP_PARSE_LINE_RET_BREAK;
+}
+
+static int conninfra_step_access_line_state_at(char *tok,
+ struct step_target_act_list_info *p_parse_info,
+ struct step_parse_line_data_param_info *p_parse_line_info)
+{
+ p_parse_line_info->act_id = conninfra_step_parse_act_id(tok);
+ if (p_parse_line_info->act_id == STEP_ACTION_INDEX_NO_DEFINE) {
+ pr_err("STEP failed: Action no define: %s\n", tok);
+ return STEP_PARSE_LINE_RET_BREAK;
+ }
+ conninfra_step_set_line_state(&p_parse_line_info->state, STEP_PARSE_LINE_STATE_AT_OP);
+
+ return STEP_PARSE_LINE_RET_CONTINUE;
+}
+
+static int conninfra_step_access_line_state_at_op(char *tok,
+ struct step_target_act_list_info *p_parse_info,
+ struct step_parse_line_data_param_info *p_parse_line_info)
+{
+ p_parse_line_info->act_params[p_parse_line_info->param_index] = tok;
+ (p_parse_line_info->param_index)++;
+
+ if (p_parse_line_info->param_index >= STEP_PARAMETER_SIZE) {
+ pr_err("STEP failed: Param too much");
+ return STEP_PARSE_LINE_RET_BREAK;
+ }
+
+ return STEP_PARSE_LINE_RET_CONTINUE;
+}
+
+static int conninfra_step_access_line_state_pd(char *tok,
+ struct step_target_act_list_info *p_parse_info,
+ struct step_parse_line_data_param_info *p_parse_line_info)
+{
+ int pd_ms = -1;
+
+ pd_ms = conninfra_step_parse_pd_expires(tok);
+ if (pd_ms == -1)
+ pr_err("STEP failed: PD ms failed %s\n", tok);
+
+ if (p_parse_info->p_pd_entry != NULL)
+ pr_err("STEP failed: Please add [PD-] after [PD+], tok = %s\n", tok);
+
+ p_parse_info->p_pd_entry = conninfra_step_get_periodic_dump_entry(pd_ms);
+ if (p_parse_info->p_pd_entry == NULL)
+ pr_err("STEP failed: p_pd_entry create fail\n");
+ else
+ p_parse_info->p_target_list = &(p_parse_info->p_pd_entry->action_list);
+
+ return STEP_PARSE_LINE_RET_BREAK;
+}
+
+
+
+
+static void conninfra_step_parse_line_data(char *line, struct step_target_act_list_info *p_parse_info,
+ STEP_WRITE_ACT_TO_LIST func_act_to_list)
+{
+ char *tok;
+ int line_ret = STEP_PARSE_LINE_RET_BREAK;
+ struct step_parse_line_data_param_info parse_line_info;
+
+ parse_line_info.param_index = 0;
+ parse_line_info.act_id = STEP_ACTION_INDEX_NO_DEFINE;
+ parse_line_info.state = STEP_PARSE_LINE_STATE_INIT;
+
+ while ((tok = osal_strsep(&line, " \t")) != NULL) {
+ if (*tok == '\0')
+ continue;
+ if (osal_strcmp(tok, "//") == 0)
+ break;
+
+ if (conninfra_step_line_state_action_map[parse_line_info.state] != NULL) {
+ line_ret = conninfra_step_line_state_action_map[parse_line_info.state] (tok,
+ p_parse_info, &parse_line_info);
+ }
+
+ if (line_ret == STEP_PARSE_LINE_RET_CONTINUE)
+ continue;
+ else
+ break;
+ }
+
+ if (parse_line_info.state == STEP_PARSE_LINE_STATE_AT_OP) {
+ func_act_to_list(p_parse_info->p_target_list, p_parse_info->drv_type,
+ parse_line_info.act_id, parse_line_info.param_index, parse_line_info.act_params);
+ } else if (parse_line_info.state == STEP_PARSE_LINE_STATE_PD_END) {
+ p_parse_info->p_target_list = conninfra_step_get_tp_list(p_parse_info->drv_type, p_parse_info->tp_id);
+ if (p_parse_info->p_pd_entry != NULL) {
+ parse_line_info.act_params[0] = (char*)p_parse_info->p_pd_entry;
+ func_act_to_list(p_parse_info->p_target_list, p_parse_info->drv_type,
+ STEP_ACTION_INDEX_PERIODIC_DUMP, parse_line_info.param_index,
+ parse_line_info.act_params);
+ p_parse_info->p_pd_entry = NULL;
+ }
+ }
+}
+
+
+
+int conninfra_step_parse_data(const char *in_buf, unsigned int size,
+ STEP_WRITE_ACT_TO_LIST func_act_to_list)
+{
+ struct step_target_act_list_info parse_info;
+ char *buf, *tmp_buf;
+ char *line;
+
+ buf = osal_malloc(size + 1);
+ if (!buf) {
+ pr_err("STEP failed: Buf malloc\n");
+ return -1;
+ }
+
+ osal_memcpy(buf, (char *)in_buf, size);
+ buf[size] = '\0';
+
+ parse_info.drv_type = STEP_DRV_TYPE_NO_DEFINE;
+ parse_info.tp_id = STEP_TP_NO_DEFINE;
+ parse_info.p_target_list = NULL;
+ parse_info.p_pd_entry = NULL;
+
+ tmp_buf = buf;
+ while ((line = osal_strsep(&tmp_buf, "\r\n")) != NULL)
+ conninfra_step_parse_line_data(line, &parse_info, func_act_to_list);
+
+ osal_free(buf);
+
+ return 0;
+}
+
+
+
+/*******************************************************************************
+ * I N T E R N A L F U N C T I O N S W I T H U T
+********************************************************************************/
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/conninfra_step_parse_act.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/conninfra_step_parse_act.c
new file mode 100755
index 0000000..d77ab73
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/conninfra_step_parse_act.c
@@ -0,0 +1,781 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#include <connectivity_build_in_adapter.h>
+
+#include <linux/firmware.h>
+#include <asm/delay.h>
+#include <linux/slab.h>
+
+#include "osal.h"
+#include "conninfra_step.h"
+#include "consys_hw.h"
+#include "consys_reg_mng.h"
+
+/*******************************************************************************
+ * F U N C T I O N D E C L A R A T I O N S
+********************************************************************************/
+
+
+/*******************************************************************************
+ * D E F I N E
+********************************************************************************/
+
+/*******************************************************************************
+ * P R I V A T E D A T A
+********************************************************************************/
+
+/*******************************************************************************
+ * I N T E R N A L F U N C T I O N S
+********************************************************************************/
+
+/*************** for debug ************************/
+/*************** for debug ************************/
+
+static int conninfra_step_parse_number_with_symbol(char *ptr, long *value)
+{
+ int ret = STEP_VALUE_INFO_UNKNOWN;
+
+ if (*ptr == '#') {
+ if (osal_strtol(ptr + 1, 10, value)) {
+ pr_err("STEP failed: str to value %s\n", ptr);
+ ret = STEP_VALUE_INFO_UNKNOWN;
+ } else {
+ ret = STEP_VALUE_INFO_SYMBOL_REG_BASE;
+ }
+ } else if (*ptr == '$') {
+ if (osal_strtol(ptr + 1, 10, value)) {
+ pr_err("STEP failed: str to value %s\n", ptr);
+ ret = STEP_VALUE_INFO_UNKNOWN;
+ } else {
+ ret = STEP_VALUE_INFO_SYMBOL_TEMP_REG;
+ }
+ } else {
+ if (osal_strtol(ptr, 0, value)) {
+ pr_err("STEP failed: str to value %s\n", ptr);
+ ret = STEP_VALUE_INFO_UNKNOWN;
+ } else {
+ ret = STEP_VALUE_INFO_NUMBER;
+ }
+ }
+
+ return ret;
+}
+
+static enum step_condition_operator_id conninfra_step_parse_operator_id(char *ptr)
+{
+ if (osal_strcmp(ptr, ">") == 0)
+ return STEP_OPERATOR_GREATER;
+ else if (osal_strcmp(ptr, ">=") == 0)
+ return STEP_OPERATOR_GREATER_EQUAL;
+ else if (osal_strcmp(ptr, "<") == 0)
+ return STEP_OPERATOR_LESS;
+ else if (osal_strcmp(ptr, "<=") == 0)
+ return STEP_OPERATOR_LESS_EQUAL;
+ else if (osal_strcmp(ptr, "==") == 0)
+ return STEP_OPERATOR_EQUAL;
+ else if (osal_strcmp(ptr, "!=") == 0)
+ return STEP_OPERATOR_NOT_EQUAL;
+ else if (osal_strcmp(ptr, "&&") == 0)
+ return STEP_OPERATOR_AND;
+ else if (osal_strcmp(ptr, "||") == 0)
+ return STEP_OPERATOR_OR;
+
+ return STEP_OPERATOR_MAX;
+}
+
+
+
+
+static unsigned int conninfra_step_parse_temp_register_id(char *ptr)
+{
+ unsigned long res;
+ int num_sym;
+
+ num_sym = conninfra_step_parse_number_with_symbol(ptr, &res);
+
+ if (num_sym == STEP_VALUE_INFO_SYMBOL_TEMP_REG)
+ return res;
+ else
+ return STEP_TEMP_REGISTER_SIZE;
+}
+
+static char *conninfra_step_save_params_msg(int num, char *params[], char *buf, int buf_size)
+{
+ int i, len, temp;
+
+ for (i = 0, len = 0; i < num; i++) {
+ if (params[i] == NULL)
+ break;
+
+ temp = osal_strlen(params[i]) + 1;
+
+ if ((len + temp) >= (buf_size - 1))
+ break;
+
+ len += temp;
+ osal_strncat(buf, params[i], temp);
+ osal_strncat(buf, " ", 1);
+ }
+ osal_strncat(buf, "\0", 1);
+
+ return buf;
+}
+
+static int conninfra_step_parse_register_address(struct step_reg_addr_info *p_reg_addr, char *ptr, long offset)
+{
+ unsigned long res;
+ unsigned int symbol;
+ int num_sym;
+
+ num_sym = conninfra_step_parse_number_with_symbol(ptr, &res);
+
+ if (num_sym == STEP_VALUE_INFO_SYMBOL_REG_BASE) {
+ symbol = (unsigned int) res;
+
+ res = consys_reg_mng_validate_idx_n_offset(symbol-1, offset);
+ if (res == 0) {
+ pr_err("STEP failed: validate symbol(%d) and ofsset(%d) fail. %s\n",
+ symbol, offset, ptr);
+ return -1;
+ }
+ res = consys_reg_mng_get_phy_addr_by_idx(symbol - 1);
+ if (res == 0) {
+ pr_err("STEP failed: validate symbol(%d) and ofsset(%d) fail. %s\n",
+ symbol, offset, ptr);
+ return -1;
+ }
+
+ p_reg_addr->address = res;
+ p_reg_addr->address_type = symbol;
+ } else if (num_sym == STEP_VALUE_INFO_NUMBER) {
+ p_reg_addr->address = res;
+ p_reg_addr->address_type = 0;
+ } else {
+ pr_err("STEP failed: number with symbol parse fail %s\n", ptr);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+
+static void conninfra_step_create_emi_output_log(struct step_emi_info *p_emi_info, int write,
+ unsigned int begin, unsigned int end)
+{
+ p_emi_info->is_write = write;
+ p_emi_info->begin_offset = begin;
+ p_emi_info->end_offset = end;
+ p_emi_info->output_mode = STEP_OUTPUT_LOG;
+}
+
+static void conninfra_step_create_emi_output_register(struct step_emi_info *p_emi_info, int write,
+ unsigned int begin, unsigned int mask, unsigned int reg_id)
+{
+ p_emi_info->is_write = write;
+ p_emi_info->begin_offset = begin;
+ p_emi_info->end_offset = begin + 0x4;
+ p_emi_info->mask = mask;
+ p_emi_info->temp_reg_id = reg_id;
+ p_emi_info->output_mode = STEP_OUTPUT_REGISTER;
+}
+
+static int _conninfra_step_create_emi_action(struct step_emi_info *p_emi_info, int param_num, char *params[])
+{
+ long write, begin, end;
+ unsigned int reg_id;
+ char buf[128] = "";
+ long mask = 0xFFFFFFFF;
+
+ if (param_num < 3) {
+ pr_err("STEP failed: Init EMI to log param(%d): %s\n", param_num,
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return -1;
+ }
+
+ if (osal_strtol(params[0], 0, &write) ||
+ osal_strtol(params[1], 0, &begin)) {
+ pr_err("STEP failed: str to value %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return -1;
+ }
+
+ if (*params[(param_num - 1)] == STEP_TEMP_REGISTER_SYMBOL) {
+ reg_id = conninfra_step_parse_temp_register_id(params[(param_num - 1)]);
+ if (reg_id >= STEP_PARAMETER_SIZE) {
+ pr_err("STEP failed: register id failed: %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return -1;
+ }
+
+ if (param_num > 3) {
+ if (osal_strtol(params[2], 0, &mask)) {
+ pr_err("STEP failed: str to value %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return -1;
+ }
+ }
+
+ conninfra_step_create_emi_output_register(p_emi_info, write, begin, mask, reg_id);
+ } else {
+ if (osal_strtol(params[2], 0, &end)) {
+ pr_err("STEP failed: str to value %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return -1;
+ }
+ conninfra_step_create_emi_output_log(p_emi_info, write, begin, end);
+ }
+
+ return 0;
+}
+
+
+/*
+ * Support:
+ * _EMI | R(0) | Begin offset | End offset
+ * _EMI | R(0) | Begin offset | mask | Output temp register ID ($)
+ * _EMI | R(0) | Begin offset | Output temp register ID ($)
+ */
+struct step_action *conninfra_step_create_emi_action(enum step_drv_type drv_type, int param_num, char *params[])
+{
+ struct step_emi_action *p_emi_act = NULL;
+ struct step_emi_info *p_emi_info = NULL;
+ int ret;
+
+ p_emi_act = kzalloc(sizeof(struct step_emi_action), GFP_KERNEL);
+ if (p_emi_act == NULL) {
+ pr_err("STEP failed: kzalloc emi fail\n");
+ return NULL;
+ }
+
+ p_emi_info = &p_emi_act->info;
+ ret = _conninfra_step_create_emi_action(p_emi_info, param_num, params);
+
+ if (ret != 0) {
+ kfree(p_emi_act);
+ return NULL;
+ }
+
+ return &(p_emi_act->base);
+}
+
+static void conninfra_step_create_read_register_output_register(struct step_register_info *p_reg_info,
+ struct step_reg_addr_info reg_addr_info, unsigned int offset, int mask, unsigned int reg_id)
+{
+ p_reg_info->is_write = 0;
+ p_reg_info->address_type = reg_addr_info.address_type;
+ p_reg_info->address = reg_addr_info.address;
+ p_reg_info->offset = offset;
+ p_reg_info->times = 1;
+ p_reg_info->delay_time = 0;
+ p_reg_info->mask = mask;
+ p_reg_info->temp_reg_id = reg_id;
+ p_reg_info->output_mode = STEP_OUTPUT_REGISTER;
+}
+
+static void conninfra_step_create_read_register_output_log(struct step_register_info *p_reg_info,
+ struct step_reg_addr_info reg_addr_info, unsigned int offset, unsigned int times, unsigned int delay_time)
+{
+ p_reg_info->is_write = 0;
+ p_reg_info->address_type = reg_addr_info.address_type;
+ p_reg_info->address = reg_addr_info.address;
+ p_reg_info->offset = offset;
+ p_reg_info->times = times;
+ p_reg_info->delay_time = delay_time;
+ p_reg_info->output_mode = STEP_OUTPUT_LOG;
+}
+
+static void conninfra_step_create_write_register_action(struct step_register_info *p_reg_info,
+ struct step_reg_addr_info reg_addr_info, unsigned int offset, int value, int mask)
+{
+ p_reg_info->is_write = 1;
+ p_reg_info->address_type = reg_addr_info.address_type;
+ p_reg_info->address = reg_addr_info.address;
+ p_reg_info->offset = offset;
+ p_reg_info->value = value;
+ p_reg_info->mask = mask;
+}
+
+static int _conninfra_step_create_register_action(struct step_register_info *p_reg_info,
+ int param_num, char *params[])
+{
+ long write;
+ struct step_reg_addr_info reg_addr_info;
+ long offset, value;
+ unsigned int reg_id = 0;
+ char buf[128] = "";
+ long mask = 0xFFFFFFFF;
+ long times = 1;
+ long delay_time = 0;
+
+ if (param_num < 4) {
+ pr_err("STEP failed: Register no params\n");
+ return -1;
+ }
+
+ if (osal_strtol(params[0], 0, &write)) {
+ pr_err("STEP failed: str to value %s\n",
+ params[0]);
+ return -1;
+ }
+
+ if (osal_strtol(params[2], 0, &offset)) {
+ pr_err("STEP failed: str to value %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return -1;
+ }
+
+ pr_info("[%s] == offset=[%x]", __func__, offset);
+
+ if (conninfra_step_parse_register_address(®_addr_info, params[1], offset) == -1) {
+ pr_err("STEP failed: init write register symbol: %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return -1;
+ }
+
+ if (write == 0) {
+ if (*params[(param_num - 1)] == STEP_TEMP_REGISTER_SYMBOL) {
+ reg_id = conninfra_step_parse_temp_register_id(params[(param_num - 1)]);
+ if (reg_id >= STEP_PARAMETER_SIZE) {
+ pr_err("STEP failed: register id failed: %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return -1;
+ }
+
+ if (param_num > 4) {
+ if (osal_strtol(params[3], 0, &mask)) {
+ pr_err("STEP failed: str to value %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return -1;
+ }
+ }
+
+ conninfra_step_create_read_register_output_register(p_reg_info, reg_addr_info, offset, mask, reg_id);
+ } else {
+ if (param_num < 5 ||
+ osal_strtol(params[3], 0, ×) ||
+ osal_strtol(params[4], 0, &delay_time)) {
+ pr_err("STEP failed: str to value %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return -1;
+ }
+
+ conninfra_step_create_read_register_output_log(p_reg_info, reg_addr_info, offset, times, delay_time);
+ }
+ } else {
+ if (osal_strtol(params[3], 0, &value)) {
+ pr_err("STEP failed: str to value %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return -1;
+ }
+
+ if (param_num > 4) {
+ if (osal_strtol(params[4], 0, &mask)) {
+ pr_err("STEP failed: str to value %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return -1;
+ }
+ }
+
+ conninfra_step_create_write_register_action(p_reg_info, reg_addr_info, offset, value, mask);
+ }
+
+ return 0;
+}
+
+
+/*
+ * Support:
+ * _REG | R(0) | Pre-define base address ID | offset | times | delay time(ms)
+ * _REG | R(0) | AP Physical address | offset | times | delay time(ms)
+ * _REG | R(0) | Pre-define base address ID | offset | mask | Output temp register ID ($)
+ * _REG | R(0) | AP Physical address | offset | mask | Output temp register ID ($)
+ * _REG | R(0) | Pre-define base address ID | offset | Output temp register ID ($)
+ * _REG | R(0) | AP Physical address | offset | Output temp register ID ($)
+ * _REG | W(1) | AP Physical address | offset | value
+ * _REG | W(1) | AP Physical address | offset | value
+ * _REG | W(1) | AP Physical address | offset | value | mask
+ * _REG | W(1) | AP Physical address | offset | value | mask
+ */
+struct step_action *conninfra_step_create_register_action(enum step_drv_type drv_type, int param_num, char *params[])
+{
+ struct step_register_action *p_reg_act = NULL;
+ struct step_register_info *p_reg_info;
+ int ret;
+
+ p_reg_act = kzalloc(sizeof(struct step_register_action), GFP_KERNEL);
+ if (p_reg_act == NULL) {
+ pr_err("STEP failed: kzalloc register fail\n");
+ return NULL;
+ }
+
+ p_reg_info = &p_reg_act->info;
+ ret = _conninfra_step_create_register_action(p_reg_info, param_num, params);
+
+ if (ret != 0) {
+ kfree(p_reg_act);
+ return NULL;
+ }
+ p_reg_info->drv_type = drv_type;
+
+ return &(p_reg_act->base);
+}
+
+
+/*
+ * Support:
+ * GPIO | R(0) | Pin number
+ */
+struct step_action *conninfra_step_create_gpio_action(enum step_drv_type drv_type, int param_num, char *params[])
+{
+ struct step_gpio_action *p_gpio_act = NULL;
+ long write, symbol;
+ char buf[128] = "";
+
+ if (param_num != 2) {
+ pr_err("STEP failed: init gpio param(%d): %s\n", param_num,
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return NULL;
+ }
+
+ if (osal_strtol(params[0], 0, &write) ||
+ osal_strtol(params[1], 0, &symbol)) {
+ pr_err("STEP failed: str to value %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return NULL;
+ }
+
+ p_gpio_act = kzalloc(sizeof(struct step_gpio_action), GFP_KERNEL);
+ if (p_gpio_act == NULL) {
+ pr_err("STEP failed: kzalloc gpio fail\n");
+ return NULL;
+ }
+ p_gpio_act->is_write = write;
+ p_gpio_act->pin_symbol = symbol;
+
+ return &(p_gpio_act->base);
+}
+
+#if 0
+/*
+ * Support:
+ * _RST
+ */
+struct step_action *conninfra_step_create_chip_reset_action(int param_num, char *params[])
+{
+ struct step_chip_reset_action *p_crst_act = NULL;
+
+ p_crst_act = kzalloc(sizeof(struct step_chip_reset_action), GFP_KERNEL);
+ if (p_crst_act == NULL) {
+ pr_err("STEP failed: kzalloc chip reset fail\n");
+ return NULL;
+ }
+
+ return &(p_crst_act->base);
+}
+#endif
+
+/*
+ * Support:
+ * [PD+] | ms
+ */
+struct step_action *conninfra_step_create_periodic_dump_action(enum step_drv_type drv_type, int param_num, char *params[])
+{
+ struct step_periodic_dump_action *p_pd_act = NULL;
+
+ if (params[0] == NULL) {
+ pr_err("STEP failed: param null\n");
+ return NULL;
+ }
+
+ p_pd_act = kzalloc(sizeof(struct step_periodic_dump_action), GFP_KERNEL);
+ if (p_pd_act == NULL) {
+ pr_err("STEP failed: kzalloc fail\n");
+ return NULL;
+ }
+
+ p_pd_act->pd_entry = (struct step_pd_entry *)params[0];
+ return &(p_pd_act->base);
+}
+
+/*
+ * Support:
+ * SHOW | Message (no space)
+ */
+struct step_action *conninfra_step_create_show_string_action(enum step_drv_type drv_type, int param_num, char *params[])
+{
+ struct step_show_string_action *p_show_act = NULL;
+ char buf[128] = "";
+
+ if (param_num != 1) {
+ pr_err("STEP failed: init show param(%d): %s\n", param_num,
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return NULL;
+ }
+
+ p_show_act = kzalloc(sizeof(struct step_show_string_action), GFP_KERNEL);
+ if (p_show_act == NULL) {
+ pr_err("STEP failed: kzalloc show string fail\n");
+ return NULL;
+ }
+
+ p_show_act->content = kzalloc((osal_strlen(params[0]) + 1), GFP_KERNEL);
+ if (p_show_act->content == NULL) {
+ pr_err("STEP failed: kzalloc show string content fail\n");
+ kfree(p_show_act);
+ return NULL;
+ }
+ osal_memcpy(p_show_act->content, params[0], osal_strlen(params[0]));
+ return &(p_show_act->base);
+}
+
+/*
+ * Support:
+ * _SLP | time (ms)
+ */
+struct step_action *conninfra_step_create_sleep_action(enum step_drv_type drv_type, int param_num, char *params[])
+{
+ struct step_sleep_action *p_sleep_act = NULL;
+ long ms;
+ char buf[128] = "";
+
+ if (param_num != 1) {
+ pr_err("STEP failed: init sleep param(%d): %s\n", param_num,
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return NULL;
+ }
+
+ if (osal_strtol(params[0], 0, &ms)) {
+ pr_err("STEP failed: str to value %s\n",
+ params[0]);
+ return NULL;
+ }
+
+ p_sleep_act = kzalloc(sizeof(struct step_sleep_action), GFP_KERNEL);
+ if (p_sleep_act == NULL) {
+ pr_err("STEP failed: kzalloc sleep fail\n");
+ return NULL;
+ }
+ p_sleep_act->ms = ms;
+
+ return &(p_sleep_act->base);
+}
+
+/*
+ * Support:
+ * COND | Check temp register ID ($) | Left temp register ID ($) | Operator | Right temp register ID ($)
+ * COND | Check temp register ID ($) | Left temp register ID ($) | Operator | value
+ */
+struct step_action *conninfra_step_create_condition_action(enum step_drv_type drv_type, int param_num, char *params[])
+{
+ struct step_condition_action *p_cond_act = NULL;
+ unsigned int res_reg_id, l_reg_id, r_reg_id = 0;
+ long value = 0;
+ int mode;
+ enum step_condition_operator_id op_id;
+ char buf[128] = "";
+
+ if (param_num != 4) {
+ pr_err("STEP failed: init sleep param(%d): %s\n", param_num,
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return NULL;
+ }
+
+ res_reg_id = conninfra_step_parse_temp_register_id(params[0]);
+ l_reg_id = conninfra_step_parse_temp_register_id(params[1]);
+ if (res_reg_id >= STEP_PARAMETER_SIZE || l_reg_id >= STEP_PARAMETER_SIZE) {
+ pr_err("STEP failed: register id failed: %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return NULL;
+ }
+
+ op_id = conninfra_step_parse_operator_id(params[2]);
+ if (op_id >= STEP_OPERATOR_MAX) {
+ pr_err("STEP failed: operator id failed: %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return NULL;
+ }
+
+ if (*params[(param_num - 1)] == STEP_TEMP_REGISTER_SYMBOL) {
+ r_reg_id = conninfra_step_parse_temp_register_id(params[3]);
+ mode = STEP_CONDITION_RIGHT_REGISTER;
+ if (r_reg_id >= STEP_PARAMETER_SIZE) {
+ pr_err("STEP failed: register id failed: %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return NULL;
+ }
+ } else {
+ if (osal_strtol(params[3], 0, &value)) {
+ pr_err("STEP failed: str to value %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return NULL;
+ }
+ mode = STEP_CONDITION_RIGHT_VALUE;
+ }
+
+ p_cond_act = kzalloc(sizeof(struct step_condition_action), GFP_KERNEL);
+ if (p_cond_act == NULL) {
+ pr_err("STEP failed: kzalloc condition fail\n");
+ return NULL;
+ }
+
+ p_cond_act->result_temp_reg_id = res_reg_id;
+ p_cond_act->l_temp_reg_id = l_reg_id;
+ p_cond_act->operator_id = op_id;
+ p_cond_act->r_temp_reg_id = r_reg_id;
+ p_cond_act->value = value;
+ p_cond_act->mode = mode;
+
+ return &(p_cond_act->base);
+}
+
+/*
+ * Support:
+ * _VAL | Save temp register ID ($) | Value
+ */
+struct step_action *conninfra_step_create_value_action(enum step_drv_type drv_type, int param_num, char *params[])
+{
+ struct step_value_action *p_val_act = NULL;
+ unsigned int reg_id;
+ long value;
+ char buf[128] = "";
+
+ if (param_num != 2) {
+ pr_err("STEP failed: init sleep param(%d): %s\n", param_num,
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return NULL;
+ }
+
+ reg_id = conninfra_step_parse_temp_register_id(params[0]);
+ if (reg_id >= STEP_PARAMETER_SIZE) {
+ pr_err("STEP failed: register id failed: %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return NULL;
+ }
+
+ if (osal_strtol(params[1], 0, &value)) {
+ pr_err("STEP failed: str to value %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return NULL;
+ }
+
+ p_val_act = kzalloc(sizeof(struct step_value_action), GFP_KERNEL);
+ if (p_val_act == NULL) {
+ pr_err("STEP failed: kzalloc value fail\n");
+ return NULL;
+ }
+
+ p_val_act->temp_reg_id = reg_id;
+ p_val_act->value = value;
+
+ return &(p_val_act->base);
+}
+
+/*
+ * Support:
+ * CEMI | Check temp register ID (#) | R(0) | Begin offset | End offset
+ * CEMI | Check temp register ID (#) | R(0) | Begin offset | mask | Output temp register ID ($)
+ * CEMI | Check temp register ID (#) | R(0) | Begin offset | Output temp register ID ($)
+ */
+struct step_action *conninfra_step_create_condition_emi_action(enum step_drv_type drv_type, int param_num, char *params[])
+{
+ struct step_condition_emi_action *p_cond_emi_act = NULL;
+ struct step_emi_info *p_emi_info = NULL;
+ unsigned int reg_id;
+ char buf[128] = "";
+ int ret;
+
+ if (param_num < 1) {
+ pr_err("STEP failed: EMI no params\n");
+ return NULL;
+ }
+
+ reg_id = conninfra_step_parse_temp_register_id(params[0]);
+ if (reg_id >= STEP_PARAMETER_SIZE) {
+ pr_err("STEP failed: condition register id failed: %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return NULL;
+ }
+
+ p_cond_emi_act = kzalloc(sizeof(struct step_condition_emi_action), GFP_KERNEL);
+ if (p_cond_emi_act == NULL) {
+ pr_err("STEP failed: kzalloc condition emi fail\n");
+ return NULL;
+ }
+
+ p_emi_info = &p_cond_emi_act->info;
+ p_cond_emi_act->cond_reg_id = reg_id;
+ ret = _conninfra_step_create_emi_action(p_emi_info, param_num - 1, ¶ms[1]);
+
+ if (ret != 0) {
+ kfree(p_cond_emi_act);
+ return NULL;
+ }
+
+ return &(p_cond_emi_act->base);
+}
+
+/*
+ * Support:
+ * CREG | Check temp register ID (#) | R(0) | Pre-define base address ID | offset | times | delay time(ms)
+ * CREG | Check temp register ID (#) | R(0) | AP Physical address | offset | times | delay time(ms)
+ * CREG | Check temp register ID (#) | R(0) | Pre-define base address ID | offset | mask | Output temp register ID ($)
+ * CREG | Check temp register ID (#) | R(0) | AP Physical address | offset | mask | Output temp register ID ($)
+ * CREG | Check temp register ID (#) | R(0) | Pre-define base address ID | offset | Output temp register ID ($)
+ * CREG | Check temp register ID (#) | R(0) | AP Physical address | offset | Output temp register ID ($)
+ * CREG | Check temp register ID (#) | W(1) | AP Physical address | offset | value
+ * CREG | Check temp register ID (#) | W(1) | AP Physical address | offset | value
+ * CREG | Check temp register ID (#) | W(1) | AP Physical address | offset | value | mask
+ * CREG | Check temp register ID (#) | W(1) | AP Physical address | offset | value | mask
+ */
+struct step_action *conninfra_step_create_condition_register_action(enum step_drv_type drv_type, int param_num, char *params[])
+{
+ struct step_condition_register_action *p_cond_reg_act = NULL;
+ struct step_register_info *p_reg_info;
+ unsigned int reg_id;
+ char buf[128] = "";
+ int ret;
+
+ if (param_num < 0) {
+ pr_err("STEP failed: Init EMI param(%d): %s\n", param_num,
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return NULL;
+ }
+
+ reg_id = conninfra_step_parse_temp_register_id(params[0]);
+ if (reg_id >= STEP_PARAMETER_SIZE) {
+ pr_err("STEP failed: condition register id failed: %s\n",
+ conninfra_step_save_params_msg(param_num, params, buf, 128));
+ return NULL;
+ }
+
+ p_cond_reg_act = kzalloc(sizeof(struct step_condition_register_action), GFP_KERNEL);
+ if (p_cond_reg_act == NULL) {
+ pr_err("STEP failed: kzalloc condition register fail\n");
+ return NULL;
+ }
+
+ p_reg_info = &p_cond_reg_act->info;
+ p_cond_reg_act->cond_reg_id = reg_id;
+ ret = _conninfra_step_create_register_action(p_reg_info, param_num - 1, ¶ms[1]);
+
+ if (ret != 0) {
+ kfree(p_cond_reg_act);
+ return NULL;
+ }
+
+ p_reg_info->drv_type = drv_type;
+
+ return &(p_cond_reg_act->base);
+}
+
+
+
+/*******************************************************************************
+ * I N T E R N A L F U N C T I O N S W I T H U T
+********************************************************************************/
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/include/conninfra_step.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/include/conninfra_step.h
new file mode 100755
index 0000000..16f55ba
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/include/conninfra_step.h
@@ -0,0 +1,304 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#ifndef _CONNINFRA_STEP_H_
+#define _CONNINFRA_STEP_H_
+
+#include <linux/list.h>
+#include <linux/workqueue.h>
+#include <linux/rwsem.h>
+#include "connsys_step.h"
+#include "conninfra_step_base.h"
+#include "conninfra.h"
+#include "consys_hw.h"
+
+#define STEP_CONFIG_NAME "CONNINFRA_STEP.cfg"
+#define STEP_VERSION 2
+
+#define STEP_PERIODIC_DUMP_WORK_QUEUE "conninfra_step_pd_wq"
+
+#define STEP_ACTION_NAME_EMI "_EMI"
+#define STEP_ACTION_NAME_REGISTER "_REG"
+#define STEP_ACTION_NAME_GPIO "GPIO"
+#define STEP_ACTION_NAME_DISABLE_RESET "DRST"
+#define STEP_ACTION_NAME_CHIP_RESET "_RST"
+#define STEP_ACTION_NAME_KEEP_WAKEUP "WAK+"
+#define STEP_ACTION_NAME_CANCEL_WAKEUP "WAK-"
+#define STEP_ACTION_NAME_SHOW_STRING "SHOW"
+#define STEP_ACTION_NAME_SLEEP "_SLP"
+#define STEP_ACTION_NAME_CONDITION "COND"
+#define STEP_ACTION_NAME_VALUE "_VAL"
+#define STEP_ACTION_NAME_CONDITION_EMI "CEMI"
+#define STEP_ACTION_NAME_CONDITION_REGISTER "CREG"
+
+enum consys_conninfra_step_trigger_point {
+ STEP_CONNINFRA_TP_NO_DEFINE = STEP_TP_NO_DEFINE,
+ /* CONNINFRA TRIGGER POINT */
+ STEP_CONNINFRA_TP_BEFORE_CHIP_RESET,
+ STEP_CONNINFRA_TP_AFTER_CHIP_RESET,
+ /* thermal */
+ STEP_CONNINFRA_TP_BEFORE_READ_THERMAL,
+ /* power on sequence */
+ STEP_CONNINFRA_TP_POWER_ON_START,
+ STEP_CONNINFRA_TP_POWER_ON_BEFORE_GET_CONNSYS_ID, /* 5 */
+ STEP_CONNINFRA_TP_POWER_ON_END,
+ /* power off */
+ STEP_CONNINFRA_TP_BEFORE_POWER_OFF,
+ /* Suspend/Resume */
+ STEP_CONNINFRA_TP_WHEN_AP_SUSPEND,
+ STEP_CONNINFRA_TP_WHEN_AP_RESUME, /* 9 */
+
+ STEP_CONNINFRA_TP_MAX,
+};
+
+
+/********* action ***********/
+
+struct step_action_list {
+ struct list_head list;
+};
+
+struct step_action {
+ struct list_head list;
+ enum step_action_id action_id;
+};
+
+
+/********** pd *****************/
+struct step_pd_entry {
+ bool is_enable;
+ unsigned int expires_ms;
+ struct step_action_list action_list;
+ struct delayed_work pd_work;
+ struct list_head list;
+};
+
+struct step_pd_struct {
+ bool is_init;
+ struct workqueue_struct *step_pd_wq;
+ struct list_head pd_list;
+};
+
+typedef int (*STEP_WRITE_ACT_TO_LIST) (struct step_action_list *, enum step_drv_type, enum step_action_id, int, char **);
+typedef void (*STEP_DO_EXTRA) (unsigned int, ...);
+
+#define STEP_OUTPUT_LOG 0
+#define STEP_OUTPUT_REGISTER 1
+
+
+/****************** ACTION *****************/
+struct step_emi_info {
+ bool is_write;
+ unsigned int begin_offset;
+ unsigned int end_offset;
+ int value;
+ unsigned int temp_reg_id;
+ int output_mode;
+ int mask;
+};
+
+struct step_emi_action {
+ struct step_emi_info info;
+ struct step_action base;
+};
+
+struct step_register_info {
+ enum step_drv_type drv_type;
+ bool is_write;
+ unsigned int address_type;
+ unsigned long address;
+ unsigned int offset;
+ unsigned int times;
+ unsigned int delay_time;
+ int value;
+ int mask;
+ unsigned int temp_reg_id;
+ int output_mode;
+};
+
+struct step_register_action {
+ struct step_register_info info;
+ struct step_action base;
+};
+
+struct step_gpio_action {
+ bool is_write;
+ unsigned int pin_symbol;
+ struct step_action base;
+};
+
+struct step_periodic_dump_action {
+ struct step_pd_entry *pd_entry;
+ struct step_action base;
+};
+
+struct step_show_string_action {
+ char *content;
+ struct step_action base;
+};
+
+struct step_sleep_action {
+ unsigned int ms;
+ struct step_action base;
+};
+
+#define STEP_CONDITION_RIGHT_REGISTER 0
+#define STEP_CONDITION_RIGHT_VALUE 1
+struct step_condition_action {
+ unsigned int result_temp_reg_id;
+ unsigned int l_temp_reg_id;
+ unsigned int r_temp_reg_id;
+ int value;
+ int mode;
+ enum step_condition_operator_id operator_id;
+ struct step_action base;
+};
+
+struct step_value_action {
+ unsigned int temp_reg_id;
+ int value;
+ struct step_action base;
+};
+
+struct step_condition_emi_action {
+ unsigned int cond_reg_id;
+ struct step_emi_info info;
+ struct step_action base;
+};
+
+struct step_condition_register_action {
+ unsigned int cond_reg_id;
+ struct step_register_info info;
+ struct step_action base;
+};
+
+#define clist_entry_action(act_struct, ptr) \
+ container_of(ptr, struct step_##act_struct##_action, base)
+
+struct step_reg_addr_info {
+ int address_type;
+ unsigned long address;
+};
+
+/************************* PARSE *************************/
+struct step_target_act_list_info {
+ enum step_drv_type drv_type;
+ //enum consys_step_trigger_point_id tp_id;
+ unsigned int tp_id;
+ struct step_action_list *p_target_list;
+ struct step_pd_entry *p_pd_entry;
+};
+
+#define STEP_PARAMETER_SIZE 10
+struct step_parse_line_data_param_info {
+ int state;
+ enum step_action_id act_id;
+ char *act_params[STEP_PARAMETER_SIZE];
+ int param_index;
+};
+
+typedef struct step_action *(*STEP_CREATE_ACTION) (enum step_drv_type, int, char *[]);
+typedef int (*STEP_DO_ACTIONS) (struct step_action *, STEP_DO_EXTRA);
+typedef void (*STEP_REMOVE_ACTION) (struct step_action *);
+struct step_action_contrl {
+ STEP_CREATE_ACTION func_create_action;
+ STEP_DO_ACTIONS func_do_action;
+ STEP_REMOVE_ACTION func_remove_action;
+};
+
+struct step_drv_type_def {
+ const char* drv_type_str;
+ int tp_max;
+ struct consys_step_register_cb *drv_cb;
+ struct step_action_list *action_list;
+};
+extern struct step_drv_type_def g_step_drv_type_def[STEP_DRV_TYPE_MAX];
+
+
+#define STEP_REGISTER_BASE_SYMBOL '#'
+#define STEP_TEMP_REGISTER_SYMBOL '$'
+
+#define STEP_VALUE_INFO_UNKNOWN -1
+#define STEP_VALUE_INFO_NUMBER 0
+#define STEP_VALUE_INFO_SYMBOL_REG_BASE 1
+#define STEP_VALUE_INFO_SYMBOL_TEMP_REG 2
+
+#define STEP_TEMP_REGISTER_SIZE 10
+struct step_env_struct {
+ bool is_enable;
+ bool is_keep_wakeup;
+ //struct step_action_list actions[STEP_DRV_TYPE_MAX][STEP_TRIGGER_POINT_MAX];
+ struct step_action_list conninfra_actions[STEP_CONNINFRA_TP_MAX];
+ struct step_action_list wf_actions[STEP_WF_TP_MAX];
+ struct step_action_list bt_actions[STEP_BT_TP_MAX];
+ struct step_action_list gps_actions[STEP_GPS_TP_MAX];
+ struct step_action_list fm_actions[STEP_FM_TP_MAX];
+
+ unsigned char __iomem *emi_base_addr;
+ unsigned int emi_size;
+
+ struct step_pd_struct pd_struct;
+ int temp_register[STEP_TEMP_REGISTER_SIZE];
+ bool is_setup;
+ struct rw_semaphore init_rwsem;
+};
+
+/********************************************************************************
+ * F U N C T I O N D E C L A R A T I O N S
+*********************************************************************************/
+void conninfra_step_init(void);
+void conninfra_step_deinit(void);
+
+void conninfra_step_do_actions(enum consys_conninfra_step_trigger_point tp_id);
+void conninfra_step_func_crtl_do_actions(enum consys_drv_type type, enum step_func_event_id opId);
+
+#ifdef CFG_CONNINFRA_STEP
+#define CONNINFRA_STEP_INIT_FUNC() conninfra_step_init()
+#define CONNINFRA_STEP_DEINIT_FUNC() conninfra_step_deinit()
+#define CONNINFRA_STEP_DO_ACTIONS_FUNC(tp) conninfra_step_do_actions(tp)
+#define CONNINFRA_STEP_FUNC_CTRL_DO_ACTIONS_FUNC(type, id) conninfra_step_func_crtl_do_actions(type, id)
+//#define conninfra_STEP_COMMAND_TIMEOUT_DO_ACTIONS_FUNC(reason) conninfra_step_command_timeout_do_actions(reason)
+
+#else
+#define CONNINFRA_STEP_INIT_FUNC()
+#define CONNINFRA_STEP_DEINIT_FUNC()
+#define CONNINFRA_STEP_DO_ACTIONS_FUNC(tp)
+#define CONNINFRA_STEP_FUNC_CTRL_DO_ACTIONS_FUNC(type, id)
+#define CONNINFRA_STEP_COMMAND_TIMEOUT_DO_ACTIONS_FUNC(reason)
+#endif
+
+/********************************************************************************
+ * D E C L A R E F O R T E S T
+*********************************************************************************/
+int conninfra_step_read_file(const char *file_name);
+int conninfra_step_parse_data(const char *in_buf, unsigned int size, STEP_WRITE_ACT_TO_LIST func_act_to_list);
+
+int conninfra_step_init_pd_env(void);
+int conninfra_step_deinit_pd_env(void);
+
+
+struct step_action_list *conninfra_step_get_tp_list(enum step_drv_type, int tp_id);
+
+struct step_pd_entry *conninfra_step_get_periodic_dump_entry(unsigned int expires);
+struct step_action *conninfra_step_create_action(enum step_drv_type drv_type, enum step_action_id act_id, int param_num, char *params[]);
+int conninfra_step_do_emi_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra);
+int conninfra_step_do_register_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra);
+int conninfra_step_do_gpio_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra);
+
+int conninfra_step_do_periodic_dump_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra);
+int conninfra_step_do_show_string_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra);
+int conninfra_step_do_sleep_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra);
+int conninfra_step_do_condition_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra);
+int conninfra_step_do_value_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra);
+int conninfra_step_do_condition_emi_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra);
+int conninfra_step_do_condition_register_action(struct step_action *p_act, STEP_DO_EXTRA func_do_extra);
+void conninfra_step_remove_action(struct step_action *p_act);
+void conninfra_step_print_version(void);
+
+void conninfra_step_do_actions_from_tp(enum step_drv_type drv_type,
+ unsigned int tp_id, char *reason);
+
+#endif /* end of _CONNINFRA_STEP_H_ */
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/include/conninfra_step_base.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/include/conninfra_step_base.h
new file mode 100755
index 0000000..4b1520a
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/include/conninfra_step_base.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#ifndef _CONNINFRA_STEP_BASE_H_
+#define _CONNINFRA_STEP_BASE_H_
+
+enum step_drv_type {
+ STEP_DRV_TYPE_NO_DEFINE = 0,
+ STEP_DRV_TYPE_CONNINFRA,
+ STEP_DRV_TYPE_BT,
+ STEP_DRV_TYPE_FM,
+ STEP_DRV_TYPE_GPS,
+ STEP_DRV_TYPE_WIFI,
+
+ STEP_DRV_TYPE_MAX,
+};
+
+enum step_func_event_id {
+ STEP_FUNC_OFF = 0,
+ STEP_FUNC_ON
+};
+
+enum step_condition_operator_id {
+ STEP_OPERATOR_GREATER = 0,
+ STEP_OPERATOR_GREATER_EQUAL,
+ STEP_OPERATOR_LESS,
+ STEP_OPERATOR_LESS_EQUAL,
+ STEP_OPERATOR_EQUAL,
+ STEP_OPERATOR_NOT_EQUAL,
+ STEP_OPERATOR_AND,
+ STEP_OPERATOR_OR,
+ STEP_OPERATOR_MAX,
+};
+
+
+
+enum step_action_id {
+ STEP_ACTION_INDEX_NO_DEFINE = 0,
+ STEP_ACTION_INDEX_EMI = 1,
+ STEP_ACTION_INDEX_REGISTER,
+ STEP_ACTION_INDEX_GPIO,
+ STEP_ACTION_INDEX_PERIODIC_DUMP,
+ STEP_ACTION_INDEX_SHOW_STRING,
+ STEP_ACTION_INDEX_SLEEP,
+ STEP_ACTION_INDEX_CONDITION,
+ STEP_ACTION_INDEX_VALUE,
+ STEP_ACTION_INDEX_CONDITION_EMI,
+ STEP_ACTION_INDEX_CONDITION_REGISTER,
+ STEP_ACTION_INDEX_MAX,
+};
+
+
+#endif /* end of _CONNINFRA_STEP_BASE_H_ */
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/include/conninfra_step_parse_act.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/include/conninfra_step_parse_act.h
new file mode 100755
index 0000000..3bf9a3c
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/debug_utility/step/include/conninfra_step_parse_act.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#ifndef _CONNINFRA_STEP_PARSE_ACT_H_
+#define _CONNINFRA_STEP_PARSE_ACT_H_
+
+#include "conninfra_step_base.h"
+
+
+struct step_action *conninfra_step_create_emi_action(enum step_drv_type drv_type, int param_num, char *params[]);
+struct step_action *conninfra_step_create_register_action(enum step_drv_type drv_type, int param_num, char *params[]);
+struct step_action *conninfra_step_create_gpio_action(enum step_drv_type drv_type, int param_num, char *params[]);
+
+struct step_action *conninfra_step_create_periodic_dump_action(enum step_drv_type drv_type, int param_num, char *params[]);
+struct step_action *conninfra_step_create_show_string_action(enum step_drv_type drv_type, int param_num, char *params[]);
+struct step_action *conninfra_step_create_sleep_action(enum step_drv_type drv_type, int param_num, char *params[]);
+struct step_action *conninfra_step_create_condition_action(enum step_drv_type drv_type, int param_num, char *params[]);
+struct step_action *conninfra_step_create_value_action(enum step_drv_type drv_type, int param_num, char *params[]);
+struct step_action *conninfra_step_create_condition_emi_action(enum step_drv_type drv_type, int param_num, char *params[]);
+struct step_action *conninfra_step_create_condition_register_action(enum step_drv_type drv_type, int param_num, char *params[]);
+
+
+#endif /* end of _CONNINFRA_STEP_PARSE_ACT_H_ */
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/include/conninfra.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/include/conninfra.h
new file mode 100755
index 0000000..c43bfb2
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/include/conninfra.h
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _CONNINFRA_H_
+#define _CONNINFRA_H_
+
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+enum consys_drv_type {
+ CONNDRV_TYPE_BT = 0,
+ CONNDRV_TYPE_FM = 1,
+ CONNDRV_TYPE_GPS = 2,
+ CONNDRV_TYPE_WIFI = 3,
+ CONNDRV_TYPE_CONNINFRA = 4,
+ CONNDRV_TYPE_MAX
+};
+
+/* Only for several project: MT6885 */
+enum consys_adie_ctl_type {
+ CONNSYS_ADIE_CTL_HOST_BT,
+ CONNSYS_ADIE_CTL_HOST_FM,
+ CONNSYS_ADIE_CTL_HOST_GPS,
+ CONNSYS_ADIE_CTL_HOST_WIFI,
+ CONNSYS_ADIE_CTL_HOST_CONNINFRA,
+ CONNSYS_ADIE_CTL_FW_BT,
+ CONNSYS_ADIE_CTL_FW_WIFI,
+ CONNSYS_ADIE_CTL_MAX
+};
+
+/* HW-specific, need sync with FW. DO NOT MODIFY */
+enum sys_spi_subsystem
+{
+ SYS_SPI_WF1 = 0x00,
+ SYS_SPI_WF = 0x01,
+ SYS_SPI_BT = 0x02,
+ SYS_SPI_FM = 0x03,
+ SYS_SPI_GPS = 0x04,
+ SYS_SPI_TOP = 0x05,
+ SYS_SPI_WF2 = 0x06,
+ SYS_SPI_WF3 = 0x07,
+ SYS_SPI_MAX
+};
+
+enum connsys_spi_speed_type {
+ CONNSYS_SPI_SPEED_26M,
+ CONNSYS_SPI_SPEED_64M,
+ CONNSYS_SPI_SPEED_MAX
+};
+
+enum connsys_clock_schematic
+{
+ CONNSYS_CLOCK_SCHEMATIC_26M_COTMS = 0,
+ CONNSYS_CLOCK_SCHEMATIC_52M_COTMS,
+ CONNSYS_CLOCK_SCHEMATIC_26M_EXTCXO,
+
+ CONNSYS_CLOCK_SCHEMATIC_MAX,
+};
+
+/* Conninfra driver allocate EMI for FW and WFDAM
+ * (FW includes: BT, WIFI and their MCU)
+ * +-----------+ +
+ * | | |
+ * | FW | |
+ * | | |
+ * +-----------+ v
+ * | |
+ * | | FW_WFDMA
+ * | | ^
+ * | WFDMA | |
+ * | | |
+ * | | |
+ * +-----------+ +
+ *
+ * MCIF region is provided by MD
+ * +-----------+
+ * | |
+ * | |
+ * | MCIF |
+ * | |
+ * +-----------+
+ */
+enum connsys_emi_type
+{
+ CONNSYS_EMI_FW_WFDMA = 0,
+ CONNSYS_EMI_FW,
+ CONNSYS_EMI_WFDMA,
+ CONNSYS_EMI_MCIF,
+
+ CONNSYS_EMI_MAX,
+};
+
+#define CONNINFRA_SPI_OP_FAIL 0x1
+
+#define CONNINFRA_CB_RET_CAL_PASS_POWER_OFF 0x0
+#define CONNINFRA_CB_RET_CAL_PASS_POWER_ON 0x2
+#define CONNINFRA_CB_RET_CAL_FAIL_POWER_OFF 0x1
+#define CONNINFRA_CB_RET_CAL_FAIL_POWER_ON 0x3
+
+#define CONNINFRA_BUS_CLOCK_WPLL 0x1
+#define CONNINFRA_BUS_CLOCK_BPLL 0x2
+#define CONNINFRA_BUS_CLOCK_ALL 0x3
+
+/* bus hang error define */
+#define CONNINFRA_INFRA_BUS_HANG 0x1
+#define CONNINFRA_AP2CONN_RX_SLP_PROT_ERR 0x2
+#define CONNINFRA_AP2CONN_TX_SLP_PROT_ERR 0x4
+#define CONNINFRA_AP2CONN_CLK_ERR 0x8
+#define CONNINFRA_INFRA_BUS_HANG_IRQ 0x10
+
+#define CONNINFRA_ERR_RST_ONGOING -0x7788
+#define CONNINFRA_ERR_WAKEUP_FAIL -0x5566
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+/* Conninfra bus clock control */
+int conninfra_bus_clock_ctrl(enum consys_drv_type drv_type, unsigned int bus_clock, int status);
+/* Clock schematic query */
+int conninfra_get_clock_schematic(void);
+
+/* SPI clock switch */
+int conninfra_spi_clock_switch(enum connsys_spi_speed_type type);
+
+/* A-die top_ck_en control, only for MT6885 */
+int conninfra_adie_top_ck_en_on(enum consys_adie_ctl_type type);
+int conninfra_adie_top_ck_en_off(enum consys_adie_ctl_type type);
+
+/* RFSPI */
+int conninfra_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data);
+int conninfra_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data);
+
+/* EMI */
+void conninfra_get_phy_addr(unsigned int *addr, unsigned int *size);
+void conninfra_get_emi_phy_addr(enum connsys_emi_type type, phys_addr_t* base, unsigned int *size);
+
+/* power on/off */
+int conninfra_pwr_on(enum consys_drv_type drv_type);
+int conninfra_pwr_off(enum consys_drv_type drv_type);
+
+/* To setup config relative data, ex: debug flag */
+void conninfra_config_setup(void);
+
+/* reg */
+/*
+ * 1 : can read
+ * 0 : can't read
+ */
+int conninfra_reg_readable(void);
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
+/* reg readable */
+/* THIS API SHOULD NOT USED IN NORMAL CASE */
+/* IF YOU NEED THIS, PLEASE DISCUSS WITH OWNER */
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
+int conninfra_reg_readable_no_lock(void);
+/*
+ * 0 : NO hang
+ * > 0 : HANG!!
+ * CONNINFRA_ERR_RST_ONGOING: whole chip reset is ongoing
+ */
+int conninfra_is_bus_hang(void);
+
+/* chip reset
+* return:
+* <0: error
+* =0: triggered
+* =1: ongoing
+*/
+int conninfra_trigger_whole_chip_rst(enum consys_drv_type drv, char *reason);
+
+int conninfra_debug_dump(void);
+
+struct whole_chip_rst_cb {
+ int (*pre_whole_chip_rst)(enum consys_drv_type drv, char *reason);
+ int (*post_whole_chip_rst)(void);
+};
+
+/* driver state query */
+
+/* VCN control */
+
+/* Thermal */
+
+/* Config */
+
+/* semaphore */
+
+/* calibration */
+
+
+
+/* subsys callback register */
+struct pre_calibration_cb {
+ int (*pwr_on_cb)(void);
+ int (*do_cal_cb)(void);
+};
+
+struct sub_drv_ops_cb {
+ /* chip reset */
+ struct whole_chip_rst_cb rst_cb;
+
+ /* calibration */
+ struct pre_calibration_cb pre_cal_cb;
+
+ /* thermal query */
+ int (*thermal_qry)(void);
+
+};
+
+int conninfra_sub_drv_ops_register(enum consys_drv_type drv_type, struct sub_drv_ops_cb *cb);
+int conninfra_sub_drv_ops_unregister(enum consys_drv_type drv_type);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _CONNINFRA_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/include/connsys_step.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/include/connsys_step.h
new file mode 100755
index 0000000..15c06a4
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/include/connsys_step.h
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+#ifndef _CONNSYS_STEP_H_
+#define _CONNSYS_STEP_H_
+
+#define STEP_TP_NO_DEFINE 0
+
+enum consys_wf_step_trigger_point {
+ STEP_WF_TP_NO_DEFINE = STEP_TP_NO_DEFINE,
+ STEP_WF_TP_COMMAND_TIMEOUT,
+ STEP_WF_TP_BEFORE_CHIP_RESET,
+ STEP_WF_TP_AFTER_CHIP_RESET,
+
+ STEP_WF_TP_MAX,
+};
+
+enum consys_bt_step_trigger_point {
+ STEP_BT_TP_NO_DEFINE = STEP_TP_NO_DEFINE,
+ STEP_BT_TP_COMMAND_TIMEOUT,
+ STEP_BT_TP_BEFORE_CHIP_RESET,
+ STEP_BT_TP_AFTER_CHIP_RESET,
+
+ STEP_BT_TP_MAX,
+};
+
+enum consys_gps_step_trigger_point {
+ STEP_GPS_TP_NO_DEFINE = STEP_TP_NO_DEFINE,
+ STEP_GPS_TP_COMMAND_TIMEOUT,
+ STEP_GPS_TP_BEFORE_CHIP_RESET,
+ STEP_GPS_TP_AFTER_CHIP_RESET,
+
+ STEP_GPS_TP_MAX,
+};
+
+enum consys_fm_step_trigger_point {
+ STEP_FM_TP_NO_DEFINE = STEP_TP_NO_DEFINE,
+ STEP_FM_TP_COMMAND_TIMEOUT,
+ STEP_FM_TP_BEFORE_CHIP_RESET,
+ STEP_FM_TP_AFTER_CHIP_RESET,
+
+ STEP_FM_TP_MAX,
+};
+
+/******************************************
+ * readable
+ * 1: can read, 0: CANNOT read
+ ******************************************/
+struct consys_step_register_cb {
+ int (*readable_cb)(unsigned long);
+};
+
+/******************************************
+ * drv down should call consys_step_xx_register(NULL);
+ ******************************************/
+void consys_step_bt_register(struct consys_step_register_cb *cb);
+void consys_step_bt_do_action(enum consys_bt_step_trigger_point);
+
+void consys_step_wf_register(struct consys_step_register_cb *cb);
+void consys_step_wf_do_action(enum consys_wf_step_trigger_point);
+
+void consys_step_gps_register(struct consys_step_register_cb *cb);
+void consys_step_gps_do_action(enum consys_gps_step_trigger_point);
+
+void consys_step_fm_register(struct consys_step_register_cb *cb);
+void consys_step_fm_do_action(enum consys_fm_step_trigger_point);
+
+
+#endif /* end of _CONNSYS_STEP_H_ */
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/init.conninfra.rc b/src/kernel/modules/connectivity/2.0/conninfra_driver/init.conninfra.rc
new file mode 100755
index 0000000..cca37bf
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/init.conninfra.rc
@@ -0,0 +1,2 @@
+on boot
+ insmod /vendor/lib/modules/conninfra.ko
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/clock_mng.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/clock_mng.c
new file mode 100755
index 0000000..9c2fd55
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/clock_mng.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#include "osal.h"
+
+#include "clock_mng.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/consys_hw.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/consys_hw.c
new file mode 100755
index 0000000..22ef3f9
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/consys_hw.c
@@ -0,0 +1,622 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#include <linux/delay.h>
+#include <linux/of_device.h>
+#include <linux/of_reserved_mem.h>
+
+#include "osal.h"
+
+#include "consys_hw.h"
+#include "emi_mng.h"
+#include "pmic_mng.h"
+#include "consys_reg_mng.h"
+#if CFG_CONNINFRA_FW_LOG_SUPPORT
+#include "connsys_debug_utility.h"
+#endif
+#if CFG_CONNINFRA_STEP_SUPPORT
+#include "connsys_step.h"
+#include "conninfra_step.h"
+#endif
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+static int mtk_conninfra_probe(struct platform_device *pdev);
+static int mtk_conninfra_remove(struct platform_device *pdev);
+static int mtk_conninfra_suspend(struct platform_device *pdev, pm_message_t state);
+static int mtk_conninfra_resume(struct platform_device *pdev);
+
+static int consys_hw_init(struct platform_device *pdev, struct conninfra_dev_cb* dev_cb);
+static int consys_hw_deinit(void);
+static int _consys_hw_conninfra_wakeup(void);
+static void _consys_hw_conninfra_sleep(void);
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+extern const struct of_device_id apconninfra_of_ids[];
+
+static struct platform_driver mtk_conninfra_dev_drv = {
+ .probe = mtk_conninfra_probe,
+ .remove = mtk_conninfra_remove,
+ .suspend = mtk_conninfra_suspend,
+ .resume = mtk_conninfra_resume,
+ .driver = {
+ .name = "mtk_conninfra",
+ .owner = THIS_MODULE,
+ .of_match_table = apconninfra_of_ids,
+ },
+};
+
+
+struct consys_hw_env conn_hw_env;
+
+const struct consys_hw_ops_struct *consys_hw_ops;
+struct platform_device *g_pdev;
+
+int g_conninfra_wakeup_ref_cnt;
+
+struct work_struct ap_resume_work;
+
+struct conninfra_dev_cb *g_conninfra_dev_cb;
+const struct conninfra_plat_data *g_conninfra_plat_data = NULL;
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+struct platform_device *get_consys_device(void)
+{
+ return g_pdev;
+}
+
+int consys_hw_get_clock_schematic(void)
+{
+ if (consys_hw_ops->consys_plt_co_clock_type)
+ return consys_hw_ops->consys_plt_co_clock_type();
+ else
+ pr_err("consys_hw_ops->consys_co_clock_type not supported\n");
+
+ return -1;
+}
+
+unsigned int consys_hw_chipid_get(void)
+{
+ if (g_conninfra_plat_data && g_conninfra_plat_data->chip_id)
+ return g_conninfra_plat_data->chip_id;
+ else if (consys_hw_ops->consys_plt_soc_chipid_get)
+ return consys_hw_ops->consys_plt_soc_chipid_get();
+ else
+ pr_err("consys_plt_soc_chipid_get not supported\n");
+
+ return 0;
+}
+
+unsigned int consys_hw_get_hw_ver(void)
+{
+ if (consys_hw_ops->consys_plt_get_hw_ver)
+ return consys_hw_ops->consys_plt_get_hw_ver();
+ return 0;
+}
+
+
+int consys_hw_reg_readable(void)
+{
+ return consys_reg_mng_reg_readable();
+}
+
+int consys_hw_is_connsys_reg(phys_addr_t addr)
+{
+ return consys_reg_mng_is_connsys_reg(addr);
+}
+
+int consys_hw_is_bus_hang(void)
+{
+ return consys_reg_mng_is_bus_hang();
+}
+
+int consys_hw_dump_bus_status(void)
+{
+ return consys_reg_mng_dump_bus_status();
+}
+
+int consys_hw_dump_cpupcr(enum conn_dump_cpupcr_type dump_type, int times, unsigned long interval_us)
+{
+ return consys_reg_mng_dump_cpupcr(dump_type, times, interval_us);
+}
+
+int consys_hw_pwr_off(unsigned int curr_status, unsigned int off_radio)
+{
+ unsigned int next_status = curr_status & ~(0x1 << off_radio);
+ int ret = 0;
+
+ if (next_status == 0) {
+
+ #if CFG_CONNINFRA_STEP_SUPPORT
+ CONNINFRA_STEP_DO_ACTIONS_FUNC(STEP_CONNINFRA_TP_BEFORE_POWER_OFF);
+ #endif
+ pr_info("Last pwoer off: %d\n", off_radio);
+ pr_info("Power off CONNSYS PART 1\n");
+ if (consys_hw_ops->consys_plt_conninfra_on_power_ctrl)
+ consys_hw_ops->consys_plt_conninfra_on_power_ctrl(0);
+ pr_info("Power off CONNSYS PART 2\n");
+ if (consys_hw_ops->consys_plt_set_if_pinmux)
+ consys_hw_ops->consys_plt_set_if_pinmux(0);
+ if (consys_hw_ops->consys_plt_clock_buffer_ctrl)
+ consys_hw_ops->consys_plt_clock_buffer_ctrl(0);
+ ret = pmic_mng_common_power_ctrl(0);
+ pr_info("Power off a-die power, ret=%d\n", ret);
+ } else {
+ pr_info("[%s] Part 0: only subsys (%d) off (curr_status=0x%x, next_status = 0x%x)\n",
+ __func__, off_radio, curr_status, next_status);
+ ret = _consys_hw_conninfra_wakeup();
+ if (consys_hw_ops->consys_plt_subsys_status_update)
+ consys_hw_ops->consys_plt_subsys_status_update(false, off_radio);
+ if (consys_hw_ops->consys_plt_spi_master_cfg)
+ consys_hw_ops->consys_plt_spi_master_cfg(next_status);
+ if (consys_hw_ops->consys_plt_low_power_setting)
+ consys_hw_ops->consys_plt_low_power_setting(curr_status, next_status);
+ if (ret == 0)
+ _consys_hw_conninfra_sleep();
+ }
+
+ return 0;
+}
+
+int consys_hw_pwr_on(unsigned int curr_status, unsigned int on_radio)
+{
+ int ret;
+ unsigned int next_status = (curr_status | (0x1 << on_radio));
+
+ /* first power on */
+ if (curr_status == 0) {
+ #if CFG_CONNINFRA_STEP_SUPPORT
+ CONNINFRA_STEP_DO_ACTIONS_FUNC(STEP_CONNINFRA_TP_POWER_ON_START);
+ #endif
+ /* POS PART 1:
+ * Set PMIC to turn on the power that AFE WBG circuit in D-die,
+ * OSC or crystal component, and A-die need.
+ */
+ ret = pmic_mng_common_power_ctrl(1);
+ if (consys_hw_ops->consys_plt_clock_buffer_ctrl)
+ consys_hw_ops->consys_plt_clock_buffer_ctrl(1);
+
+ /* POS PART 2:
+ * 1. Pinmux setting
+ * 2. Turn on MTCMOS
+ * 3. Enable AXI bus (AP2CONN slpprot)
+ */
+ if (consys_hw_ops->consys_plt_set_if_pinmux)
+ consys_hw_ops->consys_plt_set_if_pinmux(1);
+
+ udelay(500);
+ if (consys_hw_ops->consys_plt_conninfra_on_power_ctrl)
+ consys_hw_ops->consys_plt_conninfra_on_power_ctrl(1);
+
+ #if CFG_CONNINFRA_STEP_SUPPORT
+ CONNINFRA_STEP_DO_ACTIONS_FUNC(STEP_CONNINFRA_TP_POWER_ON_BEFORE_GET_CONNSYS_ID);
+ #endif
+ if (consys_hw_ops->consys_plt_polling_consys_chipid)
+ consys_hw_ops->consys_plt_polling_consys_chipid();
+
+ /* POS PART 3:
+ * 1. Set connsys EMI mapping
+ * 2. d_die_cfg
+ * 3. spi_master_cfg
+ * 4. a_die_cfg
+ * 5. afe_wbg_cal
+ * 6. patch default value
+ * 7. CONN_INFRA low power setting (srcclken wait time, mtcmos HW ctl...)
+ */
+ emi_mng_set_remapping_reg();
+ if (consys_hw_ops->consys_plt_d_die_cfg)
+ consys_hw_ops->consys_plt_d_die_cfg();
+ if (consys_hw_ops->consys_plt_spi_master_cfg)
+ consys_hw_ops->consys_plt_spi_master_cfg(next_status);
+ if (consys_hw_ops->consys_plt_a_die_cfg)
+ consys_hw_ops->consys_plt_a_die_cfg();
+ if (consys_hw_ops->consys_plt_afe_wbg_cal)
+ consys_hw_ops->consys_plt_afe_wbg_cal();
+ if (consys_hw_ops->consys_plt_subsys_pll_initial)
+ consys_hw_ops->consys_plt_subsys_pll_initial();
+ /* Record SW status on shared sysram */
+ if (consys_hw_ops->consys_plt_subsys_status_update)
+ consys_hw_ops->consys_plt_subsys_status_update(true, on_radio);
+ if (consys_hw_ops->consys_plt_low_power_setting)
+ consys_hw_ops->consys_plt_low_power_setting(curr_status, next_status);
+ #if CFG_CONNINFRA_STEP_SUPPORT
+ CONNINFRA_STEP_DO_ACTIONS_FUNC(STEP_CONNINFRA_TP_POWER_ON_END);
+ #endif
+ } else {
+ ret = _consys_hw_conninfra_wakeup();
+ /* Record SW status on shared sysram */
+ if (consys_hw_ops->consys_plt_subsys_status_update)
+ consys_hw_ops->consys_plt_subsys_status_update(true, on_radio);
+ if (consys_hw_ops->consys_plt_spi_master_cfg)
+ consys_hw_ops->consys_plt_spi_master_cfg(next_status);
+ if (consys_hw_ops->consys_plt_low_power_setting)
+ consys_hw_ops->consys_plt_low_power_setting(curr_status, next_status);
+
+ if (ret == 0)
+ _consys_hw_conninfra_sleep();
+ }
+ return 0;
+}
+
+int consys_hw_wifi_power_ctl(unsigned int enable)
+{
+ return pmic_mng_wifi_power_ctrl(enable);
+}
+
+int consys_hw_bt_power_ctl(unsigned int enable)
+{
+ return pmic_mng_bt_power_ctrl(enable);
+}
+
+int consys_hw_gps_power_ctl(unsigned int enable)
+{
+ return pmic_mng_gps_power_ctrl(enable);
+}
+
+int consys_hw_fm_power_ctl(unsigned int enable)
+{
+ return pmic_mng_fm_power_ctrl(enable);
+}
+
+
+int consys_hw_therm_query(int *temp_ptr)
+{
+ int ret = 0;
+
+ /* wake/sleep conninfra */
+ if (consys_hw_ops && consys_hw_ops->consys_plt_thermal_query) {
+ ret = _consys_hw_conninfra_wakeup();
+ if (ret)
+ return CONNINFRA_ERR_WAKEUP_FAIL;
+ #if CFG_CONNINFRA_STEP_SUPPORT
+ CONNINFRA_STEP_DO_ACTIONS_FUNC(STEP_CONNINFRA_TP_BEFORE_READ_THERMAL);
+ #endif
+ *temp_ptr = consys_hw_ops->consys_plt_thermal_query();
+ _consys_hw_conninfra_sleep();
+ } else
+ ret = -1;
+
+ return ret;
+}
+
+void consys_hw_clock_fail_dump(void)
+{
+ if (consys_hw_ops && consys_hw_ops->consys_plt_clock_fail_dump)
+ consys_hw_ops->consys_plt_clock_fail_dump();
+}
+
+
+int consys_hw_dump_power_state(void)
+{
+ if (consys_hw_ops && consys_hw_ops->consys_plt_power_state)
+ consys_hw_ops->consys_plt_power_state();
+ return 0;
+}
+
+int consys_hw_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data)
+{
+ if (consys_hw_ops->consys_plt_spi_read)
+ return consys_hw_ops->consys_plt_spi_read(subsystem, addr, data);
+ return -1;
+}
+
+int consys_hw_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data)
+{
+ if (consys_hw_ops->consys_plt_spi_write)
+ return consys_hw_ops->consys_plt_spi_write(subsystem, addr, data);
+ return -1;
+}
+
+int consys_hw_adie_top_ck_en_on(enum consys_adie_ctl_type type)
+{
+ if (consys_hw_ops->consys_plt_adie_top_ck_en_on)
+ return consys_hw_ops->consys_plt_adie_top_ck_en_on(type);
+ return -1;
+}
+
+int consys_hw_adie_top_ck_en_off(enum consys_adie_ctl_type type)
+{
+ if (consys_hw_ops->consys_plt_adie_top_ck_en_off)
+ return consys_hw_ops->consys_plt_adie_top_ck_en_off(type);
+ return -1;
+}
+
+
+static int _consys_hw_conninfra_wakeup(void)
+{
+ int ref = g_conninfra_wakeup_ref_cnt;
+ bool wakeup = false, ret;
+
+ if (consys_hw_ops->consys_plt_conninfra_wakeup) {
+ if (g_conninfra_wakeup_ref_cnt == 0) {
+ ret = consys_hw_ops->consys_plt_conninfra_wakeup();
+ if (ret) {
+ pr_err("wakeup fail!! ret=[%d]", ret);
+ return ret;
+ }
+ wakeup = true;
+ }
+ g_conninfra_wakeup_ref_cnt++;
+ }
+
+ pr_info("conninfra_wakeup refcnt=[%d]->[%d] %s",
+ ref, g_conninfra_wakeup_ref_cnt, (wakeup ? "wakeup!!" : ""));
+ return 0;
+}
+
+static void _consys_hw_conninfra_sleep(void)
+{
+ int ref = g_conninfra_wakeup_ref_cnt;
+ bool sleep = false;
+
+ if (consys_hw_ops->consys_plt_conninfra_sleep &&
+ --g_conninfra_wakeup_ref_cnt == 0) {
+ sleep = true;
+ consys_hw_ops->consys_plt_conninfra_sleep();
+ }
+ pr_info("conninfra_sleep refcnt=[%d]->[%d] %s",
+ ref, g_conninfra_wakeup_ref_cnt, (sleep ? "sleep!!" : ""));
+}
+
+int consys_hw_force_conninfra_wakeup(void)
+{
+ return _consys_hw_conninfra_wakeup();
+}
+
+int consys_hw_force_conninfra_sleep(void)
+{
+ _consys_hw_conninfra_sleep();
+ return 0;
+}
+
+int consys_hw_spi_clock_switch(enum connsys_spi_speed_type type)
+{
+ if (consys_hw_ops->consys_plt_spi_clock_switch)
+ return consys_hw_ops->consys_plt_spi_clock_switch(type);
+ return -1;
+}
+
+void consys_hw_config_setup(void)
+{
+ if (consys_hw_ops->consys_plt_config_setup)
+ consys_hw_ops->consys_plt_config_setup();
+}
+
+int consys_hw_pmic_event_cb(unsigned int id, unsigned int event)
+{
+ pmic_mng_event_cb(id, event);
+ return 0;
+}
+
+int consys_hw_bus_clock_ctrl(enum consys_drv_type drv_type, unsigned int bus_clock, int status)
+{
+ if (consys_hw_ops->consys_plt_bus_clock_ctrl)
+ return consys_hw_ops->consys_plt_bus_clock_ctrl(drv_type, bus_clock, status);
+ else
+ return -1;
+}
+
+int mtk_conninfra_probe(struct platform_device *pdev)
+{
+ int ret = -1;
+#if CFG_CONNINFRA_FW_LOG_SUPPORT
+ struct consys_emi_addr_info* emi_info = NULL;
+#endif
+
+ if (pdev)
+ g_pdev = pdev;
+ else {
+ pr_err("[%s] pdev is NULL\n", __func__);
+ return -1;
+ }
+
+ /* HW operation init */
+ if (consys_hw_init(pdev, g_conninfra_dev_cb) != 0) {
+ pr_err("consys_hw_init fail");
+ return -1;
+ }
+
+ /* Read device node */
+ if (consys_reg_mng_init(pdev, g_conninfra_plat_data) != 0) {
+ pr_err("consys_plt_read_reg_from_dts fail");
+ return -2;
+ }
+
+ if (consys_hw_ops->consys_plt_clk_get_from_dts)
+ consys_hw_ops->consys_plt_clk_get_from_dts(pdev);
+ else {
+ pr_err("consys_plt_clk_get_from_dtsfail");
+ return -3;
+ }
+
+ /* emi mng init */
+ ret = emi_mng_init(pdev, g_conninfra_plat_data);
+ if (ret) {
+ pr_err("emi_mng init fail, %d\n", ret);
+ return -4;
+ }
+
+ ret = pmic_mng_init(pdev, g_conninfra_dev_cb, g_conninfra_plat_data);
+ if (ret) {
+ pr_err("pmic_mng init fail, %d\n", ret);
+ return -5;
+ }
+
+#if CFG_CONNINFRA_FW_LOG_SUPPORT
+ /* Setup connsys log emi base */
+ emi_info = emi_mng_get_phy_addr();
+ if (emi_info) {
+ connsys_dedicated_log_path_apsoc_init((phys_addr_t)emi_info->emi_ap_phy_addr);
+ } else {
+ pr_err("Connsys log didn't init because EMI is invalid\n");
+ }
+#endif /* CONNINFRA_FW_LOG_SUPPORT */
+
+ /* Register thermal */
+ if (consys_hw_ops->consys_plt_thermal_register)
+ consys_hw_ops->consys_plt_thermal_register(pdev, g_conninfra_dev_cb);
+ else
+ pr_info("consys_plt_thermal_register is not supported.");
+
+ return 0;
+}
+
+int mtk_conninfra_remove(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = pmic_mng_deinit();
+ pr_info("pmic_mng_deinit ret=%d", ret);
+
+ ret = emi_mng_deinit();
+ pr_info("emi_mng_deinit ret=%d", ret);
+
+ if (consys_hw_ops->consys_plt_clk_detach)
+ consys_hw_ops->consys_plt_clk_detach();
+ else
+ pr_err("consys_plt_clk_detach is null");
+
+ ret = consys_reg_mng_deinit();
+ pr_info("consys_reg_mng_deinit ret=%d", ret);
+
+ ret = consys_hw_deinit();
+ pr_info("consys_hw_deinit ret=%d", ret);
+
+ if (g_pdev)
+ g_pdev = NULL;
+
+ return 0;
+}
+
+int mtk_conninfra_suspend(struct platform_device *pdev, pm_message_t state)
+{
+#if CFG_CONNINFRA_STEP_SUPPORT
+ /* suspend callback is in atomic context */
+ CONNINFRA_STEP_DO_ACTIONS_FUNC(STEP_CONNINFRA_TP_WHEN_AP_SUSPEND);
+#endif /* CFG_CONNINFRA_STEP_SUPPORT */
+
+ return 0;
+}
+
+int mtk_conninfra_resume(struct platform_device *pdev)
+{
+ /* suspend callback is in atomic context, use schedule work to execute STEP */
+
+ schedule_work(&ap_resume_work);
+ return 0;
+}
+
+
+static void consys_hw_ap_resume_handler(struct work_struct *work)
+{
+#if CFG_CONNINFRA_STEP_SUPPORT
+ CONNINFRA_STEP_DO_ACTIONS_FUNC(STEP_CONNINFRA_TP_WHEN_AP_RESUME);
+#endif /* CFG_CONNINFRA_STEP_SUPPORT */
+
+ if (g_conninfra_dev_cb && g_conninfra_dev_cb->conninfra_resume_cb)
+ (*g_conninfra_dev_cb->conninfra_resume_cb)();
+}
+
+
+int consys_hw_init(struct platform_device *pdev, struct conninfra_dev_cb* dev_cb)
+{
+ g_conninfra_plat_data = (const struct conninfra_plat_data*)of_device_get_match_data(&pdev->dev);
+ if (g_conninfra_plat_data == NULL) {
+ pr_err("[%s] Get platform data fail.", __func__);
+ return -1;
+ }
+ if (consys_hw_ops == NULL)
+ consys_hw_ops = (const struct consys_hw_ops_struct*)g_conninfra_plat_data->hw_ops;
+
+ if (consys_hw_ops == NULL)
+ pr_err("Get HW op fail");
+ return 0;
+}
+
+int consys_hw_deinit(void)
+{
+ return 0;
+}
+
+
+int mtk_conninfra_drv_init(struct conninfra_dev_cb *dev_cb)
+{
+ int iRet = 0;
+
+ g_conninfra_dev_cb = dev_cb;
+
+ pr_info("Before platform_driver_register");
+ iRet = platform_driver_register(&mtk_conninfra_dev_drv);
+ if (iRet)
+ pr_err("Conninfra platform driver registered failed(%d)\n", iRet);
+ pr_info("After platform_driver_register");
+
+ INIT_WORK(&ap_resume_work, consys_hw_ap_resume_handler);
+ pr_info("[consys_hw_init] result [%d]\n", iRet);
+
+ return iRet;
+}
+
+int mtk_conninfra_drv_deinit(void)
+{
+ platform_driver_unregister(&mtk_conninfra_dev_drv);
+ g_conninfra_dev_cb = NULL;
+ return 0;
+}
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/consys_hw_plat_data.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/consys_hw_plat_data.c
new file mode 100644
index 0000000..0b8bd32
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/consys_hw_plat_data.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+#include <linux/of_device.h>
+
+#include "consys_hw.h"
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/* Platform data */
+extern struct conninfra_plat_data mt6880_plat_data;
+
+const struct of_device_id apconninfra_of_ids[] = {
+ {
+ .compatible = "mediatek,mt6880-consys",
+ .data = (void*)&mt6880_plat_data,
+ },
+ {}
+};
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/consys_reg_mng.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/consys_reg_mng.c
new file mode 100755
index 0000000..406306a
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/consys_reg_mng.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__
+
+#include "consys_hw.h"
+#include "consys_reg_mng.h"
+#include "consys_reg_util.h"
+
+const struct consys_reg_mng_ops* g_consys_reg_ops = NULL;
+
+int consys_reg_mng_reg_readable(void)
+{
+ if (g_consys_reg_ops &&
+ g_consys_reg_ops->consys_reg_mng_check_reable)
+ return g_consys_reg_ops->consys_reg_mng_check_reable();
+ pr_err("%s not implement", __func__);
+ return -1;
+}
+
+int consys_reg_mng_is_connsys_reg(phys_addr_t addr)
+{
+ if (g_consys_reg_ops &&
+ g_consys_reg_ops->consys_reg_mng_is_consys_reg)
+ return g_consys_reg_ops->consys_reg_mng_is_consys_reg(addr);
+ return -1;
+}
+
+
+int consys_reg_mng_is_bus_hang(void)
+{
+ if (g_consys_reg_ops &&
+ g_consys_reg_ops->consys_reg_mng_is_bus_hang)
+ return g_consys_reg_ops->consys_reg_mng_is_bus_hang();
+ return -1;
+}
+
+int consys_reg_mng_dump_bus_status(void)
+{
+ if (g_consys_reg_ops &&
+ g_consys_reg_ops->consys_reg_mng_dump_bus_status)
+ return g_consys_reg_ops->consys_reg_mng_dump_bus_status();
+ return -1;
+}
+
+int consys_reg_mng_dump_conninfra_status(void)
+{
+ if (g_consys_reg_ops &&
+ g_consys_reg_ops->consys_reg_mng_dump_conninfra_status)
+ return g_consys_reg_ops->consys_reg_mng_dump_conninfra_status();
+ return -1;
+}
+
+int consys_reg_mng_dump_cpupcr(enum conn_dump_cpupcr_type dump_type, int times, unsigned long interval_us)
+{
+ if (g_consys_reg_ops &&
+ g_consys_reg_ops->consys_reg_mng_dump_cpupcr)
+ return g_consys_reg_ops->consys_reg_mng_dump_cpupcr(dump_type, times, interval_us);
+ return -1;
+}
+
+unsigned long consys_reg_mng_validate_idx_n_offset(unsigned int idx, unsigned long offset)
+{
+ if (g_consys_reg_ops&&
+ g_consys_reg_ops->consys_reg_mng_validate_idx_n_offset)
+ return g_consys_reg_ops->consys_reg_mng_validate_idx_n_offset(idx, offset);
+ return -1;
+}
+
+int consys_reg_mng_find_can_write_reg(unsigned int *idx, unsigned long* offset)
+{
+ if (g_consys_reg_ops&&
+ g_consys_reg_ops->consys_reg_mng_find_can_write_reg)
+ return g_consys_reg_ops->consys_reg_mng_find_can_write_reg(idx, offset);
+ return -1;
+}
+
+unsigned long consys_reg_mng_get_phy_addr_by_idx(unsigned int idx)
+{
+ if (g_consys_reg_ops&&
+ g_consys_reg_ops->consys_reg_mng_get_phy_addr_by_idx)
+ return g_consys_reg_ops->consys_reg_mng_get_phy_addr_by_idx(idx);
+ return -1;
+}
+
+unsigned long consys_reg_mng_get_virt_addr_by_idx(unsigned int idx)
+{
+ if (g_consys_reg_ops&&
+ g_consys_reg_ops->consys_reg_mng_get_virt_addr_by_idx)
+ return g_consys_reg_ops->consys_reg_mng_get_virt_addr_by_idx(idx);
+ return -1;
+}
+
+
+int consys_reg_mng_get_chip_id_idx_offset(unsigned int *idx, unsigned long *offset)
+{
+ if (g_consys_reg_ops&&
+ g_consys_reg_ops->consys_reg_mng_get_chip_id_idx_offset)
+ return g_consys_reg_ops->consys_reg_mng_get_chip_id_idx_offset(idx, offset);
+ return -1;
+}
+
+int consys_reg_mng_get_reg_symbol_num(void)
+{
+ if (g_consys_reg_ops&&
+ g_consys_reg_ops->consys_reg_mng_get_reg_symbol_num)
+ return g_consys_reg_ops->consys_reg_mng_get_reg_symbol_num();
+ return -1;
+}
+
+
+int consys_reg_mng_init(struct platform_device *pdev, const struct conninfra_plat_data* plat_data)
+{
+ int ret = 0;
+ if (g_consys_reg_ops == NULL)
+ g_consys_reg_ops = (const struct consys_reg_mng_ops*)plat_data->reg_ops;
+
+ if (g_consys_reg_ops &&
+ g_consys_reg_ops->consys_reg_mng_init)
+ ret = g_consys_reg_ops->consys_reg_mng_init(pdev);
+ else
+ ret = EFAULT;
+
+ return ret;
+}
+
+int consys_reg_mng_deinit(void)
+{
+ if (g_consys_reg_ops&&
+ g_consys_reg_ops->consys_reg_mng_deinit)
+ g_consys_reg_ops->consys_reg_mng_deinit();
+
+ return 0;
+}
+
+int consys_reg_mng_reg_read(unsigned long addr, unsigned int *value, unsigned int mask)
+{
+ void __iomem *vir_addr = NULL;
+
+ vir_addr = ioremap_nocache(addr, 0x100);
+ if (!vir_addr) {
+ pr_err("ioremap fail");
+ return -1;
+ }
+
+ *value = (unsigned int)CONSYS_REG_READ(vir_addr) & mask;
+
+ pr_info("[%x] mask=[%x]", *value, mask);
+
+ iounmap(vir_addr);
+ return 0;
+}
+
+int consys_reg_mng_reg_write(unsigned long addr, unsigned int value, unsigned int mask)
+{
+ void __iomem *vir_addr = NULL;
+
+ vir_addr = ioremap_nocache(addr, 0x100);
+ if (!vir_addr) {
+ pr_err("ioremap fail");
+ return -1;
+ }
+
+ CONSYS_REG_WRITE_MASK(vir_addr, value, mask);
+
+ iounmap(vir_addr);
+ return 0;
+}
+
+
+int consys_reg_mng_is_host_csr(unsigned long addr)
+{
+ if (g_consys_reg_ops &&
+ g_consys_reg_ops->consys_reg_mng_is_host_csr)
+ return g_consys_reg_ops->consys_reg_mng_is_host_csr(addr);
+ return -1;
+}
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/emi_mng.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/emi_mng.c
new file mode 100755
index 0000000..4dbcc18
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/emi_mng.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#include <linux/of.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/io.h>
+#include <linux/types.h>
+#include "osal.h"
+
+#include "consys_hw.h"
+#include "emi_mng.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+unsigned long long gConEmiSize = 0;
+phys_addr_t gConEmiPhyBase = 0x0;
+
+const struct consys_platform_emi_ops* consys_platform_emi_ops = NULL;
+
+struct consys_emi_addr_info connsys_emi_addr_info = {
+ .emi_ap_phy_addr = 0,
+ .emi_size = 0,
+ .md_emi_phy_addr = 0,
+ .md_emi_size = 0,
+};
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+
+int emi_mng_set_region_protection(void)
+{
+ if (consys_platform_emi_ops &&
+ consys_platform_emi_ops->consys_ic_emi_mpu_set_region_protection)
+ return consys_platform_emi_ops->consys_ic_emi_mpu_set_region_protection();
+ return -1;
+}
+
+int emi_mng_set_remapping_reg(void)
+{
+ if (consys_platform_emi_ops &&
+ consys_platform_emi_ops->consys_ic_emi_set_remapping_reg)
+ return consys_platform_emi_ops->consys_ic_emi_set_remapping_reg(
+ connsys_emi_addr_info.emi_ap_phy_addr,
+ connsys_emi_addr_info.md_emi_phy_addr);
+ return -1;
+}
+
+struct consys_emi_addr_info* emi_mng_get_phy_addr(void)
+{
+ return &connsys_emi_addr_info;
+}
+
+int emi_mng_init(struct platform_device *pdev, const struct conninfra_plat_data* plat_data)
+{
+ unsigned int fw_emi_size = gConEmiSize;
+#if CFG_CONNINFRA_EMI_SUPPORT
+ struct device_node *np;
+ struct reserved_mem *rmem;
+
+ np = of_parse_phandle(pdev->dev.of_node, "memory-region", 0);
+
+ if (!np) {
+ pr_info("[%s] memory region not found.");
+ return -1;
+ }
+
+ rmem = of_reserved_mem_lookup(np);
+ of_node_put(np);
+ if (!rmem) {
+ pr_info("[%s] no memory-region");
+ return -1;
+ } else {
+ gConEmiPhyBase = rmem->base;
+ gConEmiSize = rmem->size;
+ }
+#else
+ pr_info("Conninfra not support EMI reservation for %04x", plat_data->chip_id);
+#endif /* CFG_CONNINFRA_EMI_SUPPORT */
+
+ if (consys_platform_emi_ops == NULL) {
+ consys_platform_emi_ops = (const struct consys_platform_emi_ops*)plat_data->platform_emi_ops;
+ }
+
+ if (consys_platform_emi_ops && consys_platform_emi_ops->consys_ic_emi_get_fw_emi_size)
+ fw_emi_size = consys_platform_emi_ops->consys_ic_emi_get_fw_emi_size();
+ pr_info("[emi_mng_init] gConEmiPhyBase = [0x%llx] size = [0x%llx] fw size = [0x%x] ops=[%p]",
+ gConEmiPhyBase, gConEmiSize, fw_emi_size, consys_platform_emi_ops);
+
+ if (gConEmiPhyBase) {
+ connsys_emi_addr_info.emi_ap_phy_addr = gConEmiPhyBase;
+ connsys_emi_addr_info.emi_size = gConEmiSize;
+ connsys_emi_addr_info.fw_emi_size = fw_emi_size;
+ } else {
+ pr_err("consys emi memory address gConEmiPhyBase invalid\n");
+ }
+
+ if (consys_platform_emi_ops &&
+ consys_platform_emi_ops->consys_ic_emi_get_md_shared_emi)
+ consys_platform_emi_ops->consys_ic_emi_get_md_shared_emi(
+ &connsys_emi_addr_info.md_emi_phy_addr,
+ &connsys_emi_addr_info.md_emi_size);
+
+ if (consys_platform_emi_ops &&
+ consys_platform_emi_ops->consys_ic_emi_mpu_set_region_protection)
+ consys_platform_emi_ops->consys_ic_emi_mpu_set_region_protection();
+
+ return 0;
+}
+
+int emi_mng_deinit(void)
+{
+ return 0;
+}
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/clock_mng.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/clock_mng.h
new file mode 100755
index 0000000..ff62830
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/clock_mng.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_CLOCK_MNG_H_
+#define _PLATFORM_CLOCK_MNG_H_
+
+#include "osal.h"
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _PLATFORM_CLOCK_MNG_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/consys_hw.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/consys_hw.h
new file mode 100755
index 0000000..3ff7b22
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/consys_hw.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_CONSYS_HW_H_
+#define _PLATFORM_CONSYS_HW_H_
+
+#include <linux/platform_device.h>
+
+#include "conninfra.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+#define CONN_SEMA_GET_SUCCESS 0
+#define CONN_SEMA_GET_FAIL 1
+
+#define CONN_SEMA_TIMEOUT (1*1000) /* 1ms */
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+struct conninfra_dev_cb {
+ int (*conninfra_suspend_cb) (void);
+ int (*conninfra_resume_cb) (void);
+ int (*conninfra_pmic_event_notifier) (unsigned int, unsigned int);
+ int (*conninfra_thermal_query_cb) (void*, int*);
+};
+
+typedef int(*CONSYS_PLT_CLK_GET_FROM_DTS) (struct platform_device *pdev);
+typedef int(*CONSYS_PLT_CLK_DETACH) (void);
+typedef int(*CONSYS_PLT_READ_REG_FROM_DTS) (struct platform_device *pdev);
+
+typedef int(*CONSYS_PLT_CLOCK_BUFFER_CTRL) (unsigned int enable);
+typedef int(*CONSYS_PLT_CONNINFRA_ON_POWER_CTRL) (unsigned int enable);
+typedef void(*CONSYS_PLT_SET_IF_PINMUX) (unsigned int enable);
+
+typedef int(*CONSYS_PLT_POLLING_CONSYS_CHIPID) (void);
+typedef int(*CONSYS_PLT_D_DIE_CFG) (void);
+typedef int(*CONSYS_PLT_SPI_MASTER_CFG) (unsigned int next_status);
+typedef int(*CONSYS_PLT_A_DIE_CFG) (void);
+typedef int(*CONSYS_PLT_AFE_WBG_CAL) (void);
+typedef int(*CONSYS_PLT_SUBSYS_PLL_INITIAL) (void);
+typedef int(*CONSYS_PLT_LOW_POWER_SETTING) (unsigned int curr_status, unsigned int next_status);
+typedef int(*CONSYS_PLT_CONNINFRA_WAKEUP) (void);
+typedef int(*CONSYS_PLT_CONNINFRA_SLEEP) (void);
+
+typedef void(*CONSYS_PLT_AFE_REG_SETTING) (void);
+typedef unsigned int(*CONSYS_PLT_SOC_CHIPID_GET) (void);
+
+typedef void(*CONSYS_PLT_FORCE_TRIGGER_ASSERT_DEBUG_PIN) (void);
+typedef int(*CONSYS_PLT_CO_CLOCK_TYPE) (void);
+
+typedef int(*CONSYS_PLT_CHECK_REG_READABLE) (void);
+typedef void(*CONSYS_PLT_CLOCK_FAIL_DUMP) (void);
+typedef int(*CONSYS_PLT_IS_CONNSYS_REG) (unsigned int addr);
+
+
+typedef int(*CONSYS_PLT_SPI_READ)(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data);
+typedef int(*CONSYS_PLT_SPI_WRITE)(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data);
+
+typedef int(*CONSYS_PLT_ADIE_TOP_CK_EN_ON)(enum consys_adie_ctl_type type);
+typedef int(*CONSYS_PLT_ADIE_TOP_CK_EN_OFF)(enum consys_adie_ctl_type type);
+
+typedef int(*CONSYS_PLT_SPI_CLOCK_SWITCH)(enum connsys_spi_speed_type type);
+
+typedef bool(*CONSYS_PLT_IS_RC_MODE_ENABLE)(void);
+typedef int(*CONSYS_PLT_SUBSYS_STATUS_UPDATE)(bool on, int radio);
+
+typedef unsigned int(*CONSYS_PLT_GET_HW_VER)(void);
+typedef int(*CONSYS_PLT_THERMAL_QUERY)(void);
+typedef int(*CONSYS_PLT_POWER_STATE)(void);
+
+typedef void(*CONSYS_PLT_CONFIG_SETUP)(void);
+
+typedef int(*CONSYS_PLT_BUS_CLOCK_CTRL)(enum consys_drv_type drv_type, unsigned int, int);
+
+typedef int(*CONSYS_PLT_THERMAL_REGISTER)(struct platform_device *pdev, struct conninfra_dev_cb* dev_cb);
+
+struct consys_hw_ops_struct {
+ /* load from dts */
+ CONSYS_PLT_CLK_GET_FROM_DTS consys_plt_clk_get_from_dts;
+ CONSYS_PLT_CLK_DETACH consys_plt_clk_detach;
+ CONSYS_PLT_THERMAL_REGISTER consys_plt_thermal_register;
+
+ /* clock */
+ CONSYS_PLT_CLOCK_BUFFER_CTRL consys_plt_clock_buffer_ctrl;
+ CONSYS_PLT_CO_CLOCK_TYPE consys_plt_co_clock_type;
+
+ /* POS */
+ /*CONSYS_IC_HW_SPM_CLK_GATING_ENABLE consys_ic_hw_spm_clk_gating_enable;*/
+ CONSYS_PLT_CONNINFRA_ON_POWER_CTRL consys_plt_conninfra_on_power_ctrl;
+ CONSYS_PLT_SET_IF_PINMUX consys_plt_set_if_pinmux;
+
+ CONSYS_PLT_POLLING_CONSYS_CHIPID consys_plt_polling_consys_chipid;
+ CONSYS_PLT_D_DIE_CFG consys_plt_d_die_cfg;
+ CONSYS_PLT_SPI_MASTER_CFG consys_plt_spi_master_cfg;
+ CONSYS_PLT_A_DIE_CFG consys_plt_a_die_cfg;
+ CONSYS_PLT_AFE_WBG_CAL consys_plt_afe_wbg_cal;
+ CONSYS_PLT_SUBSYS_PLL_INITIAL consys_plt_subsys_pll_initial;
+ CONSYS_PLT_LOW_POWER_SETTING consys_plt_low_power_setting;
+
+ CONSYS_PLT_AFE_REG_SETTING consys_plt_afe_reg_setting;
+
+ CONSYS_PLT_SOC_CHIPID_GET consys_plt_soc_chipid_get;
+ CONSYS_PLT_CONNINFRA_WAKEUP consys_plt_conninfra_wakeup;
+ CONSYS_PLT_CONNINFRA_SLEEP consys_plt_conninfra_sleep;
+ CONSYS_PLT_IS_RC_MODE_ENABLE consys_plt_is_rc_mode_enable;
+ /*IC_BT_WIFI_SHARE_V33_SPIN_LOCK_INIT ic_bt_wifi_share_v33_spin_lock_init;*/
+ /*CONSYS_PLT_FORCE_TRIGGER_ASSERT_DEBUG_PIN consys_plt_force_trigger_assert_debug_pin;*/
+
+ CONSYS_PLT_CHECK_REG_READABLE consys_plt_check_reg_readable;
+ /* debug */
+ CONSYS_PLT_CLOCK_FAIL_DUMP consys_plt_clock_fail_dump;
+ CONSYS_PLT_GET_HW_VER consys_plt_get_hw_ver;
+
+ /* debug, used by STEP */
+ CONSYS_PLT_IS_CONNSYS_REG consys_plt_is_connsys_reg;
+
+ /* For SPI operation */
+ CONSYS_PLT_SPI_READ consys_plt_spi_read;
+ CONSYS_PLT_SPI_WRITE consys_plt_spi_write;
+
+ /* For a-die top_ck_en control */
+ CONSYS_PLT_ADIE_TOP_CK_EN_ON consys_plt_adie_top_ck_en_on;
+ CONSYS_PLT_ADIE_TOP_CK_EN_OFF consys_plt_adie_top_ck_en_off;
+
+ /* For SPI clock switch */
+ CONSYS_PLT_SPI_CLOCK_SWITCH consys_plt_spi_clock_switch;
+ CONSYS_PLT_SUBSYS_STATUS_UPDATE consys_plt_subsys_status_update;
+
+ /* thermal */
+ CONSYS_PLT_THERMAL_QUERY consys_plt_thermal_query;
+
+ /* power state */
+ CONSYS_PLT_POWER_STATE consys_plt_power_state;
+
+ CONSYS_PLT_CONFIG_SETUP consys_plt_config_setup;
+
+ CONSYS_PLT_BUS_CLOCK_CTRL consys_plt_bus_clock_ctrl;
+};
+
+struct consys_hw_env {
+ unsigned int adie_hw_version;
+ int is_rc_mode;
+};
+
+struct conninfra_plat_data {
+ const unsigned int chip_id;
+ const void* hw_ops;
+ const void* reg_ops;
+ const void* platform_emi_ops;
+ const void* platform_pmic_ops;
+};
+
+extern struct consys_hw_env conn_hw_env;
+extern struct consys_base_addr conn_reg;
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+int mtk_conninfra_drv_init(struct conninfra_dev_cb *dev_cb);
+int mtk_conninfra_drv_deinit(void);
+
+int consys_hw_pwr_off(unsigned int curr_status, unsigned int off_radio);
+int consys_hw_pwr_on(unsigned int curr_status, unsigned int on_radio);
+
+int consys_hw_wifi_power_ctl(unsigned int enable);
+int consys_hw_bt_power_ctl(unsigned int enable);
+int consys_hw_gps_power_ctl(unsigned int enable);
+int consys_hw_fm_power_ctl(unsigned int enable);
+int consys_hw_pmic_event_cb(unsigned int id, unsigned int event);
+
+unsigned int consys_hw_chipid_get(void);
+
+int consys_hw_get_clock_schematic(void);
+unsigned int consys_hw_get_hw_ver(void);
+
+/*******************************************************************************
+* tempoary for STEP
+********************************************************************************
+*/
+/*
+ * return
+ * 1 : can read
+ * 0 : can't read
+ * -1: not consys register
+ */
+int consys_hw_reg_readable(void);
+int consys_hw_is_connsys_reg(phys_addr_t addr);
+/*
+ * 0 means NO hang
+ * > 0 means hang!!
+ */
+int consys_hw_is_bus_hang(void);
+int consys_hw_dump_bus_status(void);
+
+int consys_hw_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data);
+int consys_hw_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data);
+
+int consys_hw_adie_top_ck_en_on(enum consys_adie_ctl_type type);
+int consys_hw_adie_top_ck_en_off(enum consys_adie_ctl_type type);
+
+/* NOTE: debug only*/
+int consys_hw_force_conninfra_wakeup(void);
+int consys_hw_force_conninfra_sleep(void);
+
+int consys_hw_spi_clock_switch(enum connsys_spi_speed_type type);
+
+struct platform_device *get_consys_device(void);
+struct consys_base_addr *get_conn_reg_base_addr(void);
+
+int consys_hw_therm_query(int *temp_ptr);
+void consys_hw_clock_fail_dump(void);
+
+int consys_hw_dump_power_state(void);
+void consys_hw_config_setup(void);
+int consys_hw_bus_clock_ctrl(enum consys_drv_type drv_type, unsigned int bus_clock, int status);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _PLATFORM_CONSYS_HW_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/consys_reg_base.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/consys_reg_base.h
new file mode 100755
index 0000000..563fd19
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/consys_reg_base.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_CONSYS_REG_BASE_H_
+#define _PLATFORM_CONSYS_REG_BASE_H_
+
+struct consys_reg_base_addr {
+ unsigned long vir_addr;
+ unsigned long phy_addr;
+ unsigned long long size;
+};
+
+#endif /* _PLATFORM_CONSYS_REG_BASE_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/consys_reg_mng.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/consys_reg_mng.h
new file mode 100755
index 0000000..02b584f
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/consys_reg_mng.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_CONSYS_REG_MNG_H_
+#define _PLATFORM_CONSYS_REG_MNG_H_
+
+#include <linux/platform_device.h>
+
+#include "consys_hw.h"
+
+enum conn_dump_cpupcr_type
+{
+ CONN_DUMP_CPUPCR_TYPE_BT = 1,
+ CONN_DUMP_CPUPCR_TYPE_WF = 2,
+ CONN_DUMP_CPUPCR_TYPE_ALL = 3,
+};
+
+struct consys_reg_mng_ops {
+
+ int(*consys_reg_mng_init) (struct platform_device *pdev);
+ int(*consys_reg_mng_deinit) (void);
+ int(*consys_reg_mng_check_reable) (void);
+ int(*consys_reg_mng_is_consys_reg) (unsigned int addr);
+
+ int(*consys_reg_mng_is_bus_hang) (void);
+ int(*consys_reg_mng_dump_bus_status) (void);
+ int(*consys_reg_mng_dump_conninfra_status) (void);
+ int(*consys_reg_mng_dump_cpupcr) (enum conn_dump_cpupcr_type, int times, unsigned long interval_us);
+
+ int(*consys_reg_mng_is_host_csr) (unsigned long addr);
+
+ /* STEP Utility func */
+ unsigned long (*consys_reg_mng_validate_idx_n_offset) (unsigned int idx, unsigned long offset);
+ int (*consys_reg_mng_find_can_write_reg) (unsigned int * idx, unsigned long* offset);
+ unsigned long (*consys_reg_mng_get_phy_addr_by_idx) (unsigned int idx);
+ unsigned long (*consys_reg_mng_get_virt_addr_by_idx) (unsigned int idx);
+ int (*consys_reg_mng_get_chip_id_idx_offset) (unsigned int *idx, unsigned long *offset);
+ int (*consys_reg_mng_get_reg_symbol_num) (void);
+};
+
+int consys_reg_mng_init(struct platform_device *pdev, const struct conninfra_plat_data* plat_data);
+int consys_reg_mng_deinit(void);
+
+int consys_reg_mng_reg_readable(void);
+int consys_reg_mng_is_connsys_reg(phys_addr_t addr);
+int consys_reg_mng_reg_read(unsigned long addr, unsigned int *value, unsigned int mask);
+int consys_reg_mng_reg_write(unsigned long addr, unsigned int value, unsigned int mask);
+int consys_reg_mng_is_bus_hang(void);
+int consys_reg_mng_dump_bus_status(void);
+int consys_reg_mng_dump_conninfra_status(void);
+int consys_reg_mng_dump_cpupcr(enum conn_dump_cpupcr_type dump_type, int times, unsigned long interval_us);
+
+int consys_reg_mng_is_host_csr(unsigned long addr);
+
+
+/**************** step *************************/
+/*********************************************
+ * validate the reg base address index and offset
+ * Parameters:
+ * idx: base address index
+ * offset: offset from base address
+ *
+ * Return
+ * > 0 : phy address of index
+ * = 0 : validate fail
+ *********************************************/
+unsigned long consys_reg_mng_validate_idx_n_offset(unsigned int idx, unsigned long offset);
+
+/* for consys_step_test */
+/*********************************************
+ * validate the reg base address index and offset
+ * Parameters:
+ * offset : offset of base address index
+ *
+ * Return
+ * > 0 : phy address of index
+ * < 0 : can't find
+ *********************************************/
+int consys_reg_mng_find_can_write_reg(unsigned int *idx, unsigned long* offset);
+unsigned long consys_reg_mng_get_phy_addr_by_idx(unsigned int idx);
+unsigned long consys_reg_mng_get_virt_addr_by_idx(unsigned int idx);
+
+int consys_reg_mng_get_chip_id_idx_offset(unsigned int *idx, unsigned long *offset);
+int consys_reg_mng_get_reg_symbol_num(void);
+
+#endif /* _PLATFORM_CONSYS_REG_MNG_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/consys_reg_util.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/consys_reg_util.h
new file mode 100755
index 0000000..e5d06ec
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/consys_reg_util.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_CONSYS_REG_UTIL_H_
+#define _PLATFORM_CONSYS_REG_UTIL_H_
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+/* platform dependent */
+#include "plat_def.h"
+
+#define KBYTE (1024*sizeof(char))
+
+#define GENMASK(h, l) \
+ (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
+
+#define GET_BIT_MASK(value, mask) ((value) & (mask))
+#define SET_BIT_MASK(pdest, value, mask) (*(pdest) = (GET_BIT_MASK(*(pdest), ~(mask)) | GET_BIT_MASK(value, mask)))
+#define GET_BIT_RANGE(data, end, begin) ((data) & GENMASK(end, begin))
+#define SET_BIT_RANGE(pdest, data, end, begin) (SET_BIT_MASK(pdest, data, GENMASK(end, begin)))
+
+#define CONSYS_SET_BIT(REG, BITVAL) (*((volatile unsigned int *)(REG)) |= ((unsigned int)(BITVAL)))
+#define CONSYS_CLR_BIT(REG, BITVAL) ((*(volatile unsigned int *)(REG)) &= ~((unsigned int)(BITVAL)))
+#define CONSYS_CLR_BIT_WITH_KEY(REG, BITVAL, KEY) {\
+ unsigned int val = (*(volatile unsigned int *)(REG)); \
+ val &= ~((unsigned int)(BITVAL)); \
+ val |= ((unsigned int)(KEY)); \
+ (*(volatile unsigned int *)(REG)) = val;\
+}
+#define CONSYS_REG_READ(addr) (*((volatile unsigned int *)(addr)))
+#define CONSYS_REG_READ_BIT(addr, BITVAL) (*((volatile unsigned int *)(addr)) & ((unsigned int)(BITVAL)))
+#define CONSYS_REG_WRITE(addr, data) mt_reg_sync_writel(data, addr)
+#define CONSYS_REG_WRITE_RANGE(reg, data, end, begin) {\
+ unsigned int val = CONSYS_REG_READ(reg); \
+ SET_BIT_RANGE(&val, data, end, begin); \
+ CONSYS_REG_WRITE(reg, val); \
+}
+#define CONSYS_REG_WRITE_MASK(reg, data, mask) {\
+ unsigned int val = CONSYS_REG_READ(reg); \
+ SET_BIT_MASK(&val, data, mask); \
+ CONSYS_REG_WRITE(reg, val); \
+}
+
+/*
+ * Write value with value_offset bits of right shift and size bits,
+ * to the reg_offset-th bit of address reg
+ * value -----------XXXXXXXXXXXX-------------------
+ * |<--size-->|<--value_offset-->|
+ * reg -------------OOOOOOOOOOOO-----------------
+ * |<--size-->|<--reg_offset-->|
+ * result -------------XXXXXXXXXXXX-----------------
+ */
+#define CONSYS_REG_WRITE_OFFSET_RANGE(reg, value, reg_offset, value_offset, size) ({\
+ unsigned int data = (value) >> (value_offset); \
+ data = GET_BIT_RANGE(data, size, 0); \
+ data = data << (reg_offset); \
+ CONSYS_REG_WRITE_RANGE(reg, data, ((reg_offset) + ((size) - 1)), reg_offset); \
+})
+
+#define CONSYS_REG_WRITE_BIT(reg, offset, val) CONSYS_REG_WRITE_OFFSET_RANGE(reg, ((val) & 1), offset, 0, 1)
+
+#define CONSYS_REG_BIT_POLLING(addr, bit_index, exp_val, loop, delay, success) {\
+ unsigned int polling_count = 0; \
+ unsigned int reg_value = 0; \
+ success = 0; \
+ reg_value = (CONSYS_REG_READ_BIT(addr, (0x1 << bit_index)) >> bit_index); \
+ while (reg_value != exp_val) { \
+ if (polling_count > loop) { \
+ success = -1; \
+ break; \
+ } \
+ reg_value = (CONSYS_REG_READ_BIT(addr, (0x1 << bit_index)) >> bit_index); \
+ udelay(delay); \
+ polling_count++; \
+ } \
+}
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _PLATFORM_CONSYS_REG_UTIL_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/emi_mng.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/emi_mng.h
new file mode 100755
index 0000000..f894e55
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/emi_mng.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_EMI_MNG_H_
+#define _PLATFORM_EMI_MNG_H_
+
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include "osal.h"
+
+#include "consys_hw.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+struct consys_emi_addr_info {
+ /* This include BT/WF FW and WFDMA */
+ phys_addr_t emi_ap_phy_addr;
+ unsigned int emi_size;
+ unsigned int fw_emi_size;
+ unsigned int wfdma_emi_size;
+ /* MCIF EMI get from MD */
+ phys_addr_t md_emi_phy_addr;
+ unsigned int md_emi_size;
+};
+
+typedef int(*CONSYS_IC_EMI_MPU_SET_REGION_PROTECTION) (void);
+typedef unsigned int(*CONSYS_IC_EMI_SET_REMAPPING_REG) (phys_addr_t, phys_addr_t);
+typedef void(*CONSYS_IC_EMI_GET_MD_SHARED_EMI) (phys_addr_t* phy_addr, unsigned int *size);
+typedef unsigned int (*CONSYS_IC_GET_FW_EMI_SIZE)(void);
+
+struct consys_platform_emi_ops {
+ CONSYS_IC_EMI_MPU_SET_REGION_PROTECTION consys_ic_emi_mpu_set_region_protection;
+ CONSYS_IC_EMI_SET_REMAPPING_REG consys_ic_emi_set_remapping_reg;
+ CONSYS_IC_EMI_GET_MD_SHARED_EMI consys_ic_emi_get_md_shared_emi;
+ CONSYS_IC_GET_FW_EMI_SIZE consys_ic_emi_get_fw_emi_size;
+};
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+int emi_mng_init(struct platform_device *pdev, const struct conninfra_plat_data* plat_data);
+int emi_mng_deinit(void);
+
+int emi_mng_set_region_protection(void);
+int emi_mng_set_remapping_reg(void);
+struct consys_emi_addr_info* emi_mng_get_phy_addr(void);
+
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _PLATFORM_EMI_MNG_H_ */
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/plat_def.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/plat_def.h
new file mode 100755
index 0000000..7c2a4f6
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/plat_def.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_DEF_H_
+#define _PLATFORM_DEF_H_
+
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#define mt_reg_sync_writel(v, a) \
+ do { \
+ writel((v), (void __force __iomem *)((a))); \
+ mb(); \
+ } while (0)
+
+#endif /* _PLATFORM_DEF_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/pmic_mng.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/pmic_mng.h
new file mode 100755
index 0000000..8ee3243
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/include/pmic_mng.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_PMIC_MNG_H_
+#define _PLATFORM_PMIC_MNG_H_
+
+#include <linux/platform_device.h>
+
+#include "consys_hw.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+typedef int(*CONSYS_PMIC_GET_FROM_DTS) (
+ struct platform_device *pdev,
+ struct conninfra_dev_cb* dev_cb);
+
+typedef int(*CONSYS_PMIC_COMMON_POWER_CTRL) (unsigned int enable);
+
+typedef int(*CONSYS_PMIC_WIFI_POWER_CTRL) (unsigned int enable);
+typedef int(*CONSYS_PMIC_BT_POWER_CTRL) (unsigned int enable);
+typedef int(*CONSYS_PMIC_GPS_POWER_CTRL) (unsigned int enable);
+typedef int(*CONSYS_PMIC_FM_POWER_CTRL) (unsigned int enable);
+typedef int(*CONSYS_PMIC_EVENT_NOTIFIER) (unsigned int id, unsigned int event);
+
+struct consys_platform_pmic_ops {
+ CONSYS_PMIC_GET_FROM_DTS consys_pmic_get_from_dts;
+ /* vcn 18 */
+ CONSYS_PMIC_COMMON_POWER_CTRL consys_pmic_common_power_ctrl;
+ CONSYS_PMIC_WIFI_POWER_CTRL consys_pmic_wifi_power_ctrl;
+ CONSYS_PMIC_BT_POWER_CTRL consys_pmic_bt_power_ctrl;
+ CONSYS_PMIC_GPS_POWER_CTRL consys_pmic_gps_power_ctrl;
+ CONSYS_PMIC_FM_POWER_CTRL consys_pmic_fm_power_ctrl;
+ CONSYS_PMIC_EVENT_NOTIFIER consys_pmic_event_notifier;
+};
+
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+int pmic_mng_init(
+ struct platform_device *pdev,
+ struct conninfra_dev_cb* dev_cb,
+ const struct conninfra_plat_data* plat_data);
+int pmic_mng_deinit(void);
+
+int pmic_mng_common_power_ctrl(unsigned int enable);
+int pmic_mng_wifi_power_ctrl(unsigned int enable);
+int pmic_mng_bt_power_ctrl(unsigned int enable);
+int pmic_mng_gps_power_ctrl(unsigned int enable);
+int pmic_mng_fm_power_ctrl(unsigned int enable);
+int pmic_mng_event_cb(unsigned int id, unsigned int event);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _PLATFORM_PMIC_MNG_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/include/mt6880.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/include/mt6880.h
new file mode 100755
index 0000000..a360124
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/include/mt6880.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_MT6880_H_
+#define _PLATFORM_MT6880_H_
+
+enum conn_semaphore_type
+{
+ CONN_SEMA_CHIP_POWER_ON_INDEX = 0,
+ CONN_SEMA_CALIBRATION_INDEX = 1,
+ CONN_SEMA_FW_DL_INDEX = 2,
+ CONN_SEMA_CLOCK_SWITCH_INDEX = 3,
+ CONN_SEMA_CCIF_INDEX = 4,
+ CONN_SEMA_COEX_INDEX = 5,
+ CONN_SEMA_USB_EP0_INDEX = 6,
+ CONN_SEMA_USB_SHARED_INFO_INDEX = 7,
+ CONN_SEMA_USB_SUSPEND_INDEX = 8,
+ CONN_SEMA_USB_RESUME_INDEX = 9,
+ CONN_SEMA_PCIE_INDEX = 10,
+ CONN_SEMA_RFSPI_INDEX = 11,
+ CONN_SEMA_EFUSE_INDEX = 12,
+ CONN_SEMA_THERMAL_INDEX = 13,
+ CONN_SEMA_FLASH_INDEX = 14,
+ CONN_SEMA_DEBUG_INDEX = 15,
+ CONN_SEMA_WIFI_LP_INDEX = 16,
+ CONN_SEMA_PATCH_DL_INDEX = 17,
+ CONN_SEMA_SHARED_VAR_INDEX = 18,
+ CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX = 19,
+ CONN_SEMA_NUM_MAX = 32 /* can't be omitted */
+};
+
+int consys_platform_spm_conn_ctrl(unsigned int enable);
+int consys_co_clock_type(void);
+
+struct consys_plat_thermal_data {
+ int thermal_b;
+ int slop_molecule;
+ int offset;
+ unsigned int efuse0;
+ unsigned int efuse1;
+ unsigned int efuse2;
+ unsigned int efuse3;
+};
+
+void update_thermal_data(struct consys_plat_thermal_data* input);
+#endif /* _PLATFORM_MT6880_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/include/mt6880_consys_reg.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/include/mt6880_consys_reg.h
new file mode 100755
index 0000000..2cb7ebd
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/include/mt6880_consys_reg.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_MT6880_CONSYS_REG_H_
+#define _PLATFORM_MT6880_CONSYS_REG_H_
+
+#include "consys_reg_base.h"
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+enum consys_base_addr_index {
+ CONN_INFRA_RGU_BASE = 0, /* 0x1800_0000 */
+ CONN_INFRA_CFG_BASE = 1, /* 0x1800_1000 */
+ CONN_HOST_CSR_TOP_BASE = 2, /* 0x1806_0000 */
+ INFRACFG_AO_BASE = 3, /* 0x1000_1000 */
+ TOPRGU_BASE = 4, /* 0x1000_7000 */
+ SPM_BASE = 5, /* 0x1000_6000 */
+ INFRACFG_BASE = 6, /* 0x1020_e000 */
+ CONN_WT_SLP_CTL_REG = 7, /* 0x1800_5000 */
+ CONN_AFE_CTL = 8, /* 0x1800_3000 */
+ GPIO_BASE = 9, /* 0x1000_5000 */
+ CONN_RF_SPI_MST_REG_BASE = 10, /* 0x1800_4000 */
+ CONN_SEMAPHORE_BASE = 11, /* 0x1807_0000 */
+ CONN_TOP_THERM_CTL_BASE = 12, /* 0x1800_2000 */
+ IOCFG_BM_BASE = 13, /* 0x11d1_0000 */
+ CONN_DEBUG_CTRL = 14, /* 0x1800_F000 */
+ CONN_INFRA_CLKGEN_ON_TOP = 15, /* 0x1800_9000 */
+ CONN_INFRA_BUS_CR = 16, /* 0x1800_E000, offset 0x200~0x334 */
+ CONN_INFRA_DEBUG_CTRL_AO = 17, /* 0x1802_f000, offset 0x0~0x424 */
+
+ CONSYS_BASE_ADDR_MAX
+};
+
+
+struct consys_base_addr {
+ struct consys_reg_base_addr reg_base_addr[CONSYS_BASE_ADDR_MAX];
+};
+
+extern struct consys_base_addr conn_reg;
+
+#define REG_CONN_INFRA_RGU_ADDR conn_reg.reg_base_addr[CONN_INFRA_RGU_BASE].vir_addr
+#define REG_CONN_INFRA_CFG_ADDR conn_reg.reg_base_addr[CONN_INFRA_CFG_BASE].vir_addr
+#define REG_CONN_HOST_CSR_ADDR conn_reg.reg_base_addr[CONN_HOST_CSR_TOP_BASE].vir_addr
+#define REG_INFRACFG_AO_ADDR conn_reg.reg_base_addr[INFRACFG_AO_BASE].vir_addr
+
+#define REG_TOP_RGU_ADDR conn_reg.reg_base_addr[TOPRGU_BASE].vir_addr
+#define REG_SPM_BASE_ADDR conn_reg.reg_base_addr[SPM_BASE].vir_addr
+#define REG_INFRACFG_BASE_ADDR conn_reg.reg_base_addr[INFRACFG_BASE].vir_addr
+#define REG_CONN_WT_SPL_CTL_ADDR conn_reg.reg_base_addr[CONN_WT_SLP_CTL_REG].vir_addr
+
+#define REG_CONN_AFE_CTL_BASE_ADDR conn_reg.reg_base_addr[CONN_AFE_CTL].vir_addr
+#define REG_GPIO_BASE_ADDR conn_reg.reg_base_addr[GPIO_BASE].vir_addr
+#define REG_CONN_RFSPI_ADDR conn_reg.reg_base_addr[CONN_RF_SPI_MST_REG_BASE].vir_addr
+#define REG_CONN_SEMAPHORE_ADDR conn_reg.reg_base_addr[CONN_SEMAPHORE_BASE].vir_addr
+
+#define REG_CONN_TOP_THERM_CTL_ADDR conn_reg.reg_base_addr[CONN_TOP_THERM_CTL_BASE].vir_addr
+#define REG_IOCFG_BM_ADDR conn_reg.reg_base_addr[IOCFG_BM_BASE].vir_addr
+#define REG_CONN_DEBUG_CTRL_ADDR conn_reg.reg_base_addr[CONN_DEBUG_CTRL].vir_addr
+#define REG_CONN_INFRA_CLKGEN_ON_TOP_ADDR conn_reg.reg_base_addr[CONN_INFRA_CLKGEN_ON_TOP].vir_addr
+
+#define REG_CONN_INFRA_BUS_CR_ADDR conn_reg.reg_base_addr[CONN_INFRA_BUS_CR].vir_addr
+#define REG_CONN_INFRA_DEBUG_CTRL_AO conn_reg.reg_base_addr[CONN_INFRA_DEBUG_CTRL_AO].vir_addr
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+struct consys_base_addr* get_conn_reg_base_addr(void);
+
+#endif /* _PLATFORM_MT6880_CONSYS_REG_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/include/mt6880_consys_reg_offset.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/include/mt6880_consys_reg_offset.h
new file mode 100755
index 0000000..57112a3
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/include/mt6880_consys_reg_offset.h
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_MT6880_CONSYS_REG_OFFSET_H_
+#define _PLATFORM_MT6880_CONSYS_REG_OFFSET_H_
+
+/**********************************************************************/
+/* Base: infracfg_ao (0x1000_1000) */
+/**********************************************************************/
+#define INFRA_TOPAXI_PROTECTEN 0x0220
+#define INFRA_TOPAXI_PROTECTEN_STA1 0x0228
+#define INFRA_TOPAXI_PROTECTEN_SET 0x02a0
+#define INFRA_TOPAXI_PROTECTEN_CLR 0x02a4
+
+/**********************************************************************/
+/* Base: GPIO (0x1000_5000) */
+/**********************************************************************/
+#define GPIO_MODE15_SET 0x03f4
+#define GPIO_MODE15_CLR 0x03f8
+#define GPIO_MODE16_SET 0x0404
+#define GPIO_MODE16_CLR 0x0408
+
+/**********************************************************************/
+/* Base: SPM (0x1000_6000) */
+/**********************************************************************/
+#define SPM_POWERON_CONFIG_EN 0x0000
+#define SPM_PCM_REG0_DATA 0x0100
+#define SPM_PCM_REG13_DATA 0x0110
+#define SPM_SRC_REQ_STA_0 0x0114
+#define SPM_PWR_STATUS 0x016c
+#define SPM_PWR_STATUS_2ND 0x0170
+#define SPM_CONN_PWR_CON 0x0304
+#define SPM_RC_CMD_STA_0 0x0E04
+#define SPM_RC_M04_REQ_STA_0 0x0E28
+#define SPM_RC_M05_REQ_STA_0 0x0E2C
+#define SPM_RC_M06_REQ_STA_0 0x0E30
+#define SPM_RC_M07_REQ_STA_0 0x0E34
+
+/**********************************************************************/
+/* Base: TOP RGU (0x1000_7000) */
+/**********************************************************************/
+#define TOP_RGU_WDT_SWSYSRST 0x0018
+
+/**********************************************************************/
+/* Base: IOCFG_BM (0x11D1_0000) */
+/**********************************************************************/
+#define IOCFG_BM_DRV_CFG0_SET 0x0004
+#define IOCFG_BM_DRV_CFG0_CLR 0x0008
+#define IOCFG_BM_PD_CFG0_SET 0x00d4
+#define IOCFG_BM_PD_CFG0_CLR 0x00d8
+#define IOCFG_BM_PU_CFG0_SET 0x0114
+#define IOCFG_BM_PU_CFG0_CLR 0x0118
+
+
+/**********************************************************************/
+/* Base: conn_infra_rgu (0x1800_0000) */
+/**********************************************************************/
+#define CONN_INFRA_RGU_CONN_INFRA_OFF_TOP_PWR_CTL 0x0000
+#define CONN_INFRA_RGU_SYSRAM_HWCTL_PDN_SYSRAM_HWCTL_PDN 0x0050
+#define CONN_INFRA_RGU_SYSRAM_HWCTL_SLP_SYSRAM_HWCTL_SLP 0x0054
+
+/**********************************************************************/
+/* Base: conn_infra_cfg (0x1800_1000), offset 0x0~0x654 */
+/**********************************************************************/
+#define CONN_HW_VER_OFFSET 0x0000
+#define CONN_CFG_ID_OFFSET 0x0004
+#define AP2CONN_EFUSE_DATA 0x0020
+#define CONN_INFRA_CFG_ADIE_CTL 0x0030
+#define CONN_INFRA_CFG_PWRCTRL0 0x0200
+#define CONN_INFRA_CFG_OSC_CTL_0 0x0300
+#define CONN_INFRA_CFG_OSC_CTL_1 0x0304
+#define CONN_INFRA_CFG_RC_CTL_0 0x0380
+#define CONN_INFRA_CFG_RC_CTL_0_GPS 0x0390
+#define CONN_INFRA_CFG_RC_CTL_1_GPS 0x0394
+#define CONN_INFRA_CFG_RC_CTL_0_TOP 0x03c0
+#define CONN_INFRA_CFG_RC_CTL_1_TOP 0x03c4
+#define CONN_INFRA_CFG_EMI_CTL_0 0x0400
+#define CONN_INFRA_CONN2AP_SLP_STATUS 0x0504
+#define CONN_INFRA_AP2CONN_SLP_STATUS 0x0514
+#define CONN_INFRA_ON_BUS_SLP_STATUS 0x0524
+#define CONN_INFRA_OFF_BUS_SLP_STATUS 0x0534
+#define GALS_CONN2GPS_SLP_STATUS 0x0574
+#define GALS_GPS2CONN_SLP_STATUS 0x0584
+
+#define CONN_HW_VER 0x02030100
+#define CONN_CFG_ID 0x3
+
+
+
+/**********************************************************************/
+/* Base: conn_top_therm_ctl (0x1800_2000) */
+/**********************************************************************/
+#define CONN_TOP_THERM_CTL_THERMCR1 0x0004
+#define CONN_TOP_THERM_CTL_THERM_AADDR 0x0018
+#define CONN_TOP_THERM_CTL_THERM_CAL_EN 0x0024
+
+/**********************************************************************/
+/* Base: conn_afe_ctl(0x1800_3000) */
+/**********************************************************************/
+#define CONN_AFE_CTL_RG_DIG_EN_02 0x0004
+#define CONN_AFE_CTL_RG_PLL_STB_TIME 0x00f4
+
+/**********************************************************************/
+/* Base: conn_rf_spi_mst_reg(0x1800_4000) */
+/**********************************************************************/
+#define CONN_RF_SPI_MST_REG_SPI_STA 0x0000
+#define CONN_RF_SPI_MST_REG_SPI_CRTL 0x0004
+#define CONN_RF_SPI_MST_REG_FM_CTRL 0x000c
+#define CONN_RF_SPI_MST_REG_SPI_WF_ADDR 0x0010
+#define CONN_RF_SPI_MST_REG_SPI_WF_WDAT 0x0014
+#define CONN_RF_SPI_MST_REG_SPI_WF_RDAT 0x0018
+#define CONN_RF_SPI_MST_REG_SPI_BT_ADDR 0x0020
+#define CONN_RF_SPI_MST_REG_SPI_BT_WDAT 0x0024
+#define CONN_RF_SPI_MST_REG_SPI_BT_RDAT 0x0028
+#define CONN_RF_SPI_MST_REG_SPI_FM_ADDR 0x0030
+#define CONN_RF_SPI_MST_REG_SPI_FM_WDAT 0x0034
+#define CONN_RF_SPI_MST_REG_SPI_FM_RDAT 0x0038
+#define CONN_RF_SPI_MST_REG_SPI_TOP_ADDR 0x0050
+#define CONN_RF_SPI_MST_REG_SPI_TOP_WDAT 0x0054
+#define CONN_RF_SPI_MST_REG_SPI_TOP_RDAT 0x0058
+#define CONN_RF_SPI_MST_REG_SPI_GPS_GPS_ADDR 0x0210
+#define CONN_RF_SPI_MST_REG_SPI_GPS_GPS_WDAT 0x0214
+#define CONN_RF_SPI_MST_REG_SPI_GPS_GPS_RDAT 0x0218
+
+/**********************************************************************/
+/* Base: conn_wt_slp_ctl_reg(0x1800_5000) */
+/**********************************************************************/
+#define CONN_WT_SLP_CTL_REG_WB_SLP_CTL 0x0004
+#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR1 0x0010
+#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR2 0x0014
+#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR3 0x0018
+#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR4 0x001c
+#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR5 0x0020
+#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR6 0x0024
+#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR7 0x0028
+#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR8 0x002c
+#define CONN_WT_SLP_CTL_REG_WB_BG_ON1 0x0030
+#define CONN_WT_SLP_CTL_REG_WB_BG_ON2 0x0034
+#define CONN_WT_SLP_CTL_REG_WB_BG_ON3 0x0038
+#define CONN_WT_SLP_CTL_REG_WB_BG_ON4 0x003c
+#define CONN_WT_SLP_CTL_REG_WB_BG_ON5 0x0040
+#define CONN_WT_SLP_CTL_REG_WB_BG_ON6 0x0044
+#define CONN_WT_SLP_CTL_REG_WB_BG_ON7 0x0048
+#define CONN_WT_SLP_CTL_REG_WB_BG_ON8 0x004c
+#define CONN_WT_SLP_CTL_REG_WB_BG_OFF1 0x0050
+#define CONN_WT_SLP_CTL_REG_WB_BG_OFF2 0x0054
+#define CONN_WT_SLP_CTL_REG_WB_BG_OFF3 0x0058
+#define CONN_WT_SLP_CTL_REG_WB_BG_OFF4 0x005c
+#define CONN_WT_SLP_CTL_REG_WB_BG_OFF5 0x0060
+#define CONN_WT_SLP_CTL_REG_WB_BG_OFF6 0x0064
+#define CONN_WT_SLP_CTL_REG_WB_BG_OFF7 0x0068
+#define CONN_WT_SLP_CTL_REG_WB_BG_OFF8 0x006c
+#define CONN_WT_SLP_CTL_REG_WF_CK_ADDR 0x0070
+#define CONN_WT_SLP_CTL_REG_WF_WAKE_ADDR 0x0074
+#define CONN_WT_SLP_CTL_REG_WF_ZPS_ADDR 0x0078
+#define CONN_WT_SLP_CTL_REG_BT_CK_ADDR 0x007c
+#define CONN_WT_SLP_CTL_REG_BT_WAKE_ADDR 0x0080
+#define CONN_WT_SLP_CTL_REG_TOP_CK_ADDR 0x0084
+#define CONN_WT_SLP_CTL_REG_GPS_CK_ADDR 0x0088
+#define CONN_WT_SLP_CTL_REG_WF_B0_CMD_ADDR 0x008c
+#define CONN_WT_SLP_CTL_REG_WF_B1_CMD_ADDR 0x0090
+#define CONN_WT_SLP_CTL_REG_GPS_RFBUF_ADDR 0x0094
+#define CONN_WT_SLP_CTL_REG_GPS_L5_EN_ADDR 0x0098
+#define CONN_WT_SLP_WB_SLP_TOP_CK_0 0x0120
+
+/**********************************************************************/
+/* Base: conn_infra_gpt(0x1800_7000) */
+/**********************************************************************/
+#define CONN_INFRA_GPT_BASE 0x18007000
+#define GPT2_AP_ENABLE 0x0038
+
+/**********************************************************************/
+/* Base: conn_infra_clkgen_on_top(0x1800_9000) */
+/**********************************************************************/
+#define CONN_INFRA_CKGEN_BUS_BPLL_DIV_2 0x0004
+#define CONN_INFRA_CLKGEN_ON_TOP_CKGEN_BUS 0x0a00
+
+/**********************************************************************/
+/* Base: conn_infra_bus_cr (0x1800_E000), offset 0x200~0x334 */
+/**********************************************************************/
+#define CONN_INFRA_BUS_CR_GALS_AP2CONN_GALS_DBG 0x02a0
+#define CONN_INFRA_BUS_CR_GALS_CONN2AP_GALS_DBG 0x02a4
+#define CONN_INFRA_BUS_CR_GALS_GPS2CONN_GALS_DBG 0x02B0
+#define CONN_INFRA_BUS_CR_GALS_CONN2GPS_GALS_DBG 0x02B4
+#define CONN_INFRA_BUS_CR_GALS_CONN2GPS_CTRL_0 0x02CC
+#define CONN_INFRA_BUS_OFF_TIMEOUT_CTRL 0x0300
+#define CONN_INFRA_BUS_ON_TIMEOUT_CTRL 0x031C
+
+/**********************************************************************/
+/* Base: debug_ctrl (0x1800_f000) */
+/**********************************************************************/
+#define CONN_DEBUG_CTRL_REG_OFFSET 0x0000
+
+/**********************************************************************/
+/* Base: conn_infra_debug_ctrl_ao (0x1802_f000) */
+/**********************************************************************/
+#define CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_CTRL0 0x000
+#define CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_CTRL1 0x004
+#define CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_CTRL2 0x008
+#define CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_RESULT0 0x400
+#define CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_RESULT1 0x404
+#define CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_RESULT2 0x408
+#define CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_RESULT3 0x40C
+#define CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_RESULT4 0x410
+#define CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_RESULT5 0x414
+#define CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_RESULT6 0x418
+#define CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_RESULT7 0x41C
+#define CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_RESULT8 0x420
+#define CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_RESULT9 0x424
+
+
+/**********************************************************************/
+/* Base: conn_host_csr_top (0x1806_0000) */
+/**********************************************************************/
+#define CONN_INFRA_ON_BUS_TIMEOUT_IRQ 0x014c
+#define CONN_HOST_CSR_TOP_CONN_INFRA_CFG_DBG_SEL 0x015c
+#define CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP 0x01a0
+#define CONN2AP_REMAP_GPS_PERI_BASE_ADDR 0x01dc
+#define CONN_HOST_CSR_TOP_DBG_DUMMY_0 0x02c0
+#define CONN_HOST_CSR_TOP_DBG_DUMMY_2 0x02c8
+#define CONN_HOST_CSR_TOP_DBG_DUMMY_3 0x02cc
+#define CONN_HOST_CSR_TOP_DBG_DUMMY_5 0x02d4
+#define CONN_HOST_CSR_TOP_CONN_INFRA_BUS_OFF_DBG_1 0x0414
+#define CONN_HOST_CSR_TOP_CONN_INFRA_BUS_OFF_DBG_2 0x0418
+#define CONN_HOST_CSR_TOP_CONN_INFRA_BUS_OFF_TOP_DBG_1 0x041C
+#define CONN_HOST_CSR_TOP_CONN_INFRA_BUS_OFF_TOP_DBG_2 0x0420
+#define CONN_HOST_CSR_TOP_CONN_INFRA_BUS_ON_TOP_DBG_APB_1 0x042C
+#define CONN_HOST_CSR_TOP_CONN_INFRA_BUS_ON_TOP_DBG_APB_2 0x0430
+
+
+
+#define TOP_BUS_MUC_STAT_HCLK_FR_CK_DETECT_BIT (0x1 << 1)
+#define TOP_BUS_MUC_STAT_OSC_CLK_DETECT_BIT (0x1 << 2)
+
+/**********************************************************************/
+/* Base: conn_semaphore(0x1807_0000) */
+/**********************************************************************/
+#define CONN_SEMA_OWN_BY_M0_STA_REP 0x0400
+#define CONN_SEMA_OWN_BY_M1_STA_REP 0x1400
+#define CONN_SEMAPHORE_M2_OWN_STA 0x2000
+#define CONN_SEMAPHORE_M2_OWN_REL 0x2200
+#define CONN_SEMA_OWN_BY_M2_STA_REP 0x2400
+#define CONN_SEMA_OWN_BY_M3_STA_REP 0x3400
+
+/**********************************************************************/
+/* A-die CR */
+/**********************************************************************/
+#define ATOP_CHIP_ID 0x02c
+#define ATOP_RG_TOP_THADC_BG 0x034
+#define ATOP_RG_TOP_THADC 0x038
+#define ATOP_EFUSE_CTRL 0x108
+#define ATOP_EFUSE_RDATA0 0x130
+#define ATOP_EFUSE_RDATA1 0x134
+#define ATOP_EFUSE_RDATA2 0x138
+#define ATOP_EFUSE_RDATA3 0x13c
+#define ATOP_RG_TOP_XTAL_01 0xA18
+#define ATOP_RG_TOP_XTAL_02 0xA1C
+
+#endif /* _PLATFORM_MT6880_CONSSY_REG_OFFSET_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/include/mt6880_pmic.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/include/mt6880_pmic.h
new file mode 100755
index 0000000..de954ad
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/include/mt6880_pmic.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_MT6880_PMIC_H_
+#define _PLATFORM_MT6880_PMIC_H_
+
+#include "osal.h"
+#include "pmic_mng.h"
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+struct consys_platform_pmic_ops* get_consys_platform_pmic_ops(void);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _PLATFORM_MT6880_PMIC_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/include/mt6880_pos.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/include/mt6880_pos.h
new file mode 100755
index 0000000..50ad78d
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/include/mt6880_pos.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_MT6880_POS_H_
+#define _PLATFORM_MT6880_POS_H_
+
+
+unsigned int consys_emi_set_remapping_reg(phys_addr_t, phys_addr_t);
+
+int consys_conninfra_on_power_ctrl(unsigned int enable);
+int consys_conninfra_wakeup(void);
+int consys_conninfra_sleep(void);
+void consys_set_if_pinmux(unsigned int enable);
+int consys_polling_chipid(void);
+
+int connsys_d_die_cfg(void);
+int connsys_spi_master_cfg(unsigned int);
+int connsys_a_die_cfg(void);
+int connsys_afe_wbg_cal(void);
+int connsys_subsys_pll_initial(void);
+int connsys_low_power_setting(unsigned int, unsigned int);
+
+int consys_sema_acquire_timeout(unsigned int index, unsigned int usec);
+void consys_sema_release(unsigned int index);
+
+int consys_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data);
+int consys_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data);
+int consys_spi_write_offset_range(
+ enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int value,
+ unsigned int reg_offset, unsigned int value_offset, unsigned int size);
+
+int consys_spi_clock_switch(enum connsys_spi_speed_type type);
+int consys_subsys_status_update(bool, int);
+bool consys_is_rc_mode_enable(void);
+
+#endif /* _PLATFORM_MT6880_POS_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/mt6880.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/mt6880.c
new file mode 100755
index 0000000..c0a178e
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/mt6880.c
@@ -0,0 +1,440 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__
+
+#include <linux/delay.h>
+#include <linux/memblock.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/thermal.h>
+#include <mtk-clkbuf-bridge.h>
+
+#include <connectivity_build_in_adapter.h>
+
+#include "osal.h"
+#include "conninfra.h"
+#include "conninfra_conf.h"
+#include "consys_hw.h"
+#include "consys_reg_mng.h"
+#include "consys_reg_util.h"
+#include "mt6880.h"
+#include "emi_mng.h"
+#include "mt6880_consys_reg.h"
+#include "mt6880_consys_reg_offset.h"
+#include "mt6880_pos.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+#define PLATFORM_SOC_CHIP 0x6880
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+static int consys_clk_get_from_dts(struct platform_device *pdev);
+static int consys_clk_detach(void);
+static int consys_clock_buffer_ctrl(unsigned int enable);
+static unsigned int consys_soc_chipid_get(void);
+static unsigned int consys_get_hw_ver(void);
+static void consys_clock_fail_dump(void);
+static int consys_thermal_query(void);
+static int consys_power_state(void);
+static int consys_thermal_register(struct platform_device *pdev, struct conninfra_dev_cb* dev_cb);
+static int consys_thermal_get_temp_cb(void*, int*);
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+struct consys_hw_ops_struct g_consys_hw_ops_mt6880 = {
+ /* load from dts */
+ /* TODO: mtcmos should move to a independent module */
+ .consys_plt_clk_get_from_dts = consys_clk_get_from_dts,
+ .consys_plt_clk_detach = consys_clk_detach,
+
+ /* clock */
+ .consys_plt_clock_buffer_ctrl = consys_clock_buffer_ctrl,
+ .consys_plt_co_clock_type = consys_co_clock_type,
+
+ /* POS */
+ .consys_plt_conninfra_on_power_ctrl = consys_conninfra_on_power_ctrl,
+ .consys_plt_set_if_pinmux = consys_set_if_pinmux,
+
+ .consys_plt_polling_consys_chipid = consys_polling_chipid,
+ .consys_plt_d_die_cfg = connsys_d_die_cfg,
+ .consys_plt_spi_master_cfg = connsys_spi_master_cfg,
+ .consys_plt_a_die_cfg = connsys_a_die_cfg,
+ .consys_plt_afe_wbg_cal = connsys_afe_wbg_cal,
+ .consys_plt_subsys_pll_initial = connsys_subsys_pll_initial,
+ .consys_plt_low_power_setting = connsys_low_power_setting,
+ .consys_plt_soc_chipid_get = consys_soc_chipid_get,
+ .consys_plt_conninfra_wakeup = consys_conninfra_wakeup,
+ .consys_plt_conninfra_sleep = consys_conninfra_sleep,
+ .consys_plt_is_rc_mode_enable = consys_is_rc_mode_enable,
+
+ /* debug */
+ .consys_plt_clock_fail_dump = consys_clock_fail_dump,
+ .consys_plt_get_hw_ver = consys_get_hw_ver,
+
+ .consys_plt_spi_read = consys_spi_read,
+ .consys_plt_spi_write = consys_spi_write,
+ .consys_plt_adie_top_ck_en_on = NULL,
+ .consys_plt_adie_top_ck_en_off = NULL,
+ .consys_plt_spi_clock_switch = NULL,
+ .consys_plt_subsys_status_update = NULL,
+
+ .consys_plt_thermal_query = consys_thermal_query,
+ .consys_plt_thermal_register = consys_thermal_register,
+ .consys_plt_power_state = consys_power_state,
+ .consys_plt_config_setup = NULL,
+ .consys_plt_bus_clock_ctrl = NULL,
+};
+
+
+struct consys_plat_thermal_data g_consys_plat_therm_data;
+
+/* For mt6880 */
+extern struct consys_hw_ops_struct g_consys_hw_ops_mt6880;
+extern struct consys_reg_mng_ops g_dev_consys_reg_ops_mt6880;
+extern struct consys_platform_emi_ops g_consys_platform_emi_ops_mt6880;
+extern struct consys_platform_pmic_ops g_consys_platform_pmic_ops_mt6880;
+
+const struct conninfra_plat_data mt6880_plat_data = {
+ .chip_id = PLATFORM_SOC_CHIP,
+ .hw_ops = &g_consys_hw_ops_mt6880,
+ .reg_ops = &g_dev_consys_reg_ops_mt6880,
+ .platform_emi_ops = &g_consys_platform_emi_ops_mt6880,
+ .platform_pmic_ops = &g_consys_platform_pmic_ops_mt6880,
+};
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+#if MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE
+static struct platform_device *connsys_pdev;
+#endif
+
+static const struct thermal_zone_of_device_ops tz_conninfra_thermal_ops = {
+ .get_temp = consys_thermal_get_temp_cb,
+};
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+/* mtcmos contorl */
+int consys_clk_get_from_dts(struct platform_device *pdev)
+{
+#if MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE
+ if (pdev == NULL) {
+ pr_err("%s pdev is null", __func__);
+ return -1;
+ }
+ connsys_pdev = pdev;
+ pm_runtime_enable(&connsys_pdev->dev);
+#else
+ pr_info("MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE not support");
+
+#endif /* #if MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE */
+ return 0;
+}
+
+int consys_clk_detach(void)
+{
+#if MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE
+ if (connsys_pdev == NULL)
+ return 0;
+ pm_runtime_disable(&connsys_pdev->dev);
+#endif
+ return 0;
+}
+
+int consys_platform_spm_conn_ctrl(unsigned int enable)
+{
+ int ret = 0;
+
+#if MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE
+ if (enable) {
+ ret = pm_runtime_get_sync(&connsys_pdev->dev);
+ if (ret) {
+ pr_err("Turn on oonn_infra power fail. Ret=%d", ret);
+ return -1;
+ }
+ } else {
+ ret = pm_runtime_put_sync(&connsys_pdev->dev);
+ if (ret) {
+ pr_err("Turn off conn_infra power fail. Ret=%d", ret);
+ return -1;
+ }
+
+ }
+#else
+ pr_err("Function: %s is not support", __func__);
+#endif
+ return ret;
+}
+
+int consys_clock_buffer_ctrl(unsigned int enable)
+{
+ /* This function call didn't work now.
+ * clock buffer is HW controlled, not SW controlled.
+ * Keep this function call to update status.
+ */
+ if (enable)
+ clk_buf_ctrl(CLK_BUF_CONN, true); /*open XO_WCN*/
+ else
+ clk_buf_ctrl(CLK_BUF_CONN, false); /*close XO_WCN*/
+ return 0;
+}
+
+int consys_co_clock_type(void)
+{
+ const struct conninfra_conf *conf;
+
+ /* Default solution */
+ conf = conninfra_conf_get_cfg();
+ if (NULL == conf) {
+ pr_err("[%s] Get conf fail", __func__);
+ return -1;
+ }
+ /* TODO: for co-clock mode, there are two case: 26M and 52M. Need something to distinguish it. */
+ if (conf->tcxo_gpio != 0)
+ return CONNSYS_CLOCK_SCHEMATIC_26M_EXTCXO;
+ else
+ return CONNSYS_CLOCK_SCHEMATIC_26M_COTMS;
+}
+
+unsigned int consys_soc_chipid_get(void)
+{
+ return PLATFORM_SOC_CHIP;
+}
+
+unsigned int consys_get_hw_ver(void)
+{
+ return CONN_HW_VER;
+}
+
+void consys_clock_fail_dump(void)
+{
+ pr_info("[%s]", __func__);
+}
+
+
+void update_thermal_data(struct consys_plat_thermal_data* input)
+{
+ memcpy(&g_consys_plat_therm_data, input, sizeof(struct consys_plat_thermal_data));
+#if CFG_CONNINFRA_THERMAL_SUPPORT
+ /* Special factor, not in POS */
+ /* THERMCR1 [16:17]*/
+ CONSYS_REG_WRITE(REG_CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERMCR1,
+ (CONSYS_REG_READ(REG_CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERMCR1) |
+ (0x3 << 16)));
+#endif
+}
+
+#if CFG_CONNINFRA_THERMAL_SUPPORT
+int calculate_thermal_temperature(int y)
+{
+ struct consys_plat_thermal_data *data = &g_consys_plat_therm_data;
+ int t;
+ int const_offset = 25;
+
+ /*
+ * MT6635 E1 : read 0x02C = 0x66358A00
+ * MT6635 E2 : read 0x02C = 0x66358A10
+ * MT6635 E3 : read 0x02C = 0x66358A11
+ */
+ if (conn_hw_env.adie_hw_version == 0x66358A10 ||
+ conn_hw_env.adie_hw_version == 0x66358A11)
+ const_offset = 28;
+
+ /* temperature = (y-b)*slope + (offset) */
+ /* TODO: offset + 25 : this is only for E1, E2 is 28 */
+ t = (y - (data->thermal_b == 0 ? 0x36 : data->thermal_b)) *
+ ((data->slop_molecule + 209) / 100) + (data->offset + const_offset);
+
+ pr_info("y=[%d] b=[%d] constOffset=[%d] [%d] [%d] => t=[%d]\n",
+ y, data->thermal_b, const_offset, data->slop_molecule, data->offset,
+ t);
+
+ return t;
+}
+#endif /* CFG_CONNINFRA_THERMAL_SUPPORT */
+
+int consys_thermal_query(void)
+{
+#if CFG_CONNINFRA_THERMAL_SUPPORT
+
+#define THERMAL_DUMP_NUM 11
+#define LOG_TMP_BUF_SZ 256
+#define TEMP_SIZE 13
+ void __iomem *addr = NULL;
+ int cal_val, res = 0;
+ /* Base: 0x1800_2000, CONN_TOP_THERM_CTL */
+ const unsigned int thermal_dump_crs[THERMAL_DUMP_NUM] = {
+ 0x00, 0x04, 0x08, 0x0c,
+ 0x10, 0x14, 0x18, 0x1c,
+ 0x20, 0x24, 0x28,
+ };
+ char tmp[TEMP_SIZE] = {'\0'};
+ char tmp_buf[LOG_TMP_BUF_SZ] = {'\0'};
+ unsigned int i;
+
+ addr = ioremap_nocache(CONN_INFRA_GPT_BASE, 0x100);
+ if (addr == NULL) {
+ pr_err("GPT2_CTRL_BASE remap fail");
+ return -1;
+ }
+
+ /* Hold Semaphore, TODO: may not need this, because
+ thermal cr seperate for different */
+ if (consys_sema_acquire_timeout(CONN_SEMA_THERMAL_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) {
+ pr_err("[THERM QRY] Require semaphore fail\n");
+ iounmap(addr);
+ return -1;
+ }
+
+ /* therm cal en */
+ CONSYS_SET_BIT(REG_CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN, (0x1 << 19));
+ /* GPT2 En */
+ CONSYS_SET_BIT(addr + GPT2_AP_ENABLE, 0x1);
+
+ /* thermal trigger */
+ CONSYS_SET_BIT(REG_CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN, (0x1 << 18));
+ udelay(500);
+ /* get thermal value */
+ cal_val = CONSYS_REG_READ(REG_CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN);
+ cal_val = (cal_val >> 8) & 0x7f;
+
+ /* thermal debug dump */
+ for (i = 0; i < THERMAL_DUMP_NUM; i++) {
+ snprintf(
+ tmp, TEMP_SIZE, "[0x%08x]",
+ CONSYS_REG_READ(REG_CONN_TOP_THERM_CTL_ADDR + thermal_dump_crs[i]));
+ strncat(tmp_buf, tmp, strlen(tmp));
+ }
+ res = calculate_thermal_temperature(cal_val);
+ pr_info("[%s] temp=%dC (%dmC) efuse:[0x%08x][0x%08x][0x%08x][0x%08x] thermal dump: %s",
+ __func__, res, res*1000,
+ g_consys_plat_therm_data.efuse0, g_consys_plat_therm_data.efuse1,
+ g_consys_plat_therm_data.efuse2, g_consys_plat_therm_data.efuse3,
+ tmp_buf);
+
+ /* GPT2 disable, no effect on 6880 */
+ CONSYS_CLR_BIT(addr + GPT2_AP_ENABLE, 0x1);
+
+ /* disable */
+ CONSYS_CLR_BIT(REG_CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN, (0x1 << 19));
+
+ consys_sema_release(CONN_SEMA_THERMAL_INDEX);
+
+ iounmap(addr);
+
+ return (res*1000);
+#else
+ return THERMAL_TEMP_INVALID;
+#endif /* CFG_CONNINFRA_THERMAL_SUPPORT */
+
+}
+
+int consys_thermal_get_temp_cb(void* data, int* temp)
+{
+ struct conninfra_dev_cb *dev_cb = data;
+
+ if (dev_cb && dev_cb->conninfra_thermal_query_cb) {
+ dev_cb->conninfra_thermal_query_cb(NULL, temp);
+ } else {
+ pr_info("Thermal callback is not support");
+ if (temp)
+ *temp = THERMAL_TEMP_INVALID;
+ }
+
+ return 0;
+}
+
+
+int consys_thermal_register(struct platform_device *pdev, struct conninfra_dev_cb* dev_cb)
+{
+ struct thermal_zone_device *tzdev;
+
+ if (dev_cb->conninfra_thermal_query_cb == NULL)
+ pr_info("Thermal callback is not support");
+
+ /* register thermal zone */
+ tzdev = devm_thermal_zone_of_sensor_register(
+ &pdev->dev, 0, dev_cb, &tz_conninfra_thermal_ops);
+
+ return 0;
+}
+
+int consys_power_state(void)
+{
+#if CFG_CONNINFRA_POWER_STATUS_SUPPORT
+ const char* osc_str[] = {
+ "fm ", "gps ", "bgf ", "wf ", "ap2conn ", "conn_thm ", "conn_pta ", "conn_infra_bus "
+ };
+ char buf[256] = {'\0'};
+ int r;
+ int i;
+
+ /* Setup debug select to power state
+ * debug sel: 0x1806015C[2:0]=3'b000 (default value)
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_CFG_DBG_SEL,
+ 0x0, 0x7);
+
+ r = CONSYS_REG_READ(REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_DBG_DUMMY_2);
+ for (i = 0; i < 8; i++) {
+ if ((r & (0x1 << (18 + i))) > 0)
+ strncat(buf, osc_str[i], strlen(osc_str[i]));
+ }
+ pr_info("[%s] [0x%x] %s", __func__, r, buf);
+#endif
+ return 0;
+}
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/mt6880_consys_reg.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/mt6880_consys_reg.c
new file mode 100755
index 0000000..0668676
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/mt6880_consys_reg.c
@@ -0,0 +1,634 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#include <linux/memblock.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/random.h>
+
+#include <connectivity_build_in_adapter.h>
+
+#include "consys_reg_mng.h"
+#include "mt6880_consys_reg.h"
+#include "mt6880_consys_reg_offset.h"
+#include "consys_hw.h"
+#include "consys_reg_util.h"
+
+#define LOG_TMP_BUF_SZ 256
+#define CONSYS_POWER_MODE_LEGACY "Legacy"
+#define CONSYS_POWER_MODE_RC "RC"
+
+static int consys_reg_init(struct platform_device *pdev);
+static int consys_reg_deinit(void);
+static int consys_check_reg_readable(void);
+static int consys_is_consys_reg(unsigned int addr);
+static int consys_is_bus_hang(void);
+static int consys_dump_bus_status(void);
+static int consys_dump_conninfra_status(void);
+static int consys_is_host_csr(unsigned long addr);
+
+struct consys_reg_mng_ops g_dev_consys_reg_ops_mt6880 = {
+ .consys_reg_mng_init = consys_reg_init,
+ .consys_reg_mng_deinit = consys_reg_deinit,
+
+ .consys_reg_mng_check_reable = consys_check_reg_readable,
+ .consys_reg_mng_is_consys_reg = consys_is_consys_reg,
+ .consys_reg_mng_is_bus_hang = consys_is_bus_hang,
+ .consys_reg_mng_dump_bus_status = consys_dump_bus_status,
+ .consys_reg_mng_dump_conninfra_status = consys_dump_conninfra_status,
+ .consys_reg_mng_dump_cpupcr = NULL,
+ .consys_reg_mng_is_host_csr = consys_is_host_csr,
+
+ /* step */
+ .consys_reg_mng_validate_idx_n_offset = NULL,
+ .consys_reg_mng_find_can_write_reg = NULL,
+ .consys_reg_mng_get_phy_addr_by_idx = NULL,
+ .consys_reg_mng_get_virt_addr_by_idx = NULL,
+ .consys_reg_mng_get_chip_id_idx_offset = NULL,
+ .consys_reg_mng_get_reg_symbol_num = NULL
+};
+
+
+const char* consys_base_addr_index_to_str[CONSYS_BASE_ADDR_MAX] = {
+ "CONN_INFRA_RGU_BASE",
+ "CONN_INFRA_CFG_BASE",
+ "CONN_HOST_CSR_TOP_BASE",
+ "INFRACFG_AO_BASE",
+ "TOPRGU_BASE",
+ "SPM_BASE",
+ "INFRACFG_BASE",
+ "CONN_WT_SLP_CTL_REG",
+ "CONN_AFE_CTL_REG",
+ "GPIO",
+ "CONN_RF_SPI_MST_REG",
+ "CONN_SEMAPHORE",
+ "CONN_TOP_THERM_CTL",
+ "IOCFG_BM",
+ "CONN_DEBUG_CTL",
+ "CONN_INFRA_CLKGEN_ON_TOP",
+ "CONN_INFRA_BUS_CR",
+ "CONN_INFRA_DEBUG_CTRL_AO",
+};
+
+struct consys_base_addr conn_reg;
+
+struct consys_base_addr* get_conn_reg_base_addr()
+{
+ return &conn_reg;
+}
+#if CFG_CONNINFRA_BUS_HANG_DEBUG_SUPPORT
+static void consys_bus_hang_dump_c_host_csr(void)
+{
+ unsigned int r1, r2, r3, r4, r5, r6, r7, r8;
+ char tmp[LOG_TMP_BUF_SZ] = {'\0'};
+ char tmp_buf[LOG_TMP_BUF_SZ] = {'\0'};
+ unsigned int i;
+
+ /* CONN_INFRA_DBG No.5: gps2conn gals
+ * Read gals status for debug
+ * Dump 1800_E2B0 for gals slave
+ */
+ r1 = CONSYS_REG_READ(
+ REG_CONN_INFRA_BUS_CR_ADDR + CONN_INFRA_BUS_CR_GALS_GPS2CONN_GALS_DBG);
+
+ /* CONN_INFRA_DBG No.6: conn2gps gals
+ * Read gals status for debug
+ * 1. Read 1800_E2B4 (GALS_CONN2GPS_GALS_DBG)
+ * 2. Read 1800_E2CC[7:6] for gals idle signal
+ */
+ r2 = CONSYS_REG_READ(
+ REG_CONN_INFRA_BUS_CR_ADDR + CONN_INFRA_BUS_CR_GALS_CONN2GPS_GALS_DBG);
+ r3 = CONSYS_REG_READ(
+ REG_CONN_INFRA_BUS_CR_ADDR + CONN_INFRA_BUS_CR_GALS_CONN2GPS_CTRL_0);
+
+ /* CONN_INFRA_DBG No.7: conn_infra timeout mechanism
+ * 1. off domain AHB slaves hang result to timeout
+ * - Read 1806_0414, 1806_0418
+ * 2. on domain APB slaves hang result to timeout
+ * - Read 1806_042c, 1806_0430
+ */
+ r4 = CONSYS_REG_READ(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_BUS_OFF_DBG_1);
+ r5 = CONSYS_REG_READ(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_BUS_OFF_DBG_2);
+ r6 = CONSYS_REG_READ(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_BUS_ON_TOP_DBG_APB_1);
+ r7 = CONSYS_REG_READ(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_BUS_ON_TOP_DBG_APB_2);
+
+ /* CONN_INFRA_DBG No.8: bus_debug_monitor
+ * 1. Read 1802_F000[8] to confirm if the irq is resulted by bus hang
+ * timeout mechanisim
+ * 2. Read 0x 1802_F408 ~ 0x1802_F424 to see the command information
+ * which resulting bus hang
+ */
+ r8 = CONSYS_REG_READ(
+ REG_CONN_INFRA_DEBUG_CTRL_AO + CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_CTRL0);
+ for (i = 0x408; i <= 0x424; i += 4) {
+ snprintf(tmp, LOG_TMP_BUF_SZ, "[%x]",
+ CONSYS_REG_READ(REG_CONN_INFRA_DEBUG_CTRL_AO + i));
+ strncat(tmp_buf, tmp, strlen(tmp));
+ }
+
+ pr_info("[CONN_BUS_C_1][%x][%x][%x][%x][%x][%x][%x][%x]",
+ r1, r2, r3, r4, r5, r6, r7, r8);
+ pr_info("[CONN_BUS_C_2]%s", tmp_buf);
+}
+#endif
+
+static void consys_bus_hang_dump_c(void)
+{
+#if CFG_CONNINFRA_BUS_HANG_DEBUG_SUPPORT
+ char tmp[LOG_TMP_BUF_SZ] = {'\0'};
+ char tmp_buf[LOG_TMP_BUF_SZ] = {'\0'};
+ int i;
+ const static unsigned int conninfra_cfg_dump_list[] =
+ {0x504, 0x514, 0x524, 0x534, 0x574, 0x584};
+ const static unsigned int conninfra_bus_cr[] =
+ {0x2a0, 0x2a4, 0x2b0, 0x2b4, 0x2a0, 0x2a4};
+ void __iomem *addr = NULL;
+ unsigned int ary12, ary13;
+
+ consys_bus_hang_dump_c_host_csr();
+
+ /* ary12: 0x1020_E810 CONN2AP_GALS_SLV_DBG
+ * ary13: 0x1020_E814 AP2CONN_GALS_MST_DBG
+ */
+ addr = ioremap_nocache(0x1020E810, 0x20);
+ if (addr != NULL) {
+ ary12 = CONSYS_REG_READ(addr);
+ ary13 = CONSYS_REG_READ(addr + 0x4);
+ iounmap(addr);
+ } else {
+ ary12 = 0xdeaddead;
+ ary13 = 0xdeaddead;
+ pr_err("[%s] ioremap error", __func__);
+ }
+
+ /* CONN_INFRA_DBG No.2: sleep protect
+ * ary0: 0x1800_1504
+ * ary1: 0x1800_1514
+ * ary2: 0x1800_1524
+ * ary3: 0x1800_1534
+ * ary4: 0x1800_1574
+ * ary5: 0x1800_1584
+ * ary6: 0x1800_E2A0
+ * ary7: 0x1800_E2A4
+ * ary8: 0x1800_E2B0
+ * ary9: 0x1800_E2B4
+ */
+ /* CONN_INFRA_DBG No.3: ap2conn gals
+ * Read gals status for debug
+ * ary10: Read 1800_E2A0 for gals slave
+ */
+
+ /* CONN_INFRA_DBG No.4: conn2ap gals
+ * Read gals status for debug
+ * ary11: Read 1800_E2A4 for gals master
+ */
+
+ for (i = 0; i < sizeof(conninfra_cfg_dump_list)/sizeof(unsigned int); i++)
+ {
+ snprintf(tmp, LOG_TMP_BUF_SZ, "[%x]",
+ CONSYS_REG_READ(REG_CONN_INFRA_CFG_ADDR + conninfra_cfg_dump_list[i]));
+ strncat(tmp_buf, tmp, strlen(tmp));
+ }
+
+ for (i = 0; i < sizeof(conninfra_bus_cr)/sizeof(unsigned int); i++)
+ {
+ snprintf(tmp, LOG_TMP_BUF_SZ, "[%x]",
+ CONSYS_REG_READ(REG_CONN_INFRA_BUS_CR_ADDR + conninfra_bus_cr[i]));
+ strncat(tmp_buf, tmp, strlen(tmp));
+ }
+ pr_info("[CONN_BUS_C]%s[%x][%x]", tmp_buf, ary12, ary13);
+#endif
+}
+
+static void consys_bus_hang_dump_a(void)
+{
+#if CFG_CONNINFRA_BUS_HANG_DEBUG_SUPPORT
+ unsigned int r1, r2, r7, r8, r9, r10, r11, r12, r13;
+ void __iomem *addr = NULL;
+
+ /* SPM CR */
+ /* r1: PCM_REG13_DATA 0x1000_6110
+ * [4]: conn_ddr_en
+ * [13]: conn_state
+ * [14]: conn_srcclkena
+ * [15]: conn_apsrc_req
+ */
+ r1 = CONSYS_REG_READ(
+ REG_SPM_BASE_ADDR + SPM_PCM_REG13_DATA);
+
+ /* r2: SRC_REQ_STA_0 0x1000_6114
+ * [12]: CONN_SRCCLKENA
+ * [14]: CONN_INFRA_REQ
+ * [15]: CONN_APSRC_REQ
+ * [16]: CONN_VRF18_REQ
+ * [17]: CONN_DDR_EN
+ */
+ r2 = CONSYS_REG_READ(
+ REG_SPM_BASE_ADDR + SPM_SRC_REQ_STA_0);
+
+ /* r7: SPM debug CR 0x1000_6100
+ * 0x10006100[0] sc_26m_ck_off
+ * 1'b0: 26M on; 1'b1
+ * 0x10006100[3] sc_axi_ck_off
+ * 1'b0: bus ck on; 1'b1 bus ck off
+ * 0x10006100[5] sc_md26m_ck_off
+ * 1'b0: MD 26M on; 1'b1 MD 26M off
+ * 0x10006100[20] sc_cksq0_off
+ * 1'b0: clock square0 on; 1'b1 clock square off
+ */
+ r7 = CONSYS_REG_READ(
+ REG_SPM_BASE_ADDR + SPM_PCM_REG0_DATA);
+
+ /*
+ * 0x1000_6304[2] : pwr_on
+ * 0x1000_616c[1] : pwr_ack
+ * 0x1000_6304[3] : pwr_on_s
+ * 0x1000_6170[1] : pwr_ack_s
+ * 0x1000_6304[1] : iso_en
+ * 0x1000_6304[0] : ap_sw_rst
+ * r8: 0x1000_616C
+ * r9: 0x1000_6170
+ * r10: 0x1000_6304
+ */
+ r8 = CONSYS_REG_READ(
+ REG_SPM_BASE_ADDR + SPM_PWR_STATUS);
+ r9 = CONSYS_REG_READ(
+ REG_SPM_BASE_ADDR + SPM_PWR_STATUS_2ND);
+ r10 = CONSYS_REG_READ(
+ REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON);
+
+ /* r11: TOPCKGEN infra bus clock 0x10000010[2:0]
+ * 0: tck_26m_mx9_ck => 26M
+ * 1: mainpll_d4_d4 => 136.5M
+ * 2: mainpll_d7_d2 => 156M
+ * 3: mainpll_d4_d2 => 273M
+ * 4: mainpll_d5_d2 => 218.4M
+ * 5: mainpll_d6_d2 => 182M
+ * 6: osc_d4 => 65M
+ */
+ addr = ioremap_nocache(0x10000000, 0x20);
+ if (addr != NULL) {
+ r11 = CONSYS_REG_READ(addr + 0x10);
+ iounmap(addr);
+ } else {
+ r11 = 0xdeaddead;
+ pr_err("[%s] ioremap error", __func__);
+ }
+
+ /* ap2conn gals sleep protect status
+ * - 0x1000_1220 [13] / 0x1000_1228 [13] (rx/tx) (sleep protect enable ready)
+ * both of them should be 1'b0 (CR at ap side)
+ * r12 : 0x1000_1220 (rx)
+ * r13 : 0x1000_1228 (tx)
+ */
+ r12 = CONSYS_REG_READ(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN);
+ r13 = CONSYS_REG_READ(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1);
+
+ pr_info("[CONN_BUS_A] %s [%x][%x] [%x][%x][%x][%x] [%x] [%x][%x]",
+ CONSYS_POWER_MODE_LEGACY, r1, r2,
+ r7, r8, r9, r10,
+ r11,
+ r12, r13);
+#endif
+}
+
+static void consys_bus_hang_dump_b(void)
+{
+#if CFG_CONNINFRA_BUS_HANG_DEBUG_SUPPORT
+ unsigned int r1, r2, r3, r4, r5, r6, r7;
+
+ /* r1: 0x180602C0
+ * [4] conn_srcclkena_ack
+ * [5] conn_ap_bus_ack
+ * [6] conn_apsrc_ack
+ * [7] conn_ddr_en_ack
+ */
+ r1 = CONSYS_REG_READ(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_DBG_DUMMY_0);
+
+ /*****************
+ * Debug sel
+ *****************/
+ /* r2: 0x1806015C[2:0] = 3'b000 (default)
+ * Dump 0x180602C8
+ * [25]: conn_infra_bus_osc_en
+ * [24]: conn_pta_osc_en
+ * [23]: conn_thm_osc_en
+ * [22]: ap2conn_osc_en
+ * [21]: wfsys_osc_en
+ * [20]: bgfsys_osc_en
+ * [19]: gpssys_osc_en
+ * [18]: fmsys_osc_en
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_CFG_DBG_SEL,
+ 0x0, 0x7);
+ r2 = CONSYS_REG_READ(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_DBG_DUMMY_2);
+
+ /* r3: 0x1806015C[2:0] = 3'b010
+ * Dump 0x180602C8
+ * [12]: conn_srcclkena_0_bblpm_ack
+ * [13]: conn_srcclkena_0_fpm_ack
+ * [28]: conn_srcclkena_1_bblpm_ack
+ * [29]: conn_srcclkena_1_fpm_ack
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_CFG_DBG_SEL,
+ 0x2, 0x7);
+ r3 = CONSYS_REG_READ(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_DBG_DUMMY_2);
+
+ /* r4: 0x1806015C[2:0] = 3'b011
+ * Dump 0x180602C8
+ * [12]: conn_srcclkena_2_bblpm_ack
+ * [13]: conn_srcclkena_2_fpm_ack
+ * [28]: conn_srcclkena_3_bblpm_ack
+ * [29]: conn_srcclkena_3_fpm_ack
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_CFG_DBG_SEL,
+ 0x3, 0x7);
+ r4 = CONSYS_REG_READ(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_DBG_DUMMY_2);
+
+ /* r5: MTCMOS
+ * 0x1806_02CC[15]: power_enable
+ * 0x1806_02CC[14]: pwr_on
+ * 1'b0: power off; 1'b1: power on
+ * 0x1806_02CC[13]: pwr_ack
+ * 1'b0: power off; 1'b1: power on
+ * 0x1806_02CC[12]: pwr_on_s
+ * 1'b0: power off; 1'b1: power on
+ * 0x1806_02CC[11]: pwr_ack_s
+ * 1'b0: power off; 1'b1: power on
+ * 0x1806_02CC[10]: iso_en
+ * 1'b0: power on; 1'b1: power off
+ * 0x1806_02CC[9]: conn_infra_off_xreset_b
+ * 1'b0: power off; 1'b1: power on
+ * 0x1806_02CC[8]: conn_infra_off_hreset_b
+ * 1'b0: power off; 1'b1: power on
+ */
+ r5 = CONSYS_REG_READ(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_DBG_DUMMY_3);
+
+ /* Check conn_infra off bus clock
+ * - write 0x1 to 0x1806_0000[0], reset clock detect
+ * - 0x1806_0000[2] conn_infra off bus clock (should be 1'b1 if clock exist)
+ * - 0x1806_0000[1] osc clock (should be 1'b1 if clock exist)
+ */
+ CONSYS_SET_BIT(REG_CONN_HOST_CSR_ADDR, 0x1);
+ udelay(1);
+ r6 = CONSYS_REG_READ(REG_CONN_HOST_CSR_ADDR);
+
+ /* Check conn_infra off domain bus hang irq status
+ * - 0x1806_02D4[0], should be 1'b1, or means conn_infra off bus might hang
+ */
+ r7 = CONSYS_REG_READ(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_DBG_DUMMY_5);
+
+ pr_info("[CONN_BUS_B] %s [%x] [%x][%x][%x] [%x] [%x][%x]",
+ CONSYS_POWER_MODE_LEGACY, r1,
+ r2, r3, r4, /* debug select */
+ r5,
+ r6, r7);
+#endif
+}
+
+static int consys_dump_bus_status(void)
+{
+ consys_bus_hang_dump_c();
+ return 0;
+}
+
+static int consys_dump_conninfra_status(void)
+{
+ consys_bus_hang_dump_a();
+ consys_bus_hang_dump_b();
+ return 0;
+}
+
+static int consys_is_bus_hang(void)
+{
+ int ret = 0;
+#if CFG_CONNINFRA_BUS_HANG_DEBUG_SUPPORT
+ int r;
+
+ /* dump SPM register */
+ consys_bus_hang_dump_a();
+
+ /* ap2conn gals sleep protect status
+ * - 0x1000_1220 [13] / 0x1000_1228 [13] (rx/tx) (sleep protect enable ready)
+ * both of them should be 1'b0 ~(CR at ap side)
+ * 0x1000_1220 (rx)
+ * 0x1000_1228 (tx)
+ */
+ r = CONSYS_REG_READ_BIT(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN,
+ (0x1 << 13));
+ if (r != 0)
+ return CONNINFRA_AP2CONN_RX_SLP_PROT_ERR;
+ r = CONSYS_REG_READ_BIT(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1,
+ (0x1 << 13));
+ if (r != 0)
+ return CONNINFRA_AP2CONN_TX_SLP_PROT_ERR;
+
+ consys_bus_hang_dump_b();
+
+ /* AP2CONN_INFRA OFF
+ * 1. Check "AP2CONN_INFRA ON step is ok"
+ * 2. Check conn_infra off bus clock
+ * - write 0x1 to 0x1806_0000[0], reset clock detect
+ * - 0x1806_0000[2] conn_infra off bus clock (should be 1'b1 if clock exist)
+ * - 0x1806_0000[1] osc clock (should be 1'b1 if clock exist)
+ * 3. Check conn_infra off domain bus hang irq status
+ * - 0x1806_02d4[0], should be 1'b1, or means conn_infra off bus might hang
+ */
+ CONSYS_SET_BIT(REG_CONN_HOST_CSR_ADDR, 0x1);
+ udelay(1);
+ r = CONSYS_REG_READ(REG_CONN_HOST_CSR_ADDR);
+ if ((r & TOP_BUS_MUC_STAT_HCLK_FR_CK_DETECT_BIT) == 0 ||
+ (r & TOP_BUS_MUC_STAT_OSC_CLK_DETECT_BIT) == 0) {
+ pr_info("[%s] readable fail = bus clock", __func__);
+ consys_bus_hang_dump_c_host_csr();
+ return 0;
+ }
+
+ r = CONSYS_REG_READ_BIT(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_DBG_DUMMY_5, 0x1);
+ if (r == 0x0) {
+ ret |= CONNINFRA_INFRA_BUS_HANG_IRQ;
+ }
+
+ consys_bus_hang_dump_c();
+#endif /* CFG_CONNINFRA_BUS_HANG_DEBUG_SUPPORT */
+ return ret;
+
+}
+
+int consys_check_reg_readable(void)
+{
+#if CFG_CONNINFRA_BUS_HANG_DEBUG_SUPPORT
+ int r;
+ unsigned int rnd;
+ int delay_time = 1, spent = delay_time, max_wait = 16000; // 1.6 ms
+ int retry = max_wait / 10;
+
+ /* AP2CONN_INFRA ON */
+ /* 1. Check ap2conn gals sleep protect status
+ * - 0x1000_1220 [13] / 0x1000_1228 [13](rx/tx) (sleep protect enable ready)
+ * both of them should be 1'b0 (CR at ap side)
+ */
+ r = CONSYS_REG_READ_BIT(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN,
+ (0x1 << 13));
+ if (r != 0)
+ return 0;
+
+ r = CONSYS_REG_READ_BIT(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1,
+ (0x1 << 13));
+ if (r != 0)
+ return 0;
+
+ /* AP2CONN_INFRA OFF
+ * 1. Check "AP2CONN_INFRA ON step is ok"
+ * 2. Check conn_infra off bus clock
+ * - write 0x1 to 0x1806_0000[0], reset clock detect
+ * - 0x1806_0000[2] conn_infra off bus clock (should be 1'b1 if clock exist)
+ * - 0x1806_0000[1] osc clock (should be 1'b1 if clock exist)
+ * 3. Check conn_infra off domain bus hang irq status
+ * - 0x1806_02d4[0], should be 1'b1, or means conn_infra off bus might hang
+ */
+ while (retry > 0 && spent < max_wait) {
+ CONSYS_SET_BIT(REG_CONN_HOST_CSR_ADDR, 0x1);
+ udelay(delay_time);
+ r = CONSYS_REG_READ(REG_CONN_HOST_CSR_ADDR);
+ if ((r & TOP_BUS_MUC_STAT_HCLK_FR_CK_DETECT_BIT) == 0 ||
+ (r & TOP_BUS_MUC_STAT_OSC_CLK_DETECT_BIT) == 0) {
+ spent += delay_time;
+ retry--;
+ if (retry == 0)
+ pr_info("[%s] retry=0 r=[%x]", __func__, r);
+ else
+ delay_time = 10;
+ rnd = get_random_int() % 10;
+ spent += rnd;
+ udelay(rnd);
+ continue;
+ }
+ break;
+ }
+ if (retry == 0 || spent >= max_wait) {
+ pr_info("[%s] readable fail = bus clock retry=[%d] spent=[%d]", __func__,
+ retry, spent);
+ return 0;
+ }
+
+ r = CONSYS_REG_READ_BIT(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_DBG_DUMMY_5, 0x1);
+ if (r == 0x0)
+ return 0;
+
+#endif /* CFG_CONNINFRA_BUS_HANG_DEBUG_SUPPORT */
+ return 1;
+}
+
+
+int consys_is_consys_reg(unsigned int addr)
+{
+ return 0;
+}
+
+
+static int consys_is_host_csr(unsigned long addr)
+{
+ struct consys_reg_base_addr *host_csr_addr =
+ &conn_reg.reg_base_addr[CONN_HOST_CSR_TOP_BASE];
+
+ if (addr >= host_csr_addr->phy_addr &&
+ addr < host_csr_addr->phy_addr + host_csr_addr->size)
+ return 1;
+ return 0;
+}
+
+int consys_reg_init(struct platform_device *pdev)
+{
+ int ret = -1;
+ struct device_node *node = NULL;
+ struct consys_reg_base_addr *base_addr = NULL;
+ struct resource res;
+ int flag, i = 0;
+
+ node = pdev->dev.of_node;
+ pr_info("[%s] node=[%p]\n", __func__, node);
+ if (node) {
+ for (i = 0; i < CONSYS_BASE_ADDR_MAX; i++) {
+ base_addr = &conn_reg.reg_base_addr[i];
+
+ ret = of_address_to_resource(node, i, &res);
+ if (ret) {
+ pr_err("Get Reg Index(%d-%s) failed",
+ i, consys_base_addr_index_to_str[i]);
+ continue;
+ }
+
+ base_addr->phy_addr = res.start;
+ base_addr->vir_addr =
+ (unsigned long) of_iomap(node, i);
+ of_get_address(node, i, &(base_addr->size), &flag);
+
+ pr_info("Get Index(%d-%s) phy(0x%zx) baseAddr=(0x%zx) size=(0x%zx)",
+ i, consys_base_addr_index_to_str[i], base_addr->phy_addr,
+ base_addr->vir_addr, base_addr->size);
+ }
+
+ } else {
+ pr_err("[%s] can't find CONSYS compatible node\n", __func__);
+ return ret;
+ }
+ return 0;
+
+}
+
+static int consys_reg_deinit(void)
+{
+ int i = 0;
+
+ for (i = 0; i < CONSYS_BASE_ADDR_MAX; i++) {
+ if (conn_reg.reg_base_addr[i].vir_addr) {
+ pr_info("[%d] Unmap %s (0x%zx)",
+ i, consys_base_addr_index_to_str[i],
+ conn_reg.reg_base_addr[i].vir_addr);
+ iounmap((void __iomem*)conn_reg.reg_base_addr[i].vir_addr);
+ conn_reg.reg_base_addr[i].vir_addr = 0;
+ }
+ }
+
+ return 0;
+}
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/mt6880_emi.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/mt6880_emi.c
new file mode 100755
index 0000000..edd76ef
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/mt6880_emi.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__
+
+#include "consys_hw.h"
+#include "emi_mng.h"
+#include "mt6880_pos.h"
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+struct consys_platform_emi_ops g_consys_platform_emi_ops_mt6880 = {
+ .consys_ic_emi_mpu_set_region_protection = NULL,
+ .consys_ic_emi_set_remapping_reg = consys_emi_set_remapping_reg,
+ .consys_ic_emi_get_md_shared_emi = NULL,
+ .consys_ic_emi_get_fw_emi_size = NULL,
+};
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/mt6880_pmic.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/mt6880_pmic.c
new file mode 100755
index 0000000..13b08ad
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/mt6880_pmic.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__
+
+#include <connectivity_build_in_adapter.h>
+#include <linux/memblock.h>
+#include <linux/platform_device.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/regulator/consumer.h>
+#include <linux/notifier.h>
+
+#include "consys_hw.h"
+#include "consys_reg_util.h"
+#include "osal.h"
+#include "mt6880_pmic.h"
+#include "mt6880_pos.h"
+#include "mt6880_consys_reg.h"
+#include "mt6880_consys_reg_offset.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+static int consys_plt_pmic_get_from_dts(struct platform_device *pdev, struct conninfra_dev_cb* dev_cb);
+
+static int consys_plt_pmic_common_power_ctrl(unsigned int enable);
+static int consys_plt_pmic_gps_power_ctrl(unsigned int enable);
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+const struct consys_platform_pmic_ops g_consys_platform_pmic_ops_mt6880 = {
+ .consys_pmic_get_from_dts = consys_plt_pmic_get_from_dts,
+ .consys_pmic_common_power_ctrl = consys_plt_pmic_common_power_ctrl,
+ .consys_pmic_wifi_power_ctrl = NULL,
+ .consys_pmic_bt_power_ctrl = NULL,
+ .consys_pmic_gps_power_ctrl = consys_plt_pmic_gps_power_ctrl,
+ .consys_pmic_fm_power_ctrl = NULL,
+ .consys_pmic_event_notifier = NULL,
+};
+
+#if CFG_CONNINFRA_PMIC_SUPPORT
+struct regulator *reg_VCN18;
+#endif
+
+static struct conninfra_dev_cb* g_dev_cb;
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+int consys_plt_pmic_get_from_dts(struct platform_device *pdev, struct conninfra_dev_cb* dev_cb)
+{
+
+ g_dev_cb = dev_cb;
+#if CFG_CONNINFRA_PMIC_SUPPORT
+ reg_VCN18 = regulator_get(&pdev->dev, "vcn18");
+ if (!reg_VCN18)
+ pr_err("Regulator_get VCN_18 fail\n");
+#endif /* CFG_CONNINFRA_PMIC_SUPPORT */
+ return 0;
+}
+
+int consys_plt_pmic_common_power_ctrl(unsigned int enable)
+{
+#if CFG_CONNINFRA_PMIC_SUPPORT
+ int ret;
+
+ /* Only support legacy mode */
+ if (enable) {
+ /* Set PMIC VCN18 LDO SW_OP_EN =1, SW_EN = 1, SW_LP =0
+ * (sw enable & into normal mode)
+ */
+ /* SW_LP=0, default is 0 */
+ /* Setup voltage */
+ regulator_set_voltage(reg_VCN18, 1800000, 1800000);
+ /* SW_EN=1 */
+ ret = regulator_enable(reg_VCN18);
+ if (ret)
+ pr_err("[%s] regulator_enable return error %d", __func__, ret);
+ } else {
+ /* Set PMIC VCN18 LDO SW_OP_EN =0, SW_EN = 0, SW_LP =0 (sw disable)
+ */
+ regulator_disable(reg_VCN18);
+ }
+#endif /* CFG_CONNINFRA_PMIC_SUPPORT */
+ return 0;
+}
+
+int consys_plt_pmic_gps_power_ctrl(unsigned int enable)
+{
+ return 0;
+}
+
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/mt6880_pos.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/mt6880_pos.c
new file mode 100755
index 0000000..7bdf385
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6880/mt6880_pos.c
@@ -0,0 +1,1585 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+/* platform dependent */
+#include "plat_def.h"
+/* macro for read/write cr */
+#include "consys_reg_util.h"
+#include "consys_reg_mng.h"
+/* cr base address */
+#include "mt6880_consys_reg.h"
+/* cr offset */
+#include "mt6880_consys_reg_offset.h"
+/* For function declaration */
+#include "mt6880_pos.h"
+#include "mt6880.h"
+
+#include <linux/ratelimit.h>
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+#define CONN_INFRA_SYSRAM__A_DIE_DIG_TOP_CK_EN_MASK 0x7f
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+const static char* g_spi_system_name[SYS_SPI_MAX] = {
+ "SYS_SPI_WF1",
+ "SYS_SPI_WF",
+ "SYS_SPI_BT",
+ "SYS_SPI_FM",
+ "SYS_SPI_GPS",
+ "SYS_SPI_TOP",
+ "SYS_SPI_WF2",
+ "SYS_SPI_WF3",
+};
+
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+static int consys_spi_read_nolock(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data);
+static int consys_spi_write_nolock(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data);
+static void consys_spi_write_offset_range_nolock(
+ enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int value,
+ unsigned int reg_offset, unsigned int value_offset, unsigned int size);
+#if CFG_CONNINFRA_THERMAL_SUPPORT
+static int connsys_a_die_thermal_cal(
+ int efuse_valid,
+ unsigned int efuse0, unsigned int efuse1, unsigned int efuse2, unsigned int efuse3);
+#endif
+static int consys_polling_chipid_int(unsigned int retry, unsigned int sleep_ms);
+static int consys_adie_top_ck_en_top_ctrl(bool on);
+
+static int consys_sema_acquire(enum conn_semaphore_type index);
+
+unsigned int consys_emi_set_remapping_reg(
+ phys_addr_t con_emi_base_addr,
+ phys_addr_t md_shared_emi_base_addr)
+{
+ /* 0x1806_01DC[19:0], gps_ap_peri_base[19:0] = 0x0_1000 (un-related to emi)
+ * conn2ap peri ramappinng -> 0x1000_0000
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_HOST_CSR_ADDR + CONN2AP_REMAP_GPS_PERI_BASE_ADDR,
+ 0x01000, 0xFFFFF);
+
+ return 0;
+}
+
+int consys_conninfra_on_power_ctrl(unsigned int enable)
+{
+#if MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE
+ int ret;
+#else
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ int check;
+#endif
+#endif
+
+ if (enable) {
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* Turn on SPM clock (apply this for SPM's CONNSYS power control related CR accessing)
+ * address: 0x1000_6000[0]
+ * 0x1000_6000[31:16]
+ * Data: [0]=1'b1
+ * [31:16]=16'h0b16 (key)
+ * Action: write
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_SPM_BASE_ADDR + SPM_POWERON_CONFIG_EN, 0x0b160001, 0xffff0001);
+#endif
+
+ /* Power on Connsys MTCMOS */
+#if MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE
+ ret = consys_platform_spm_conn_ctrl(enable);
+ if (ret) {
+ pr_err("Turn on oonn_infra power fail.\n");
+ return -1;
+ }
+#else /* MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE */
+ pr_info("Turn on conn_infra power by POS steps\n");
+ /* Assert "conn_infra_on" primary part power on, set "connsys_on_domain_pwr_on"=1
+ * Address: 0x1000_6304[2]
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, (0x1<<2));
+
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* Check "conn_infra_on" primary part power status, check "connsys_on_domain_pwr_ack"=1
+ * (polling "10 times" and each polling interval is "0.5ms")
+ * Address: 0x1000_616C[1]
+ * Data: 1'b1
+ * Action: polling
+ */
+ check = 0;
+ CONSYS_REG_BIT_POLLING(REG_SPM_BASE_ADDR + SPM_PWR_STATUS, 1, 1, 10, 500, check);
+ if (check != 0)
+ pr_err("Check conn_infra_on primary power fail. 0x1000_616C is 0x%08x. Expect [1] as 1.\n",
+ CONSYS_REG_READ(REG_SPM_BASE_ADDR + SPM_PWR_STATUS));
+#endif
+
+ /* Assert "conn_infra_on" secondary part power on, set "connsys_on_domain_pwr_on_s"=1
+ * Address: 0x1000_6304[3]
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, (0x1<<3));
+
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* Check "conn_infra_on" secondary part power status,
+ * check "connsys_on_domain_pwr_ack_s"=1
+ * (polling "10 times" and each polling interval is "0.5ms")
+ * Address: 0x1000_6170[1]
+ * Data: 1'b1
+ * Action: polling
+ */
+ check = 0;
+ CONSYS_REG_BIT_POLLING(REG_SPM_BASE_ADDR + SPM_PWR_STATUS_2ND, 1, 1, 10, 500, check);
+ if (check != 0)
+ pr_err("Check conn_infra_on secondary power fail. 0x1000_6170 is 0x%08x. Expect [1] as 1.\n",
+ CONSYS_REG_READ(REG_SPM_BASE_ADDR + SPM_PWR_STATUS_2ND));
+#endif
+
+ /* Turn on AP-to-CONNSYS bus clock, set "conn_clk_dis"=0
+ * (apply this for bus clock toggling)
+ * Address: 0x1000_6304[4]
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, (0x1<<4));
+
+ /* Wait 1 us */
+ udelay(1);
+
+ /* De-assert "conn_infra_on" isolation, set "connsys_iso_en"=0
+ * Address: 0x1000_6304[1]
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, (0x1<<1));
+
+ /* De-assert CONNSYS S/W reset (TOP RGU CR),
+ * set "ap_sw_rst_b"=1
+ * Address: WDT_SWSYSRST[9] (0x1000_7018[9])
+ * WDT_SWSYSRST[31:24] (0x1000_7018[31:24])
+ * Data: [9]=1'b0
+ * [31:24]=8'h88 (key)
+ * Action: Write
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_TOP_RGU_ADDR + TOP_RGU_WDT_SWSYSRST, 0x88000000, 0xff000200);
+
+ /* De-assert CONNSYS S/W reset (SPM CR), set "ap_sw_rst_b"=1
+ * Address: CONN_PWR_CON[0] (0x1000_6304[0])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x1);
+
+ /* Wait 0.5ms */
+ udelay(500);
+
+ /* conn2ap/ap2conn slpprot disable */
+ /* Turn off AHB RX bus sleep protect (AP2CONN AHB Bus protect)
+ * (apply this for INFRA AHB bus accessing when CONNSYS had been turned on)
+ * Address: 0x1000_12A4[31:0] (INFRA_TOPAXI_PROTECTEN_CLR)
+ * Data: 32'h1000_0000
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_CLR, 0x10000000);
+
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* Check AHB RX bus sleep protect turn off
+ * (polling "100 times" and each polling interval is "0.5ms")
+ * Address: 0x1000_1228[28] (INFRA_TOPAXI_PROTECTEN2_STA1[2])
+ * Data: 1'b0
+ * Action: polling
+ */
+ check = 0;
+ CONSYS_REG_BIT_POLLING(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1, 28, 0x0, 100, 500, check);
+ if (check != 0)
+ pr_err("Polling AHB RX bus sleep protect turn off fail. status=0x%08x\n",
+ CONSYS_REG_READ(REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1));
+#endif
+
+ /* Turn off AXI Rx bus sleep protect (CONN2AP AXI Rx Bus protect)
+ * (disable sleep protection when CONNSYS had been turned on)
+ * Note : Should turn off AXI Rx sleep protection first.
+ * Address:
+ * INFRA_TOPAXI_PROTECTEN_CLR (0x1000_12A4[31:0])
+ * Value: 32'h0000_4000
+ * Action: write32
+ */
+ CONSYS_REG_WRITE(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_CLR, 0x00004000);
+
+ /* Turn off AXI TX bus sleep protect (AP2CONN AXI Bus protect)
+ * (apply this for INFRA AXI bus accessing when CONNSYS had been turned on)
+ *
+ * INFRA_TOPAXI_PROTECTEN_CLR (0x1000_12A4) = 32'h0800_0000
+ */
+ CONSYS_REG_WRITE(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_CLR, 0x08000000);
+
+ /* Turn off AHB TX bus sleep protect (AP2CONN AXI Bus protect)
+ * (apply this for INFRA AXI bus accessing when CONNSYS had been turned on)
+ *
+ * INFRA_TOPAXI_PROTECTEN_CLR (0x1000_12A4[31:0]) = 32'h0000_2000
+ */
+ CONSYS_REG_WRITE(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_CLR, 0x00002000);
+
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* Check AHB TX bus sleep protect turn off
+ * (polling ""100 times"" and each polling interval is ""0.5ms"")
+ * If AP2CONN (TX/RX) protect turn off fail, power on fail.
+ * (DRV access connsys CR will trigger bus hang,
+ * because bus transaction wiil queue at GALS, )
+ *
+ * INFRA_TOPAXI_PROTECTEN_STA1[13] (0x1000_1228[13]) = 1'b0
+ * Action: polling
+ * Note: AP2CONN AHB bus related setting
+ */
+ check = 0;
+ CONSYS_REG_BIT_POLLING(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1, 13, 0x0, 100, 500, check);
+ if (check != 0) {
+ pr_err("Polling 0x1000_1228[13] fail, exp is 0 but get 0x%08x",
+ CONSYS_REG_READ(REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1));
+ return -1;
+ }
+#endif /* CONFIG_FPGA_EARLY_PORTING */
+ /* Wait 6ms (apply this for CONNSYS XO clock ready) */
+ msleep(6);
+#endif /* MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE */
+ } else {
+ /* conn2ap/ap2conn slpprot enable */
+#if MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE
+ pr_info("Turn off conn_infra power by SPM API\n");
+ ret = consys_platform_spm_conn_ctrl(enable);
+ if (ret) {
+ pr_err("Turn off conn_infra power fail, ret=%d\n", ret);
+ return -1;
+ }
+#else
+ /* Turn on AHB TX bus sleep protect (AP2CONN AXI Bus protect)
+ * (apply this for INFRA AXI bus protection to prevent bus hang when
+ * CONNSYS had been turned off)
+ * Address: 0x1000_12a0[31:0]
+ * Data: 0x0000_2000
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_SET,
+ 0x00002000);
+
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* check AHB TX bus sleep protect turn on (polling "100 times")
+ * Address: 0x1000_1228[13]
+ * Data: 1'b1
+ * Action: polling
+ */
+ check = 0;
+ CONSYS_REG_BIT_POLLING(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1,
+ 13, 1, 100, 1000, check);
+ if (check)
+ pr_err("Polling AHB TX bus sleep protect turn on fail.\n");
+#endif /* CONFIG_FPGA_EARLY_PORTING */
+
+ /* Turn on AXI Tx bus sleep protect (CONN2AP AXI Tx Bus protect)
+ * (apply this for INFRA AXI bus protection to prevent bus hang
+ * when CONNSYS had been turned off)
+ * Note:
+ * Should turn on AXI Tx sleep protection first.
+ * Address:
+ * INFRA_TOPAXI_PROTECTEN_SET
+ * 0x1000_12A0[31:0]=32'h0800_0000
+ */
+ CONSYS_REG_WRITE(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_SET,
+ 0x08000000);
+
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* Check AXI Tx bus sleep protect turn on
+ * (polling "100 times", polling interval is 1ms)
+ * Address: INFRA_TOPAXI_PROTECTEN_STA1[27] (0x1000_1228[27])
+ * Value: 1'b1
+ */
+ check = 0;
+ CONSYS_REG_BIT_POLLING(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1,
+ 27, 1, 100, 1000, check);
+ if (check)
+ pr_err("Polling AXI Tx bus sleep protect turn on fail.");
+#endif
+
+ /* Turn on AXI Rx bus sleep protect (CONN2AP AXI RX Bus protect)
+ * (apply this for INFRA AXI bus protection to prevent bus hang when
+ * CONNSYS had been turned off)
+ * Note:
+ * Should turn on AXI Rx sleep protection after
+ * AXI Tx sleep protection has been turn on.
+ * Address: 0x1000_12A0[31:0]
+ * Data: 0x0000_4000
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_SET,
+ 0x00004000);
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* check AXI Rx bus sleep protect turn on
+ * (polling "100 times", polling interval is 1ms)
+ * Address: 0x1000_1228[14]
+ * Data: 1'b1
+ * Action: polling
+ */
+ check = 0;
+ CONSYS_REG_BIT_POLLING(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1,
+ 14, 1, 100, 1000, check);
+ if (check)
+ pr_err("Polling AXI Rx bus sleep protect turn on fail.\n");
+#endif
+ /* Turn on AHB RX bus sleep protect (AP2CONN AXI Bus protect)
+ * (apply this for INFRA AXI bus protection to prevent bus hang
+ * when CONNSYS had been turned off)
+ * INFRA_TOPAXI_PROTECTEN_SET
+ * 0x1000_12A0[31:0]=32'h1000_0000
+ */
+ CONSYS_REG_WRITE(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_SET,
+ 0x10000000);
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* Check AHB RX bus sleep protect turn on (polling "10 times")
+ * INFRA_TOPAXI_PROTECTEN_STA1[28] (0x1000_1228[28]), value: 1'b1
+ */
+ check = 0;
+ CONSYS_REG_BIT_POLLING(
+ REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1,
+ 28, 1, 100, 1000, check);
+ if (check)
+ pr_err("Polling AHB RX bus (AP2CONN) sleep protect turn on fail.");
+#endif
+ /* Power off connsys MTCMOS */
+ /* Assert "conn_infra_on" isolation, set "connsys_iso_en"=1
+ * Address: CONN_PWR_CON[1] (0x1000_6304[1])
+ * Value: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, (0x1<<1));
+
+ /* Assert CONNSYS S/W reset (SPM CR), set "ap_sw_rst_b"=0
+ * Address: CONN_PWR_CON[0] (0x1000_6304[0])
+ * Value: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x1);
+
+ /* Assert CONNSYS S/W reset(TOP RGU CR), set "ap_sw_rst_b"=0
+ * Address: WDT_SWSYSRST[9] (0x1000_7018[9])
+ * WDT_SWSYSRST[31:24] (0x1000_7018[31:24])
+ * Value: [9]=1'b1
+ * [31:24]=8'h88 (key)
+ * Action: write
+ * Note: this CR value for reset control is active high (0: not reset, 1: reset)
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_TOP_RGU_ADDR + TOP_RGU_WDT_SWSYSRST,
+ 0x88000200,
+ 0xff000200);
+
+ /* Turn off AP-to-CONNSYS bus clock, set "conn_clk_dis"=1
+ * (apply this for bus clock gating)
+ * Address: CONN_PWR_CON[4] (0x1000_6304[4])
+ * Value: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, (0x1<<4));
+
+ /* wait 1us (?) */
+ udelay(1);
+
+ /* De-assert "conn_infra_on" primary part power on,
+ * set "connsys_on_domain_pwr_on"=0
+ * Address: CONN_PWR_CON[2] (0x1000_6304[2])
+ * Value: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, (0x1<<2));
+
+ /* De-assert "conn_infra_on" secondary part power on,
+ * set "connsys_on_domain_pwr_on_s"=0
+ * Address: CONN_PWR_CON[3] (0x1000_6304[3])
+ * Value: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, (0x1<<3));
+#endif /* MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE */
+ }
+ return 0;
+}
+
+int consys_conninfra_wakeup(void)
+{
+ /* Wake up conn_infra
+ * Address: CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP (0x180601a0)
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP,
+ 0x1);
+
+ /* Check CONNSYS version ID
+ * (polling "10 times" for specific project code and each polling interval is "1ms")
+ */
+ if (consys_polling_chipid_int(10, 1) != 0) {
+ pr_err("[%s] Polling chip id fail\n", __func__);
+ return -1;
+ }
+ return 0;
+}
+
+int consys_conninfra_sleep(void)
+{
+ /* Release conn_infra force on
+ * Address: CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP (0x180601a0)
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP,
+ 0x0);
+ return 0;
+}
+
+void consys_set_if_pinmux(unsigned int enable)
+{
+ if (enable) {
+ /* Set pinmux for the interface between D-die and A-die (Aux1)
+ * (CONN_HRST_B/CONN_TOP_CLK/CONN_TOP_DATA)
+ * Address:
+ * 0x1000_53F8 = 32'hF0000000 (GPIO_MODE15_CLR[30:28]: GPIO127
+ * 0x1000_53F4 = 32'h10000000 (GPIO_MODE15_SET[30:28]: GPIO127
+ * 0x1000_5408 = 32'h000000FF (GPIO_MODE16_CLR[2:0]: GPIO128, [6:4]:GPIO129)
+ * 0x1000_5404 = 32'h00000011 (GPIO_MODE16_SET[2:0]: GPIO128, [6:4]:GPIO129)
+ * Note: GPIO127/GPIO128/GPIO129
+ */
+ CONSYS_REG_WRITE(REG_GPIO_BASE_ADDR + GPIO_MODE15_CLR, 0xf0000000);
+ CONSYS_REG_WRITE(REG_GPIO_BASE_ADDR + GPIO_MODE15_SET, 0x10000000);
+ CONSYS_REG_WRITE(REG_GPIO_BASE_ADDR + GPIO_MODE16_CLR, 0x000000ff);
+ CONSYS_REG_WRITE(REG_GPIO_BASE_ADDR + GPIO_MODE16_SET, 0x00000011);
+
+ /* Set pinmux driving to 2mA
+ * Address:
+ * 0x11D1_0008 = 32'h000001ff
+ * (DRV_CFG0_CLR[2:0]: conn_hrst_b, [5:3]: conn_top_clk, [8:6]: conn_top_data)
+ * Action: write32
+ * CODA: IOCFG_BM
+ */
+ CONSYS_REG_WRITE(REG_IOCFG_BM_ADDR + IOCFG_BM_DRV_CFG0_CLR, 0x000001ff);
+
+ /* POS update: 20200325, fix typo */
+ /* Set CONN_TOP_CLK/CONN_TOP_DATA driving to 4mA
+ * Address:
+ * 0x11D1_0004 = 32'h00000048 (00000000_00000000_00000000_01001000)
+ * (DRV_CFG0_SET[2:0]: conn_hrst_b, [5:3]: conn_top_clk, [8:6]: conn_top_data)
+ * Action: write32
+ * CODA: IOCFG_BM
+ */
+ CONSYS_REG_WRITE(REG_IOCFG_BM_ADDR + IOCFG_BM_DRV_CFG0_SET, 0x00000048);
+
+ /* Set pinmux PUPD setting
+ * Clear CONN_TOP_DATA PD setting
+ * Address:
+ * 0x11D1_00d8 = 32'h00000010
+ * (PD_CFG0_CLR[4]: conn_top_data, 1:CLEAR bit)
+ * CODA: IOCFG_BM
+ */
+ CONSYS_REG_WRITE(REG_IOCFG_BM_ADDR + IOCFG_BM_PD_CFG0_CLR, 0x00000010);
+
+ /* Set pinmux PUPD setting
+ * CONN_TOP_DATA as PU
+ * Address:
+ * 0x11D1_0114 = 32'h00000010
+ * (PU_CFG0_SET[4]: conn_top_data, 1: SET bit)
+ * CODA: IOCFG_BM
+ */
+ CONSYS_REG_WRITE(REG_IOCFG_BM_ADDR + IOCFG_BM_PU_CFG0_SET, 0x00000010);
+ } else {
+ /* Set pinmux for the interface between D-die and A-die (Aux0)
+ * 0x1000_53F8=32'hF0000000
+ * 0x1000_5408=32'h000000FF
+ */
+ CONSYS_REG_WRITE(REG_GPIO_BASE_ADDR + GPIO_MODE15_CLR, 0xf0000000);
+ CONSYS_REG_WRITE(REG_GPIO_BASE_ADDR + GPIO_MODE16_CLR, 0x000000ff);
+ /* Set pinmux PUPD setting
+ * Clear CONN_TOP_DATA PU setting
+ * 0x11D1_0118=32'h00000010
+ * [2]: conn_hrst_b
+ * [3]: conn_top_clk
+ * [4]: conn_top_data
+ */
+ CONSYS_REG_WRITE(REG_GPIO_BASE_ADDR + IOCFG_BM_PU_CFG0_CLR, 0x00000010);
+ /* Set pinmux PUPD setting
+ * CONN_TOP_DATA as PD
+ * 0x11D1_00d4=32'h00000010
+ * [2]: conn_hrst_b
+ * [3]: conn_top_clk
+ * [4]: conn_top_data
+ */
+ CONSYS_REG_WRITE(REG_GPIO_BASE_ADDR + IOCFG_BM_PD_CFG0_SET, 0x00000010);
+ }
+#ifdef CONFIG_FPGA_EARLY_PORTING
+ pr_info("[%s] not for FPGA\n", __func__);
+#endif
+}
+
+int consys_polling_chipid_int(unsigned int retry, unsigned int sleep_ms)
+{
+ unsigned int count = retry + 1;
+ unsigned int consys_hw_ver = 0;
+ unsigned int consys_configuration_id = 0;
+
+ while (--count > 0) {
+ consys_hw_ver = CONSYS_REG_READ(
+ REG_CONN_INFRA_CFG_ADDR +
+ CONN_HW_VER_OFFSET);
+ if (consys_hw_ver == CONN_HW_VER) {
+ consys_configuration_id = CONSYS_REG_READ(
+ REG_CONN_INFRA_CFG_ADDR + CONN_CFG_ID_OFFSET);
+ pr_info("Consys HW version id(0x%x) cfg_id=(0x%x)\n",
+ consys_hw_ver, consys_configuration_id);
+ break;
+ }
+ msleep(sleep_ms);
+ }
+
+ if (count == 0) {
+ pr_err("Read CONSYS version id fail. Expect 0x%x but get 0x%x\n",
+ CONN_HW_VER, consys_hw_ver);
+ return -1;
+ }
+
+ return 0;
+}
+
+int consys_polling_chipid(void)
+{
+ return consys_polling_chipid_int(10, 1);
+}
+
+int connsys_d_die_cfg(void)
+{
+ unsigned int efuse;
+ /* Read D-die Efuse
+ * Address: AP2CONN_EFUSE_DATA (0x1800_1020)
+ * Data:
+ * Action: read
+ */
+ efuse = CONSYS_REG_READ(REG_CONN_INFRA_CFG_ADDR + AP2CONN_EFUSE_DATA);
+ pr_info("D-die efuse: 0x%08x", efuse);
+
+ /* POS update: 20200325: Update conn_infra sysram hwctrl setting
+ */
+#if 0
+ /* conn_infra sysram hw control setting -> disable hw power down
+ * Address: CONN_INFRA_RGU_SYSRAM_HWCTL_PDN_SYSRAM_HWCTL_PDN (0x1800_0050)
+ * Data: 32'h0
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ REG_CONN_INFRA_RGU_ADDR + CONN_INFRA_RGU_SYSRAM_HWCTL_PDN_SYSRAM_HWCTL_PDN, 0x0);
+
+ /* conn_infra sysram hw control setting -> enable hw sleep
+ * Address: CONN_INFRA_RGU_SYSRAM_HWCTL_SLP_SYSRAM_HWCTL_SLP (0x1800_0054)
+ * Data: 32'h0000_00FF
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ REG_CONN_INFRA_RGU_ADDR + CONN_INFRA_RGU_SYSRAM_HWCTL_SLP_SYSRAM_HWCTL_SLP,
+ 0x000000ff);
+#endif
+ return 0;
+}
+
+int connsys_spi_master_cfg(unsigned int next_status)
+{
+ /* TOP_CK_ADDR 0x18005084[11:0] 0x02C
+ *
+ * GPS_CK_ADDR 0x18005088[11:0] 0xA0C
+ * GPS_L5_CK_ADDR 0x18005088[27:16] 0xAFC
+ * => 0x1800_5088=0x0afc_0a0c
+ *
+ * GPS_RFBUF_ADR 0x18005094[11:0] 0x0FC
+ * GPS_L5_EN_ADDR 0x18005098[11:0] 0x0F8
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_TOP_CK_ADDR,
+ 0x02c, 0xfff);
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_GPS_CK_ADDR,
+ 0x0afc0a0c, 0x0fff0fff);
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_GPS_RFBUF_ADDR,
+ 0x0fc, 0xfff);
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_GPS_L5_EN_ADDR,
+ 0x0f8, 0xfff);
+
+ /* CMD_LENGTH 0x18005004[4:0] 0x8
+ * WB_BG_ADDR1 0x18005010 0xA03C
+ * WB_BG_ADDR2 0x18005014 0xA03C
+ * WB_BG_ADDR3 0x18005018 0xAA18
+ * WB_BG_ADDR4 0x1800501C 0xAA18
+ * WB_BG_ADDR5 0x18005020 0xA0C8
+ * WB_BG_ADDR6 0x18005024 0xAA00
+ * WB_BG_ADDR7 0x18005028 0xA0B4
+ * WB_BG_ADDR8 0x1800502C 0xA34C
+ * WB_BG_ON1 0x18005030 0x00000000
+ * WB_BG_ON2 0x18005034 0x00000000
+ * WB_BG_ON3 0x18005038 0x74E0FFF5
+ * WB_BG_ON4 0x1800503C 0x76E8FFF5
+ * WB_BG_ON5 0x18005040 0x00000000
+ * WB_BG_ON6 0x18005044 0xFFFFFFFF
+ * WB_BG_ON7 0x18005048 0x00000019
+ * WB_BG_ON8 0x1800504C 0x00010400
+ * WB_BG_OFF1 0x18005050 0x57400000
+ * WB_BG_OFF2 0x18005054 0x57400000
+ * WB_BG_OFF3 0x18005058 0x44E0FFF5
+ * WB_BG_OFF4 0x1800505C 0x44E0FFF5
+ * WB_BG_OFF5 0x18005060 0x00000001
+ * WB_BG_OFF6 0x18005064 0x00000000
+ * WB_BG_OFF7 0x18005068 0x00040019
+ * WB_BG_OFF8 0x1800506C 0x00410440
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_SLP_CTL,
+ 0x8, 0x1f);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR1,
+ 0xa03c);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR2,
+ 0xa03c);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR3,
+ 0xaa18);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR4,
+ 0xaa18);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR5,
+ 0xa0c8);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR6,
+ 0xaa00);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR7,
+ 0xa0b4);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR8,
+ 0xa34c);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON1,
+ 0x0);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON2,
+ 0x0);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON3,
+ 0x74E0FFF5);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON4,
+ 0x76E8FFF5);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON5,
+ 0x0);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON6,
+ 0xFFFFFFFF);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON7,
+ 0x00000019);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON8,
+ 0x00010400);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF1,
+ 0x57400000);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF2,
+ 0x57400000);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF3,
+ 0x44E0FFF5);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF4,
+ 0x44E0FFF5);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF5,
+ 0x00000001);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF6,
+ 0x00000000);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF7,
+ 0x00040019);
+ CONSYS_REG_WRITE(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF8,
+ 0x00410440);
+
+ return 0;
+}
+
+#ifndef CONFIG_FPGA_EARLY_PORTING
+/*****************************************************************************
+* FUNCTION
+* connsys_a_die_efuse_read
+* DESCRIPTION
+* Read a-die efuse
+* PARAMETERS
+* efuse_addr: read address
+* RETURNS
+* int
+* 0: fail, efuse is invalid
+* 1: success, efuse is valid
+*****************************************************************************/
+static int connsys_a_die_efuse_read_nolock(
+ unsigned int efuse_addr,
+ unsigned int* data0, unsigned int* data1,
+ unsigned int* data2, unsigned int* data3)
+{
+ int ret = 0;
+ int retry = 0;
+ int ret0, ret1, ret2, ret3;
+
+ if (data0 == NULL || data1 == NULL || data2 == NULL || data3 == NULL) {
+ pr_err("[%s] invalid parameter (%p, %p, %p, %p)",
+ __func__, data0, data1, data2, data3);
+ return 0;
+ }
+ /* Efuse control clear, clear Status /trigger
+ * Address: ATOP EFUSE_CTRL_write_efsrom_kick_and_read_kick_busy_flag (0x108[30])
+ * Data: 1'b0
+ * Action: TOPSPI_WR
+ */
+ consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, &ret);
+ ret &= ~(0x1 << 30);
+ consys_spi_write_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, ret);
+
+ /* Efuse Read 1st 16byte
+ * Address:
+ * ATOP EFUSE_CTRL_efsrom_mode (0x108[7:6]) = 2'b00
+ * ATOP EFUSE_CTRL_efsrom_ain (0x108[25:16]) = efuse_addr (0)
+ * ATOP EFUSE_CTRL_write_efsrom_kick_and_read_kick_busy_flag (0x108[30]) = 1'b1
+ * Action: TOPSPI_WR
+ */
+ consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, &ret);
+ ret &= ~(0x43ff00c0);
+ ret |= (0x1 << 30);
+ ret |= ((efuse_addr << 16) & 0x3ff0000);
+ consys_spi_write_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, ret);
+
+ /* Polling EFUSE busy = low
+ * (each polling interval is "30us" and polling timeout is 2ms)
+ * Address:
+ * ATOP EFUSE_CTRL_write_efsrom_kick_and_read_kick_busy_flag (0x108[30]) = 1'b0
+ * Action: TOPSPI_Polling
+ */
+ consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, &ret);
+ while ((ret & (0x1 << 30)) != 0 && retry < 70) {
+ retry++;
+ udelay(30);
+ consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, &ret);
+ }
+ if ((ret & (0x1 << 30)) != 0) {
+ pr_info("[%s] EFUSE busy, retry failed(%d)\n", __func__, retry);
+ }
+
+ /* Check efuse_valid & return
+ * Address: ATOP EFUSE_CTRL_csri_efsrom_dout_vld_sync_1_ (0x108[29])
+ * Action: TOPSPI_RD
+ */
+ /* if (efuse_valid == 1'b1)
+ * Read Efuse Data to global var
+ */
+ consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, &ret);
+ if (((ret & (0x1 << 29)) >> 29) == 1) {
+ ret0 = consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_RDATA0, data0);
+ ret1 = consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_RDATA1, data1);
+ ret2 = consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_RDATA2, data2);
+ ret3 = consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_RDATA3, data3);
+
+ pr_info("efuse = [0x%08x, 0x%08x, 0x%08x, 0x%08x]", *data0, *data1, *data2, *data3);
+ if (ret0 || ret1 || ret2 || ret3)
+ pr_err("efuse read error: [%d, %d, %d, %d]", ret0, ret1, ret2, ret3);
+ ret = 1;
+ } else {
+ pr_err("EFUSE is invalid\n");
+ ret = 0;
+ }
+ return ret;
+}
+#endif
+
+#if CFG_CONNINFRA_THERMAL_SUPPORT
+static int connsys_a_die_thermal_cal(
+ int efuse_valid,
+ unsigned int efuse0, unsigned int efuse1, unsigned int efuse2, unsigned int efuse3)
+{
+ struct consys_plat_thermal_data input;
+
+ memset(&input, 0, sizeof(struct consys_plat_thermal_data));
+ if (efuse_valid) {
+ if (efuse1 & (0x1 << 7)) {
+ consys_spi_write_offset_range_nolock(
+ SYS_SPI_TOP, ATOP_RG_TOP_THADC_BG, efuse1, 12, 3, 4);
+ consys_spi_write_offset_range_nolock(
+ SYS_SPI_TOP, ATOP_RG_TOP_THADC, efuse1, 23, 0, 3);
+ }
+ if(efuse1 & (0x1 << 15)) {
+ consys_spi_write_offset_range_nolock(
+ SYS_SPI_TOP, ATOP_RG_TOP_THADC, efuse1, 26, 13, 2);
+ input.slop_molecule = (efuse1 & 0x1f00) >> 8;
+ pr_info("slop_molecule=[%d]", input.slop_molecule);
+ }
+ if (efuse1 & (0x1 << 23)) {
+ /* [22:16] */
+ input.thermal_b = (efuse1 & 0x7f0000) >> 16;
+ pr_info("thermal_b =[%d]", input.thermal_b);
+ }
+ if (efuse1 & (0x1 << 31)) {
+ input.offset = (efuse1 & 0x7f000000) >> 24;
+ pr_info("offset=[%d]", input.offset);
+ }
+ }
+ input.efuse0 = efuse0;
+ input.efuse1 = efuse1;
+ input.efuse2 = efuse2;
+ input.efuse3 = efuse3;
+
+ update_thermal_data(&input);
+ return 0;
+}
+#endif /* CFG_CONNINFRA_THERMAL_SUPPORT */
+
+int connsys_a_die_cfg(void)
+{
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ int check;
+ unsigned int adie_chip_id = 0x0;
+ int efuse_valid = 0;
+ unsigned int efuse0 = 0, efuse1 = 0, efuse2 = 0, efuse3 = 0;
+
+ /* De-assert A-die reset
+ * Address:
+ * CONN_INFRA_CFG_ADIE_CTL_ADIE_RSTB (0x18001030[0])
+ * Value: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_ADIE_CTL, 0x1);
+
+ /* Get semaphore once */
+ if (consys_sema_acquire_timeout(CONN_SEMA_RFSPI_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) {
+ pr_err("[%s] Require semaphore fail\n", __func__);
+ return -1;
+ }
+
+ /* Read MT6635 ID
+ * Address:
+ * ATOP CHIP_ID
+ * 0x02C[31:16]: hw_code
+ * 0x02C[15:0]: hw_ver
+ * Action: TOPSPI_RD
+ * Note:
+ * MT6635 E1 : read 0x02C = 0x66358A00;
+ * MT6635 E2 : read 0x02C = 0x66358A10;
+ * MT6635 E3 : read 0x02C = 0x66358A11;
+ */
+ check = consys_spi_read_nolock(SYS_SPI_TOP, ATOP_CHIP_ID, &adie_chip_id);
+ if (check) {
+ /* Release semaphore */
+ consys_sema_release(CONN_SEMA_RFSPI_INDEX);
+ pr_err("[%s] Get ATOP_CHIP_ID fail, check=%d", __func__, check);
+ return -1;
+ }
+ pr_info("A-die CHIP ID is 0x%x", adie_chip_id);
+ conn_hw_env.adie_hw_version = adie_chip_id;
+ conn_hw_env.is_rc_mode = 0;
+
+ /* Update spi fm read extra bit setting
+ * CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_EN 0x1800400C[15]=1'b0
+ * CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_CNT 0x1800400C[7:0]=8'h0
+ * Action: write
+ * Note:
+ * Need update this setting when fm is at power-off state,
+ * otherwise spi access FM CR will fail
+ */
+ CONSYS_CLR_BIT(REG_CONN_RFSPI_ADDR + CONN_RF_SPI_MST_REG_FM_CTRL, (0x1 << 15));
+ CONSYS_CLR_BIT(REG_CONN_RFSPI_ADDR + CONN_RF_SPI_MST_REG_FM_CTRL, (0xff));
+
+ /* Update Thermal addr for 6635
+ * CONN_TOP_THERM_CTL_THERM_AADDR
+ * 0x18002018=32'h50305A00
+ */
+ CONSYS_REG_WRITE(REG_CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_AADDR, 0x50305A00);
+
+ /* Rread efuse Data(000) */
+ efuse_valid = connsys_a_die_efuse_read_nolock(0x0, &efuse0, &efuse1, &efuse2, &efuse3);
+ /* Thermal Cal (TOP) */
+#if CFG_CONNINFRA_THERMAL_SUPPORT
+ connsys_a_die_thermal_cal(efuse_valid, efuse0, efuse1, efuse2, efuse3);
+#endif
+ /* Increase XOBUF supply-V
+ * ATOP RG_TOP_XTAL_01 (0XA18) = 32'hF6E8FFF5
+ * Action: TOPSPI_WR
+ */
+ consys_spi_write_nolock(SYS_SPI_TOP, ATOP_RG_TOP_XTAL_01, 0xF6E8FFF5);
+
+ /* Increase XOBUF supply-R for MT6635 E1
+ * ATOP RG_TOP_XTAL_02 (0XA1C)
+ * if(MT6635 E1) //rf_hw_ver = 0x8a00
+ * 32'hD5555FFF
+ * else
+ * 32'h0x55555FFF
+ * Action: TOPSPI_WR
+ */
+ if (adie_chip_id == 0x66358a00)
+ consys_spi_write_nolock(SYS_SPI_TOP, ATOP_RG_TOP_XTAL_02, 0xD5555FFF);
+ else
+ consys_spi_write_nolock(SYS_SPI_TOP, ATOP_RG_TOP_XTAL_02, 0x55555FFF);
+
+ /* Release semaphore */
+ consys_sema_release(CONN_SEMA_RFSPI_INDEX);
+#endif
+
+ return 0;
+}
+
+int connsys_afe_wbg_cal(void)
+{
+ /* 20200622:
+ * Confirmed with DE, all config are default value, now.
+ */
+ return 0;
+}
+
+int connsys_subsys_pll_initial(void)
+{
+ /* Check with DE, only 26M on mobile phone */
+ /* CONN_AFE_CTL_RG_PLL_STB_TIME_RG_WBG_BPLL_STB_TIME 0x180030F4[30:16] 0x314
+ * CONN_AFE_CTL_RG_PLL_STB_TIME_RG_WBG_WPLL_STB_TIME 0x180030F4[14:0] 0x521
+ * CONN_AFE_CTL_RG_DIG_EN_02_RG_WBG_EN_BT_PLL 0x18003004[7:6] 0x1
+ * CONN_AFE_CTL_RG_DIG_EN_02_RG_WBG_EN_WF_PLL 0x18003004[1:0] 0x3
+ * CONN_AFE_CTL_RG_DIG_EN_02_RG_WBG_EN_MCU_PLL 0x18003004[3:2] 0x1
+ * CONN_AFE_CTL_RG_DIG_EN_02_RG_WBG_EN_MCU_PLL_WF 0x18003004[17:16] 0x3
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_PLL_STB_TIME,
+ 0x03140521, 0x7fff7fff);
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_02,
+ 0x30047, 0x300cf);
+
+ return 0;
+}
+
+int connsys_low_power_setting(unsigned int curr_status, unsigned int next_status)
+{
+ /* For this 6880, only GPS is need. Other should be reject. */
+ if (curr_status != 0 || next_status != (0x1 << CONNDRV_TYPE_GPS)) {
+ pr_err("[%s] Unsupport status: curr(0x%08x), next(0x%08x)",
+ __func__, curr_status, next_status);
+ return -1;
+ }
+ /* Unmask on2off/off2on slpprot_rdy enable checker @conn_infra off power off
+ * => check slpprot_rdy = 1'b1 and go to sleep
+ *
+ * CONN_INFRA_CFG_PWRCTRL0_CONN_INFRA_CFG_SLP_RDY_MASK
+ * 0x18001200[15:12] = 4'h1
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_PWRCTRL0, (0x1 << 12), 0xf000);
+
+ if (!consys_is_rc_mode_enable()) {
+ /* Legacy mode */
+ /* Disable conn_top rc osc_ctrl_top
+ * CONN_INFRA_CFG_RC_CTL_0_CONN_INFRA_OSC_RC_EN
+ * 0x18001380[7] = 1'b0
+ */
+ CONSYS_CLR_BIT(REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0, (0x1<<7));
+ /* Legacy OSC control stable time
+ *
+ * CONN_INFRA_CFG_OSC_CTL_0_XO_VCORE_RDY_STABLE_TIME
+ * 0x18001300[7:0]=8'd6
+ * CONN_INFRA_CFG_OSC_CTL_0_XO_INI_STABLE_TIME
+ * 0x18001300[15:8]=8'd7
+ * CONN_INFRA_CFG_OSC_CTL_0_XO_BG_STABLE_TIME
+ * 0x18001300[23:16]=8'd8
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_OSC_CTL_0,
+ 0x080706, 0x00ffffff);
+ /* Legacy OSC control unmask conn_srcclkena_ack
+ * CONN_INFRA_CFG_OSC_CTL_1_ACK_FOR_XO_STATE_MASK
+ * 0x18001304[16] = 1'b0
+ */
+ CONSYS_CLR_BIT(
+ REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_OSC_CTL_1, (0x1<<16));
+ } else {
+ /* RC mode */
+ /* GPS RC OSC control stable time
+ * CONN_INFRA_CFG_RC_CTL_1_GPS_XO_VCORE_RDY_STABLE_TIME_0
+ * 0x18001394[7:0]=8'd6
+ * CONN_INFRA_CFG_RC_CTL_1_GPS_XO_INI_STABLE_TIME_0
+ * 0x18001394[15:8]=8'd7
+ * CONN_INFRA_CFG_RC_CTL_1_GPS_XO_BG_STABLE_TIME_0
+ * 0x18001394[23:16]=8'd8
+ * CONN_INFRA_CFG_RC_CTL_1_GPS_XO_VCORE_OFF_STABLE_TIME_0
+ * 0x18001394[31:24]=8'd2
+ * 0x18001394[7:0]
+ */
+ CONSYS_REG_WRITE(
+ REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_1_GPS, 0x02080706);
+ /* GPS RC OSC control unmask conn_srcclkena_ack
+ * CONN_INFRA_CFG_RC_CTL_0_GPS_ACK_FOR_XO_STATE_MASK_0
+ * 0x18001390[15] = 1'b0
+ */
+ CONSYS_CLR_BIT(
+ REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0_GPS, (0x1<<15));
+ /* TOP RC OSC control stable time
+ * CONN_INFRA_CFG_RC_CTL_1_TOP_XO_VCORE_RDY_STABLE_TIME_3
+ * 0x180013C4[7:0]=8'd6
+ * CONN_INFRA_CFG_RC_CTL_1_TOP_XO_INI_STABLE_TIME_3
+ * 0x180013C4[15:8]=8'd7
+ * CONN_INFRA_CFG_RC_CTL_1_TOP_XO_BG_STABLE_TIME_3
+ * 0x180013C4[23:16]=8'd8
+ * CONN_INFRA_CFG_RC_CTL_1_TOP_XO_VCORE_OFF_STABLE_TIME_3
+ * 0x180013C4[31:24]=8'd2"
+ */
+ CONSYS_REG_WRITE(
+ REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_1_TOP,
+ 0x02080706);
+ /* TOP RC OSC control unmask conn_srcclkena_ack
+ * CONN_INFRA_CFG_RC_CTL_0_TOP_ACK_FOR_XO_STATE_MASK_3
+ * 0x180013C0[15]=1'b0
+ */
+ CONSYS_CLR_BIT(
+ REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0_TOP, (0x1<<15));
+
+ /* Enable conn_top rc osc_ctrl_gps
+ * CONN_INFRA_CFG_RC_CTL_0_GPSSYS_OSC_RC_EN
+ * 0x18001380[4]=1'b1
+ */
+ CONSYS_SET_BIT(
+ REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0, (0x1<<4));
+ /* Set conn_srcclkena control by conn_infra_emi_ctl
+ * CONN_INFRA_CFG_EMI_CTL_0_CONN_EMI_RC_EN
+ * 0x18001400[0]=1'b1
+ */
+ CONSYS_SET_BIT(
+ REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_EMI_CTL_0, 0x1);
+
+ /* Disable legacy osc control
+ * CONN_INFRA_CFG_RC_CTL_0_OSC_LEGACY_EN
+ * 0x18001380[0]=1'b0
+ */
+ CONSYS_CLR_BIT(
+ REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0, 0x1);
+ }
+ /* conn2ap sleep protect release bypass ddr_en_ack check
+ * CONN_INFRA_CFG_EMI_CTL_0_DDR_EN_BP_PROT
+ * 0x18001400[18]=1'b1
+ */
+ CONSYS_SET_BIT(
+ REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_EMI_CTL_0, (0x1<<18));
+ /* Enable ddr_en timeout, timeout value = 1023T (Bus clock)
+ * CONN_INFRA_CFG_EMI_CTL_0_DDR_CNT_LIMIT
+ * 0x18001400[14:4]=11'd1023
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_EMI_CTL_0, 0x3ff0, 0x7ff0);
+ /* Enable ddr_en timeout value update (rising edge)
+ * CONN_INFRA_CFG_EMI_CTL_0_DDR_EN_CNT_UPDATE
+ * 0x18001400[15]=1'b1
+ */
+ CONSYS_SET_BIT(
+ REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_EMI_CTL_0, (0x1<<15));
+ /* Disable ddr_en timeout value update (falling edge)
+ * CONN_INFRA_CFG_EMI_CTL_0_DDR_EN_CNT_UPDATE
+ * 0x18001400[15]=1'b0
+ */
+ CONSYS_CLR_BIT(
+ REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_EMI_CTL_0, (0x1<<15));
+
+ /* Disable conn_infra off pwr_ack mask
+ * CONN_INFRA_RGU_CONN_INFRA_OFF_TOP_PWR_CTL_CONN_INFRA_OFF_TOP_PWR_ACK_S_MASK
+ * 0x18000000[31:16]=16'h494E (key)
+ * 0x18000000[6]=1'b0
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_INFRA_RGU_ADDR + CONN_INFRA_RGU_CONN_INFRA_OFF_TOP_PWR_CTL,
+ 0x494e0000, 0xffff0040);
+
+ /* Disable A-die top_ck_en (for Bring-up keep a-die dig_top ck on)
+ * Call common API
+ * ATOP Clock default on, need to turn off manually
+ */
+ consys_adie_top_ck_en_top_ctrl(0);
+
+ /* Select conn_infra_cfg debug_sel to low power related
+ * CONN_HOST_CSR_TOP_CONN_INFRA_CFG_DBG_SEL_CONN_INFRA_CFG_DBG_SEL
+ * 0x1806015c[2:0]=3'b000
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_CFG_DBG_SEL,
+ 0x0, 0x7);
+
+ /* OFF domain AHB slaves timeout limit setting
+ * CONN_INFRA_BUS_CR_CONN_INFRA_BUS_OFF_TIMEOUT_CTRL_CONN_INFRA_OFF_TIMEOUT_LIMIT
+ * 0x1800E300[14:7]=8'h02
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_INFRA_BUS_CR_ADDR + CONN_INFRA_BUS_OFF_TIMEOUT_CTRL,
+ (0x2 << 7), 0x7f80);
+
+ /* Enable off domain AHB slaves timeout
+ * CONN_INFRA_BUS_CR_CONN_INFRA_BUS_OFF_TIMEOUT_CTRL_CONN_INFRA_OFF_TIMEOUT_EN
+ * 0x1800E300[2]=1'b1
+ * CONN_INFRA_BUS_CR_CONN_INFRA_BUS_OFF_TIMEOUT_CTRL_CONN_INFRA_OFF_AHB_MUX_EN
+ * 0x1800E300[1]=1'b1
+ * CONN_INFRA_BUS_CR_CONN_INFRA_BUS_OFF_TIMEOUT_CTRL_CONN_INFRA_OFF_APB_MUX_EN
+ * 0x1800E300[0]=1'b1
+ */
+ CONSYS_SET_BIT(
+ REG_CONN_INFRA_BUS_CR_ADDR + CONN_INFRA_BUS_OFF_TIMEOUT_CTRL,
+ 0x7);
+
+ /* ON domain APB slaves timeout limit setting
+ * CONN_INFRA_BUS_CR_CONN_INFRA_BUS_ON_TIMEOUT_CTRL_CONN_INFRA_ON_TIMEOUT_LIMIT
+ * 0x1800E31C[14:7]=8'h02
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_INFRA_BUS_CR_ADDR + CONN_INFRA_BUS_ON_TIMEOUT_CTRL,
+ (0x2 << 7), 0x7f80);
+
+ /* Enable on domain APB slaves timeout
+ * CONN_INFRA_BUS_CR_CONN_INFRA_BUS_ON_TIMEOUT_CTRL_CONN_INFRA_ON_TIMEOUT_EN
+ * 0x1800E31C[2]=1'b1
+ * CONN_INFRA_BUS_CR_CONN_INFRA_BUS_ON_TIMEOUT_CTRL_CONN_INFRA_ON_AHB_MUX_EN
+ * 0x1800E31C[1]=1'b1
+ * CONN_INFRA_BUS_CR_CONN_INFRA_BUS_ON_TIMEOUT_CTRL_CONN_INFRA_ON_APB_MUX_EN
+ * 0x1800E31C[0]=1'b1
+ */
+ CONSYS_SET_BIT(
+ REG_CONN_INFRA_BUS_CR_ADDR + CONN_INFRA_BUS_ON_TIMEOUT_CTRL,
+ 0x7);
+
+ /* Hold timeout reset
+ * CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_VDNR_GEN_ON_U_DEBUG_CTRL_AO_CONN_INFRA_ON_CTRL0_reset_setting
+ * 0x1802F000[9] = 1'b1
+ */
+ CONSYS_SET_BIT(
+ REG_CONN_INFRA_DEBUG_CTRL_AO + CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_CTRL0,
+ (0x1 << 9));
+
+ /* Set conn_infra bus timeout value
+ * CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_VDNR_GEN_ON_U_DEBUG_CTRL_AO_CONN_INFRA_ON_CTRL0_timeout_thres
+ * 0x1802F000[31:16]=16'h23BC
+ */
+ CONSYS_REG_WRITE_MASK(
+ REG_CONN_INFRA_DEBUG_CTRL_AO + CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_CTRL0,
+ 0x23BC0000, 0xFFFF0000);
+
+ /* Enable conn_infra bus timeout
+ * CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_VDNR_GEN_ON_U_DEBUG_CTRL_AO_CONN_INFRA_ON_CTRL0_debug_en
+ * 0x1802F000[2]=1'b1
+ * CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_VDNR_GEN_ON_U_DEBUG_CTRL_AO_CONN_INFRA_ON_CTRL0_debug_cken
+ * 0x1802F000[3]=1'b1
+ */
+ CONSYS_SET_BIT(
+ REG_CONN_INFRA_DEBUG_CTRL_AO + CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_CTRL0,
+ 0xc);
+
+ /* Release timeout reset
+ * CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_VDNR_GEN_ON_U_DEBUG_CTRL_AO_CONN_INFRA_ON_CTRL0_reset_setting
+ * 0x1802F000[9] = 1'b0
+ */
+ CONSYS_CLR_BIT(
+ REG_CONN_INFRA_DEBUG_CTRL_AO + CONN_INFRA_DEBUG_CTRL_AO_CONN_INFRA_ON_CTRL0,
+ (0x1 << 9));
+
+ /* Enable conn_infra_cfg setting
+ * (osc_en would pull low after conn_infra mtcmos off)
+ * CONN_INFRA_CFG_PWRCTRL0_HWCTL_OSC_ON_CHECK_TOP_PWR_EN
+ * 0x1800_1200[9]=1'b1
+ */
+ CONSYS_SET_BIT(
+ REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_PWRCTRL0, (0x1 << 9));
+
+ /* Enable bpll divder2 enable for conn_infra bus hclk
+ * CONN_INFRA_CLKGEN_ON_TOP_CKGEN_BUS_BPLL_DIV_2_BPLL_DIV_2_DIV_EN
+ * 0x18009004[0]=1'b1
+ */
+ CONSYS_SET_BIT(
+ REG_CONN_INFRA_CLKGEN_ON_TOP_ADDR + CONN_INFRA_CKGEN_BUS_BPLL_DIV_2, 0x1);
+
+ /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+ /* !!!!!!!!!!!!!!!!!!!!!! CANNOT add code after HERE!!!!!!!!!!!!!!!!!!!!!!!!!! */
+ /* !!!!!!!!!!!!!!!!!!!!!!! conninfra may go to sleep !!!!!!!!!!!!!!!!!!!!!!!!! */
+ /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+ /* Disable conn_infra bus clock sw control ==> conn_infra bus clock hw control
+ * CONN_INFRA_CFG_CKGEN_BUS_HCLK_CKSEL_SWCTL
+ * 0x1800_9A00[23]=1'b0
+ */
+ CONSYS_CLR_BIT(
+ REG_CONN_INFRA_CLKGEN_ON_TOP_ADDR + CONN_INFRA_CLKGEN_ON_TOP_CKGEN_BUS, (0x1<<23));
+ /* Conn_infra HW_CONTROL => conn_infra enter dsleep mode
+ * CONN_INFRA_CFG_PWRCTRL0_HW_CONTROL
+ * 0x1800_1200[0]=1'b1
+ */
+ CONSYS_SET_BIT(
+ REG_CONN_INFRA_CFG_ADDR + CONN_INFRA_CFG_PWRCTRL0, 0x1);
+ return 0;
+}
+
+static int consys_sema_acquire(enum conn_semaphore_type index)
+{
+ if (CONSYS_REG_READ_BIT(
+ REG_CONN_SEMAPHORE_ADDR + CONN_SEMAPHORE_M2_OWN_STA + index*4, 0x1) == 0x1) {
+ return CONN_SEMA_GET_SUCCESS;
+ } else {
+ return CONN_SEMA_GET_FAIL;
+ }
+}
+
+int consys_sema_acquire_timeout(unsigned int index, unsigned int usec)
+{
+ int i;
+
+ if (index >= CONN_SEMA_NUM_MAX) {
+ pr_err("[%s] wrong index: %d", __func__, index);
+ return CONN_SEMA_GET_FAIL;
+ }
+
+ for (i = 0; i < usec; i++) {
+ if (consys_sema_acquire(index) == CONN_SEMA_GET_SUCCESS) {
+ return CONN_SEMA_GET_SUCCESS;
+ }
+ udelay(1);
+ }
+ pr_err("Get semaphore 0x%x timeout, dump status:\n", index);
+ pr_err("M2:[0x%x] M3:[0x%x]\n",
+ CONSYS_REG_READ(REG_CONN_SEMAPHORE_ADDR + CONN_SEMA_OWN_BY_M2_STA_REP),
+ CONSYS_REG_READ(REG_CONN_SEMAPHORE_ADDR + CONN_SEMA_OWN_BY_M3_STA_REP));
+ return CONN_SEMA_GET_FAIL;
+}
+
+void consys_sema_release(unsigned int index)
+{
+ if (index >= CONN_SEMA_NUM_MAX) {
+ pr_err("[%s] wrong index: %d", __func__, index);
+ return;
+ }
+
+ CONSYS_REG_WRITE(
+ (REG_CONN_SEMAPHORE_ADDR + CONN_SEMAPHORE_M2_OWN_REL + index*4), 0x1);
+}
+
+struct spi_op {
+ unsigned int busy_cr;
+ unsigned int polling_bit;
+ unsigned int addr_cr;
+ unsigned int read_addr_format;
+ unsigned int write_addr_format;
+ unsigned int write_data_cr;
+ unsigned int read_data_cr;
+ unsigned int read_data_mask;
+};
+
+static const struct spi_op spi_op_array[SYS_SPI_MAX] = {
+ /* SYS_SPI_WF1 */
+ {
+ CONN_RF_SPI_MST_REG_SPI_STA, 1,
+ CONN_RF_SPI_MST_REG_SPI_WF_ADDR, 0x00001000, 0x00000000,
+ CONN_RF_SPI_MST_REG_SPI_WF_WDAT,
+ CONN_RF_SPI_MST_REG_SPI_WF_RDAT, 0xffffffff
+ },
+ /* SYS_SPI_WF */
+ {
+ CONN_RF_SPI_MST_REG_SPI_STA, 1,
+ CONN_RF_SPI_MST_REG_SPI_WF_ADDR, 0x00003000, 0x00002000,
+ CONN_RF_SPI_MST_REG_SPI_WF_WDAT,
+ CONN_RF_SPI_MST_REG_SPI_WF_RDAT, 0xffffffff
+ },
+ /* SYS_SPI_BT */
+ {
+ CONN_RF_SPI_MST_REG_SPI_STA, 2,
+ CONN_RF_SPI_MST_REG_SPI_BT_ADDR, 0x00005000, 0x00004000,
+ CONN_RF_SPI_MST_REG_SPI_BT_WDAT,
+ CONN_RF_SPI_MST_REG_SPI_BT_RDAT, 0x000000ff
+ },
+ /* SYS_SPI_FM */
+ {
+ CONN_RF_SPI_MST_REG_SPI_STA, 3,
+ CONN_RF_SPI_MST_REG_SPI_FM_ADDR, 0x00007000, 0x00006000,
+ CONN_RF_SPI_MST_REG_SPI_FM_WDAT,
+ CONN_RF_SPI_MST_REG_SPI_FM_RDAT, 0x0000ffff
+ },
+ /* SYS_SPI_GPS */
+ {
+ CONN_RF_SPI_MST_REG_SPI_STA, 4,
+ CONN_RF_SPI_MST_REG_SPI_GPS_GPS_ADDR, 0x00009000, 0x00008000,
+ CONN_RF_SPI_MST_REG_SPI_GPS_GPS_WDAT,
+ CONN_RF_SPI_MST_REG_SPI_GPS_GPS_RDAT, 0x0000ffff
+ },
+ /* SYS_SPI_TOP */
+ {
+ CONN_RF_SPI_MST_REG_SPI_STA, 5,
+ CONN_RF_SPI_MST_REG_SPI_TOP_ADDR, 0x0000b000, 0x0000a000,
+ CONN_RF_SPI_MST_REG_SPI_TOP_WDAT,
+ CONN_RF_SPI_MST_REG_SPI_TOP_RDAT, 0xffffffff
+ },
+ /* SYS_SPI_WF2 */
+ {
+ CONN_RF_SPI_MST_REG_SPI_STA, 1,
+ CONN_RF_SPI_MST_REG_SPI_WF_ADDR, 0x0000d000, 0x0000c000,
+ CONN_RF_SPI_MST_REG_SPI_WF_WDAT,
+ CONN_RF_SPI_MST_REG_SPI_WF_RDAT, 0xffffffff
+ },
+ /* SYS_SPI_WF3 */
+ {
+ CONN_RF_SPI_MST_REG_SPI_STA, 1,
+ CONN_RF_SPI_MST_REG_SPI_WF_ADDR, 0x0000f000, 0x0000e000,
+ CONN_RF_SPI_MST_REG_SPI_WF_WDAT,
+ CONN_RF_SPI_MST_REG_SPI_WF_RDAT, 0xffffffff
+ },
+};
+
+static int consys_spi_read_nolock(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data)
+{
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* Read action:
+ * 1. Polling busy_cr[polling_bit] should be 0
+ * 2. Write addr_cr with data being {read_addr_format | addr[11:0]}
+ * 3. Trigger SPI by writing write_data_cr as 0
+ * 4. Polling busy_cr[polling_bit] as 0
+ * 5. Read data_cr[data_mask]
+ */
+ int check = 0;
+ const struct spi_op* op = &spi_op_array[subsystem];
+
+ if (!data) {
+ pr_err("[%s] invalid data ptr\n", __func__);
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+
+ CONSYS_REG_BIT_POLLING(
+ REG_CONN_RFSPI_ADDR + op->busy_cr,
+ op->polling_bit, 0, 100, 50, check);
+ if (check != 0) {
+ pr_err("[%s][%d][STEP1] polling 0x%08lx bit %d fail. Value=0x%08x\n",
+ __func__, subsystem, REG_CONN_RFSPI_ADDR + op->busy_cr,
+ op->polling_bit,
+ CONSYS_REG_READ(REG_CONN_RFSPI_ADDR + op->busy_cr));
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+
+ CONSYS_REG_WRITE(
+ REG_CONN_RFSPI_ADDR + op->addr_cr,
+ (op->read_addr_format | addr));
+
+ CONSYS_REG_WRITE(REG_CONN_RFSPI_ADDR + op->write_data_cr, 0);
+
+ check = 0;
+ CONSYS_REG_BIT_POLLING(
+ REG_CONN_RFSPI_ADDR + op->busy_cr,
+ op->polling_bit, 0, 100, 50, check);
+ if (check != 0) {
+ pr_err("[%s][%d][STEP4] polling 0x%08lx bit %d fail. Value=0x%08x\n",
+ __func__, subsystem, REG_CONN_RFSPI_ADDR + op->busy_cr,
+ op->polling_bit,
+ CONSYS_REG_READ(REG_CONN_RFSPI_ADDR + op->busy_cr));
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+
+ check = CONSYS_REG_READ_BIT(REG_CONN_RFSPI_ADDR + op->read_data_cr, op->read_data_mask);
+ *data = check;
+#else
+ *data = 0;
+#endif /* CONFIG_FPGA_EARLY_PORTING */
+ return 0;
+}
+
+int consys_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data)
+{
+ int ret;
+
+ /* Get semaphore before read */
+ if (consys_sema_acquire_timeout(CONN_SEMA_RFSPI_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) {
+ pr_err("[SPI READ] Require semaphore fail\n");
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+
+ ret = consys_spi_read_nolock(subsystem, addr, data);
+
+ consys_sema_release(CONN_SEMA_RFSPI_INDEX);
+
+ return ret;
+}
+
+static int consys_spi_write_nolock(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data)
+{
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ int check = 0;
+ const struct spi_op* op = &spi_op_array[subsystem];
+
+ /* Write action:
+ * 1. Wait busy_cr[polling_bit] as 0
+ * 2. Write addr_cr with data being {write_addr_format | addr[11:0]
+ * 3. Write write_data_cr ad data
+ * 4. Wait busy_cr[polling_bit] as 0
+ */
+ CONSYS_REG_BIT_POLLING(
+ REG_CONN_RFSPI_ADDR + op->busy_cr,
+ op->polling_bit, 0, 100, 50, check);
+ if (check != 0) {
+ pr_err("[%s][%d][STEP1] polling 0x%08lx bit %d fail. Value=0x%08x\n",
+ __func__, subsystem, REG_CONN_RFSPI_ADDR + op->busy_cr,
+ op->polling_bit,
+ CONSYS_REG_READ(REG_CONN_RFSPI_ADDR + op->busy_cr));
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+
+ CONSYS_REG_WRITE(REG_CONN_RFSPI_ADDR + op->addr_cr, (op->write_addr_format | addr));
+
+ CONSYS_REG_WRITE(REG_CONN_RFSPI_ADDR + op->write_data_cr, data);
+
+ check = 0;
+ CONSYS_REG_BIT_POLLING(
+ REG_CONN_RFSPI_ADDR + op->busy_cr,
+ op->polling_bit, 0, 100, 50, check);
+ if (check != 0) {
+ pr_err("[%s][%d][STEP4] polling 0x%08lx bit %d fail. Value=0x%08x\n",
+ __func__, subsystem, REG_CONN_RFSPI_ADDR + op->busy_cr,
+ op->polling_bit,
+ CONSYS_REG_READ(REG_CONN_RFSPI_ADDR + op->busy_cr));
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+#endif /* CONFIG_FPGA_EARLY_PORTING */
+ return 0;
+
+}
+
+
+int consys_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data)
+{
+ int ret;
+
+ /* Get semaphore before read */
+ if (consys_sema_acquire_timeout(CONN_SEMA_RFSPI_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) {
+ pr_err("[SPI WRITE] Require semaphore fail\n");
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+
+ ret = consys_spi_write_nolock(subsystem, addr, data);
+
+ consys_sema_release(CONN_SEMA_RFSPI_INDEX);
+ return ret;
+}
+
+int consys_spi_write_offset_range(
+ enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int value,
+ unsigned int reg_offset, unsigned int value_offset, unsigned int size)
+{
+ if (consys_sema_acquire_timeout(CONN_SEMA_RFSPI_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) {
+ pr_err("[SPI READ] Require semaphore fail\n");
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+ consys_spi_write_offset_range_nolock(
+ subsystem, addr, value, reg_offset, value_offset, size);
+
+ consys_sema_release(CONN_SEMA_RFSPI_INDEX);
+ return 0;
+}
+
+static void consys_spi_write_offset_range_nolock(
+ enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int value,
+ unsigned int reg_offset, unsigned int value_offset, unsigned int size)
+{
+ unsigned int data = 0, data2;
+ unsigned int reg_mask;
+ int ret;
+
+ pr_info("[%s][%s] addr=0x%04x value=0x%08x reg_offset=%d value_offset=%d size=%d",
+ __func__, g_spi_system_name[subsystem], addr, value, reg_offset, value_offset, size);
+ value = (value >> value_offset);
+ value = GET_BIT_RANGE(value, size, 0);
+ value = (value << reg_offset);
+ ret = consys_spi_read_nolock(subsystem, addr, &data);
+ if (ret) {
+ pr_err("[%s][%s] Get 0x%08x error, ret=%d",
+ __func__, g_spi_system_name[subsystem], addr, ret);
+ return;
+ }
+ reg_mask = GENMASK(reg_offset + size - 1, reg_offset);
+ data2 = data & (~reg_mask);
+ data2 = (data2 | value);
+ consys_spi_write_nolock(subsystem, addr, data2);
+ pr_info("[%s][%s] Write CR:0x%08x from 0x%08x to 0x%08x",
+ __func__, g_spi_system_name[subsystem],
+ addr, data, data2);
+}
+
+static int consys_adie_top_ck_en_top_ctrl(bool on)
+{
+ int check = 0;
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* 0x18005120[0] == 1'b1/1'b0
+ * 1'b1/1'b0: Enable/Disable dig_top_ck in Adie
+ * Adress in Adie: 12'hA00
+ */
+ if (on)
+ CONSYS_SET_BIT(REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_WB_SLP_TOP_CK_0, (0x1 << 0));
+ else
+ CONSYS_CLR_BIT(REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_WB_SLP_TOP_CK_0, (0x1 << 0));
+
+ /* POLLING 0x18005120[1] == 1'b0
+ * Wait 0x18005120[1] == 1'b0 (Wait finish status)
+ */
+ CONSYS_REG_BIT_POLLING(
+ REG_CONN_WT_SPL_CTL_ADDR + CONN_WT_SLP_WB_SLP_TOP_CK_0,
+ 1, 0, 10, 10, check);
+ if (check == -1) {
+ pr_err("[%s] %s fail\n", __func__, (on? "turn on" : "turn off"));
+ }
+#endif
+ return check;
+}
+
+bool consys_is_rc_mode_enable(void)
+{
+ /* Not support RC mode */
+ return 0;
+}
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885.h
new file mode 100755
index 0000000..6b06700
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_MT6885_H_
+#define _PLATFORM_MT6885_H_
+
+enum conn_semaphore_type
+{
+ CONN_SEMA_CHIP_POWER_ON_INDEX = 0,
+ CONN_SEMA_CALIBRATION_INDEX = 1,
+ CONN_SEMA_FW_DL_INDEX = 2,
+ CONN_SEMA_CLOCK_SWITCH_INDEX = 3,
+ CONN_SEMA_CCIF_INDEX = 4,
+ CONN_SEMA_COEX_INDEX = 5,
+ CONN_SEMA_USB_EP0_INDEX = 6,
+ CONN_SEMA_USB_SHARED_INFO_INDEX = 7,
+ CONN_SEMA_USB_SUSPEND_INDEX = 8,
+ CONN_SEMA_USB_RESUME_INDEX = 9,
+ CONN_SEMA_PCIE_INDEX = 10,
+ CONN_SEMA_RFSPI_INDEX = 11,
+ CONN_SEMA_EFUSE_INDEX = 12,
+ CONN_SEMA_THERMAL_INDEX = 13,
+ CONN_SEMA_FLASH_INDEX = 14,
+ CONN_SEMA_DEBUG_INDEX = 15,
+ CONN_SEMA_WIFI_LP_INDEX = 16,
+ CONN_SEMA_PATCH_DL_INDEX = 17,
+ CONN_SEMA_SHARED_VAR_INDEX = 18,
+ CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX = 19,
+ CONN_SEMA_NUM_MAX = 32 /* can't be omitted */
+};
+
+int consys_platform_spm_conn_ctrl(unsigned int enable);
+int consys_co_clock_type(void);
+
+struct consys_plat_thermal_data {
+ int thermal_b;
+ int slop_molecule;
+ int offset;
+};
+
+void update_thermal_data(struct consys_plat_thermal_data* input);
+#endif /* _PLATFORM_MT6885_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885_consys_reg.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885_consys_reg.h
new file mode 100755
index 0000000..70fc7cd
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885_consys_reg.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_MT6885_CONSYS_REG_H_
+#define _PLATFORM_MT6885_CONSYS_REG_H_
+
+#include "consys_reg_base.h"
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+enum consys_base_addr_index {
+ CONN_INFRA_RGU_BASE_INDEX = 0,
+ CONN_INFRA_CFG_BASE_INDEX = 1,
+ CONN_HOST_CSR_TOP_BASE_INDEX = 2,
+ INFRACFG_AO_BASE_INDEX = 3,
+ TOPRGU_BASE_INDEX= 4,
+ SPM_BASE_INDEX = 5,
+ INFRACFG_BASE_INDEX = 6,
+ CONN_WT_SLP_CTL_REG_INDEX = 7,
+ CONN_AFE_CTL_INDEX = 8,
+ CONN_INFRA_SYSRAM_INDEX = 9,
+ GPIO_INDEX = 10,
+ CONN_RF_SPI_MST_REG_INDEX = 11,
+ CONN_SEMAPHORE_INDEX = 12,
+ CONN_TOP_THERM_CTL_INDEX = 13,
+ IOCFG_RT_INDEX = 14, /* Base: 0x11EA_0000 */
+ CONN_DEBUG_CTRL = 15, /* Base: 0x1800_f000 */
+
+ CONSYS_BASE_ADDR_MAX
+};
+
+
+struct consys_base_addr {
+ struct consys_reg_base_addr reg_base_addr[CONSYS_BASE_ADDR_MAX];
+};
+
+extern struct consys_base_addr conn_reg;
+
+#define CON_REG_INFRA_RGU_ADDR conn_reg.reg_base_addr[CONN_INFRA_RGU_BASE_INDEX].vir_addr
+#define CON_REG_INFRA_CFG_ADDR conn_reg.reg_base_addr[CONN_INFRA_CFG_BASE_INDEX].vir_addr
+#define CON_REG_HOST_CSR_ADDR conn_reg.reg_base_addr[CONN_HOST_CSR_TOP_BASE_INDEX].vir_addr
+#define CON_REG_INFRACFG_AO_ADDR conn_reg.reg_base_addr[INFRACFG_AO_BASE_INDEX].vir_addr
+
+#define CON_REG_TOP_RGU_ADDR conn_reg.reg_base_addr[TOPRGU_BASE_INDEX].vir_addr
+#define CON_REG_SPM_BASE_ADDR conn_reg.reg_base_addr[SPM_BASE_INDEX].vir_addr
+#define CON_REG_INFRACFG_BASE_ADDR conn_reg.reg_base_addr[INFRACFG_BASE_INDEX].vir_addr
+#define CON_REG_WT_SPL_CTL_ADDR conn_reg.reg_base_addr[CONN_WT_SLP_CTL_REG_INDEX].vir_addr
+
+#define CONN_AFE_CTL_BASE_ADDR conn_reg.reg_base_addr[CONN_AFE_CTL_INDEX].vir_addr
+#define CONN_INFRA_SYSRAM_BASE_ADDR conn_reg.reg_base_addr[CONN_INFRA_SYSRAM_INDEX].vir_addr
+#define GPIO_BASE_ADDR conn_reg.reg_base_addr[GPIO_INDEX].vir_addr
+#define CONN_REG_RFSPI_ADDR conn_reg.reg_base_addr[CONN_RF_SPI_MST_REG_INDEX].vir_addr
+
+#define CONN_REG_SEMAPHORE_ADDR conn_reg.reg_base_addr[CONN_SEMAPHORE_INDEX].vir_addr
+#define CONN_TOP_THERM_CTL_ADDR conn_reg.reg_base_addr[CONN_TOP_THERM_CTL_INDEX].vir_addr
+#define IOCFG_RT_ADDR conn_reg.reg_base_addr[IOCFG_RT_INDEX].vir_addr
+#define CONN_DEBUG_CTRL_ADDR conn_reg.reg_base_addr[CONN_DEBUG_CTRL].vir_addr
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+struct consys_base_addr* get_conn_reg_base_addr(void);
+
+#endif /* _PLATFORM_MT6885_CONSYS_REG_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885_consys_reg_offset.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885_consys_reg_offset.h
new file mode 100755
index 0000000..0dc808e
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885_consys_reg_offset.h
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_MT6885_CONSYS_REG_OFFSET_H_
+#define _PLATFORM_MT6885_CONSYS_REG_OFFSET_H_
+
+
+/**********************************************************************/
+/* Base: infracfg_ao (0x1000_1000) */
+/**********************************************************************/
+#define INFRA_TOPAXI_PROTECTEN_STA1_OFFSET 0x0228
+#define INFRA_TOPAXI_PROTECTEN_SET_OFFSET 0x02a0
+#define INFRA_TOPAXI_PROTECTEN_CLR_OFFSET 0x02a4
+#define INFRA_TOPAXI_PROTECTEN2_CLR_OFFSET 0x0718
+#define INFRA_TOPAXI_PROTECTEN2_SET_OFFSET 0x0714
+#define INFRA_TOPAXI_PROTECTEN2_STA1_OFFSET 0x0724
+
+/**********************************************************************/
+/* Base: GPIO (0x1000_5000) */
+/**********************************************************************/
+#define GPIO_DIR5_SET 0x0054
+
+#define GPIO_DOUT5_SET 0x0154
+
+#define GPIO_MODE19 0x0430
+#define GPIO_MODE21 0x0450
+#define GPIO_MODE22 0x0460
+
+/**********************************************************************/
+/* Base: SPM (0x1000_6000) */
+/**********************************************************************/
+#define SPM_POWERON_CONFIG_EN 0x0000
+#define SPM_PCM_REG13_DATA 0x0110
+#define SPM_PCM_REG7_DATA 0x0100
+#define SPM_SRC_REQ_STA_0 0x0114
+#define SPM_BUS_PROTECT_RDY 0x0150
+#define SPM_BUS_PROTECT2_RDY 0x0158
+#define SPM_PWR_STATUS 0x016c
+#define SPM_PWR_STATUS_2ND 0x0170
+#define SPM_CONN_PWR_CON 0x0304
+#define SPM_PLL_CON 0x044C
+#define SPM_RC_CENTRAL_CFG1 0x0504
+#define SPM_PCM_WDT_LATCH_SPARE_0 0x084C
+
+#define SPM_RC_RC_M04_REQ_STA_0 0xE28
+#define SPM_RC_RC_M05_REQ_STA_0 0xE2C
+#define SPM_RC_RC_M06_REQ_STA_0 0xE30
+#define SPM_RC_RC_M07_REQ_STA_0 0xE34
+
+/**********************************************************************/
+/* Base: TOP RGU (0x1000_7000) */
+/**********************************************************************/
+#define TOP_RGU_WDT_SWSYSRST 0x0018
+
+
+/**********************************************************************/
+/* Base: INFRACFG (0x1020_e000) */
+/**********************************************************************/
+#define INFRA_AP2MD_GALS_CTL 0x0504
+#define INFRA_CONN2AP_GLAS_RC_ST 0x0804
+
+/**********************************************************************/
+/* Base: IOCFG_RT (0x11EA_0000) */
+/**********************************************************************/
+#define IOCFG_RT_DRV_CFG0 0x0000
+#define IOCFG_RT_PD_CFG0_SET 0x0054
+#define IOCFG_RT_PD_CFG0_CLR 0x0058
+#define IOCFG_RT_PU_CFG0_SET 0x0074
+#define IOCFG_RT_PU_CFG0_CLR 0x0078
+
+/**********************************************************************/
+/* Base: conn_infra_rgu (0x1800_0000) */
+/**********************************************************************/
+#define CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_CTL 0x0008
+#define CONN_INFRA_RGU_SYSRAM_HWCTL_PDN 0x0038
+#define CONN_INFRA_RGU_SYSRAM_HWCTL_SLP 0x003c
+#define CONN_INFRA_RGU_CO_EXT_MEM_HWCTL_PDN 0x0050
+#define CONN_INFRA_RGU_CO_EXT_MEM_HWCTL_SLP 0x0054
+#define CONN_INFRA_RGU_DEBUG_SEL 0x0090
+
+/**********************************************************************/
+/* Base: conn_infra_cfg (0x1800_1000) */
+/**********************************************************************/
+#define CONN_HW_VER_OFFSET 0x0000
+#define CONN_CFG_ID_OFFSET 0x0004
+#define CONN_INFRA_CFG_LIGHT_SECURITY_CTRL 0x00f0
+
+#define CONN_INFRA_CFG_GALS_AP2CONN_GALS_DBG 0x0160
+#define CONN_INFRA_CFG_GALS_CONN2AP_TX_SLP_CTRL 0x0630
+#define CONN_INFRA_CFG_GALS_CONN2AP_RX_SLP_CTRL 0x0634
+#define CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL 0x061C
+#define CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL 0x0618
+#define CONN_INFRA_CFG_GALS_BT2CONN_SLP_CTRL 0x0614
+#define CONN_INFRA_CFG_GALS_CONN2BT_SLP_CTRL 0x0610
+
+#define CONN_INFRA_CFG_WF_SLP_CTRL 0x0620
+#define CONN_INFRA_CFG_ON_BUS_SLP_CTRL 0x0628
+#define CONN_INFRA_CFG_OFF_BUS_SLP_CTRL 0x062C
+
+
+#define CONN_INFRA_CFG_OSC_CTL_0 0x0800
+#define CONN_INFRA_CFG_OSC_CTL_1 0x0804
+#define CONN_INFRA_CFG_OSC_STATUS 0x080C
+#define CONN_INFRA_CFG_PLL_STATUS 0x0810
+
+#define AP2CONN_EFUSE_DATA 0x0818
+#define CONN_INFRA_CFG_RC_CTL_0 0x0834
+#define CONN_INFRA_CFG_RC_CTL_0 0x0834
+#define CONN_INFRA_CFG_RC_CTL_0_GPS 0x0838
+#define CONN_INFRA_CFG_RC_CTL_1_GPS 0x083C
+#define CONN_INFRA_CFG_RC_CTL_0_BT 0x0840
+#define CONN_INFRA_CFG_RC_CTL_1_BT 0x0844
+#define CONN_INFRA_CFG_RC_CTL_0_WF 0x0848
+#define CONN_INFRA_CFG_RC_CTL_1_WF 0x084c
+#define CONN_INFRA_CFG_RC_CTL_1_TOP 0x0854
+#define CONN_INFRA_CFG_RC_CTL_0_TOP 0x0850
+#define CONN_INFRA_CFG_PWRCTRL0 0x0860
+#define CONN_INFRA_CFG_ADIE_CTL 0x0900
+#define CONN_INFRA_CFG_CKGEN_BUS 0x0a00
+#define CONN_INFRA_CFG_DBG_MUX_SEL 0x0b00
+#define CONN_INFRA_CFG_EMI_CTL_0 0x0c00
+
+#define CONN_HW_VER 0x20010000
+#define CONN_CFG_ID 0x3
+
+/**********************************************************************/
+/* Base: conn_top_therm_ctl (0x1800_2000) */
+/**********************************************************************/
+#define CONN_TOP_THERM_CTL_THERMCR1 0x0004
+#define CONN_TOP_THERM_CTL_THERM_AADDR 0x0018
+#define CONN_TOP_THERM_CTL_THERM_CAL_EN 0x0024
+
+/**********************************************************************/
+/* Base: conn_afe_ctl(0x1800_3000) */
+/**********************************************************************/
+#define CONN_AFE_CTL_RG_DIG_EN_01 0x0000
+#define CONN_AFE_CTL_RG_DIG_EN_02 0x0004
+#define CONN_AFE_CTL_RG_DIG_EN_03 0x0008
+#define CONN_AFE_CTL_RG_WBG_AFE_01 0x0010
+#define CONN_AFE_CTL_RG_WBG_RCK_01 0x0018
+#define CONN_AFE_CTL_RG_WBG_GL1_01 0x0040
+#define CONN_AFE_CTL_RG_WBG_BT_TX_03 0x0058
+#define CONN_AFE_CTL_RG_WBG_WF0_TX_03 0x0078
+#define CONN_AFE_CTL_RG_WBG_WF1_TX_03 0x0094
+#define CONN_AFE_CTL_RG_PLL_STB_TIME 0x00f4
+#define CONN_AFE_CTL_RG_WBG_GL5_01 0x0100
+
+
+/**********************************************************************/
+/* Base: conn_rf_spi_mst_reg(0x1800_4000) */
+/**********************************************************************/
+#define CONN_RF_SPI_MST_REG_SPI_STA 0x0000
+#define CONN_RF_SPI_MST_REG_SPI_CRTL 0x0004
+#define CONN_RF_SPI_MST_REG_FM_CTRL 0x000c
+#define CONN_RF_SPI_MST_REG_SPI_WF_ADDR 0x0010
+#define CONN_RF_SPI_MST_REG_SPI_WF_WDAT 0x0014
+#define CONN_RF_SPI_MST_REG_SPI_WF_RDAT 0x0018
+#define CONN_RF_SPI_MST_REG_SPI_BT_ADDR 0x0020
+#define CONN_RF_SPI_MST_REG_SPI_BT_WDAT 0x0024
+#define CONN_RF_SPI_MST_REG_SPI_BT_RDAT 0x0028
+#define CONN_RF_SPI_MST_REG_SPI_FM_ADDR 0x0030
+#define CONN_RF_SPI_MST_REG_SPI_FM_WDAT 0x0034
+#define CONN_RF_SPI_MST_REG_SPI_FM_RDAT 0x0038
+#define CONN_RF_SPI_MST_REG_SPI_TOP_ADDR 0x0050
+#define CONN_RF_SPI_MST_REG_SPI_TOP_WDAT 0x0054
+#define CONN_RF_SPI_MST_REG_SPI_TOP_RDAT 0x0058
+#define CONN_RF_SPI_MST_REG_SPI_GPS_GPS_ADDR 0x0210
+#define CONN_RF_SPI_MST_REG_SPI_GPS_GPS_WDAT 0x0214
+#define CONN_RF_SPI_MST_REG_SPI_GPS_GPS_RDAT 0x0218
+
+
+/**********************************************************************/
+/* Base: conn_wt_slp_ctl_reg(0x1800_5000) */
+/**********************************************************************/
+#define CONN_WTSLP_CTL_REG_WB_STA 0x0008
+#define CONN_WT_SLP_CTL_REG_WB_SLP_CTL 0x0004
+#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR1 0x0010
+#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR2 0x0014
+#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR3 0x0018
+#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR4 0x001c
+#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR5 0x0020
+#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR6 0x0024
+#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR7 0x0028
+#define CONN_WT_SLP_CTL_REG_WB_BG_ADDR8 0x002c
+#define CONN_WT_SLP_CTL_REG_WB_BG_ON1 0x0030
+#define CONN_WT_SLP_CTL_REG_WB_BG_ON2 0x0034
+#define CONN_WT_SLP_CTL_REG_WB_BG_ON3 0x0038
+#define CONN_WT_SLP_CTL_REG_WB_BG_ON4 0x003c
+#define CONN_WT_SLP_CTL_REG_WB_BG_ON5 0x0040
+#define CONN_WT_SLP_CTL_REG_WB_BG_ON6 0x0044
+#define CONN_WT_SLP_CTL_REG_WB_BG_ON7 0x0048
+#define CONN_WT_SLP_CTL_REG_WB_BG_ON8 0x004c
+#define CONN_WT_SLP_CTL_REG_WB_BG_OFF1 0x0050
+#define CONN_WT_SLP_CTL_REG_WB_BG_OFF2 0x0054
+#define CONN_WT_SLP_CTL_REG_WB_BG_OFF3 0x0058
+#define CONN_WT_SLP_CTL_REG_WB_BG_OFF4 0x005c
+#define CONN_WT_SLP_CTL_REG_WB_BG_OFF5 0x0060
+#define CONN_WT_SLP_CTL_REG_WB_BG_OFF6 0x0064
+#define CONN_WT_SLP_CTL_REG_WB_BG_OFF7 0x0068
+#define CONN_WT_SLP_CTL_REG_WB_BG_OFF8 0x006c
+#define CONN_WT_SLP_CTL_REG_WB_WF_CK_ADDR 0x0070
+#define CONN_WT_SLP_CTL_REG_WB_WF_WAKE_ADDR 0x0074
+#define CONN_WT_SLP_CTL_REG_WB_WF_ZPS_ADDR 0x0078
+#define CONN_WT_SLP_CTL_REG_WB_BT_CK_ADDR 0x007c
+#define CONN_WT_SLP_CTL_REG_WB_BT_WAKE_ADDR 0x0080
+#define CONN_WT_SLP_CTL_REG_WB_TOP_CK_ADDR 0x0084
+#define CONN_WT_SLP_CTL_REG_WB_GPS_CK_ADDR 0x0088
+#define CONN_WT_SLP_CTL_REG_WB_WF_B0_CMD_ADDR 0x008c
+#define CONN_WT_SLP_CTL_REG_WB_WF_B1_CMD_ADDR 0x0090
+#define CONN_WT_SLP_CTL_REG_WB_GPS_RFBUF_ADDR 0x0094
+#define CONN_WT_SLP_CTL_REG_WB_GPS_L5_EN_ADDR 0x0098
+
+/**********************************************************************/
+/* Base: GPT2 timer (0x1800_a000) */
+/**********************************************************************/
+#define CONN_GPT2_CTRL_BASE 0x1800a000
+#define CONN_GPT2_CTRL_THERMAL_EN 0x38
+
+/**********************************************************************/
+/* Base: debug_ctrl (0x1800_f000) */
+/**********************************************************************/
+#define CONN_DEBUG_CTRL_REG_OFFSET 0x0000
+
+
+/**********************************************************************/
+/* Base: conn_infra_sysram(0x1805_0000) */
+/**********************************************************************/
+#define CONN_INFRA_SYSRAM_SW_CR_A_DIE_CHIP_ID 0x2800
+#define CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_0 0x2804
+#define CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_1 0x2808
+#define CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_2 0x280C
+#define CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_3 0x2810
+
+#define CONN_INFRA_SYSRAM_SW_CR_D_DIE_EFUSE 0x2820
+
+#define CONN_INFRA_SYSRAM_SW_CR_A_DIE_TOP_CK_EN_CTRL 0x2830
+#define CONN_INFRA_SYSRAM_SW_CR_RADIO_STATUS 0x2834
+
+#define CONN_INFRA_SYSRAM_SW_CR_OFFSET 0x2800
+#define CONN_INFRA_SYSRAM_SW_CR_SIZE (4 * 1024)
+
+
+/**********************************************************************/
+/* Base: conn_host_csr_top (0x1806_0000) */
+/**********************************************************************/
+#define CONN_HOST_CSR_TOP_CSR_DEADFEED_EN_CR 0x0124
+#define CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_AO_DEBUGSYS 0x0128
+#define CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT 0x0148
+#define CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL 0x0184
+#define CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP 0x01a0
+/* remap */
+#define CONN2AP_REMAP_MCU_EMI_BASE_ADDR_OFFSET 0x01c4
+#define CONN2AP_REMAP_MD_SHARE_EMI_BASE_ADDR_OFFSET 0x01cc
+#define CONN2AP_REMAP_GPS_EMI_BASE_ADDR_OFFSET 0x01d0
+#define CONN2AP_REMAP_WF_PERI_BASE_ADDR_OFFSET 0x01d4
+#define CONN2AP_REMAP_BT_PERI_BASE_ADDR_OFFSET 0x01d8
+#define CONN2AP_REMAP_GPS_PERI_BASE_ADDR_OFFSET 0x01dc
+
+#define CONN_HOST_CSR_WM_MCU_PC_DBG 0x0204
+#define CONN_HOST_CSR_WM_MCU_GPR_DBG 0x0208
+#define CONN_HOST_CSR_BGF_MCU_PC_DBG 0x022C
+
+#define CONN_HOST_CSR_DBG_DUMMY_0 0x02C0
+#define CONN_HOST_CSR_DBG_DUMMY_2 0x02C8
+#define CONN_HOST_CSR_DBG_DUMMY_3 0x02CC
+#define CONN_HOST_CSR_DBG_DUMMY_4 0x02D0
+#define CONN_HOST_CSR_TOP_BUS_TIMEOUT_IRQ 0x02d4
+
+#define TOP_BUS_MUC_STAT_HCLK_FR_CK_DETECT_BIT (0x1 << 1)
+#define TOP_BUS_MUC_STAT_OSC_CLK_DETECT_BIT (0x1 << 2)
+#define TOP_SLP_PROT_CTRL_CONN_INFRA_ON2OFF_SLP_PROT_ACK_BIT (0x1 << 5)
+
+/**********************************************************************/
+/* Base: conn_semaphore(0x1807_0000) */
+/**********************************************************************/
+#define CONN_SEMA_OWN_BY_M0_STA_REP 0x0400
+#define CONN_SEMA_OWN_BY_M1_STA_REP 0x1400
+#define CONN_SEMAPHORE_M2_OWN_STA 0x2000
+#define CONN_SEMAPHORE_M2_OWN_REL 0x2200
+#define CONN_SEMA_OWN_BY_M2_STA_REP 0x2400
+#define CONN_SEMA_OWN_BY_M3_STA_REP 0x3400
+
+/**********************************************************************/
+/* A-die CR */
+/**********************************************************************/
+#define ATOP_CHIP_ID 0x02c
+#define ATOP_RG_TOP_THADC_BG 0x034
+#define ATOP_RG_TOP_THADC 0x038
+#define ATOP_WRI_CTR2 0x064
+#define ATOP_RG_ENCAL_WBTAC_IF_SW 0x070
+#define ATOP_SMCTK11 0x0BC
+#define ATOP_EFUSE_CTRL 0x108
+#define ATOP_EFUSE_RDATA0 0x130
+#define ATOP_EFUSE_RDATA1 0x134
+#define ATOP_EFUSE_RDATA2 0x138
+#define ATOP_EFUSE_RDATA3 0x13c
+#define ATOP_RG_WF0_TOP_01 0x380
+#define ATOP_RG_WF0_BG 0x384
+#define ATOP_RG_WF1_BG 0x394
+#define ATOP_RG_WF1_TOP_01 0x390
+#define ATOP_RG_TOP_XTAL_01 0xA18
+#define ATOP_RG_TOP_XTAL_02 0xA1C
+
+
+#endif /* _PLATFORM_MT6885_CONSSY_REG_OFFSET_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885_emi.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885_emi.h
new file mode 100755
index 0000000..2d62bf5
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885_emi.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_MT6885_EMI_H_
+#define _PLATFORM_MT6885_EMI_H_
+
+#include "osal.h"
+#include "emi_mng.h"
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+struct consys_platform_emi_ops* get_consys_platform_emi_ops(void);
+
+struct consys_emi_addr_info* consys_emi_get_phy_addr(void);
+int consys_emi_mpu_set_region_protection(void);
+void consys_emi_get_md_shared_emi(phys_addr_t*, unsigned int*);
+unsigned int consys_emi_get_fw_emi_size(void);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _PLATFORM_MT6885_EMI_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885_pmic.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885_pmic.h
new file mode 100755
index 0000000..d39491e
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885_pmic.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_MT6885_H_
+#define _PLATFORM_MT6885_H_
+
+#include "osal.h"
+#include "pmic_mng.h"
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+struct consys_platform_pmic_ops* get_consys_platform_pmic_ops(void);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _PLATFORM_MT6885_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885_pos.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885_pos.h
new file mode 100755
index 0000000..c28c0ce
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/include/mt6885_pos.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _PLATFORM_MT6885_POS_H_
+#define _PLATFORM_MT6885_POS_H_
+
+
+unsigned int consys_emi_set_remapping_reg(phys_addr_t, phys_addr_t);
+
+int consys_conninfra_on_power_ctrl(unsigned int enable);
+int consys_conninfra_wakeup(void);
+int consys_conninfra_sleep(void);
+void consys_set_if_pinmux(unsigned int enable);
+int consys_polling_chipid(void);
+
+int connsys_d_die_cfg(void);
+int connsys_spi_master_cfg(unsigned int);
+int connsys_a_die_cfg(void);
+int connsys_afe_wbg_cal(void);
+int connsys_subsys_pll_initial(void);
+int connsys_low_power_setting(unsigned int, unsigned int);
+
+int consys_sema_acquire_timeout(enum conn_semaphore_type index, unsigned int usec);
+void consys_sema_release(enum conn_semaphore_type index);
+
+int consys_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data);
+int consys_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data);
+int consys_spi_write_offset_range(
+ enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int value,
+ unsigned int reg_offset, unsigned int value_offset, unsigned int size);
+
+int consys_adie_top_ck_en_on(enum consys_adie_ctl_type type);
+int consys_adie_top_ck_en_off(enum consys_adie_ctl_type type);
+
+int consys_spi_clock_switch(enum connsys_spi_speed_type type);
+int consys_subsys_status_update(bool, int);
+bool consys_is_rc_mode_enable(void);
+
+void consys_config_setup(void);
+
+#endif /* _PLATFORM_MT6885_POS_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/mt6885.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/mt6885.c
new file mode 100755
index 0000000..f66ec53
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/mt6885.c
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/memblock.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <mtk_clkbuf_ctl.h>
+
+#include <connectivity_build_in_adapter.h>
+
+#include "osal.h"
+#include "conninfra.h"
+#include "conninfra_conf.h"
+#include "consys_hw.h"
+#include "consys_reg_mng.h"
+#include "consys_reg_util.h"
+#include "mt6885.h"
+#include "emi_mng.h"
+#include "mt6885_emi.h"
+#include "mt6885_consys_reg.h"
+#include "mt6885_consys_reg_offset.h"
+#include "mt6885_pos.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+#define CONSYS_PWR_SPM_CTRL 1
+#define PLATFORM_SOC_CHIP 0x6885
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+static int consys_clk_get_from_dts(struct platform_device *pdev);
+static int consys_clock_buffer_ctrl(unsigned int enable);
+static unsigned int consys_soc_chipid_get(void);
+static unsigned int consys_get_hw_ver(void);
+static void consys_clock_fail_dump(void);
+static int consys_thermal_query(void);
+static int consys_power_state(void);
+static int consys_bus_clock_ctrl(enum consys_drv_type, unsigned int, int);
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+struct consys_hw_ops_struct g_consys_hw_ops_mt6885 = {
+ /* load from dts */
+ /* TODO: mtcmos should move to a independent module */
+ .consys_plt_clk_get_from_dts = consys_clk_get_from_dts,
+
+ /* clock */
+ .consys_plt_clock_buffer_ctrl = consys_clock_buffer_ctrl,
+ .consys_plt_co_clock_type = consys_co_clock_type,
+
+ /* POS */
+ .consys_plt_conninfra_on_power_ctrl = consys_conninfra_on_power_ctrl,
+ .consys_plt_set_if_pinmux = consys_set_if_pinmux,
+
+ .consys_plt_polling_consys_chipid = consys_polling_chipid,
+ .consys_plt_d_die_cfg = connsys_d_die_cfg,
+ .consys_plt_spi_master_cfg = connsys_spi_master_cfg,
+ .consys_plt_a_die_cfg = connsys_a_die_cfg,
+ .consys_plt_afe_wbg_cal = connsys_afe_wbg_cal,
+ .consys_plt_subsys_pll_initial = connsys_subsys_pll_initial,
+ .consys_plt_low_power_setting = connsys_low_power_setting,
+ .consys_plt_soc_chipid_get = consys_soc_chipid_get,
+ .consys_plt_conninfra_wakeup = consys_conninfra_wakeup,
+ .consys_plt_conninfra_sleep = consys_conninfra_sleep,
+ .consys_plt_is_rc_mode_enable = consys_is_rc_mode_enable,
+
+ /* debug */
+ .consys_plt_clock_fail_dump = consys_clock_fail_dump,
+ .consys_plt_get_hw_ver = consys_get_hw_ver,
+ /* debug, used by STEP */
+ //.consys_plt_is_connsys_reg;
+
+ .consys_plt_sema_acquire_timeout = consys_sema_acquire_timeout,
+ .consys_plt_sema_release = consys_sema_release,
+ .consys_plt_spi_read = consys_spi_read,
+ .consys_plt_spi_write = consys_spi_write,
+ .consys_plt_adie_top_ck_en_on = consys_adie_top_ck_en_on,
+ .consys_plt_adie_top_ck_en_off = consys_adie_top_ck_en_off,
+ .consys_plt_spi_clock_switch = consys_spi_clock_switch,
+ .consys_plt_subsys_status_update = consys_subsys_status_update,
+
+ .consys_plt_thermal_query = consys_thermal_query,
+ .consys_plt_power_state = consys_power_state,
+ .consys_plt_config_setup = consys_config_setup,
+ .consys_plt_bus_clock_ctrl = consys_bus_clock_ctrl,
+};
+
+
+struct clk *clk_scp_conn_main; /*ctrl conn_power_on/off */
+struct consys_plat_thermal_data g_consys_plat_therm_data;
+
+/* For mt6885 */
+extern struct consys_hw_ops_struct g_consys_hw_ops_mt6885;
+extern struct consys_reg_mng_ops g_dev_consys_reg_ops_mt6885;
+extern struct consys_platform_emi_ops g_consys_platform_emi_ops_mt6885;
+extern struct consys_platform_pmic_ops g_consys_platform_pmic_ops_mt6885;
+
+const struct conninfra_plat_data mt6885_plat_data = {
+ .chip_id = PLATFORM_SOC_CHIP,
+ .hw_ops = &g_consys_hw_ops_mt6885,
+ .reg_ops = &g_dev_consys_reg_ops_mt6885,
+ .platform_emi_ops = &g_consys_platform_emi_ops_mt6885,
+ .platform_pmic_ops = &g_consys_platform_pmic_ops_mt6885,
+};
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#if 0
+struct consys_hw_ops_struct* get_consys_platform_ops(void)
+{
+ return &g_consys_hw_ops_mt6885;
+}
+#endif
+
+/* mtcmos contorl */
+int consys_clk_get_from_dts(struct platform_device *pdev)
+{
+ clk_scp_conn_main = devm_clk_get(&pdev->dev, "conn");
+ if (IS_ERR(clk_scp_conn_main)) {
+ pr_err("[CCF]cannot get clk_scp_conn_main clock.\n");
+ return PTR_ERR(clk_scp_conn_main);
+ }
+ pr_debug("[CCF]clk_scp_conn_main=%p\n", clk_scp_conn_main);
+
+ return 0;
+}
+
+int consys_platform_spm_conn_ctrl(unsigned int enable)
+{
+ int ret = 0;
+
+ if (enable) {
+ ret = clk_prepare_enable(clk_scp_conn_main);
+ if (ret) {
+ pr_err("Turn on oonn_infra power fail. Ret=%d\n", ret);
+ return -1;
+ }
+ } else {
+ clk_disable_unprepare(clk_scp_conn_main);
+
+ }
+
+ return ret;
+}
+
+int consys_clock_buffer_ctrl(unsigned int enable)
+{
+ /* This function call didn't work now.
+ * clock buffer is HW controlled, not SW controlled.
+ * Keep this function call to update status.
+ */
+ if (enable)
+ KERNEL_clk_buf_ctrl(CLK_BUF_CONN, true); /*open XO_WCN*/
+ else
+ KERNEL_clk_buf_ctrl(CLK_BUF_CONN, false); /*close XO_WCN*/
+ return 0;
+}
+
+int consys_co_clock_type(void)
+{
+ const struct conninfra_conf *conf;
+
+ /* Default solution */
+ conf = conninfra_conf_get_cfg();
+ if (NULL == conf) {
+ pr_err("[%s] Get conf fail", __func__);
+ return -1;
+ }
+ /* TODO: for co-clock mode, there are two case: 26M and 52M. Need something to distinguish it. */
+ if (conf->tcxo_gpio != 0)
+ return CONNSYS_CLOCK_SCHEMATIC_26M_EXTCXO;
+ else
+ return CONNSYS_CLOCK_SCHEMATIC_26M_COTMS;
+}
+
+unsigned int consys_soc_chipid_get(void)
+{
+ return PLATFORM_SOC_CHIP;
+}
+
+unsigned int consys_get_hw_ver(void)
+{
+ return CONN_HW_VER;
+}
+
+void consys_clock_fail_dump(void)
+{
+ pr_info("[%s]", __func__);
+}
+
+
+void update_thermal_data(struct consys_plat_thermal_data* input)
+{
+ memcpy(&g_consys_plat_therm_data, input, sizeof(struct consys_plat_thermal_data));
+ /* Special factor, not in POS */
+ /* THERMCR1 [16:17]*/
+ CONSYS_REG_WRITE(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERMCR1,
+ (CONSYS_REG_READ(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERMCR1) |
+ (0x3 << 16)));
+
+}
+
+int calculate_thermal_temperature(int y)
+{
+ struct consys_plat_thermal_data *data = &g_consys_plat_therm_data;
+ int t;
+ int const_offset = 25;
+
+ /*
+ * MT6635 E1 : read 0x02C = 0x66358A00
+ * MT6635 E2 : read 0x02C = 0x66358A10
+ * MT6635 E3 : read 0x02C = 0x66358A11
+ */
+ if (conn_hw_env.adie_hw_version == 0x66358A10 ||
+ conn_hw_env.adie_hw_version == 0x66358A11)
+ const_offset = 28;
+
+ /* temperature = (y-b)*slope + (offset) */
+ /* TODO: offset + 25 : this is only for E1, E2 is 28 */
+ t = (y - (data->thermal_b == 0 ? 0x36 : data->thermal_b)) *
+ ((data->slop_molecule + 209) / 100) + (data->offset + const_offset);
+
+ pr_info("y=[%d] b=[%d] constOffset=[%d] [%d] [%d] => t=[%d]\n",
+ y, data->thermal_b, const_offset, data->slop_molecule, data->offset,
+ t);
+
+ return t;
+}
+
+int consys_thermal_query(void)
+{
+#define THERMAL_DUMP_NUM 11
+#define LOG_TMP_BUF_SZ 256
+#define TEMP_SIZE 13
+ void __iomem *addr = NULL;
+ int cal_val, res = 0;
+ /* Base: 0x1800_2000, CONN_TOP_THERM_CTL */
+ const unsigned int thermal_dump_crs[THERMAL_DUMP_NUM] = {
+ 0x00, 0x04, 0x08, 0x0c,
+ 0x10, 0x14, 0x18, 0x1c,
+ 0x20, 0x24, 0x28,
+ };
+ char tmp[TEMP_SIZE] = {'\0'};
+ char tmp_buf[LOG_TMP_BUF_SZ] = {'\0'};
+ unsigned int i;
+ unsigned int efuse0, efuse1, efuse2, efuse3;
+
+ addr = ioremap_nocache(CONN_GPT2_CTRL_BASE, 0x100);
+ if (addr == NULL) {
+ pr_err("GPT2_CTRL_BASE remap fail");
+ return -1;
+ }
+
+ consys_adie_top_ck_en_on(CONNSYS_ADIE_CTL_HOST_CONNINFRA);
+
+ /* Hold Semaphore, TODO: may not need this, because
+ thermal cr seperate for different */
+ if (consys_sema_acquire_timeout(CONN_SEMA_THERMAL_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) {
+ pr_err("[THERM QRY] Require semaphore fail\n");
+ consys_adie_top_ck_en_off(CONNSYS_ADIE_CTL_HOST_CONNINFRA);
+ iounmap(addr);
+ return -1;
+ }
+
+ /* therm cal en */
+ CONSYS_REG_WRITE(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN,
+ (CONSYS_REG_READ(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN) |
+ (0x1 << 19)));
+ /* GPT2 En */
+ CONSYS_REG_WRITE(addr + CONN_GPT2_CTRL_THERMAL_EN,
+ (CONSYS_REG_READ(addr + CONN_GPT2_CTRL_THERMAL_EN) |
+ 0x1));
+
+ /* thermal trigger */
+ CONSYS_REG_WRITE(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN,
+ (CONSYS_REG_READ(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN) |
+ (0x1 << 18)));
+ udelay(500);
+ /* get thermal value */
+ cal_val = CONSYS_REG_READ(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN);
+ cal_val = (cal_val >> 8) & 0x7f;
+
+ /* thermal debug dump */
+ efuse0 = CONSYS_REG_READ(CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_0);
+ efuse1 = CONSYS_REG_READ(CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_1);
+ efuse2 = CONSYS_REG_READ(CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_2);
+ efuse3 = CONSYS_REG_READ(CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_3);
+ for (i = 0; i < THERMAL_DUMP_NUM; i++) {
+ snprintf(
+ tmp, TEMP_SIZE, "[0x%08x]",
+ CONSYS_REG_READ(CONN_TOP_THERM_CTL_ADDR + thermal_dump_crs[i]));
+ strncat(tmp_buf, tmp, strlen(tmp));
+ }
+ pr_info("[%s] efuse:[0x%08x][0x%08x][0x%08x][0x%08x] thermal dump: %s",
+ __func__, efuse0, efuse1, efuse2, efuse3, tmp_buf);
+
+ res = calculate_thermal_temperature(cal_val);
+
+ /* GPT2 disable, no effect on 6885 */
+ CONSYS_REG_WRITE(addr + CONN_GPT2_CTRL_THERMAL_EN,
+ (CONSYS_REG_READ(addr + CONN_GPT2_CTRL_THERMAL_EN) &
+ ~(0x1)));
+
+ /* disable */
+ CONSYS_REG_WRITE(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN,
+ (CONSYS_REG_READ(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_CAL_EN) &
+ ~(0x1 << 19)));
+
+ consys_sema_release(CONN_SEMA_THERMAL_INDEX);
+ consys_adie_top_ck_en_off(CONNSYS_ADIE_CTL_HOST_CONNINFRA);
+
+ iounmap(addr);
+
+ return res;
+}
+
+
+int consys_power_state(void)
+{
+ const char* osc_str[] = {
+ "fm ", "gps ", "bgf ", "wf ", "ap2conn ", "conn_thm ", "conn_pta ", "conn_infra_bus "
+ };
+ char buf[256] = {'\0'};
+ int r = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_2);
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ if ((r & (0x1 << (18 + i))) > 0)
+ strncat(buf, osc_str[i], strlen(osc_str[i]));
+ }
+ pr_info("[%s] [0x%x] %s", __func__, r, buf);
+ return 0;
+}
+
+int consys_bus_clock_ctrl(enum consys_drv_type drv_type, unsigned int bus_clock, int status)
+{
+ static unsigned int conninfra_bus_clock_wpll_state = 0;
+ static unsigned int conninfra_bus_clock_bpll_state = 0;
+ unsigned int wpll_state = conninfra_bus_clock_wpll_state;
+ unsigned int bpll_state = conninfra_bus_clock_bpll_state;
+ bool wpll_switch = false, bpll_switch = false;
+ int check;
+
+ if (status) {
+ /* Turn on */
+ /* Enable BPLL */
+ if (bus_clock & CONNINFRA_BUS_CLOCK_BPLL) {
+
+ if (conninfra_bus_clock_bpll_state == 0) {
+ CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_03, (0x1 << 21));
+ udelay(30);
+ bpll_switch = true;
+ }
+ conninfra_bus_clock_bpll_state |= (0x1 << drv_type);
+ }
+ /* Enable WPLL */
+ if (bus_clock & CONNINFRA_BUS_CLOCK_WPLL) {
+ if (conninfra_bus_clock_wpll_state == 0) {
+ CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_03, (0x1 << 20));
+ udelay(50);
+ wpll_switch = true;
+ }
+ conninfra_bus_clock_wpll_state |= (0x1 << drv_type);
+ }
+ pr_info("drv=[%d] conninfra_bus_clock_wpll=[%u]->[%u] %s conninfra_bus_clock_bpll=[%u]->[%u] %s",
+ drv_type,
+ wpll_state, conninfra_bus_clock_wpll_state, (wpll_switch ? "enable" : ""),
+ bpll_state, conninfra_bus_clock_bpll_state, (bpll_switch ? "enable" : ""));
+ } else {
+ /* Turn off */
+ /* Turn off WPLL */
+ if (bus_clock & CONNINFRA_BUS_CLOCK_WPLL) {
+ conninfra_bus_clock_wpll_state &= ~(0x1<<drv_type);
+ if (conninfra_bus_clock_wpll_state == 0) {
+ CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_03, (0x1 << 20));
+ wpll_switch = true;
+ }
+ }
+ /* Turn off BPLL */
+ if (bus_clock & CONNINFRA_BUS_CLOCK_BPLL) {
+ conninfra_bus_clock_bpll_state &= ~(0x1<<drv_type);
+ if (conninfra_bus_clock_bpll_state == 0) {
+ CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_03, (0x1 << 21));
+ bpll_switch = true;
+ }
+ }
+ pr_info("drv=[%d] conninfra_bus_clock_wpll=[%u]->[%u] %s conninfra_bus_clock_bpll=[%u]->[%u] %s",
+ drv_type,
+ wpll_state, conninfra_bus_clock_wpll_state, (wpll_switch ? "disable" : ""),
+ bpll_state, conninfra_bus_clock_bpll_state, (bpll_switch ? "disable" : ""));
+ if (consys_reg_mng_reg_readable() == 0) {
+ check = consys_reg_mng_is_bus_hang();
+ pr_info("[%s] not readable, bus hang check=[%d]", __func__, check);
+ }
+ }
+ return 0;
+}
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/mt6885_consys_reg.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/mt6885_consys_reg.c
new file mode 100755
index 0000000..13d83be
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/mt6885_consys_reg.c
@@ -0,0 +1,817 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#include <linux/memblock.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/random.h>
+
+#include <connectivity_build_in_adapter.h>
+
+#include "consys_reg_mng.h"
+#include "mt6885_consys_reg.h"
+#include "mt6885_consys_reg_offset.h"
+#include "consys_hw.h"
+#include "consys_reg_util.h"
+
+#define LOG_TMP_BUF_SZ 256
+#define CONSYS_POWER_MODE_LEGACY "Legacy"
+#define CONSYS_POWER_MODE_RC "RC"
+
+static int consys_reg_init(struct platform_device *pdev);
+static int consys_reg_deinit(void);
+static int consys_check_reg_readable(void);
+static int consys_is_consys_reg(unsigned int addr);
+static int consys_is_bus_hang(void);
+static int consys_dump_bus_status(void);
+static int consys_dump_conninfra_status(void);
+static int consys_dump_cpupcr(enum conn_dump_cpupcr_type, int times, unsigned long interval_us);
+static int consys_is_host_csr(unsigned long addr);
+
+static unsigned long consys_reg_validate_idx_n_offset(unsigned int idx, unsigned long offset);
+static int consys_find_can_write_reg(unsigned int *idx, unsigned long *offset);
+
+static unsigned long consys_reg_get_phy_addr_by_idx(unsigned int idx);
+static unsigned long consys_reg_get_virt_addr_by_idx(unsigned int idx);
+
+static int consys_reg_get_chip_id_idx_offset(unsigned int *idx, unsigned long *offset);
+static int consys_reg_get_reg_symbol_num(void);
+
+struct consys_reg_mng_ops g_dev_consys_reg_ops_mt6885 = {
+ .consys_reg_mng_init = consys_reg_init,
+ .consys_reg_mng_deinit = consys_reg_deinit,
+
+ .consys_reg_mng_check_reable = consys_check_reg_readable,
+ .consys_reg_mng_is_consys_reg = consys_is_consys_reg,
+ .consys_reg_mng_is_bus_hang = consys_is_bus_hang,
+ .consys_reg_mng_dump_bus_status = consys_dump_bus_status,
+ .consys_reg_mng_dump_conninfra_status = consys_dump_conninfra_status,
+ .consys_reg_mng_dump_cpupcr = consys_dump_cpupcr,
+ .consys_reg_mng_is_host_csr = consys_is_host_csr,
+
+ /* step */
+ .consys_reg_mng_validate_idx_n_offset = consys_reg_validate_idx_n_offset,
+ .consys_reg_mng_find_can_write_reg = consys_find_can_write_reg,
+
+ .consys_reg_mng_get_phy_addr_by_idx = consys_reg_get_phy_addr_by_idx,
+ .consys_reg_mng_get_virt_addr_by_idx = consys_reg_get_virt_addr_by_idx,
+ .consys_reg_mng_get_chip_id_idx_offset = consys_reg_get_chip_id_idx_offset,
+ .consys_reg_mng_get_reg_symbol_num = consys_reg_get_reg_symbol_num
+};
+
+
+const char* consys_base_addr_index_to_str[CONSYS_BASE_ADDR_MAX] = {
+ "CONN_INFRA_RGU_BASE",
+ "CONN_INFRA_CFG_BASE",
+ "CONN_HOST_CSR_TOP_BASE",
+ "INFRACFG_AO_BASE",
+ "TOPRGU_BASE",
+ "SPM_BASE",
+ "INFRACFG_BASE",
+ "CONN_WT_SLP_CTL_REG",
+ "CONN_AFE_CTL_REG",
+ "CONN_INFRA_SYSRAM",
+ "GPIO",
+ "CONN_RF_SPI_MST_REG",
+ "CONN_SEMAPHORE",
+ "CONN_TOP_THERM_CTL",
+ "IOCFG_RT",
+};
+
+struct consys_base_addr conn_reg;
+
+#if 0
+struct consys_reg_mng_ops* get_consys_reg_mng_ops(void)
+{
+ return &g_dev_consys_reg_ops_mt6885;
+}
+#endif
+
+struct consys_base_addr* get_conn_reg_base_addr()
+{
+ return &conn_reg;
+}
+
+static void consys_bus_hang_dump_c(void)
+{
+ unsigned long debug_addr, out_addr;
+ unsigned long value;
+ int i;
+ unsigned long debug_setting[] = {
+ 0xf0001, 0xe0001, 0xd0001, 0xc0001, 0xb0001, 0xa0001,
+ 0x90001, 0x80001, 0x70001, 0x60001, 0x50001, 0x40001,
+ 0x30001, 0x20001, 0x10001, 0x30002, 0x20002, 0x10002,
+ 0x40003, 0x30003, 0x20003, 0x10003
+ };
+
+ /* CONN2AP GALS RX status
+ * 0x1020_E804
+ *
+ * CONNINFRA sleep protect
+ * 0x1000_6158[2] ap2conn gals rx slp prot
+ * 0x1000_6150[13] ap2conn gals tx slp prot
+ *
+ * conninfra on2off off2on slp prot
+ * 0x1806_0184[5] conn_infra on2off slp prot
+ * 0x1806_0184[3] conn_infra off2on slp prot
+ */
+ pr_info("[CONN_BUS_C] [%x][%x][%x] [%x]",
+ CONSYS_REG_READ(CON_REG_INFRACFG_BASE_ADDR + INFRA_CONN2AP_GLAS_RC_ST),
+ CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_BUS_PROTECT2_RDY),
+ CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_BUS_PROTECT_RDY),
+ CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL)
+ );
+
+ debug_addr = CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_AO_DEBUGSYS;
+ out_addr = CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_DEBUG_CTRL_AO2SYS_OUT;
+
+ for (i = 0; i < ARRAY_SIZE(debug_setting); i++) {
+ CONSYS_REG_WRITE(debug_addr, debug_setting[i]);
+ value = CONSYS_REG_READ(out_addr);
+ pr_info("[CONN_BUS_C] addr=0x%x value=0x%08x", debug_setting[i], value);
+ }
+}
+
+static void consys_bus_hang_dump_a_rc(void)
+{
+ unsigned int i;
+ char tmp[LOG_TMP_BUF_SZ] = {'\0'};
+ char tmp_buf[LOG_TMP_BUF_SZ] = {'\0'};
+
+ for (i = 0xE50; i <= 0xE94; i += 4) {
+ snprintf(tmp, LOG_TMP_BUF_SZ, "[%x]",
+ CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + i));
+ strncat(tmp_buf, tmp, strlen(tmp));
+ }
+ pr_info("[rc_trace] %s", tmp_buf);
+
+ memset(tmp_buf, '\0', LOG_TMP_BUF_SZ);
+ for (i = 0xE98; i <= 0xED4; i += 4) {
+ snprintf(tmp, LOG_TMP_BUF_SZ, "[%x]",
+ CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + i));
+ strncat(tmp_buf, tmp, strlen(tmp));
+ }
+ pr_info("[rc_timer] %s", tmp_buf);
+}
+
+static void consys_bus_hang_dump_a(void)
+{
+ void __iomem *addr = NULL;
+ unsigned int r1, r2, r3, r4, r5, r6, r7 = 0, r8 = 0, r9 = 0, r10, r11;
+ char tmp_buf[LOG_TMP_BUF_SZ] = {'\0'};
+ char rc_buf[LOG_TMP_BUF_SZ] = {'\0'};
+
+ /*
+ * r1 : 0x1000_6110
+ * r2 : 0x1000_6114
+ */
+ snprintf(tmp_buf, LOG_TMP_BUF_SZ, "[%s] [0x%x][0x%x]",
+ (conn_hw_env.is_rc_mode ? CONSYS_POWER_MODE_RC : CONSYS_POWER_MODE_LEGACY),
+ CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_PCM_REG13_DATA),
+ CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_SRC_REQ_STA_0));
+
+ /* RC REQ STA
+ * r3 : 0x1000_6E28
+ * r4 : 0x1000_6E2C
+ * r5 : 0x1000_6E30
+ * r6 : 0x1000_6E34
+ */
+ snprintf(rc_buf, LOG_TMP_BUF_SZ, "[%x][%x][%x][%x]",
+ CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_RC_RC_M04_REQ_STA_0),
+ CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_RC_RC_M05_REQ_STA_0),
+ CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_RC_RC_M06_REQ_STA_0),
+ CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_RC_RC_M07_REQ_STA_0));
+
+ /*
+ * 0x1000684C [28] DEBUG_IDX_VTCXO_STATE
+ * 0x1000684C [29] DEBUG_IDX_INFRA_STATE
+ * 0x1000684C [30] DEBUG_IDX_VRF18_STATE
+ * 0x1000684C [31] DEBUG_IDX_APSRC_STATE
+ * r7: 0x1000684C
+ */
+ r1 = CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_PCM_WDT_LATCH_SPARE_0);
+
+ /*
+ * 0x10006100[0] sc_26m_ck_off 1'b0: 26M on; 1'b1
+ * 0x10006100[3] sc_axi_ck_off 1'b0: bus ck on; 1'b1 bus ck off
+ * 0x10006100[5] sc_md26m_ck_off 1'b0: MD 26M on; 1'b1 MD 26M off
+ * 0x10006100[20] sc_cksq0_off 1'b0: clock square0 on; 1'b1 clock square off
+ * r8:0x10006100
+ */
+ r2 = CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_PCM_REG7_DATA);
+
+ /*
+ * 0x1000_6304[2] : pwr_on
+ * 0x1000_616c[1] : pwr_ack
+ * 0x1000_6304[3] : pwr_on_s
+ * 0x1000_6170[1] : pwr_ack_s
+ * 0x1000_6304[1] : iso_en
+ * 0x1000_6304[0] : ap_sw_rst
+ * r9 : 0x1000_616C
+ * r10 : 0x1000_6170
+ * r11 : 0x1000_6304
+ */
+ r3 = CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_PWR_STATUS);
+ r4 = CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_PWR_STATUS_2ND);
+ r5 = CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON);
+
+ /*
+ * sc_md_32k_ck_off
+ * r12 : 0x1000_644C
+ */
+ r6 = CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_PLL_CON);
+
+ /*
+ * infra bus clock
+ * r13 : 0x1000_0000 pdn_conn_32k
+ * r14 : 0x1000_0010[2:0]
+ * 0: tck_26m_mx9_ck => 26M
+ * 1: mainpll_d4_d4 => 136.5M
+ * 2: mainpll_d7_d2 => 156M
+ * 3: mainpll_d4_d2 => 273M
+ * 4: mainpll_d5_d2 => 218.4M
+ * 5: mainpll_d6_d2 => 182M
+ * 6: osc_d4 => 65M
+ */
+ addr = ioremap_nocache(0x10000000, 0x20);
+ if (addr != NULL) {
+ r7 = CONSYS_REG_READ(addr);
+ r8 = CONSYS_REG_READ(addr + 0x10);
+ iounmap(addr);
+ }
+
+ /*
+ * r15 : 0x1000_0200 sc_md2_32k_off_en
+ */
+ addr = ioremap_nocache(0x10000200, 0x20);
+ if (addr != NULL) {
+ r9 = CONSYS_REG_READ(addr);
+ iounmap(addr);
+ }
+
+ /* ap2conn gals sleep protect status
+ * - 0x1000_1724 [2] / 0x1000_1228 [13] (infracfg_ao)(rx/tx) (sleep protect enable raedy)
+ * r16 : 0x1000_1724
+ * r17 : 0x1000_1228
+ */
+ r10 = CONSYS_REG_READ(CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN2_STA1_OFFSET);
+ r11 = CONSYS_REG_READ(CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1_OFFSET);
+
+ pr_info("[CONN_BUS_A] %s %s [%x][%x][%x][%x][%x][%x] [%x][%x] [%x][%x][%x]", tmp_buf,
+ rc_buf, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11);
+
+ consys_bus_hang_dump_a_rc();
+}
+
+static void consys_bus_hang_dump_b(void)
+{
+ char tmp_buf[LOG_TMP_BUF_SZ] = {'\0'};
+ unsigned int r1, r2, r3, r4, r5, r6, r7;
+
+ /* Legacy Mode */
+ /*
+ * 0x180602c0
+ * [4]: conn_srcclkena_ack
+ * [5]: conn_ap_bus_ack
+ * [6]: conn_apsrc_ack
+ * [7]: conn_ddr_en_ack
+ * cr1 : 0x1806_02c0
+ */
+ snprintf(tmp_buf, LOG_TMP_BUF_SZ, "[%s] [%x]",
+ (conn_hw_env.is_rc_mode ? CONSYS_POWER_MODE_RC : CONSYS_POWER_MODE_LEGACY),
+ CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_0));
+
+ /* RC Mode */
+ /*
+ * debug sel 0x18001B00[2:0] 3'b010
+ * 0x1806_02C8
+ * [12] conn_srcclkena_0_bblpm_ack
+ * [13] conn_srcclkena_0_fpm_ack
+ * [28] conn_srcclkena_1_bblpm_ack
+ * [29] conn_srcclkena_1_fpm_ack
+ * cr2 : 0x1806_02c8
+ */
+ r1 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_2);
+
+ /*
+ * Consys status check
+ * debug sel 0x18001B00[2:0] 3'b011
+ * 0x1806_02C8
+ * [25] conninfra_bus_osc_en
+ * [24] conn_pta_osc_en
+ * [23] conn_thm_osc_en
+ * [22] ap2conn_osc_en
+ * [21] wfsys_osc_en
+ * [20] bgfsys_osc_en
+ * [19] gpssys_osc_en
+ * [18] fmsys_osc_en
+ */
+ /*CONSYS_REG_WRITE_MASK(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_DBG_MUX_SEL,
+ 0x2, 0x7);*/
+ /*r1 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_3);*/
+
+ /* Conninfra Off power state
+ * 0x1806_02CC
+ * [15] power_enable
+ * [14] power_on
+ * [13] pwer_ack
+ * [12] pwr_on_s
+ * [11] pwr_ack_s
+ * [10] iso_en
+ * [9] conn_infra_off_xreset_b
+ * [8] conn_infra_off_hreset_b
+ *
+ * cr3 : 0x1806_02CC
+ */
+ r2 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_3);
+
+
+ /* conn_infra_on clock 0x1020E504[0] = 1’b1
+ *
+ * cr4 : 0x1020_E504
+ */
+ r3 = CONSYS_REG_READ(CON_REG_INFRACFG_BASE_ADDR +
+ INFRA_AP2MD_GALS_CTL);
+
+ /* Check conn_infra off bus clock
+ * - write 0x1 to 0x1806_0000[0], reset clock detect
+ * - 0x1806_0000[2] conn_infra off bus clock (should be 1'b1 if clock exist)
+ * - 0x1806_0000[1] osc clock (should be 1'b1 if clock exist)
+ *
+ * cr5 : 0x1806_0000
+ */
+ CONSYS_SET_BIT(CON_REG_HOST_CSR_ADDR, 0x1);
+ udelay(200);
+ r4 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR);
+
+ /* conn_infra on2off sleep protect status
+ * - 0x1806_0184[5] (sleep protect enable raedy), should be 1'b0
+ * cr6 : 0x1806_0000
+ */
+ r5 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL);
+
+ /* CONN_HOST_CSR_DBG_DUMMY_4
+ * cr7 : 0x1806_02D0
+ */
+ r6 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_4);
+
+ /* 0x1806_02D4: dump bus timeout irq status
+ * cr8 : 0x1806_02D4
+ */
+ r7 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_BUS_TIMEOUT_IRQ);
+
+ pr_info("[CONN_BUS_B] infra_off %s [%x][%x] [%x][%x][%x] [%x] [%x]"
+ , tmp_buf, r1, r2, r3, r4, r5, r6, r7);
+ pr_info("[CONN_BUS_B] 0x1806_0294:[0x%08x] 0x1806_0220:[0x%08x]\n",
+ CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + 0x0294),
+ CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + 0x0220));
+}
+
+#if 0
+static void consys_bus_hang_dump_d(void)
+{
+ int r1;
+
+ /* check if consys off on
+ * 0x1806_02cc[8] 1'b1 ==> pwr on, 1'b0 ==> pwr off
+ */
+ r1 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_3);
+ if (((r1 >> 8) & 0x01) == 0) {
+ pr_info("[CONN_BUS_D] conninfra off is not on");
+ return;
+ }
+
+ /* PLL & OSC status
+ * 0x18001810[1] bpll_rdy
+ * 0x18001810[0] wpll_rdy
+ *
+ * OSC
+ * 0x1800_180C
+ * [3] : bus_bpll_sw_rdy, 1'b1 conninfra bus clock=166.4M
+ * [2] : bus_bpll_sw_rdy, 1'b1 conninfra bus clock=83.2M
+ * [1] : bus_bpll_sw_rdy, 1'b1 conninfra bus clock=32M
+ * [0] : bus_bpll_sw_rdy, 1'b1 conninfra bus clock=osc
+ *
+ * 0x1800_1160[22] ap2conn gals rx slp prot
+ * 0x1800_1630[3] conn2ap gals tx slp prot
+ * 0x1800_1634[3] conn2ap gals rx slp prot
+ *
+ * 0x1800_1628[3] conn_infra on2off slp pro
+ * 0x1800_162c[3] conn_infra off2on slp pro
+ *
+ * 0x1800_161C[3] gps2conn gals tx slp prot
+ * 0x1800_161C[7] gps2conn gals rx slp prot
+ * 0x1800_1618[7] conn2gps gals rx slp prot
+ * 0x1800_1618[3] conn2gps gals tx slp prot
+ *
+ * 0x1800_1614[3] bt2conn gals tx slp prot
+ * 0x1800_1614[7] bt2conn gals rx slp prot
+ * 0x1800_1610[3] conn2bt gals tx slp prot
+ * 0x1800_1610[7] conn2bt gals rx slp prot
+ *
+ * 0x1800_1620[3] wf2conn slp prot
+ */
+ pr_info("[CONN_BUS_D] [%x][%x] [%x][%x][%x] [%x][%x] [%x][%x] [%x][%x] [%x]",
+ CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_PLL_STATUS), /* PLL */
+ CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_OSC_STATUS), /* OSC */
+
+ CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_GALS_AP2CONN_GALS_DBG),
+ CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_GALS_CONN2AP_TX_SLP_CTRL),
+ CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_GALS_CONN2AP_RX_SLP_CTRL),
+
+ CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_ON_BUS_SLP_CTRL), /* on2off */
+ CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_OFF_BUS_SLP_CTRL),/* off2on */
+
+ CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_GALS_GPS2CONN_SLP_CTRL), /* gps2conn */
+ CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_GALS_CONN2GPS_SLP_CTRL), /* conn2gps */
+
+ CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_GALS_BT2CONN_SLP_CTRL), /* bt2conn */
+ CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_GALS_CONN2BT_SLP_CTRL), /* conn2bt */
+
+ CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_WF_SLP_CTRL) /* w2conn */
+ );
+}
+#endif
+
+static int consys_dump_bus_status(void)
+{
+ consys_bus_hang_dump_c();
+ return 0;
+}
+
+static int consys_dump_conninfra_status(void)
+{
+ consys_bus_hang_dump_a();
+ consys_bus_hang_dump_b();
+ return 0;
+}
+
+int consys_dump_cpupcr(enum conn_dump_cpupcr_type type, int times, unsigned long interval_us)
+{
+ int i;
+
+ for (i = 0; i < times; i++) {
+ pr_info("%s: wm pc=0x%x, wm lp=0x%x, bt pc=0x%x",
+ __func__,
+ CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_WM_MCU_PC_DBG),
+ CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_WM_MCU_GPR_DBG),
+ CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_BGF_MCU_PC_DBG));
+ if (interval_us > 1000)
+ usleep_range(interval_us - 100, interval_us + 100);
+ else
+ udelay(interval_us);
+ }
+
+ return 0;
+}
+
+static int consys_is_bus_hang(void)
+{
+ int r;
+
+ /* dump SPM register */
+ consys_bus_hang_dump_a();
+
+ /* STEP - 1 */
+ /*
+ * check kernel API lastbus_timeout_dump
+ * if return > 0 -> return 0x1
+ */
+
+ /* 1. Check ap2conn gals sleep protect status
+ * - 0x1000_1724 [2] / 0x1000_1228 [13] (infracfg_ao)(rx/tx) (sleep protect enable raedy)
+ * both of them should be 1'b0 (CR at ap side)
+ */
+ r = CONSYS_REG_READ_BIT(CON_REG_INFRACFG_AO_ADDR +
+ INFRA_TOPAXI_PROTECTEN2_STA1_OFFSET, (0x1 << 2));
+ if (r != 0)
+ return CONNINFRA_AP2CONN_RX_SLP_PROT_ERR;
+
+
+ r = CONSYS_REG_READ_BIT(CON_REG_INFRACFG_AO_ADDR +
+ INFRA_TOPAXI_PROTECTEN_STA1_OFFSET, (0x1 << 13));
+ if (r != 0)
+ return CONNINFRA_AP2CONN_TX_SLP_PROT_ERR;
+
+ /* STEP - 2 */
+ consys_bus_hang_dump_b();
+
+ /* 2. Check conn_infra_on clock 0x1020E504[0] = 1’b1 */
+ r = CONSYS_REG_READ_BIT(CON_REG_INFRACFG_BASE_ADDR +
+ INFRA_AP2MD_GALS_CTL, 0x1);
+ if (r != 1)
+ return CONNINFRA_AP2CONN_CLK_ERR;
+
+#if 0
+ /* 3. Check conn_infra off bus clock
+ * - write 0x1 to 0x1806_0000[0], reset clock detect
+ * - 0x1806_0000[2] conn_infra off bus clock (should be 1'b1 if clock exist)
+ * - 0x1806_0000[1] osc clock (should be 1'b1 if clock exist)
+ */
+ CONSYS_SET_BIT(CON_REG_HOST_CSR_ADDR, 0x1);
+ udelay(500);
+ r = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR);
+ if ((r & TOP_BUS_MUC_STAT_HCLK_FR_CK_DETECT_BIT) == 0 ||
+ (r & TOP_BUS_MUC_STAT_OSC_CLK_DETECT_BIT) == 0)
+ ret |= CONNINFRA_INFRA_BUS_CLK_ERR;
+#endif
+
+ /* 4. Check conn_infra off domain bus hang irq status
+ * - 0x1806_02d4[0], should be 1'b1, or means conn_infra off bus might hang
+ */
+ r = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_BUS_TIMEOUT_IRQ);
+
+ if ((r & 0x1) != 0x1) {
+ pr_err("conninfra off bus might hang cirq=[0x%08x]", r);
+ consys_bus_hang_dump_c();
+ return CONNINFRA_INFRA_BUS_HANG_IRQ;
+ }
+ consys_bus_hang_dump_c();
+
+#if 0
+ /* 5. Check conn_infra on2off sleep protect status
+ * - 0x1806_0184[5] (sleep protect enable raedy), should be 1'b0
+ */
+ r = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL);
+ if (r & TOP_SLP_PROT_CTRL_CONN_INFRA_ON2OFF_SLP_PROT_ACK_BIT)
+ ret |= CONNINFRA_ON2OFF_SLP_PROT_ERR;
+ if (ret) {
+ pr_info("[%s] ret=[%x]", __func__, ret);
+ consys_bus_hang_dump_c();
+ return ret;
+ }
+#endif
+ /*consys_bus_hang_dump_d();*/
+
+ return 0;
+
+}
+
+int consys_check_reg_readable(void)
+{
+ int r;
+ unsigned int rnd;
+ int delay_time = 1, spent = delay_time, max_wait = 16000; // 1.6 ms
+ int retry = max_wait / 10;
+
+ /* STEP - 1 */
+ /*
+ * check kernel API lastbus_timeout_dump
+ * if return > 0 -> return 0x1
+ */
+
+
+ /* 1. Check ap2conn gals sleep protect status
+ * - 0x1000_1724 [2] / 0x1000_1228 [13] (infracfg_ao)(rx/tx) (sleep protect enable raedy)
+ * both of them should be 1'b0 (CR at ap side)
+ */
+ r = CONSYS_REG_READ_BIT(CON_REG_INFRACFG_AO_ADDR +
+ INFRA_TOPAXI_PROTECTEN2_STA1_OFFSET, (0x1 << 2));
+ if (r != 0)
+ return 0;
+
+ r = CONSYS_REG_READ_BIT(CON_REG_INFRACFG_AO_ADDR +
+ INFRA_TOPAXI_PROTECTEN_STA1_OFFSET, (0x1 << 13));
+ if (r != 0)
+ return 0;
+
+ /* STEP - 2 */
+
+ /* 2. Check conn_infra_on clock 0x1020E504[0] = 1’b1 */
+ r = CONSYS_REG_READ_BIT(CON_REG_INFRACFG_BASE_ADDR +
+ INFRA_AP2MD_GALS_CTL, 0x1);
+ if (r != 1)
+ return 0;
+
+ /* 3. Check conn_infra off bus clock
+ * - write 0x1 to 0x1806_0000[0], reset clock detect
+ * - 0x1806_0000[1] conn_infra off bus clock (should be 1'b1 if clock exist)
+ * - 0x1806_0000[2] osc clock (should be 1'b1 if clock exist)
+ */
+
+ while (retry > 0 && spent < max_wait) {
+ CONSYS_SET_BIT(CON_REG_HOST_CSR_ADDR, 0x1);
+ udelay(delay_time);
+ r = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR);
+ if ((r & TOP_BUS_MUC_STAT_HCLK_FR_CK_DETECT_BIT) == 0 ||
+ (r & TOP_BUS_MUC_STAT_OSC_CLK_DETECT_BIT) == 0) {
+ spent += delay_time;
+ retry--;
+ if (retry == 0)
+ pr_info("[%s] retry=0 r=[%x]", __func__, r);
+ else
+ delay_time = 10;
+ rnd = get_random_int() % 10;
+ spent += rnd;
+ udelay(rnd);
+ continue;
+ }
+ break;
+ }
+ if (retry == 0 || spent >= max_wait) {
+ pr_info("[%s] readable fail = bus clock retry=[%d] spent=[%d]", __func__,
+ retry, spent);
+ return 0;
+ }
+
+ /* 4. Check conn_infra off domain bus hang irq status
+ * - 0x1806_02d4[0], should be 1'b1, or means conn_infra off bus might hang
+ */
+ r = CONSYS_REG_READ_BIT(CON_REG_HOST_CSR_ADDR +
+ CONN_HOST_CSR_TOP_BUS_TIMEOUT_IRQ, 0x1);
+ if (r != 0x1)
+ return 0;
+
+ /* 5. Check conn_infra on2off sleep protect status
+ * - 0x1806_0184[5] (sleep protect enable raedy), should be 1'b0
+ */
+ r = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL);
+ if (r & TOP_SLP_PROT_CTRL_CONN_INFRA_ON2OFF_SLP_PROT_ACK_BIT)
+ return 0;
+
+ return 1;
+}
+
+
+int consys_is_consys_reg(unsigned int addr)
+{
+ return 0;
+}
+
+
+static int consys_is_host_csr(unsigned long addr)
+{
+ struct consys_reg_base_addr *host_csr_addr =
+ &conn_reg.reg_base_addr[CONN_HOST_CSR_TOP_BASE_INDEX];
+
+ if (addr >= host_csr_addr->phy_addr &&
+ addr < host_csr_addr->phy_addr + host_csr_addr->size)
+ return 1;
+ return 0;
+}
+
+unsigned long consys_reg_validate_idx_n_offset(unsigned int idx, unsigned long offset)
+{
+ unsigned long res;
+
+ if (idx < 0 || idx >= CONSYS_BASE_ADDR_MAX) {
+ pr_warn("ConsysReg failed: No support the base %d\n", idx);
+ return 0;
+ }
+
+ res = conn_reg.reg_base_addr[idx].phy_addr;
+
+ if (res == 0) {
+ pr_warn("ConsysReg failed: No support the base idx is 0 index=[%d]\n", idx);
+ return 0;
+ }
+
+ if (offset >= conn_reg.reg_base_addr[idx].size) {
+ pr_warn("ConnReg failed: index(%d), offset(%d) over max size(%llu) %s\n",
+ idx, (int) offset, conn_reg.reg_base_addr[idx].size);
+ return 0;
+ }
+ return res;
+}
+
+int consys_find_can_write_reg(unsigned int *idx, unsigned long *offset)
+{
+ int i;
+ size_t addr = 0, addr_offset;
+ int max, mask = 0x0000000F;
+ int before, after, ret;
+
+ addr = conn_reg.reg_base_addr[CONN_INFRA_RGU_BASE_INDEX].vir_addr;
+ max = conn_reg.reg_base_addr[CONN_INFRA_RGU_BASE_INDEX].size;
+
+ pr_info("[%s] addr=[%p]\n", __func__, addr);
+
+ for (i = 0x0; i < max; i += 0x4) {
+ ret = 0;
+ addr_offset = addr + i;
+ before = CONSYS_REG_READ(addr_offset);
+ CONSYS_REG_WRITE_MASK(addr_offset, 0xFFFFFFFF, mask);
+ after = CONSYS_REG_READ(addr_offset);
+ if ((after & mask) != (0xFFFFFFFF & mask))
+ ret = -1;
+
+ CONSYS_REG_WRITE_MASK(addr_offset, 0x0, mask);
+ after = CONSYS_REG_READ(addr_offset);
+ if ((after & mask) != (0x0 & mask))
+ ret = -1;
+
+ CONSYS_REG_WRITE_MASK(addr_offset, before, mask);
+
+ pr_info("[%s] addr=[%p] [%d]\n", __func__, addr_offset, ret);
+ if (ret == 0) {
+ *idx = CONN_INFRA_RGU_BASE_INDEX;
+ *offset = i;
+ return 0;
+ }
+ }
+ return -1;
+
+}
+
+
+unsigned long consys_reg_get_phy_addr_by_idx(unsigned int idx)
+{
+ if (idx >= CONSYS_BASE_ADDR_MAX)
+ return 0;
+ return conn_reg.reg_base_addr[idx].phy_addr;
+}
+
+unsigned long consys_reg_get_virt_addr_by_idx(unsigned int idx)
+{
+ if (idx >= CONSYS_BASE_ADDR_MAX)
+ return 0;
+ return conn_reg.reg_base_addr[idx].vir_addr;
+}
+
+
+int consys_reg_get_chip_id_idx_offset(unsigned int *idx, unsigned long *offset)
+{
+ *idx = CONN_INFRA_CFG_BASE_INDEX;
+ *offset = CONN_CFG_ID_OFFSET;
+ return 0;
+}
+
+int consys_reg_get_reg_symbol_num(void)
+{
+ return CONSYS_BASE_ADDR_MAX;
+}
+
+
+int consys_reg_init(struct platform_device *pdev)
+{
+ int ret = -1;
+ struct device_node *node = NULL;
+ struct consys_reg_base_addr *base_addr = NULL;
+ struct resource res;
+ int flag, i = 0;
+
+ node = pdev->dev.of_node;
+ pr_info("[%s] node=[%p]\n", __func__, node);
+ if (node) {
+ for (i = 0; i < CONSYS_BASE_ADDR_MAX; i++) {
+ base_addr = &conn_reg.reg_base_addr[i];
+
+ ret = of_address_to_resource(node, i, &res);
+ if (ret) {
+ pr_err("Get Reg Index(%d-%s) failed",
+ i, consys_base_addr_index_to_str[i]);
+ continue;
+ }
+
+ base_addr->phy_addr = res.start;
+ base_addr->vir_addr =
+ (unsigned long) of_iomap(node, i);
+ of_get_address(node, i, &(base_addr->size), &flag);
+
+ pr_info("Get Index(%d-%s) phy(0x%zx) baseAddr=(0x%zx) size=(0x%zx)",
+ i, consys_base_addr_index_to_str[i], base_addr->phy_addr,
+ base_addr->vir_addr, base_addr->size);
+ }
+
+ } else {
+ pr_err("[%s] can't find CONSYS compatible node\n", __func__);
+ return ret;
+ }
+ return 0;
+
+}
+
+static int consys_reg_deinit(void)
+{
+ int i = 0;
+
+ for (i = 0; i < CONSYS_BASE_ADDR_MAX; i++) {
+ if (conn_reg.reg_base_addr[i].vir_addr) {
+ pr_info("[%d] Unmap %s (0x%zx)",
+ i, consys_base_addr_index_to_str[i],
+ conn_reg.reg_base_addr[i].vir_addr);
+ iounmap((void __iomem*)conn_reg.reg_base_addr[i].vir_addr);
+ conn_reg.reg_base_addr[i].vir_addr = 0;
+ }
+ }
+
+ return 0;
+}
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/mt6885_emi.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/mt6885_emi.c
new file mode 100755
index 0000000..ab5e9b2
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/mt6885_emi.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__
+
+#include <linux/memblock.h>
+#include <linux/platform_device.h>
+#ifdef CONFIG_MTK_EMI
+#include <mt_emi_api.h>
+#endif
+#include <linux/of_reserved_mem.h>
+
+#include <memory/mediatek/emi.h>
+#include "mt6885_emi.h"
+#include "mt6885.h"
+#include "mt6885_consys_reg.h"
+#include "consys_hw.h"
+#include "consys_reg_util.h"
+#include "mt6885_pos.h"
+
+/* For MCIF */
+#include <mtk_ccci_common.h>
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+#define REGION_CONN 27
+
+#define DOMAIN_AP 0
+#define DOMAIN_CONN 2
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+extern unsigned long long gConEmiSize;
+extern phys_addr_t gConEmiPhyBase;
+
+struct consys_platform_emi_ops g_consys_platform_emi_ops_mt6885 = {
+ .consys_ic_emi_mpu_set_region_protection = consys_emi_mpu_set_region_protection,
+ .consys_ic_emi_set_remapping_reg = consys_emi_set_remapping_reg,
+ .consys_ic_emi_get_md_shared_emi = consys_emi_get_md_shared_emi,
+ .consys_ic_emi_get_fw_emi_size = consys_emi_get_fw_emi_size,
+};
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#if 0
+struct consys_platform_emi_ops* get_consys_platform_emi_ops(void)
+{
+ return &g_consys_platform_emi_ops_mt6885;
+}
+#endif
+
+int consys_emi_mpu_set_region_protection(void)
+{
+ struct emimpu_region_t region;
+ unsigned long long start = gConEmiPhyBase;
+ unsigned long long end = gConEmiPhyBase + gConEmiSize - 1;
+
+ mtk_emimpu_init_region(®ion, REGION_CONN);
+ mtk_emimpu_set_addr(®ion, start, end);
+ mtk_emimpu_set_apc(®ion, DOMAIN_AP, MTK_EMIMPU_NO_PROTECTION);
+ mtk_emimpu_set_apc(®ion, DOMAIN_CONN, MTK_EMIMPU_NO_PROTECTION);
+ mtk_emimpu_set_protection(®ion);
+ mtk_emimpu_free_region(®ion);
+
+ pr_info("setting MPU for EMI share memory\n");
+ return 0;
+}
+
+void consys_emi_get_md_shared_emi(phys_addr_t* base, unsigned int* size)
+{
+#ifdef CONFIG_MTK_ECCCI_DRIVER
+ phys_addr_t mdPhy = 0;
+ int ret;
+
+ mdPhy = get_smem_phy_start_addr(MD_SYS1, SMEM_USER_RAW_MD_CONSYS, &ret);
+ if (ret) {
+ pr_info("MCIF base=0x%llx size=0x%x", mdPhy, ret);
+ if (base)
+ *base = mdPhy;
+ if (size)
+ *size = ret;
+ } else
+ pr_info("MCIF is not supported");
+#else
+ pr_info("[%s] ECCCI Driver is not supported.\n", __func__);
+ if (base)
+ *base = 0;
+ if (size)
+ *size = 0;
+
+#endif
+}
+
+unsigned int consys_emi_get_fw_emi_size(void)
+{
+ return 0x450000;
+}
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/mt6885_pmic.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/mt6885_pmic.c
new file mode 100755
index 0000000..56ba9e7
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/mt6885_pmic.c
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__
+
+#include <connectivity_build_in_adapter.h>
+#include <linux/memblock.h>
+#include <linux/platform_device.h>
+#include <linux/of_reserved_mem.h>
+#include <upmu_common.h>
+#include <linux/regulator/consumer.h>
+#include <linux/notifier.h>
+#include <pmic_api_buck.h>
+
+#include "consys_hw.h"
+#include "consys_reg_util.h"
+#include "osal.h"
+#include "mt6885_pmic.h"
+#include "mt6885_pos.h"
+#include "mt6885_consys_reg.h"
+#include "mt6885_consys_reg_offset.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+static int consys_plt_pmic_get_from_dts(struct platform_device *pdev, struct conninfra_dev_cb* dev_cb);
+
+static int consys_plt_pmic_common_power_ctrl(unsigned int enable);
+static int consys_plt_pmic_wifi_power_ctrl(unsigned int enable);
+static int consys_plt_pmic_bt_power_ctrl(unsigned int enable);
+static int consys_plt_pmic_gps_power_ctrl(unsigned int enable);
+static int consys_plt_pmic_fm_power_ctrl(unsigned int enable);
+/* VCN33_1 is enable when BT or Wi-Fi is on */
+static int consys_pmic_vcn33_1_power_ctl(bool enable, struct regulator* reg_VCN33_1);
+/* VCN33_2 is enable when Wi-Fi is on */
+static int consys_pmic_vcn33_2_power_ctl(bool enable);
+
+static int consys_plt_pmic_event_notifier(unsigned int id, unsigned int event);
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+struct consys_platform_pmic_ops g_consys_platform_pmic_ops_mt6885 = {
+ .consys_pmic_get_from_dts = consys_plt_pmic_get_from_dts,
+ /* vcn 18 */
+ .consys_pmic_common_power_ctrl = consys_plt_pmic_common_power_ctrl,
+ .consys_pmic_wifi_power_ctrl = consys_plt_pmic_wifi_power_ctrl,
+ .consys_pmic_bt_power_ctrl = consys_plt_pmic_bt_power_ctrl,
+ .consys_pmic_gps_power_ctrl = consys_plt_pmic_gps_power_ctrl,
+ .consys_pmic_fm_power_ctrl = consys_plt_pmic_fm_power_ctrl,
+ .consys_pmic_event_notifier = consys_plt_pmic_event_notifier,
+};
+
+struct regulator *reg_VCN13;
+struct regulator *reg_VCN18;
+struct regulator *reg_VCN33_1_BT;
+struct regulator *reg_VCN33_1_WIFI;
+struct regulator *reg_VCN33_2_WIFI;
+struct notifier_block vcn13_nb;
+
+static struct conninfra_dev_cb* g_dev_cb;
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+#if 0
+struct consys_platform_pmic_ops* get_consys_platform_pmic_ops(void)
+{
+ return &g_consys_platform_pmic_ops_mt6885;
+}
+#endif
+
+static int consys_vcn13_oc_notify(struct notifier_block *nb, unsigned long event,
+ void *unused)
+{
+ if (event != REGULATOR_EVENT_OVER_CURRENT)
+ return NOTIFY_OK;
+
+ if (g_dev_cb != NULL && g_dev_cb->conninfra_pmic_event_notifier != NULL)
+ g_dev_cb->conninfra_pmic_event_notifier(0, 0);
+ return NOTIFY_OK;
+}
+
+static int consys_plt_pmic_event_notifier(unsigned int id, unsigned int event)
+{
+#define ATOP_DUMP_NUM 10
+#define LOG_TMP_BUF_SZ 256
+ static int oc_counter = 0;
+ int ret;
+ unsigned int adie_value = 0;
+ unsigned int value1 = 0, value2 = 0, value3 = 0;
+ const unsigned int adie_cr_list[ATOP_DUMP_NUM] = {
+ 0xa10, 0x90, 0x94, 0xa0,
+ 0xa18, 0xa1c, 0xc8, 0x3c,
+ 0x0b4, 0x34c
+ };
+ int index;
+ char tmp[LOG_TMP_BUF_SZ] = {'\0'};
+ char tmp_buf[LOG_TMP_BUF_SZ] = {'\0'};
+
+ oc_counter++;
+ pr_info("[%s] VCN13 OC times: %d\n", __func__, oc_counter);
+
+ consys_hw_is_bus_hang();
+ ret = consys_hw_force_conninfra_wakeup();
+ if (ret) {
+ pr_err("[%s] force conninfra wakeup fail\n", __func__);
+ return NOTIFY_OK;
+ }
+
+ value1 = CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_ADIE_CTL);
+ value2 = CONSYS_REG_READ(CON_REG_WT_SPL_CTL_ADDR + 0xa8);
+ if (consys_sema_acquire_timeout(CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_SUCCESS) {
+ value3 = CONSYS_REG_READ(CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_TOP_CK_EN_CTRL);
+ consys_sema_release(CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX);
+ pr_info("[VCN13 OC] D-die: 0x1800_1900:0x%08x 0x1800_50A8:0x%08x 0x1805_2830:0x%08x\n", value1, value2, value3);
+ } else {
+ pr_info("[VCN13 OC] D-die: 0x1800_1900:0x%08x 0x1800_50A8:0x%08x\n", value1, value2);
+ }
+
+ for (index = 0; index < ATOP_DUMP_NUM; index++) {
+ consys_spi_read(SYS_SPI_TOP, adie_cr_list[index], &adie_value);
+ snprintf(tmp, LOG_TMP_BUF_SZ, " [0x%04x: 0x%08x]", adie_cr_list[index], adie_value);
+ strncat(tmp_buf, tmp, strlen(tmp));
+ }
+ pr_info("[VCN13 OC] ATOP:%s\n", tmp_buf);
+ consys_hw_force_conninfra_sleep();
+
+ return NOTIFY_OK;
+}
+
+int consys_plt_pmic_get_from_dts(struct platform_device *pdev, struct conninfra_dev_cb* dev_cb)
+{
+ int ret;
+
+ g_dev_cb = dev_cb;
+//#if CONSYS_PMIC_CTRL_ENABLE
+ reg_VCN13 = devm_regulator_get_optional(&pdev->dev, "vcn13");
+ if (!reg_VCN13)
+ pr_err("Regulator_get VCN_13 fail\n");
+ else {
+ vcn13_nb.notifier_call = consys_vcn13_oc_notify;
+ ret = devm_regulator_register_notifier(reg_VCN13, &vcn13_nb);
+ if (ret) {
+ pr_info("VCN13 regulator notifier request failed\n");
+ }
+ }
+ reg_VCN18 = regulator_get(&pdev->dev, "vcn18");
+ if (!reg_VCN18)
+ pr_err("Regulator_get VCN_18 fail\n");
+ reg_VCN33_1_BT = regulator_get(&pdev->dev, "vcn33_1_bt");
+ if (!reg_VCN33_1_BT)
+ pr_err("Regulator_get VCN33_1_BT fail\n");
+ reg_VCN33_1_WIFI = regulator_get(&pdev->dev, "vcn33_1_wifi");
+ if (!reg_VCN33_1_WIFI)
+ pr_err("Regulator_get VCN33_1_WIFI fail\n");
+ reg_VCN33_2_WIFI = regulator_get(&pdev->dev, "vcn33_2_wifi");
+ if (!reg_VCN33_2_WIFI)
+ pr_err("Regulator_get VCN33_WIFI fail\n");
+//#endif
+ return 0;
+}
+
+int consys_pmic_vcn33_1_power_ctl(bool enable, struct regulator *reg_VCN33_1)
+{
+ int ret;
+ if (enable) {
+ if (consys_is_rc_mode_enable()) {
+ /* PMRC_EN[6][5] HW_OP_EN = 1, HW_OP_CFG = 0 */
+ KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN6, 0, 1, HW_OFF);
+ KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN5, 0, 1, HW_OFF);
+ /* SW_LP =0 */
+ KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 0);
+ regulator_set_voltage(reg_VCN33_1, 3300000, 3300000);
+ /* SW_EN=0 */
+ /* For RC mode, we don't have to control VCN33_1 & VCN33_2 */
+ #if 0
+ /* regulator_disable(reg_VCN33_1); */
+ #endif
+ } else {
+ /* HW_OP_EN = 1, HW_OP_CFG = 0 */
+ KERNEL_pmic_ldo_vcn33_1_lp(SRCLKEN0, 1, 1, HW_OFF);
+ /* SW_LP =0 */
+ KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_1_LP, 0);
+ regulator_set_voltage(reg_VCN33_1, 3300000, 3300000);
+ /* SW_EN=1 */
+ ret = regulator_enable(reg_VCN33_1);
+ if (ret)
+ pr_err("Enable VCN33_1 fail. ret=%d\n", ret);
+ }
+ } else {
+ if (consys_is_rc_mode_enable()) {
+ /* Do nothing */
+ } else {
+ regulator_disable(reg_VCN33_1);
+ }
+ }
+ return 0;
+}
+
+int consys_pmic_vcn33_2_power_ctl(bool enable)
+{
+ int ret;
+
+ if (enable) {
+ if (consys_is_rc_mode_enable()) {
+ /* PMRC_EN[6] HW_OP_EN = 1, HW_OP_CFG = 0 */
+ KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN6, 0, 1, HW_OFF);
+ /* SW_LP =0 */
+ KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_2_LP, 0);
+ regulator_set_voltage(reg_VCN33_2_WIFI, 3300000, 3300000);
+ /* SW_EN=0 */
+ /* For RC mode, we don't have to control VCN33_1 & VCN33_2 */
+ #if 0
+ regulator_disable(reg_VCN33_2_WIFI);
+ #endif
+ } else {
+ /* HW_OP_EN = 1, HW_OP_CFG = 0 */
+ KERNEL_pmic_ldo_vcn33_2_lp(SRCLKEN0, 1, 1, HW_OFF);
+ /* SW_LP =0 */
+ KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN33_2_LP, 0);
+ regulator_set_voltage(reg_VCN33_2_WIFI, 3300000, 3300000);
+ /* SW_EN=1 */
+ ret = regulator_enable(reg_VCN33_2_WIFI);
+ if (ret)
+ pr_err("Enable VCN33_2 fail. ret=%d\n", ret);
+ }
+ } else {
+ if (consys_is_rc_mode_enable()) {
+ /* Do nothing */
+ } else {
+ regulator_disable(reg_VCN33_2_WIFI);
+ }
+ }
+ return 0;
+}
+
+int consys_plt_pmic_common_power_ctrl(unsigned int enable)
+{
+ int ret;
+
+ if (enable) {
+ if (consys_is_rc_mode_enable()) {
+ /* RC mode */
+ /* VCN18 */
+ /* PMRC_EN[7][6][5][4] HW_OP_EN = 1, HW_OP_CFG = 0 */
+ KERNEL_pmic_ldo_vcn18_lp(SRCLKEN7, 0, 1, HW_OFF);
+ KERNEL_pmic_ldo_vcn18_lp(SRCLKEN6, 0, 1, HW_OFF);
+ KERNEL_pmic_ldo_vcn18_lp(SRCLKEN5, 0, 1, HW_OFF);
+ KERNEL_pmic_ldo_vcn18_lp(SRCLKEN4, 0, 1, HW_OFF);
+ /* SW_LP =1 */
+ KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 1);
+ regulator_set_voltage(reg_VCN18, 1800000, 1800000);
+ ret = regulator_enable(reg_VCN18);
+ if (ret)
+ pr_err("Enable VCN18 fail. ret=%d\n", ret);
+
+ /* VCN13 */
+ /* PMRC_EN[7][6][5][4] HW_OP_EN = 1, HW_OP_CFG = 0 */
+ KERNEL_pmic_ldo_vcn13_lp(SRCLKEN7, 0, 1, HW_OFF);
+ KERNEL_pmic_ldo_vcn13_lp(SRCLKEN6, 0, 1, HW_OFF);
+ KERNEL_pmic_ldo_vcn13_lp(SRCLKEN5, 0, 1, HW_OFF);
+ KERNEL_pmic_ldo_vcn13_lp(SRCLKEN4, 0, 1, HW_OFF);
+ /* SW_LP =1 */
+ KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, 1);
+ regulator_set_voltage(reg_VCN13, 1300000, 1300000);
+ ret = regulator_enable(reg_VCN13);
+ if (ret)
+ pr_err("Enable VCN13 fail. ret=%d\n", ret);
+ } else {
+ /* Legacy mode */
+ /* HW_OP_EN = 1, HW_OP_CFG = 1 */
+ KERNEL_pmic_ldo_vcn18_lp(SRCLKEN0, 1, 1, HW_LP);
+ /* SW_LP=0 */
+ KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN18_LP, 0);
+ regulator_set_voltage(reg_VCN18, 1800000, 1800000);
+ /* SW_EN=1 */
+ ret = regulator_enable(reg_VCN18);
+ if (ret)
+ pr_err("Enable VCN18 fail. ret=%d\n", ret);
+
+ /* HW_OP_EN = 1, HW_OP_CFG = 1 */
+ KERNEL_pmic_ldo_vcn13_lp(SRCLKEN0, 1, 1, HW_LP);
+ regulator_set_voltage(reg_VCN13, 1300000, 1300000);
+ /* SW_LP=0 */
+ KERNEL_pmic_set_register_value(PMIC_RG_LDO_VCN13_LP, 0);
+ /* SW_EN=1 */
+ ret = regulator_enable(reg_VCN13);
+ if (ret)
+ pr_err("Enable VCN13 fail. ret=%d\n", ret);
+ }
+ } else {
+ regulator_disable(reg_VCN13);
+ regulator_disable(reg_VCN18);
+ }
+ return 0;
+}
+
+int consys_plt_pmic_wifi_power_ctrl(unsigned int enable)
+{
+ int ret;
+
+ ret = consys_pmic_vcn33_1_power_ctl(enable, reg_VCN33_1_WIFI);
+ if (ret)
+ pr_err("%s VCN33_1 fail\n", (enable? "Enable" : "Disable"));
+ ret = consys_pmic_vcn33_2_power_ctl(enable);
+ if (ret)
+ pr_err("%s VCN33_2 fail\n", (enable? "Enable" : "Disable"));
+ return ret;
+}
+
+int consys_plt_pmic_bt_power_ctrl(unsigned int enable)
+{
+ if (enable) {
+ /* request VS2 to 1.4V by VS2 VOTER (use bit 4) */
+ KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOTER_EN_SET, 0x10);
+ /* Set VCN13 to 1.32V */
+ KERNEL_pmic_set_register_value(PMIC_RG_VCN13_VOCAL, 0x2);
+ } else {
+ /* restore VCN13 to 1.3V */
+ KERNEL_pmic_set_register_value(PMIC_RG_VCN13_VOCAL, 0);
+ /* clear bit 4 of VS2 VOTER then VS2 can restore to 1.35V */
+ KERNEL_pmic_set_register_value(PMIC_RG_BUCK_VS2_VOTER_EN_CLR, 0x10);
+ }
+ return consys_pmic_vcn33_1_power_ctl(enable, reg_VCN33_1_BT);
+}
+
+int consys_plt_pmic_gps_power_ctrl(unsigned int enable)
+{
+ return 0;
+}
+
+int consys_plt_pmic_fm_power_ctrl(unsigned int enable)
+{
+ return 0;
+}
+
+
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/mt6885_pos.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/mt6885_pos.c
new file mode 100755
index 0000000..267f0d2
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/mt6885/mt6885_pos.c
@@ -0,0 +1,2310 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#include "consys_hw.h" /* for semaphore index */
+/* platform dependent */
+#include "plat_def.h"
+/* macro for read/write cr */
+#include "consys_reg_util.h"
+#include "consys_reg_mng.h"
+/* cr base address */
+#include "mt6885_consys_reg.h"
+/* cr offset */
+#include "mt6885_consys_reg_offset.h"
+/* For function declaration */
+#include "mt6885_pos.h"
+#include "mt6885.h"
+
+#include <linux/ratelimit.h>
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+#define CONN_INFRA_SYSRAM__A_DIE_DIG_TOP_CK_EN_MASK 0x7f
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+struct a_die_reg_config {
+ unsigned int reg;
+ unsigned int mask;
+ unsigned int config;
+};
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+const static char* gAdieCtrlType[CONNSYS_ADIE_CTL_MAX] =
+{
+ "CONNSYS_ADIE_CTL_HOST_BT",
+ "CONNSYS_ADIE_CTL_HOST_FM",
+ "CONNSYS_ADIE_CTL_HOST_GPS",
+ "CONNSYS_ADIE_CTL_HOST_WIFI",
+ "CONNSYS_ADIE_CTL_HOST_CONNINFRA",
+ "CONNSYS_ADIE_CTL_FW_BT",
+ "CONNSYS_ADIE_CTL_FW_WIFI",
+};
+
+const static char* g_spi_system_name[SYS_SPI_MAX] = {
+ "SYS_SPI_WF1",
+ "SYS_SPI_WF",
+ "SYS_SPI_BT",
+ "SYS_SPI_FM",
+ "SYS_SPI_GPS",
+ "SYS_SPI_TOP",
+ "SYS_SPI_WF2",
+ "SYS_SPI_WF3",
+};
+
+#define ADIE_CONFIG_NUM 2
+
+// E1 WF/GPS/FM on(default)
+const static struct a_die_reg_config adie_e1_default[ADIE_CONFIG_NUM] =
+{
+ {ATOP_RG_TOP_XTAL_01, 0xc180, 0xc180},
+ {ATOP_RG_TOP_XTAL_02, 0xf0ff0080, 0xd0550080},
+};
+
+const static struct a_die_reg_config adie_e1_bt_only[ADIE_CONFIG_NUM] =
+{
+ {ATOP_RG_TOP_XTAL_01, 0xc180, 0xc100},
+ {ATOP_RG_TOP_XTAL_02, 0xf0ff0080, 0xf0ff0000},
+};
+
+const static struct a_die_reg_config adie_e2_default[ADIE_CONFIG_NUM] =
+{
+ {ATOP_RG_TOP_XTAL_01, 0xc180, 0xc180},
+ {ATOP_RG_TOP_XTAL_02, 0xf0ff0080, 0x50550080},
+};
+
+const static struct a_die_reg_config adie_e2_bt_only[ADIE_CONFIG_NUM] =
+{
+ {ATOP_RG_TOP_XTAL_01, 0xc180, 0x100},
+ {ATOP_RG_TOP_XTAL_02, 0xf0ff0080, 0x70ff0000},
+};
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+static int consys_spi_read_nolock(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data);
+static int consys_spi_write_nolock(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data);
+static void consys_spi_write_offset_range_nolock(
+ enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int value,
+ unsigned int reg_offset, unsigned int value_offset, unsigned int size);
+static int connsys_a_die_thermal_cal(int efuse_valid, unsigned int efuse);
+
+unsigned int consys_emi_set_remapping_reg(
+ phys_addr_t con_emi_base_addr,
+ phys_addr_t md_shared_emi_base_addr)
+{
+ /* EMI Registers remapping */
+ CONSYS_REG_WRITE_OFFSET_RANGE(CON_REG_HOST_CSR_ADDR + CONN2AP_REMAP_MCU_EMI_BASE_ADDR_OFFSET,
+ con_emi_base_addr, 0, 16, 20);
+
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_HOST_CSR_ADDR + CONN2AP_REMAP_WF_PERI_BASE_ADDR_OFFSET,
+ 0x01000, 0xFFFFF);
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_HOST_CSR_ADDR + CONN2AP_REMAP_BT_PERI_BASE_ADDR_OFFSET,
+ 0x01000, 0xFFFFF);
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_HOST_CSR_ADDR + CONN2AP_REMAP_GPS_PERI_BASE_ADDR_OFFSET,
+ 0x01000, 0xFFFFF);
+
+ if (md_shared_emi_base_addr) {
+ CONSYS_REG_WRITE_OFFSET_RANGE(
+ CON_REG_HOST_CSR_ADDR + CONN2AP_REMAP_MD_SHARE_EMI_BASE_ADDR_OFFSET,
+ md_shared_emi_base_addr, 0, 16, 20);
+ }
+ pr_info("connsys_emi_base=[0x%llx] mcif_emi_base=[0x%llx] remap cr: connsys=[0x%08x] mcif=[0x%08x]\n",
+ con_emi_base_addr, md_shared_emi_base_addr,
+ CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN2AP_REMAP_MCU_EMI_BASE_ADDR_OFFSET),
+ CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN2AP_REMAP_MD_SHARE_EMI_BASE_ADDR_OFFSET));
+ return 0;
+}
+
+int consys_conninfra_on_power_ctrl(unsigned int enable)
+{
+ int check;
+ if (enable) {
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* Turn on SPM clock (apply this for SPM's CONNSYS power control related CR accessing)
+ * address: 0x1000_6000[0]
+ * 0x1000_6000[31:16]
+ * Data: [0]=1'b1
+ * [31:16]=16'h0b16 (key)
+ * Action: write
+ */
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_SPM_BASE_ADDR + SPM_POWERON_CONFIG_EN, 0x0b160001, 0xffff0001);
+#endif
+
+ /* Turn on ap2conn host_ck CG (ECO)
+ * Address: INFRA_AP2MD_GALS_CTL[0] (0x1020E504[0])
+ * Value: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CON_REG_INFRACFG_BASE_ADDR + INFRA_AP2MD_GALS_CTL, 0x1);
+
+#if MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE
+ check = consys_platform_spm_conn_ctrl(enable);
+ if (check) {
+ pr_err("Turn on oonn_infra power fail.\n");
+ return -1;
+ }
+#else
+ pr_info("Turn on conn_infra power by POS steps\n");
+ /* Assert "conn_infra_on" primary part power on, set "connsys_on_domain_pwr_on"=1
+ * Address: 0x1000_6304[2]
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x4);
+
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* Check "conn_infra_on" primary part power status, check "connsys_on_domain_pwr_ack"=1
+ * (polling "10 times" and each polling interval is "0.5ms")
+ * Address: 0x1000_616C[1]
+ * Data: 1'b1
+ * Action: polling
+ */
+ check = 0;
+ CONSYS_REG_BIT_POLLING(CON_REG_SPM_BASE_ADDR + SPM_PWR_STATUS, 1, 1, 500, 10, check);
+ if (check != 0)
+ pr_err("Check conn_infra_on primary power fail. 0x1000_616C is 0x%08x. Expect [1] as 1.\n",
+ CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_PWR_STATUS));
+#endif
+
+ /* Assert "conn_infra_on" secondary part power on, set "connsys_on_domain_pwr_on_s"=1
+ * Address: 0x1000_6304[3]
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x8);
+
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* Check "conn_infra_on" secondary part power status,
+ * check "connsys_on_domain_pwr_ack_s"=1
+ * (polling "10 times" and each polling interval is "0.5ms")
+ * Address: 0x1000_6170[1]
+ * Data: 1'b1
+ * Action: polling
+ */
+ check = 0;
+ CONSYS_REG_BIT_POLLING(CON_REG_SPM_BASE_ADDR + SPM_PWR_STATUS_2ND, 1, 1, 500, 10, check);
+ if (check != 0)
+ pr_err("Check conn_infra_on secondary power fail. 0x1000_6170 is 0x%08x. Expect [1] as 1.\n",
+ CONSYS_REG_READ(CON_REG_SPM_BASE_ADDR + SPM_PWR_STATUS_2ND));
+#endif
+
+ /* Turn on AP-to-CONNSYS bus clock, set "conn_clk_dis"=0
+ * (apply this for bus clock toggling)
+ * Address: 0x1000_6304[4]
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x10);
+
+ /* Wait 1 us */
+ udelay(1);
+
+ /* De-assert "conn_infra_on" isolation, set "connsys_iso_en"=0
+ * Address: 0x1000_6304[1]
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x2);
+
+ /* De-assert CONNSYS S/W reset (TOP RGU CR),
+ * set "ap_sw_rst_b"=1
+ * Address: WDT_SWSYSRST[9] (0x1000_7018[9])
+ * WDT_SWSYSRST[31:24] (0x1000_7018[31:24])
+ * Data: [9]=1'b0
+ * [31:24]=8'h88 (key)
+ * Action: Write
+ */
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_TOP_RGU_ADDR + TOP_RGU_WDT_SWSYSRST,0x88000000, 0xff000200);
+
+ /* De-assert CONNSYS S/W reset (SPM CR), set "ap_sw_rst_b"=1
+ * Address: CONN_PWR_CON[0] (0x1000_6304[0])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x1);
+
+ /* Wait 0.5ms */
+ udelay(500);
+
+ /* Disable AXI bus sleep protect */
+ /* Turn off AXI RX bus sleep protect (AP2CONN AHB Bus protect)
+ * (apply this for INFRA AHB bus accessing when CONNSYS had been turned on)
+ * Address: 0x1000_1718[31:0] (INFRA_TOPAXI_PROTECTEN2_CLR)
+ * Data: 0x0000_0002
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN2_CLR_OFFSET,
+ 0x00000002);
+
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* Check AHB RX bus sleep protect turn off
+ * (polling "10 times" and each polling interval is "0.5ms")
+ * Address: 0x1000_1724[2] (INFRA_TOPAXI_PROTECTEN2_STA1[2])
+ * Data: 1'b0
+ * Action: polling
+ */
+ check = 0;
+ CONSYS_REG_BIT_POLLING(
+ CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN2_STA1_OFFSET,
+ 2, 0, 10, 500, check);
+ if (check != 0)
+ pr_err("Polling AHB RX bus sleep protect turn off fail. status=0x%08x\n",
+ CONSYS_REG_READ(CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN2_STA1_OFFSET));
+#endif
+
+ /* Turn off AXI Rx bus sleep protect (CONN2AP AXI Rx Bus protect)
+ * (disable sleep protection when CONNSYS had been turned on)
+ * Note : Should turn off AHB Rx sleep protection first.
+ */
+ CONSYS_REG_WRITE(
+ CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_CLR_OFFSET,
+ 0x00004000);
+#if 0 /* POS update 20190819: Skip check */
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* Check AXI Rx bus sleep protect turn off
+ * (polling "10 times" and each polling interval is "0.5ms")
+ * Address: 0x1000_1228[14] (INFRA_TOPAXI_PROTECTEN_STA1[14])
+ * Data: 1'b0
+ * Action: polling
+ */
+ CONSYS_REG_BIT_POLLING(
+ CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1_OFFSET,
+ 14, 0, 10, 50, check);
+ if (check != 0)
+ pr_err("Polling AXI bus sleep protect turn off fail. Status=0x%08x\n",
+ CONSYS_REG_READ(CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1_OFFSET));
+#endif
+#endif
+ /* Turn off AXI TX bus sleep protect (AP2CONN AXI Bus protect)
+ * (apply this for INFRA AXI bus accessing when CONNSYS had been turned on)
+ */
+ CONSYS_REG_WRITE(
+ CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_CLR_OFFSET,
+ 0x00002000);
+
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ /* Check AXI TX bus sleep protect turn off
+ * (polling "10 times" and each polling interval is "0.5ms")
+ * Address: 0x1000_1228[13] (INFRA_TOPAXI_PROTECTEN_STA1[13])
+ * Data: 1'b0
+ * Action: polling
+ */
+ CONSYS_REG_BIT_POLLING(
+ CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1_OFFSET,
+ 13, 0, 10, 500, check);
+ if (check != 0)
+ pr_err("polling AHB TX bus sleep protect turn off fail. Status=0x%08x\n",
+ CONSYS_REG_READ(CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1_OFFSET));
+#endif
+#endif /* MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE */
+ } else {
+
+ /* Enable AXI bus sleep protect */
+#if MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE
+ pr_info("Turn off conn_infra power by SPM API\n");
+ check = consys_platform_spm_conn_ctrl(enable);
+ if (check) {
+ pr_err("Turn off conn_infra power fail, ret=%d\n", check);
+ return -1;
+ }
+#else
+ /* Turn on AXI TX bus sleep protect (AP2CONN AXI Bus protect)
+ * (apply this for INFRA AXI bus protection to prevent bus hang when
+ * CONNSYS had been turned off)
+ * Address: 0x1000_12a0[31:0]
+ * Data: 0x0000_2000
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_SET_OFFSET,
+ 0x00002000);
+
+ /* check AHB TX bus sleep protect turn on (polling "10 times")
+ * Address: 0x1000_1228[13]
+ * Data: 1'b1
+ * Action: polling
+ */
+ CONSYS_REG_BIT_POLLING(
+ CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1_OFFSET,
+ 13, 1, 0, 500, check);
+ if (check)
+ pr_err("Polling AHB TX bus sleep protect turn on fail.\n");
+
+ /* Turn on AXI Rx bus sleep protect (CONN2AP AXI RX Bus protect)
+ * (apply this for INFRA AXI bus protection to prevent bus hang when
+ * CONNSYS had been turned off)
+ * Note:
+ * Should turn on AXI Rx sleep protection after
+ * AXI Tx sleep protection has been turn on.
+ * Address: 0x1000_12A0[31:0]
+ * Data: 0x0000_4000
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_SET_OFFSET,
+ 0x00004000);
+
+ /* check AXI Rx bus sleep protect turn on
+ * (polling "100 times", polling interval is 1ms)
+ * Address: 0x1000_1228[14]
+ * Data: 1'b1
+ * Action: polling
+ */
+ CONSYS_REG_BIT_POLLING(
+ CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN_STA1_OFFSET,
+ 14, 1, 10, 1000, check);
+ if (check)
+ pr_err("Polling AXI Rx bus sleep protect turn on fail.\n");
+
+ /* Turn on AXI RX bus sleep protect (AP2CONN AXI Bus protect)
+ * (apply this for INFRA AXI bus protection to prevent bus hang when
+ * CONNSYS had been turned off)
+ * Address: 0x1000_1714[31:0] (INFRA_TOPAXI_PROTECTEN2_SET)
+ * Data: 0x0000_0002
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN2_SET_OFFSET,
+ 0x00000002);
+ /* check AHB RX bus sleep protect turn on (polling "10 times")
+ * Address: 0x1000_1724[2] (INFRA_TOPAXI_PROTECTEN2_STA1[2])
+ * Value: 1'b1
+ * Action: polling
+ */
+ CONSYS_REG_BIT_POLLING(
+ CON_REG_INFRACFG_AO_ADDR + INFRA_TOPAXI_PROTECTEN2_STA1_OFFSET,
+ 2, 1, 10, 0, check);
+ if (check)
+ pr_err("Polling AHB RX bus sleep protect turn on fail.\n");
+
+ /* Assert "conn_infra_on" isolation, set "connsys_iso_en"=1
+ * Address: CONN_PWR_CON[1] (0x1000_6304[1])
+ * Value: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x2);
+
+ /* Assert CONNSYS S/W reset (SPM CR), set "ap_sw_rst_b"=0
+ * Address: CONN_PWR_CON[0] (0x1000_6304[0])
+ * Value: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x1);
+
+ /* Assert CONNSYS S/W reset(TOP RGU CR), set "ap_sw_rst_b"=0
+ * Address: WDT_SWSYSRST[9] (0x1000_7018[9])
+ * WDT_SWSYSRST[31:24] (0x1000_7018[31:24])
+ * Value: [9]=1'b1
+ * [31:24]=8'h88 (key)
+ * Action: write
+ * Note: this CR value for reset control is active high (0: not reset, 1: reset)
+ */
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_TOP_RGU_ADDR + TOP_RGU_WDT_SWSYSRST,
+ 0x88000200,
+ 0xff000200);
+
+ /* Turn off AP-to-CONNSYS bus clock, set "conn_clk_dis"=1
+ * (apply this for bus clock gating)
+ * Address: CONN_PWR_CON[4] (0x1000_6304[4])
+ * Value: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x10);
+
+ /* wait 1us (?) */
+ udelay(1);
+
+ /* De-assert "conn_infra_on" primary part power on,
+ * set "connsys_on_domain_pwr_on"=0
+ * Address: CONN_PWR_CON[2] (0x1000_6304[2])
+ * Value: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x4);
+
+ /* De-assert "conn_infra_on" secondary part power on,
+ * set "connsys_on_domain_pwr_on_s"=0
+ * Address: CONN_PWR_CON[3] (0x1000_6304[3])
+ * Value: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CON_REG_SPM_BASE_ADDR + SPM_CONN_PWR_CON, 0x8);
+#endif /* MTK_CONNINFRA_CLOCK_BUFFER_API_AVAILABLE */
+
+ /* Turn off ap2conn host_ck CG (ECO)
+ * Address: INFRA_AP2MD_GALS_CTL[0] (0x1020E504[0])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CON_REG_INFRACFG_BASE_ADDR + INFRA_AP2MD_GALS_CTL, 0x1);
+ }
+ return 0;
+}
+
+int consys_conninfra_wakeup(void)
+{
+ int check, r1, r2;
+ unsigned int retry = 10;
+ unsigned int consys_hw_ver = 0;
+ int polling_fail_retry = 2;
+ unsigned long polling_fail_delay = 20000; /* 20ms */
+
+ /* Wake up conn_infra
+ * Address: CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP (0x180601a0)
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP,
+ 0x1);
+
+ /* Check ap2conn slpprot_rdy
+ * (polling "10 times" for specific project code and each polling interval is "1ms")
+ * Address: CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL_CONN_INFRA_ON2OFF_SLP_PROT_ACK (0x1806_0184[5])
+ * Data: 1'b0
+ * Action: polling
+ */
+ while (polling_fail_retry > 0) {
+ check = 0;
+ CONSYS_REG_BIT_POLLING(
+ CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL, 5, 0, 10, 1000, check);
+
+ if (check) {
+ pr_err("[%s] Check ap2conn slpprot_rdy fail. value=0x%x WAKEUP_TOP=[0x%x]\n",
+ __func__,
+ CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL),
+ CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP));
+ }
+
+ if (consys_reg_mng_reg_readable() == 0) {
+ check = consys_reg_mng_is_bus_hang();
+ r1 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_3);
+ r2 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP);
+ pr_info("[%s] check=[%d] r1=[0x%x] r2=[0x%x]", __func__, check, r1, r2);
+ consys_reg_mng_dump_cpupcr(CONN_DUMP_CPUPCR_TYPE_ALL, 10, 200);
+ if (check > 0) {
+ return -1;
+ }
+ check = -1;
+ }
+
+ if (check == 0)
+ break;
+
+ /* delay 20 ms */
+ usleep_range(polling_fail_delay - 200, polling_fail_delay + 200);
+ polling_fail_retry--;
+ }
+
+ if (check != 0) {
+ pr_err("[%s] wakeup fail retry %d", __func__, polling_fail_retry);
+ return -1;
+ }
+
+ /* Check CONNSYS version ID
+ * (polling "10 times" for specific project code and each polling interval is "1ms")
+ * Address: CONN_HW_VER (0x1800_1000[31:0])
+ * Data: 32'h2001_0000
+ * Action: polling
+ */
+ check = 0;
+ while (retry-- > 0) {
+ consys_hw_ver = CONSYS_REG_READ(
+ CON_REG_INFRA_CFG_ADDR +
+ CONN_HW_VER_OFFSET);
+ if (consys_hw_ver == CONN_HW_VER) {
+ check = 0;
+ pr_info("[%s] Polling chip id success (0x%x)\n", __func__, consys_hw_ver);
+ break;
+ }
+ check = -1;
+ }
+ if (check != 0)
+ pr_err("[%s] Polling chip id fail (0x%x)\n", __func__, consys_hw_ver);
+
+ return check;
+}
+
+int consys_conninfra_sleep(void)
+{
+ /* Release conn_infra force on
+ * Address: CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP (0x180601a0)
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP,
+ 0x0);
+
+ return 0;
+}
+
+void consys_set_if_pinmux(unsigned int enable)
+{
+#ifndef CONFIG_FPGA_EARLY_PORTING
+ if (enable) {
+ /* Set pinmux for the interface between D-die and A-die
+ * (CONN_HRST_B / CONN_TOP_CLK / CONN_TOP_DATA / CONN_WB_PTA /
+ * CONN_BT_CLK / CONN_BT_DATA / CONN_WF_CTRL0 / CONN_WF_CTRL1 /
+ * CONN_WF_CTRL2 / CONN_WF_CTRL3 / CONN_WF_CTRL4)
+ */
+ /* GPIO 172: 0x1000_5450[18:16] */
+ /* GPIO 173: 0x1000_5450[22:20] */
+ /* GPIO 174: 0x1000_5450[26:24] */
+ /* GPIO 175: 0x1000_5450[30:28] */
+ CONSYS_REG_WRITE_MASK(GPIO_BASE_ADDR + GPIO_MODE21, 0x11110000, 0xffff0000);
+
+ /* GPIO 176: 0x1000_5460[2:0] */
+ /* GPIO 177: 0x1000_5460[6:4] */
+ /* GPIO 178: 0x1000_5460[10:8] */
+ /* GPIO 179: 0x1000_5460[14:12] */
+ /* GPIO 180: 0x1000_5460[18:16] */
+ /* GPIO 181: 0x1000_5460[22:20] */
+ /* GPIO 182: 0x1000_5460[26:24] */
+ CONSYS_REG_WRITE_MASK(GPIO_BASE_ADDR + GPIO_MODE22, 0x01111111, 0x0fffffff);
+
+ /* Set pinmux driving to 2mA
+ * Address:
+ * 0x11EA_0000[5:3]/0x11EA_0000[8:6]/0x11EA_0000[11:9]
+ * 0x11EA_0000[14:12]/0x11EA_0000[17:15]
+ * Data: 3'b000
+ * Action: write
+ * Note: IOCFG_RT
+ */
+ CONSYS_REG_WRITE_MASK(IOCFG_RT_ADDR + IOCFG_RT_DRV_CFG0, 0x0, 0x3fff8);
+
+ /* Set CONN_TOP_CLK/CONN_TOP_DATA/CONN_BT_CLK/CONN_BT_DATA driving to 4mA
+ * (CONN_TOP_DATA driving config is the same position with
+ * CONN_WF_CTRL0/CONN_WF_CTRL1/CONN_WF_CTRL2/CONN_WF_CTRL3/CONN_WF_CTRL4)
+ * Address:
+ * CONN_TOP_CLK 0x11EA_0000[17:15] = 3b'001
+ * CONN_TOP_DATA 0x11EA_0000[5:3] = 3b'001
+ * CONN_BT_CLK 0x11EA_0000[8:6] = 3b'001
+ * CONN_BT_DATA 0x11EA_0000[11:9] = 3b'001
+ * Action: write
+ */
+ CONSYS_REG_WRITE_MASK(IOCFG_RT_ADDR + IOCFG_RT_DRV_CFG0, 0x8248, 0x38ff8);
+
+ /* Set pinmux PUPD setting
+ * Clear CONN_TOP_DATA/CONN_BT_DATA PD setting
+ * Address: 0x11EA_0058[14][11]
+ * Data: 2'b11
+ * Action: write
+ * Note: IOCFG_RT
+ */
+ CONSYS_REG_WRITE_MASK(IOCFG_RT_ADDR + IOCFG_RT_PD_CFG0_CLR, 0x4800, 0x4800);
+
+ /* Set pinmux PUPD
+ * Setting CONN_TOP_DATA/CONN_BT_DATA as PU
+ * Address: 0x11EA_0074[14][11]
+ * Data: 2'b11
+ * Action: write
+ * Note: IOCFG_RT
+ */
+ CONSYS_REG_WRITE_MASK(IOCFG_RT_ADDR + IOCFG_RT_PU_CFG0_SET, 0x4800, 0x4800);
+
+ /* If TCXO mode, set GPIO155 pinmux for TCXO mode (AUX4)
+ * (CONN_TCXOENA_REQ)
+ * Address: 0x1000_5430[14:12]
+ * Data: 3'b100
+ * Action: write
+ */
+ if (consys_co_clock_type() == CONNSYS_CLOCK_SCHEMATIC_26M_EXTCXO) {
+ /* TODO: need customization for TCXO GPIO */
+ CONSYS_REG_WRITE_MASK(GPIO_BASE_ADDR + GPIO_MODE19, 0x4000, 0x7000);
+ }
+ } else {
+ /* Set pinmux for the interface between D-die and A-die (Aux0)
+ * Address:
+ * 0x1000_5450[26:24]/0x1000_5450[18:16]/0x1000_5450[22:20]
+ * 0x1000_5450[30:28]/0x1000_5460[2:0]/0x1000_5460[6:4]
+ * 0x1000_5460[10:8]/0x1000_5460[14:12]/0x1000_5460[18:16]
+ * 0x1000_5460[22:20]/0x1000_5460[26:24]
+ * Data: 3'b000
+ * Action: write
+ */
+ CONSYS_REG_WRITE_MASK(GPIO_BASE_ADDR + GPIO_MODE21, 0x0, 0xffff0000);
+ CONSYS_REG_WRITE_MASK(GPIO_BASE_ADDR + GPIO_MODE22, 0x0, 0x0fffffff);
+
+ /* Set pinmux PUPD setting
+ * Clear CONN_TOP_DATA/CONN_BT_DATA PU setting
+ * Address: 0x11EA_0078[14][11]
+ * Data: 2'b11
+ * Action: write
+ */
+ CONSYS_REG_WRITE_MASK(IOCFG_RT_ADDR + IOCFG_RT_PU_CFG0_CLR, 0x4800, 0x4800);
+
+ /* Set pinmux PUPD setting
+ * CONN_TOP_DATA/CONN_BT_DATA as PD
+ * Address: 0x11EA_0054[14][11]
+ * Data: 2'b11
+ *Action: write
+ */
+ CONSYS_REG_WRITE_MASK(IOCFG_RT_ADDR + IOCFG_RT_PD_CFG0_SET, 0x4800, 0x4800);
+
+ /* If TCXO mode, set GPIO155 pinmux to GPIO mode
+ * Address: 0x1000_5430[14:12]
+ * Data: 3'b000
+ * Action: write
+ */
+ if (consys_co_clock_type() == CONNSYS_CLOCK_SCHEMATIC_26M_EXTCXO) {
+ CONSYS_REG_WRITE_MASK(GPIO_BASE_ADDR + GPIO_MODE19, 0x0, 0x7000);
+ }
+ }
+#else
+ pr_info("[%s] not for FPGA\n", __func__);
+#endif
+}
+
+int consys_polling_chipid(void)
+{
+ unsigned int retry = 11;
+ unsigned int consys_hw_ver = 0;
+ unsigned int consys_configuration_id = 0;
+ int ret = -1;
+
+ while (--retry > 0) {
+ consys_hw_ver = CONSYS_REG_READ(
+ CON_REG_INFRA_CFG_ADDR +
+ CONN_HW_VER_OFFSET);
+ if (consys_hw_ver == CONN_HW_VER) {
+ consys_configuration_id = CONSYS_REG_READ(
+ CON_REG_INFRA_CFG_ADDR + CONN_CFG_ID_OFFSET);
+ pr_info("Consys HW version id(0x%x) cfg_id=(0x%x)\n",
+ consys_hw_ver, consys_configuration_id);
+ ret = 0;
+ break;
+ }
+ msleep(20);
+ }
+
+ if (retry == 0) {
+ pr_err("Read CONSYS version id fail. Expect 0x%x but get 0x%x\n",
+ consys_hw_ver, CONN_HW_VER, consys_hw_ver);
+ return -1;
+ }
+
+ /* Disable conn_infra deadfeed function(workaround)
+ * Address: CONN_HOST_CSR_TOP_CSR_DEADFEED_EN_CR_AP2CONN_DEADFEED_EN (0x1806_0124[0])
+ * Data: 1'b0
+ * Action: write
+ * Note: workaround for deadfeed CDC issue
+ */
+ CONSYS_CLR_BIT(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CSR_DEADFEED_EN_CR, 0x1);
+
+#ifdef CONFIG_FPGA_EARLY_PORTING
+ /* For FPGA workaround */
+ CONSYS_SET_BIT(CON_REG_INFRA_CFG_ADDR + 0x0c04,
+ ((0x1 << 1) | (0x1 << 9) | (0x1 << 17) | (0x1 << 25)));
+ pr_info("Workaround for FPGA: Check %x\n", CON_REG_INFRA_CFG_ADDR + 0x0c04);
+#endif
+
+ return ret;
+}
+
+int connsys_d_die_cfg(void)
+{
+ /* Read D-die Efuse
+ * Address: AP2CONN_EFUSE_DATA (0x1800_1818)
+ * Data:
+ * Action: read
+ */
+ CONSYS_REG_WRITE(
+ CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_D_DIE_EFUSE,
+ CONSYS_REG_READ(CON_REG_INFRA_CFG_ADDR + AP2CONN_EFUSE_DATA));
+
+ /* conn_infra sysram hw control setting -> disable hw power down
+ * Address: CONN_INFRA_RGU_SYSRAM_HWCTL_PDN_SYSRAM_HWCTL_PDN (0x1800_0038)
+ * Data: 32'h0
+ * Action: write
+ */
+ CONSYS_REG_WRITE(CON_REG_INFRA_RGU_ADDR + CONN_INFRA_RGU_SYSRAM_HWCTL_PDN, 0x0);
+
+ /* conn_infra sysram hw control setting -> enable hw sleep
+ * Address: CONN_INFRA_RGU_SYSRAM_HWCTL_SLP_SYSRAM_HWCTL_SLP (0x1800_003C)
+ * Data: 32'h0000_00FF
+ * Action: write
+ */
+ CONSYS_REG_WRITE(CON_REG_INFRA_RGU_ADDR + CONN_INFRA_RGU_SYSRAM_HWCTL_SLP, 0x000000ff);
+
+ /* co-ext memory hw control setting -> disable hw power down
+ * Address: CONN_INFRA_RGU_CO_EXT_MEM_HWCTL_PDN_CO_EXT_MEM_HWCTL_PDN (0x1800_0050)
+ * Data: 32'h0
+ * Action: write
+ */
+ CONSYS_REG_WRITE(CON_REG_INFRA_RGU_ADDR + CONN_INFRA_RGU_CO_EXT_MEM_HWCTL_PDN, 0x0);
+
+ /* co-ext memory hw control setting -> enable hw sleep
+ * Address: CONN_INFRA_RGU_CO_EXT_MEM_HWCTL_SLP_CO_EXT_MEM_HWCTL_SLP (0x1800_0054)
+ * Data: 32'h0000_0001
+ * Action: write
+ */
+ CONSYS_REG_WRITE(CON_REG_INFRA_RGU_ADDR + CONN_INFRA_RGU_CO_EXT_MEM_HWCTL_SLP, 0x1);
+
+ return 0;
+}
+
+int connsys_spi_master_cfg(unsigned int next_status)
+{
+ unsigned int bt_only = 0;
+
+ if ((next_status & (~(0x1 << CONNDRV_TYPE_BT))) == 0)
+ bt_only = 1;
+
+ /* CONN_WT_SLP_CTL_REG_WB_WF_CK_ADDR_ADDR(0x070) = 0x0AF40A04
+ * CONN_WT_SLP_CTL_REG_WB_WF_WAKE_ADDR_ADDR(0x74) = 0x00A00090
+ * CONN_WT_SLP_CTL_REG_WB_WF_ZPS_ADDR_ADDR(0x78) = 0x009c008c
+ * CONN_WT_SLP_CTL_REG_WB_BT_CK_ADDR_ADDR(0x7c[11:0]) = 0xa08
+ * CONN_WT_SLP_CTL_REG_WB_BT_WAKE_ADDR_ADDR(0x80[11:0]) = 0x094
+ * CONN_WT_SLP_CTL_REG_WB_TOP_CK_ADDR_ADDR(0x84[11:0]) = 0xA2c
+ * CONN_WT_SLP_CTL_REG_WB_GPS_CK_ADDR_ADDR(0x88) = 0x0AFC0A0C
+ * CONN_WT_SLP_CTL_REG_WB_WF_B0_CMD_ADDR_ADDR(0x8c[11:0]) = 0x0F0
+ * CONN_WT_SLP_CTL_REG_WB_WF_B1_CMD_ADDR_ADDR(0x90[11:0]) = 0x0F4
+ * CONN_WT_SLP_CTL_REG_WB_GPS_RFBUF_ADDR(0x18005094[11:0]) = 0x0FC
+ * CONN_WT_SLP_CTL_REG_WB_GPS_L5_EN_ADDR(0x18005098[11:0]) = 0x0F8
+ */
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_WF_CK_ADDR, 0x0AF40A04);
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_WF_WAKE_ADDR, 0x00A00090);
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_WF_ZPS_ADDR, 0x009C008C);
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BT_CK_ADDR,
+ 0xa08, 0xfff);
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BT_WAKE_ADDR,
+ 0x094, 0xfff);
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_TOP_CK_ADDR,
+ 0xa2c, 0xfff);
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_GPS_CK_ADDR,
+ 0x0AFC0A0C);
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_WF_B0_CMD_ADDR,
+ 0x0f0, 0xfff);
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_WF_B1_CMD_ADDR,
+ 0x0f4, 0xfff);
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_GPS_RFBUF_ADDR,
+ 0x0FC, 0xfff);
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_GPS_L5_EN_ADDR,
+ 0x0F8, 0xfff);
+
+ /* CONN_WT_SLP_CTL_REG_WB_SLP_CTL_CMD_LENGTH(0x004[4:0]) = 0x8
+ * CONN_WT_SLP_CTL_REG_WB_BG_ADDR1_WB_BG_ADDR1(0x10[15:0]) = 0xA03C
+ * CONN_WT_SLP_CTL_REG_WB_BG_ADDR2_WB_BG_ADDR2(0x14[15:0]) = 0xA03C
+ * CONN_WT_SLP_CTL_REG_WB_BG_ADDR3_WB_BG_ADDR3(0x18[15:0]) = 0xAA18
+ * CONN_WT_SLP_CTL_REG_WB_BG_ADDR4_WB_BG_ADDR4(0x1c[15:0]) = 0xAA18
+ * CONN_WT_SLP_CTL_REG_WB_BG_ADDR5_WB_BG_ADDR5(0x20[15:0]) = 0xA0C8
+ * CONN_WT_SLP_CTL_REG_WB_BG_ADDR6_WB_BG_ADDR6(0x24[15:0]) = 0xAA00
+ * CONN_WT_SLP_CTL_REG_WB_BG_ADDR7_WB_BG_ADDR7(0x28[15:0]) = 0xA0B4
+ * CONN_WT_SLP_CTL_REG_WB_BG_ADDR8_WB_BG_ADDR8(0x2c[15:0]) = 0xA34C
+ * CONN_WT_SLP_CTL_REG_WB_BG_ON1_WB_BG_ON1(0x30) = 0x00000000
+ * CONN_WT_SLP_CTL_REG_WB_BG_ON2_WB_BG_ON2(0x34) = 0x00000000
+ * if (BT_only) {
+ * CONN_WT_SLP_CTL_REG_WB_BG_ON3_WB_BG_ON3(0x38) = 0x74E03F75
+ * CONN_WT_SLP_CTL_REG_WB_BG_ON4_WB_BG_ON4(0x3c) = 0x76E83F75
+ * } else {
+ * CONN_WT_SLP_CTL_REG_WB_BG_ON3_WB_BG_ON3(0x38) = 0x74E0FFF5
+ * CONN_WT_SLP_CTL_REG_WB_BG_ON4_WB_BG_ON4(0x3c) = 0x76E8FFF5
+ * }
+ * CONN_WT_SLP_CTL_REG_WB_BG_ON5_WB_BG_ON5(0x40) = 0x00000000
+ * CONN_WT_SLP_CTL_REG_WB_BG_ON6_WB_BG_ON6(0x44) = 0xFFFFFFFF
+ * CONN_WT_SLP_CTL_REG_WB_BG_ON7_WB_BG_ON7(0x48) = 0x00000019
+ * CONN_WT_SLP_CTL_REG_WB_BG_ON8_WB_BG_ON8(0x4c) = 0x00010400
+ * CONN_WT_SLP_CTL_REG_WB_BG_OFF1_WB_BG_OFF1(0x50) = 0x57400000
+ * CONN_WT_SLP_CTL_REG_WB_BG_OFF2_WB_BG_OFF2(0x54) = 0x57400000
+ * if (BT only) {
+ * CONN_WT_SLP_CTL_REG_WB_BG_OFF3_WB_BG_OFF3(0x58) = 0x44E03F75
+ * CONN_WT_SLP_CTL_REG_WB_BG_OFF4_WB_BG_OFF4(0x5c) = 0x44E03F75
+ * } else {
+ * CONN_WT_SLP_CTL_REG_WB_BG_OFF3_WB_BG_OFF3(0x58) = 0x44E0FFF5
+ * CONN_WT_SLP_CTL_REG_WB_BG_OFF4_WB_BG_OFF4(0x5c) = 0x44E0FFF5
+ * }
+ * CONN_WT_SLP_CTL_REG_WB_BG_OFF5_WB_BG_OFF5(0x60) = 0x00000001
+ * CONN_WT_SLP_CTL_REG_WB_BG_OFF6_WB_BG_OFF6(0x64) = 0x00000001
+ * CONN_WT_SLP_CTL_REG_WB_RG_OFF7_WB_BG_OFF7(0x68) = 0x00040019
+ * CONN_WT_SLP_CTL_REG_WB_RG_OFF8_WB_BG_OFF8(0x6c) = 0x00410440
+ */
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_SLP_CTL,
+ 0x8, 0x1f);
+
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR1,
+ 0xa03c, 0xffff);
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR2,
+ 0xa03c, 0xffff);
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR3,
+ 0xaa18, 0xffff);
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR4,
+ 0xaa18, 0xffff);
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR5,
+ 0xa0c8, 0xffff);
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR6,
+ 0xaa00, 0xffff);
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR7,
+ 0xa0b4, 0xffff);
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ADDR8,
+ 0xa34c, 0xffff);
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON1, 0x00000000);
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON2, 0x00000000);
+ if (bt_only) {
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON3, 0x74E03F75);
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON4, 0x76E83F75);
+ } else {
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON3, 0x74E0fff5);
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON4, 0x76E8FFF5);
+ }
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON5, 0x00000000);
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON6, 0xFFFFFFFF);
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON7, 0x00000019);
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_ON8, 0x00010400);
+
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF1, 0x57400000);
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF2, 0x57400000);
+ if (bt_only) {
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF3, 0x44E03F75);
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF4, 0x44E03F75);
+ } else {
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF3, 0x44e0fff5);
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF4, 0x44e0fff5);
+ }
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF5, 0x00000001);
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF6, 0x00000000);
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF7, 0x00040019);
+ CONSYS_REG_WRITE(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WT_SLP_CTL_REG_WB_BG_OFF8, 0x00410440);
+
+ return 0;
+}
+
+//#ifndef CONFIG_FPGA_EARLY_PORTING
+/*****************************************************************************
+* FUNCTION
+* connsys_a_die_efuse_read
+* DESCRIPTION
+* Read a-die efuse
+* PARAMETERS
+* efuse_addr: read address
+* RETURNS
+* int
+* 0: fail, efuse is invalid
+* 1: success, efuse is valid
+*****************************************************************************/
+static int connsys_a_die_efuse_read(unsigned int efuse_addr)
+{
+ int ret = 0;
+ int retry = 0;
+ unsigned int efuse0 = 0, efuse1 = 0, efuse2 = 0, efuse3 = 0;
+ int ret0, ret1, ret2, ret3;
+
+ /* Get semaphore before read */
+ if (consys_sema_acquire_timeout(CONN_SEMA_RFSPI_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) {
+ pr_err("[EFUSE READ] Require semaphore fail\n");
+ return 0;
+ }
+
+ /* Efuse control clear, clear Status /trigger
+ * Address: ATOP EFUSE_CTRL_write_efsrom_kick_and_read_kick_busy_flag (0x108[30])
+ * Data: 1'b0
+ * Action: TOPSPI_WR
+ */
+ consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, &ret);
+ ret &= ~(0x1 << 30);
+ consys_spi_write_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, ret);
+
+ /* Efuse Read 1st 16byte
+ * Address:
+ * ATOP EFUSE_CTRL_efsrom_mode (0x108[7:6]) = 2'b00
+ * ATOP EFUSE_CTRL_efsrom_ain (0x108[25:16]) = efuse_addr (0)
+ * ATOP EFUSE_CTRL_write_efsrom_kick_and_read_kick_busy_flag (0x108[30]) = 1'b1
+ * Action: TOPSPI_WR
+ */
+ consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, &ret);
+ ret &= ~(0x43ff00c0);
+ ret |= (0x1 << 30);
+ ret |= ((efuse_addr << 16) & 0x1ff0000);
+ consys_spi_write_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, ret);
+
+ /* Polling EFUSE busy = low
+ * (each polling interval is "30us" and polling timeout is 2ms)
+ * Address:
+ * ATOP EFUSE_CTRL_write_efsrom_kick_and_read_kick_busy_flag (0x108[30]) = 1'b0
+ * Action: TOPSPI_Polling
+ */
+ consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, &ret);
+ while ((ret & (0x1 << 30)) != 0 && retry < 70) {
+ retry++;
+ udelay(30);
+ consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, &ret);
+ }
+ if ((ret & (0x1 << 30)) != 0) {
+ pr_info("[%s] EFUSE busy, retry failed(%d)\n", __func__, retry);
+ }
+
+ /* Check efuse_valid & return
+ * Address: ATOP EFUSE_CTRL_csri_efsrom_dout_vld_sync_1_ (0x108[29])
+ * Action: TOPSPI_RD
+ */
+ /* if (efuse_valid == 1'b1)
+ * Read Efuse Data to global var
+ */
+ consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_CTRL, &ret);
+ if (((ret & (0x1 << 29)) >> 29) == 1) {
+ ret0 = consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_RDATA0, &efuse0);
+
+ CONSYS_REG_WRITE(
+ CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_0,
+ efuse0);
+
+ ret1 = consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_RDATA1, &efuse1);
+ CONSYS_REG_WRITE(
+ CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_1,
+ efuse1);
+ /* Sub-task: thermal cal */
+ connsys_a_die_thermal_cal(1, efuse1);
+
+ ret2 = consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_RDATA2, &efuse2);
+ CONSYS_REG_WRITE(
+ CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_2,
+ efuse2);
+
+ ret3 = consys_spi_read_nolock(SYS_SPI_TOP, ATOP_EFUSE_RDATA3, &efuse3);
+ CONSYS_REG_WRITE(
+ CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_EFUSE_DATA_3,
+ efuse3);
+
+ pr_info("efuse = [0x%08x, 0x%08x, 0x%08x, 0x%08x]", efuse0, efuse1, efuse2, efuse3);
+ if (ret0 || ret1 || ret2 || ret3)
+ pr_err("efuse read error: [%d, %d, %d, %d]", ret0, ret1, ret2, ret3);
+ ret = 1;
+ } else {
+ connsys_a_die_thermal_cal(0, 0);
+ pr_err("EFUSE is invalid\n");
+ ret = 0;
+ }
+
+ consys_sema_release(CONN_SEMA_RFSPI_INDEX);
+ return ret;
+}
+
+static int connsys_a_die_thermal_cal(int efuse_valid, unsigned int efuse)
+{
+ struct consys_plat_thermal_data input;
+ memset(&input, 0, sizeof(struct consys_plat_thermal_data));
+
+ if (efuse_valid) {
+ if (efuse & (0x1 << 7)) {
+ consys_spi_write_offset_range_nolock(
+ SYS_SPI_TOP, ATOP_RG_TOP_THADC_BG, efuse, 12, 3, 4);
+ consys_spi_write_offset_range_nolock(
+ SYS_SPI_TOP, ATOP_RG_TOP_THADC, efuse, 23, 0, 3);
+ }
+ if(efuse & (0x1 << 15)) {
+ consys_spi_write_offset_range_nolock(
+ SYS_SPI_TOP, ATOP_RG_TOP_THADC, efuse, 26, 13, 2);
+ input.slop_molecule = (efuse & 0x1f00) >> 8;
+ pr_info("slop_molecule=[%d]", input.slop_molecule);
+ }
+ if (efuse & (0x1 << 23)) {
+ /* [22:16] */
+ input.thermal_b = (efuse & 0x7f0000) >> 16;
+ pr_info("thermal_b =[%d]", input.thermal_b);
+ }
+ if (efuse & (0x1 << 31)) {
+ input.offset = (efuse & 0x7f000000) >> 24;
+ pr_info("offset=[%d]", input.offset);
+ }
+ }
+ update_thermal_data(&input);
+ return 0;
+}
+//#endif
+
+int connsys_a_die_cfg(void)
+{
+ int efuse_valid;
+ bool adie_26m = true;
+ unsigned int adie_id = 0;
+
+ if (consys_co_clock_type() == CONNSYS_CLOCK_SCHEMATIC_52M_COTMS) {
+ pr_info("A-die clock 52M\n");
+ adie_26m = false;
+ }
+ /* First time to setup conninfra sysram, clean it. */
+ memset_io(
+ (volatile void*)CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_OFFSET,
+ 0x0,
+ CONN_INFRA_SYSRAM_SW_CR_SIZE);
+
+
+ /* if(A-die XTAL = 26MHz ) {
+ * CONN_WF_CTRL2 swtich to GPIO mode, GPIO output value
+ * before patch download swtich back to CONN mode.
+ * }
+ */
+ /* Address:
+ * 0x1000_5054 = 32'h0010_0000
+ * 0x1000_5154 = 32'h0010_0000
+ * 0x1000_5460[18:16] = 3'b000
+ * Actin: write
+ * Note: MT6635 strap pinmux, set CONN_WF_CTRL2 as GPIO
+ */
+ if (adie_26m) {
+ CONSYS_REG_WRITE(GPIO_BASE_ADDR + GPIO_DIR5_SET, 0x00100000);
+ CONSYS_REG_WRITE(GPIO_BASE_ADDR + GPIO_DOUT5_SET, 0x00100000);
+ CONSYS_REG_WRITE_MASK(GPIO_BASE_ADDR + GPIO_MODE22, 0x0, 0x70000);
+ }
+ /* sub-task: a-die cfg */
+ /* De-assert A-die reset
+ * Address: CONN_INFRA_CFG_ADIE_CTL_ADIE_RSTB (0x18001900[0])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_ADIE_CTL, 0x1);
+
+ /* Read MT6635 ID
+ * Address: ATOP CHIP_ID
+ * 0x02C[31:16]: hw_code
+ * 0x02C[15:0]: hw_ver
+ * Data:
+ * MT6635 E1 : read 0x02C = 0x66358A00
+ * MT6635 E2 : read 0x02C = 0x66358A10
+ * MT6635 E3 : read 0x02C = 0x66358A11
+ * Action: TOPSPI_RD
+ */
+ consys_spi_read(SYS_SPI_TOP, ATOP_CHIP_ID, &adie_id);
+ conn_hw_env.adie_hw_version = adie_id;
+ conn_hw_env.is_rc_mode = consys_is_rc_mode_enable();
+ pr_info("A-die CHIP_ID=0x%08x rc=%d\n", adie_id, conn_hw_env.is_rc_mode);
+
+ CONSYS_REG_WRITE(
+ CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_CHIP_ID,
+ adie_id);
+
+ /* Patch to FW from 7761(WF0_WRI_SX_CAL_MAP/WF1_WRI_SX_CAL_MAP)
+ * Address: ATOP WRI_CTR2 (0x064)
+ * Data: 32'h00007700
+ * Action: TOPSPI_WR
+ */
+ consys_spi_write(SYS_SPI_TOP, ATOP_WRI_CTR2, 0x00007700);
+
+ /* Set WF low power cmd as DBDC mode & legacy interface
+ * Address: ATOP SMCTK11 (0x0BC)
+ * Data: 32'h00000021
+ * Action: TOPSPI_WR
+ */
+ consys_spi_write(SYS_SPI_TOP, ATOP_SMCTK11, 0x00000021);
+
+ /* Update spi fm read extra bit setting
+ * Address:
+ * CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_EN (0x1800400C[15])
+ * CONN_RF_SPI_MST_REG_FM_CTRL_FM_RD_EXT_CNT (0x1800400C[7:0])
+ * Data:
+ * 0x1800400C[15] = 1'b0
+ * 0x1800400C[7:0] = 8'h0
+ * Action: write
+ */
+ CONSYS_REG_WRITE_MASK(
+ CONN_REG_RFSPI_ADDR + CONN_RF_SPI_MST_REG_FM_CTRL, 0x0, 0x80ff);
+
+ /* Update Thermal addr for 6635
+ * Address: CONN_TOP_THERM_CTL_THERM_AADDR (0x18002018)
+ * Data: 32'h50305A00
+ * Action: write
+ */
+ CONSYS_REG_WRITE(CONN_TOP_THERM_CTL_ADDR + CONN_TOP_THERM_CTL_THERM_AADDR, 0x50305A00);
+
+ /* Sub-task: read a-die efuse */
+ efuse_valid = connsys_a_die_efuse_read(0);
+
+ /* Set WF_PAD to HighZ
+ * Address: ATOP RG_ENCAL_WBTAC_IF_SW (0x070)
+ * Data: 32'h80000000
+ * Action: TOPSPI_WR
+ */
+ consys_spi_write(SYS_SPI_TOP, ATOP_RG_ENCAL_WBTAC_IF_SW, 0x80000000);
+
+ /* Disable CAL LDO
+ * Address: ATOP RG_WF0_TOP_01 (0x380)
+ * Data: 32'h000E8002
+ * Action: TOPSPI_WR
+ * Note: AC mode
+ */
+ consys_spi_write(SYS_SPI_TOP, ATOP_RG_WF0_TOP_01, 0x000e8002);
+
+ /* Disable CAL LDO
+ * Address: ATOP RG_WF1_TOP_01 (0x390)
+ * Data: 32'h000E8002
+ * Action: TOPSPI_WR
+ * Note: AC mode
+ */
+ consys_spi_write(SYS_SPI_TOP, ATOP_RG_WF1_TOP_01, 0x000e8002);
+
+ /* Increase XOBUF supply-V
+ * Address: ATOP RG_TOP_XTAL_01 (0xA18)
+ * Data: 32'hF6E8FFF5
+ * Action: TOPSPI_WR
+ */
+ consys_spi_write(SYS_SPI_TOP, ATOP_RG_TOP_XTAL_01, 0xF6E8FFF5);
+
+ /* Increase XOBUF supply-R for MT6635 E1
+ * Address: ATOP RG_TOP_XTAL_02 (0xA1C)
+ * Data:
+ * if(MT6635 E1) //rf_hw_ver = 0x8a00
+ * 32'hD5555FFF
+ * else
+ * 32'h0x55555FFF
+ * Action: TOPSPI_WR
+ */
+ if (adie_id == 0x66358a00) {
+ consys_spi_write(SYS_SPI_TOP, ATOP_RG_TOP_XTAL_02, 0xD5555FFF);
+ } else {
+ consys_spi_write(SYS_SPI_TOP, ATOP_RG_TOP_XTAL_02, 0x55555FFF);
+ }
+
+ /* Initial IR value for WF0 THADC
+ * Address: ATOP RG_WF0_BG (0x384)
+ * Data: 0x00002008
+ * Action: TOPSPI_WR
+ */
+ consys_spi_write(SYS_SPI_TOP, ATOP_RG_WF0_BG, 0x2008);
+
+ /* Initial IR value for WF1 THADC
+ * Address: ATOP RG_WF1_BG (0x394)
+ * Data: 0x00002008
+ * Action: TOPSPI_WR
+ */
+ consys_spi_write(SYS_SPI_TOP, ATOP_RG_WF1_BG, 0x2008);
+
+ /* if(A-die XTAL = 26MHz ) {
+ * CONN_WF_CTRL2 swtich to CONN mode
+ * }
+ */
+ /* Adress: 0x1000_5460[18:16] = 3'b001
+ * Action: write
+ * Note: MT6635 strap pinmux, set CONN_WF_CTRL2 as conn mode
+ */
+ if (adie_26m) {
+ CONSYS_REG_WRITE_MASK(GPIO_BASE_ADDR + GPIO_MODE22, 0x10000, 0x70000);
+ }
+ return 0;
+}
+
+int connsys_afe_wbg_cal(void)
+{
+ /* Default value update; 1: AFE WBG CR (if needed)
+ * note that this CR must be backuped and restored by command batch engine
+ * Address:
+ * CONN_AFE_CTL_RG_WBG_AFE_01(0x18003010) = 32'h00000000
+ * CONN_AFE_CTL_RG_WBG_RCK_01(0x18003018) = 32'h144B0160
+ * CONN_AFE_CTL_RG_WBG_GL1_01(0x18003040) = 32'h10990C13
+ * CONN_AFE_CTL_RG_WBG_GL5_01(0x18003100) = 32'h10990C13
+ * CONN_AFE_CTL_RG_WBG_BT_TX_03 (0x18003058) = 32'hCD258051
+ * CONN_AFE_CTL_RG_WBG_WF0_TX_03 (0x18003078) = 32'hC5258251
+ * CONN_AFE_CTL_RG_WBG_WF1_TX_03 (0x18003094) = 32'hC5258251
+ */
+ CONSYS_REG_WRITE(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_WBG_AFE_01,
+ 0x0);
+ CONSYS_REG_WRITE(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_WBG_RCK_01,
+ 0x144B0160);
+ CONSYS_REG_WRITE(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_WBG_GL1_01,
+ 0x10990C13);
+ CONSYS_REG_WRITE(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_WBG_GL5_01,
+ 0x10990C13);
+ CONSYS_REG_WRITE(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_WBG_BT_TX_03,
+ 0xCD258051);
+ CONSYS_REG_WRITE(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_WBG_WF0_TX_03,
+ 0xC5258251);
+ CONSYS_REG_WRITE(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_WBG_WF1_TX_03,
+ 0xC5258251);
+
+ /* AFE WBG CAL SEQ1 (RC calibration) */
+ /* AFE WBG RC calibration, set "AFE RG_WBG_EN_RCK" = 1
+ * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_RCK (0x18003000[0])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, 0x1);
+ udelay(60);
+ /* AFE WBG RC calibration */
+ /* AFE WBG RC calibration, set "AFE RG_WBG_EN_RCK" = 0
+ * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_RCK (0x18003000[0])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, 0x1);
+
+ /* AFE WBG CAL SEQ2 (TX calibration) */
+ /* AFE WBG TX calibration, set "AFE RG_WBG_EN_BPLL_UP" = 1
+ * Address: CONN_AFE_CTL_RG_DIG_EN_03_RG_WBG_EN_BPLL_UP (0x18003008[21])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_03, (0x1 << 21));
+ udelay(30);
+ /* AFE WBG TX calibration, set "AFE RG_WBG_EN_WPLL_UP" = 1
+ * Address: CONN_AFE_CTL_RG_DIG_EN_03_RG_WBG_EN_WPLL_UP (0x18003008[20])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_03, (0x1 << 20));
+ udelay(60);
+ /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_BT" = 1
+ * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_BT (0x18003000[21])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 21));
+ /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_WF0" = 1
+ * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_WF0 (0x18003000[20])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 20));
+ /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_WF1" = 1
+ * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_WF1 (0x18003000[19])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 19));
+ /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_WF2" = 1
+ * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_WF2 (0x18003000[18])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 18));
+ /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_WF3" = 1
+ * Addres: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_WF3 (0x18003000[17])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 17));
+ udelay(800);
+ /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_BT" = 0
+ * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_BT (0x18003000[21])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 21));
+ /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_WF0" = 0
+ * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_WF0 (0x18003000[20])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 20));
+ /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_WF1" = 0
+ * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_WF1 (0x18003000[19])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 19));
+ /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_WF2" = 0
+ * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_WF2 (0x18003000[18])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 18));
+ /* AFE WBG TX calibration, set "AFE RG_WBG_EN_TXCAL_WF3" = 0
+ * Address: CONN_AFE_CTL_RG_DIG_EN_01_RG_WBG_EN_TXCAL_WF3 (0x18003000[17])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_01, (0x1 << 17));
+ /* AFE WBG TX calibration, set "AFE RG_WBG_EN_BPLL_UP" = 0
+ * Address: CONN_AFE_CTL_RG_DIG_EN_03_RG_WBG_EN_BPLL_UP (0x18003008[21])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_03, (0x1 << 21));
+ /* AFE WBG TX calibration, set "AFE RG_WBG_EN_WPLL_UP" = 0
+ * Address:i CONN_AFE_CTL_RG_DIG_EN_03_RG_WBG_EN_WPLL_UP (0x18003008[20])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_03, (0x1 << 20));
+
+ /* Initial BT path if WF is in cal(need set this CR after WBG cal)
+ * Address: ATOP RG_ENCAL_WBTAC_IF_SW (0x070)
+ * Data: 32'h00000005
+ * Action: write
+ */
+ consys_spi_write(SYS_SPI_TOP, ATOP_RG_ENCAL_WBTAC_IF_SW, 0x5);
+ return 0;
+}
+
+int connsys_subsys_pll_initial(void)
+{
+ /* Check with DE, only 26M on mobile phone */
+
+ CONSYS_REG_WRITE_MASK(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_PLL_STB_TIME,
+ 0x314521, 0x7fff7fff);
+ CONSYS_REG_WRITE_MASK(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_02,
+ 0x4f, 0xcf);
+#if 0
+ switch (xtal_freq) {
+ case 0: /* SYS_XTAL_40000K */
+ CONSYS_REG_WRITE_MASK(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_PLL_STB_TIME,
+ 0x4bc7e4, 0x7fff7fff);
+ CONSYS_REG_WRITE_MASK(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_02,
+ 0x4e, 0xcf);
+ break;
+ case 1: /* SYS_XTAL_26000K */
+ CONSYS_REG_WRITE_MASK(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_PLL_STB_TIME,
+ 0x314521, 0x7fff7fff);
+ CONSYS_REG_WRITE_MASK(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_02,
+ 0x4f, 0xcf);
+ break;
+ case 2: /* SYS_XTAL_25000K */
+ CONSYS_REG_WRITE_MASK(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_PLL_STB_TIME,
+ 0x2f64ef, 0x7fff7fff);
+ CONSYS_REG_WRITE_MASK(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_02,
+ 0xcf, 0xcf);
+ break;
+ case 3: /* SYS_XTAL_24000K */
+ CONSYS_REG_WRITE_MASK(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_PLL_STB_TIME,
+ 0x2d74bc, 0x7fff7fff);
+ CONSYS_REG_WRITE_MASK(
+ CONN_AFE_CTL_BASE_ADDR + CONN_AFE_CTL_RG_DIG_EN_02,
+ 0x4e, 0xcf);
+ break;
+ }
+#endif
+ return 0;
+}
+
+// Special setting for BT low power
+static int connsys_bt_low_power_setting(bool bt_only)
+{
+ int hw_version;
+ const struct a_die_reg_config* config = NULL;
+ unsigned int ret, i;
+
+ hw_version = CONSYS_REG_READ(
+ CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_CHIP_ID);
+
+ if (bt_only) {
+ /* E1 */
+ if (hw_version == 0x66358A00) {
+ config = adie_e1_bt_only;
+ } else if (hw_version == 0x66358A10 || hw_version == 0x66358A11) {
+ config = adie_e2_bt_only;
+ } else
+ pr_err("[%s] wrong adie version (0x%08x)\n", __func__, hw_version);
+ } else {
+ if (hw_version == 0x66358A00) {
+ config = adie_e1_default;
+ } else if (hw_version == 0x66358A10 || hw_version == 0x66358A11) {
+ config = adie_e2_default;
+ } else
+ pr_err("[%s] wrong adie version (0x%08x)\n", __func__, hw_version);
+ }
+
+ if (config == NULL)
+ return -1;
+
+ consys_adie_top_ck_en_on(CONNSYS_ADIE_CTL_HOST_CONNINFRA);
+
+ /* Get semaphore before read */
+ if (consys_sema_acquire_timeout(CONN_SEMA_RFSPI_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) {
+ pr_err("[EFUSE READ] Require semaphore fail\n");
+ consys_adie_top_ck_en_off(CONNSYS_ADIE_CTL_HOST_CONNINFRA);
+ return -1;
+ }
+
+ for (i = 0; i < ADIE_CONFIG_NUM; i++) {
+ consys_spi_read_nolock(SYS_SPI_TOP, config[i].reg, &ret);
+ ret &= (~config[i].mask);
+ ret |= config[i].config;
+ consys_spi_write_nolock(SYS_SPI_TOP, config[i].reg, ret);
+ }
+
+ consys_sema_release(CONN_SEMA_RFSPI_INDEX);
+
+ consys_adie_top_ck_en_off(CONNSYS_ADIE_CTL_HOST_CONNINFRA);
+
+ return 0;
+}
+
+void connsys_debug_select_config(void)
+{
+#if 0
+ /* select conn_infra_cfg debug_sel to low pwoer related
+ * Address: 0x18001B00[2:0]
+ * Data: 3'b000
+ * Action: write
+ */
+ CONSYS_REG_WRITE_MASK(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_DBG_MUX_SEL,
+ 0x0, 0x7);
+#else
+ /* select conn_infra_cfg debug_sel to BPLL/WPLL status
+ * Address: 0x18001B00[2:0]
+ * Data: 3’b001
+ * Action: write
+ */
+ CONSYS_REG_WRITE_MASK(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_DBG_MUX_SEL,
+ 0x1, 0x7);
+ {
+ void __iomem *vir_addr = NULL;
+ vir_addr = ioremap_nocache(0x18006000, 0x1000);
+ if (vir_addr) {
+ /* wpll_rdy/bpll_rdy status dump
+ * 1.???Set 0x1800_604C = 0xFFFF_FFFF
+ * 2.???Set 0c1800_6058[1] = 0x1
+ * 3.???Set 0x1800_603C = 0x0000_0100
+ * 4.???Set 0x1800_601C = 0x0302_0100
+ * 5.???Set 0x1800_6020 = 0x0706_0504
+ * 6.???Set 0x1800_6024 = 0x0b0a_0908
+ * 7.???Set 0x1800_6028 = 0x0f0e_0d0c
+ * 8.???Set 0x1800_602C = 0x1312_1110
+ * 9.???Set 0x1800_6030 = 0x1716_1514
+ * 10.??Set 0x1800_6034 = 0x1b1a_1918
+ * 11.??Set 0x1800_6038 = 0x1f1e_1d1c
+ */
+ CONSYS_REG_WRITE(vir_addr + 0x004c, 0xffffffff);
+ CONSYS_SET_BIT(vir_addr + 0x0058, 0x1);
+ CONSYS_REG_WRITE(vir_addr + 0x3c, 0x00000100);
+ CONSYS_REG_WRITE(vir_addr + 0x1c, 0x03020100);
+ CONSYS_REG_WRITE(vir_addr + 0x20, 0x07060504);
+ CONSYS_REG_WRITE(vir_addr + 0x24, 0x0b0a0908);
+ CONSYS_REG_WRITE(vir_addr + 0x28, 0x0f0e0d0c);
+ CONSYS_REG_WRITE(vir_addr + 0x2c, 0x13121110);
+ CONSYS_REG_WRITE(vir_addr + 0x30, 0x17161514);
+ CONSYS_REG_WRITE(vir_addr + 0x34, 0x1b1a1918);
+ CONSYS_REG_WRITE(vir_addr + 0x38, 0x1f1e1d1c);
+ iounmap(vir_addr);
+ } else {
+ pr_err("remap 0x1800_6000 fail\n");
+ }
+ }
+#endif
+
+}
+
+
+int connsys_low_power_setting(unsigned int curr_status, unsigned int next_status)
+{
+ bool bt_only = false;
+
+ if ((next_status & (~(0x1 << CONNDRV_TYPE_BT))) == 0)
+ bt_only = true;
+
+ pr_info("[%s] current_status=%d bt_only = %d\n", __func__, curr_status, bt_only);
+
+ /* First subsys on */
+ if (curr_status == 0) {
+ /* Enable AP2CONN GALS Slave sleep protect en with conn_infra on2off/off2on & wfdma2conn
+ * sleep protect en
+ * Address: CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL_WFDMA2CONN_SLP_PROT_AP2CONN_EN_ENABLE
+ * CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL_CONN_INFRA_ON2OFF_SLP_PROT_AP2CONN_EN_ENABLE
+ * CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL_CONN_INFRA_OFF2ON_SLP_PROT_AP2CONN_EN_ENABLE (0x1806_0184[11:9])
+ * Data: 3'b111
+ * Action: write
+ */
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_SLP_PROT_CTRL,
+ 0xe00, 0xe00);
+
+ /* Unmask on2off/off2on slpprot_rdy enable checker @conn_infra off power off=> check slpprot_rdy = 1'b1 and go to sleep
+ * Address: CONN_INFRA_CFG_PWRCTRL0_CONN_INFRA_CFG_SLP_RDY_MASK (0x18001860[15:12])
+ * Data: 4'h0
+ * Action: write
+ */
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_PWRCTRL0,
+ 0x1000, 0xf000);
+
+ /* conn_infra low power setting */
+ if (!consys_is_rc_mode_enable()) {
+ /* Default mode (non-RC) */
+ /* Disable conn_top rc osc_ctrl_top
+ * Address: CONN_INFRA_CFG_RC_CTL_0_CONN_INFRA_OSC_RC_EN (0x18001834[7])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0, (0x1 << 7));
+ /* Legacy OSC control stable time
+ * Address:
+ * CONN_INFRA_CFG_OSC_CTL_0_XO_VCORE_RDY_STABLE_TIME (0x18001800[7:0]) = 8'd6
+ * CONN_INFRA_CFG_OSC_CTL_0_XO_INI_STABLE_TIME (0x18001800[15:8]) = 8'd7
+ * CONN_INFRA_CFG_OSC_CTL_0_XO_BG_STABLE_TIME (0x18001800[23:16]) = 8'd8
+ * Action: write
+ */
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_OSC_CTL_0, 0x080706, 0xffffff);
+ /* Legacy OSC control unmask conn_srcclkena_ack
+ * Address: CONN_INFRA_CFG_OSC_CTL_1_ACK_FOR_XO_STATE_MASK (0x18001804[16])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_OSC_CTL_1, (0x1 << 16));
+ } else {
+ /* RC mode */
+ /* GPS RC OSC control stable time
+ * Address:
+ * CONN_INFRA_CFG_RC_CTL_1_GPS_XO_VCORE_RDY_STABLE_TIME_0 (0x1800183C[7:0]) = 8'd6
+ * CONN_INFRA_CFG_RC_CTL_1_GPS_XO_INI_STABLE_TIME_0 (0x1800183C[15:8]) = 8'd7
+ * CONN_INFRA_CFG_RC_CTL_1_GPS_XO_BG_STABLE_TIME_0 (0x1800183C[23:16]) = 8'd8
+ * CONN_INFRA_CFG_RC_CTL_1_GPS_XO_VCORE_OFF_STABLE_TIME_0 (0x1800183C[31:24]) = 8'd2
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_1_GPS,
+ 0x02080706);
+
+ /* GPS RC OSC control unmask conn_srcclkena_ack
+ * Address: CONN_INFRA_CFG_RC_CTL_0_GPS_ACK_FOR_XO_STATE_MASK_0 (0x18001838[15])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0_GPS, (0x1 << 15));
+
+ /* BT RC OSC control stable time
+ * Address:
+ * CONN_INFRA_CFG_RC_CTL_1_BT_XO_VCORE_RDY_STABLE_TIME_1 (0x18001844[7:0]) = 8'd6
+ * CONN_INFRA_CFG_RC_CTL_1_BT_XO_INI_STABLE_TIME_1 (0x18001844[15:8]) = 8'd7
+ * CONN_INFRA_CFG_RC_CTL_1_BT_XO_BG_STABLE_TIME_1 (0x18001844[23:16]) = 8'd8
+ * CONN_INFRA_CFG_RC_CTL_1_BT_XO_VCORE_OFF_STABLE_TIME_1 (0x18001844[31:24]) = 8'd2
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_1_BT,
+ 0x02080706);
+
+ /* BT RC OSC control unmask conn_srcclkena_ack
+ * Address: CONN_INFRA_CFG_RC_CTL_0_BT_ACK_FOR_XO_STATE_MASK_1 (0x18001840[15])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0_BT, (0x1 << 15));
+
+ /* WF RC OSC control stable time
+ * Address:
+ * CONN_INFRA_CFG_RC_CTL_1_WF_XO_VCORE_RDY_STABLE_TIME_2 (0x1800184C[7:0]) = 8'd6
+ * CONN_INFRA_CFG_RC_CTL_1_WF_XO_INI_STABLE_TIME_2 (0x1800184C[15:8]) = 8'd7
+ * CONN_INFRA_CFG_RC_CTL_1_WF_XO_BG_STABLE_TIME_2 (0x1800184C[23:16]) = 8'd8
+ * CONN_INFRA_CFG_RC_CTL_1_WF_XO_VCORE_OFF_STABLE_TIME_2 (0x1800184C[31:24])= 8'd2
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_1_WF,
+ 0x02080706);
+
+ /* WF RC OSC control unmask conn_srcclkena_ack
+ * Address: CONN_INFRA_CFG_RC_CTL_0_WF_ACK_FOR_XO_STATE_MASK_2 (0x18001848[15])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0_WF, (0x1 << 15));
+
+ /* TOP RC OSC control stable time
+ * Address:
+ * CONN_INFRA_CFG_RC_CTL_1_TOP_XO_VCORE_RDY_STABLE_TIME_3 (0x18001854[7:0]) = 8'd6
+ * CONN_INFRA_CFG_RC_CTL_1_TOP_XO_INI_STABLE_TIME_3 (0x18001854[15:8]) = 8'd7
+ * CONN_INFRA_CFG_RC_CTL_1_TOP_XO_BG_STABLE_TIME_3 (0x18001854[23:16]) = 8'd8
+ * CONN_INFRA_CFG_RC_CTL_1_TOP_XO_VCORE_OFF_STABLE_TIME_3 (0x18001854[31:24]) = 8'd2
+ * Action: write
+ */
+ CONSYS_REG_WRITE(
+ CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_1_TOP,
+ 0x02080706);
+
+ /* TOP RC OSC control unmask conn_srcclkena_ack
+ * Address: CONN_INFRA_CFG_RC_CTL_0_TOP_ACK_FOR_XO_STATE_MASK_3 (0x18001850[15])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(
+ CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0_TOP,
+ (0x1 << 15));
+
+ /* Enable conn_top rc osc_ctrl_gps
+ * Address: CONN_INFRA_CFG_RC_CTL_0_GPSSYS_OSC_RC_EN (0x18001834[4])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(
+ CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0,
+ (0x1 << 4));
+
+ /* Enable conn_top rc osc_ctrl_bt
+ * Address: CONN_INFRA_CFG_RC_CTL_0_BTSYS_OSC_RC_EN (0x18001834[5])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(
+ CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0,
+ (0x1 << 5));
+
+ /* Enable conn_top rc osc_ctrl_wf
+ * Address: CONN_INFRA_CFG_RC_CTL_0_WFSYS_OSC_RC_EN (0x18001834[6])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(
+ CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0,
+ (0x1 << 6));
+
+ /* set conn_srcclkena control by conn_infra_emi_ctl
+ * Address: CONN_INFRA_CFG_EMI_CTL_0_CONN_EMI_RC_EN (0x18001C00[0])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(
+ CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_EMI_CTL_0, 0x1);
+
+ /* Disable legacy osc control
+ * Address: CONN_INFRA_CFG_RC_CTL_0_OSC_LEGACY_EN (0x18001834[0])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(
+ CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_RC_CTL_0,
+ 0x1);
+ }
+ /* conn2ap sleep protect release bypass ddr_en_ack check
+ * Address: CONN_INFRA_CFG_EMI_CTL_0_EMI_SLPPROT_BP_DDR_EN (0x18001C00[18])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_EMI_CTL_0, 0x40000);
+
+ /* Enable ddr_en timeout, timeout value = 1023 T (Bus clock)
+ * Address: CONN_INFRA_CFG_EMI_CTL_0_DDR_CNT_LIMIT (0x18001C00[14:4])
+ * Data: 11'd1023
+ * Action: write
+ */
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_EMI_CTL_0,
+ 0x3ff0, 0x7ff0);
+
+ /* A-die clock buffer setting for BT only and others mode */
+ connsys_bt_low_power_setting(bt_only);
+
+ /* Enable conn_infra_clkgen BPLL source (hw workaround)
+ * Address: CONN_INFRA_CFG_CKGEN_BUS_RFSPI_DIV_EN (0x1800_1A00[28])
+ * Data: 1'b1
+ * Action: write
+ */
+ CONSYS_SET_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_CKGEN_BUS, (0x1 << 28));
+
+ /* Bus light security
+ * Address:
+ * CONN_INFRA_CFG_LIGHT_SECURITY_CTRL_R_CONN_INFRA_BT_PAIR1_EN
+ * CONN_INFRA_CFG_LIGHT_SECURITY_CTRL_R_CONN_INFRA_BT_PAIR0_EN
+ * CONN_INFRA_CFG_LIGHT_SECURITY_CTRL_R_CONN_INFRA_WF_PAIR1_EN
+ * CONN_INFRA_CFG_LIGHT_SECURITY_CTRL_R_CONN_INFRA_WF_PAIR0_EN
+ * 0x1800_10F0[4][3][1][0] = 6'h1B
+ * Action: write
+ */
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_LIGHT_SECURITY_CTRL,
+ ((0x1 << 4) | (0x1 << 3) | (0x1 << 1) | 0x1),
+ ((0x1 << 4) | (0x1 << 3) | (0x1 << 1) | 0x1));
+
+ /* if(BT on or GPS on)
+ * Conn_infrapower on bgfsys on (woraround)
+ * Address:
+ * 0x18000008[31:16] = 16'h4254 (key)
+ * CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_CTL[7] (0x18000008[7]) = 1'b1
+ * Action: write
+ */
+ /* Check with DE, write 1 -> 1 is ok */
+ if ((next_status & ((0x1 << CONNDRV_TYPE_BT) | (0x1 << CONNDRV_TYPE_GPS))) != 0) {
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_INFRA_RGU_ADDR + CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_CTL,
+ ((0x42540000) | (0x1 << 7)), 0xffff0080);
+ }
+
+ consys_config_setup();
+ connsys_debug_select_config();
+ /*
+ * set 0x1800_0090 = 4'h6
+ */
+ CONSYS_REG_WRITE(CON_REG_INFRA_RGU_ADDR + CONN_INFRA_RGU_DEBUG_SEL, 0x6);
+
+ /******************************************************/
+ /* power ctrl : 0x1800_1860[9] = 1'b1 */
+ /******************************************************/
+ CONSYS_SET_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_PWRCTRL0, 0x200);
+
+ /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+ /* !!!!!!!!!!!!!!!!!!!!!! CANNOT add code after HERE!!!!!!!!!!!!!!!!!!!!!!!!!! */
+ /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+ /* Disable conn_infra bus clock sw control ==> conn_infra bus clock hw control
+ * Address: CONN_INFRA_CFG_CKGEN_BUS_HCLK_CKSEL_SWCTL (0x1800_1A00[23])
+ * Data: 1'b0
+ * Action: write
+ */
+ CONSYS_CLR_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_CKGEN_BUS, (0x1 << 23));
+
+ /* Conn_infra HW_CONTROL => conn_infra enter dsleep mode
+ * Address: CONN_INFRA_CFG_PWRCTRL0_HW_CONTROL (0x1800_1860[0])
+ * Data: 1'b1
+ * Action: write
+ * Note: enable conn_infra off domain as HW control
+ */
+ CONSYS_SET_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_PWRCTRL0, 0x1);
+ } else {
+ /* for subsys on/off, only update BT low power setting */
+ connsys_bt_low_power_setting(bt_only);
+
+ /* Workaround */
+ if ((next_status & ((0x1 << CONNDRV_TYPE_BT) | (0x1 << CONNDRV_TYPE_GPS))) != 0) {
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_INFRA_RGU_ADDR + CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_CTL,
+ ((0x42540000) | (0x1 << 7)), 0xffff0080);
+ } else {
+ CONSYS_REG_WRITE_MASK(
+ CON_REG_INFRA_RGU_ADDR + CONN_INFRA_RGU_BGFSYS_ON_TOP_PWR_CTL,
+ 0x42540000, 0xffff0080);
+ }
+
+ consys_config_setup();
+ connsys_debug_select_config();
+ }
+ /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+ /* !!!!!!!!!!!!!!!!!!!!!!!!CANNOT add code HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+ /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+ return 0;
+}
+
+static int consys_sema_acquire(enum conn_semaphore_type index)
+{
+ if (CONSYS_REG_READ_BIT(
+ CONN_REG_SEMAPHORE_ADDR + CONN_SEMAPHORE_M2_OWN_STA + index*4, 0x1) == 0x1) {
+ return CONN_SEMA_GET_SUCCESS;
+ } else {
+ return CONN_SEMA_GET_FAIL;
+ }
+}
+
+int consys_sema_acquire_timeout(enum conn_semaphore_type index, unsigned int usec)
+{
+ int i, check, r1, r2;
+
+ /* debug for bus hang */
+ if (consys_reg_mng_reg_readable() == 0) {
+ check = consys_reg_mng_is_bus_hang();
+ if (check > 0) {
+ r1 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_DBG_DUMMY_3);
+ r2 = CONSYS_REG_READ(CON_REG_HOST_CSR_ADDR + CONN_HOST_CSR_TOP_CONN_INFRA_WAKEPU_TOP_CONN_INFRA_WAKEPU_TOP);
+ pr_info("[%s] check=[%d] r1=[0x%x] r2=[0x%x]", __func__, check, r1, r2);
+ consys_reg_mng_dump_bus_status();
+ consys_reg_mng_dump_cpupcr(CONN_DUMP_CPUPCR_TYPE_ALL, 10, 200);
+ return CONN_SEMA_GET_FAIL;
+ }
+ }
+
+ for (i = 0; i < usec; i++) {
+ if (consys_sema_acquire(index) == CONN_SEMA_GET_SUCCESS) {
+ return CONN_SEMA_GET_SUCCESS;
+ }
+ udelay(1);
+ }
+
+ pr_err("Get semaphore 0x%x timeout, dump status:\n", index);
+ pr_err("M0:[0x%x] M1:[0x%x] M2:[0x%x] M3:[0x%x]\n",
+ CONSYS_REG_READ(CONN_REG_SEMAPHORE_ADDR + CONN_SEMA_OWN_BY_M0_STA_REP),
+ CONSYS_REG_READ(CONN_REG_SEMAPHORE_ADDR + CONN_SEMA_OWN_BY_M1_STA_REP),
+ CONSYS_REG_READ(CONN_REG_SEMAPHORE_ADDR + CONN_SEMA_OWN_BY_M2_STA_REP),
+ CONSYS_REG_READ(CONN_REG_SEMAPHORE_ADDR + CONN_SEMA_OWN_BY_M3_STA_REP));
+ consys_reg_mng_dump_cpupcr(CONN_DUMP_CPUPCR_TYPE_ALL, 10, 200);
+
+ return CONN_SEMA_GET_FAIL;
+}
+
+void consys_sema_release(enum conn_semaphore_type index)
+{
+ CONSYS_REG_WRITE(
+ (CONN_REG_SEMAPHORE_ADDR + CONN_SEMAPHORE_M2_OWN_REL + index*4), 0x1);
+}
+
+struct spi_op {
+ unsigned int busy_cr;
+ unsigned int polling_bit;
+ unsigned int addr_cr;
+ unsigned int read_addr_format;
+ unsigned int write_addr_format;
+ unsigned int write_data_cr;
+ unsigned int read_data_cr;
+ unsigned int read_data_mask;
+};
+
+static const struct spi_op spi_op_array[SYS_SPI_MAX] = {
+ /* SYS_SPI_WF1 */
+ {
+ CONN_RF_SPI_MST_REG_SPI_STA, 1,
+ CONN_RF_SPI_MST_REG_SPI_WF_ADDR, 0x00001000, 0x00000000,
+ CONN_RF_SPI_MST_REG_SPI_WF_WDAT,
+ CONN_RF_SPI_MST_REG_SPI_WF_RDAT, 0xffffffff
+ },
+ /* SYS_SPI_WF */
+ {
+ CONN_RF_SPI_MST_REG_SPI_STA, 1,
+ CONN_RF_SPI_MST_REG_SPI_WF_ADDR, 0x00003000, 0x00002000,
+ CONN_RF_SPI_MST_REG_SPI_WF_WDAT,
+ CONN_RF_SPI_MST_REG_SPI_WF_RDAT, 0xffffffff
+ },
+ /* SYS_SPI_BT */
+ {
+ CONN_RF_SPI_MST_REG_SPI_STA, 2,
+ CONN_RF_SPI_MST_REG_SPI_BT_ADDR, 0x00005000, 0x00004000,
+ CONN_RF_SPI_MST_REG_SPI_BT_WDAT,
+ CONN_RF_SPI_MST_REG_SPI_BT_RDAT, 0x000000ff
+ },
+ /* SYS_SPI_FM */
+ {
+ CONN_RF_SPI_MST_REG_SPI_STA, 3,
+ CONN_RF_SPI_MST_REG_SPI_FM_ADDR, 0x00007000, 0x00006000,
+ CONN_RF_SPI_MST_REG_SPI_FM_WDAT,
+ CONN_RF_SPI_MST_REG_SPI_FM_RDAT, 0x0000ffff
+ },
+ /* SYS_SPI_GPS */
+ {
+ CONN_RF_SPI_MST_REG_SPI_STA, 4,
+ CONN_RF_SPI_MST_REG_SPI_GPS_GPS_ADDR, 0x00009000, 0x00008000,
+ CONN_RF_SPI_MST_REG_SPI_GPS_GPS_WDAT,
+ CONN_RF_SPI_MST_REG_SPI_GPS_GPS_RDAT, 0x0000ffff
+ },
+ /* SYS_SPI_TOP */
+ {
+ CONN_RF_SPI_MST_REG_SPI_STA, 5,
+ CONN_RF_SPI_MST_REG_SPI_TOP_ADDR, 0x0000b000, 0x0000a000,
+ CONN_RF_SPI_MST_REG_SPI_TOP_WDAT,
+ CONN_RF_SPI_MST_REG_SPI_TOP_RDAT, 0xffffffff
+ },
+ /* SYS_SPI_WF2 */
+ {
+ CONN_RF_SPI_MST_REG_SPI_STA, 1,
+ CONN_RF_SPI_MST_REG_SPI_WF_ADDR, 0x0000d000, 0x0000c000,
+ CONN_RF_SPI_MST_REG_SPI_WF_WDAT,
+ CONN_RF_SPI_MST_REG_SPI_WF_RDAT, 0xffffffff
+ },
+ /* SYS_SPI_WF3 */
+ {
+ CONN_RF_SPI_MST_REG_SPI_STA, 1,
+ CONN_RF_SPI_MST_REG_SPI_WF_ADDR, 0x0000f000, 0x0000e000,
+ CONN_RF_SPI_MST_REG_SPI_WF_WDAT,
+ CONN_RF_SPI_MST_REG_SPI_WF_RDAT, 0xffffffff
+ },
+};
+
+static int consys_spi_read_nolock(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data)
+{
+ /* Read action:
+ * 1. Polling busy_cr[polling_bit] should be 0
+ * 2. Write addr_cr with data being {read_addr_format | addr[11:0]}
+ * 3. Trigger SPI by writing write_data_cr as 0
+ * 4. Polling busy_cr[polling_bit] as 0
+ * 5. Read data_cr[data_mask]
+ */
+ int check = 0;
+ const struct spi_op* op = &spi_op_array[subsystem];
+
+ if (!data) {
+ pr_err("[%s] invalid data ptr\n", __func__);
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+
+ CONSYS_REG_BIT_POLLING(
+ CONN_REG_RFSPI_ADDR + op->busy_cr,
+ op->polling_bit, 0, 100, 50, check);
+ if (check != 0) {
+ pr_err("[%s][%d][STEP1] polling 0x%08x bit %d fail. Value=0x%08x\n",
+ __func__, subsystem, CONN_REG_RFSPI_ADDR + op->busy_cr,
+ op->polling_bit,
+ CONSYS_REG_READ(CONN_REG_RFSPI_ADDR + op->busy_cr));
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+
+ CONSYS_REG_WRITE(
+ CONN_REG_RFSPI_ADDR + op->addr_cr,
+ (op->read_addr_format | addr));
+
+ CONSYS_REG_WRITE(CONN_REG_RFSPI_ADDR + op->write_data_cr, 0);
+
+ check = 0;
+ CONSYS_REG_BIT_POLLING(
+ CONN_REG_RFSPI_ADDR + op->busy_cr,
+ op->polling_bit, 0, 100, 50, check);
+ if (check != 0) {
+ pr_err("[%s][%d][STEP4] polling 0x%08x bit %d fail. Value=0x%08x\n",
+ __func__, subsystem, CONN_REG_RFSPI_ADDR + op->busy_cr,
+ op->polling_bit,
+ CONSYS_REG_READ(CONN_REG_RFSPI_ADDR + op->busy_cr));
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+
+ check = CONSYS_REG_READ_BIT(CONN_REG_RFSPI_ADDR + op->read_data_cr, op->read_data_mask);
+ *data = check;
+
+ return 0;
+}
+
+int consys_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data)
+{
+ int ret;
+
+ /* Get semaphore before read */
+ if (consys_sema_acquire_timeout(CONN_SEMA_RFSPI_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) {
+ pr_err("[SPI READ] Require semaphore fail\n");
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+
+ ret = consys_spi_read_nolock(subsystem, addr, data);
+
+ consys_sema_release(CONN_SEMA_RFSPI_INDEX);
+
+ return ret;
+}
+
+static int consys_spi_write_nolock(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data)
+{
+ int check = 0;
+ const struct spi_op* op = &spi_op_array[subsystem];
+
+ /* Write action:
+ * 1. Wait busy_cr[polling_bit] as 0
+ * 2. Write addr_cr with data being {write_addr_format | addr[11:0]
+ * 3. Write write_data_cr ad data
+ * 4. Wait busy_cr[polling_bit] as 0
+ */
+ CONSYS_REG_BIT_POLLING(
+ CONN_REG_RFSPI_ADDR + op->busy_cr,
+ op->polling_bit, 0, 100, 50, check);
+ if (check != 0) {
+ pr_err("[%s][%d][STEP1] polling 0x%08x bit %d fail. Value=0x%08x\n",
+ __func__, subsystem, CONN_REG_RFSPI_ADDR + op->busy_cr,
+ op->polling_bit,
+ CONSYS_REG_READ(CONN_REG_RFSPI_ADDR + op->busy_cr));
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+
+ CONSYS_REG_WRITE(CONN_REG_RFSPI_ADDR + op->addr_cr, (op->write_addr_format | addr));
+
+ CONSYS_REG_WRITE(CONN_REG_RFSPI_ADDR + op->write_data_cr, data);
+
+ check = 0;
+ CONSYS_REG_BIT_POLLING(
+ CONN_REG_RFSPI_ADDR + op->busy_cr,
+ op->polling_bit, 0, 100, 50, check);
+ if (check != 0) {
+ pr_err("[%s][%d][STEP4] polling 0x%08x bit %d fail. Value=0x%08x\n",
+ __func__, subsystem, CONN_REG_RFSPI_ADDR + op->busy_cr,
+ op->polling_bit,
+ CONSYS_REG_READ(CONN_REG_RFSPI_ADDR + op->busy_cr));
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+
+ return 0;
+}
+
+
+int consys_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data)
+{
+ int ret;
+
+ /* Get semaphore before read */
+ if (consys_sema_acquire_timeout(CONN_SEMA_RFSPI_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) {
+ pr_err("[SPI WRITE] Require semaphore fail\n");
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+
+ ret = consys_spi_write_nolock(subsystem, addr, data);
+
+ consys_sema_release(CONN_SEMA_RFSPI_INDEX);
+ return ret;
+}
+
+int consys_spi_write_offset_range(
+ enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int value,
+ unsigned int reg_offset, unsigned int value_offset, unsigned int size)
+{
+ if (consys_sema_acquire_timeout(CONN_SEMA_RFSPI_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) {
+ pr_err("[SPI READ] Require semaphore fail\n");
+ return CONNINFRA_SPI_OP_FAIL;
+ }
+ consys_spi_write_offset_range_nolock(
+ subsystem, addr, value, reg_offset, value_offset, size);
+
+ consys_sema_release(CONN_SEMA_RFSPI_INDEX);
+ return 0;
+}
+
+static void consys_spi_write_offset_range_nolock(
+ enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int value,
+ unsigned int reg_offset, unsigned int value_offset, unsigned int size)
+{
+ unsigned int data = 0, data2;
+ unsigned int reg_mask;
+ int ret;
+
+ pr_info("[%s][%s] addr=0x%04x value=0x%08x reg_offset=%d value_offset=%d size=%d",
+ __func__, g_spi_system_name[subsystem], addr, value, reg_offset, value_offset, size);
+ value = (value >> value_offset);
+ value = GET_BIT_RANGE(value, size, 0);
+ value = (value << reg_offset);
+ ret = consys_spi_read_nolock(subsystem, addr, &data);
+ if (ret) {
+ pr_err("[%s][%s] Get 0x%08x error, ret=%d",
+ __func__, g_spi_system_name[subsystem], addr, ret);
+ return;
+ }
+ reg_mask = GENMASK(reg_offset + size - 1, reg_offset);
+ data2 = data & (~reg_mask);
+ data2 = (data2 | value);
+ consys_spi_write_nolock(subsystem, addr, data2);
+ pr_info("[%s][%s] Write CR:0x%08x from 0x%08x to 0x%08x",
+ __func__, g_spi_system_name[subsystem],
+ addr, data, data2);
+}
+
+
+static int consys_adie_top_ck_en_ctrl(bool on)
+{
+ int check = 0;
+
+ if (on)
+ CONSYS_SET_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_ADIE_CTL, (0x1 << 1));
+ else
+ CONSYS_CLR_BIT(CON_REG_INFRA_CFG_ADDR + CONN_INFRA_CFG_ADIE_CTL, (0x1 << 1));
+
+ CONSYS_REG_BIT_POLLING(
+ CON_REG_WT_SPL_CTL_ADDR + CONN_WTSLP_CTL_REG_WB_STA,
+ 26, 0, 100, 5, check);
+ if (check == -1) {
+ pr_err("[%s] op=%d fail\n", __func__, on);
+ }
+ return check;
+
+}
+
+int consys_adie_top_ck_en_on(enum consys_adie_ctl_type type)
+{
+ unsigned int status;
+ int ret;
+
+ if (type >= CONNSYS_ADIE_CTL_MAX) {
+ pr_err("[%s] invalid parameter(%d)\n", __func__, type);
+ return -1;
+ }
+
+ if (consys_sema_acquire_timeout(CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) {
+ pr_err("[%s][%s] acquire semaphore (%d) timeout\n",
+ __func__, gAdieCtrlType[type], CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX);
+ return -1;
+ }
+
+ status = CONSYS_REG_READ(
+ CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_TOP_CK_EN_CTRL);
+ if ((status & CONN_INFRA_SYSRAM__A_DIE_DIG_TOP_CK_EN_MASK) == 0) {
+ ret = consys_adie_top_ck_en_ctrl(true);
+ }
+ CONSYS_SET_BIT(
+ CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_TOP_CK_EN_CTRL, (0x1 << type));
+
+ consys_sema_release(CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX);
+ return 0;
+}
+
+int consys_adie_top_ck_en_off(enum consys_adie_ctl_type type)
+{
+ unsigned int status;
+ int ret = 0;
+
+ if (type >= CONNSYS_ADIE_CTL_MAX) {
+ pr_err("[%s] invalid parameter(%d)\n", __func__, type);
+ return -1;
+ }
+
+ if (consys_sema_acquire_timeout(CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) {
+ pr_err("[%s][%s] acquire semaphoreaore (%d) timeout\n",
+ __func__, gAdieCtrlType[type], CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX);
+ return -1;
+ }
+
+ status = CONSYS_REG_READ(
+ CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_TOP_CK_EN_CTRL);
+ if ((status & (0x1 << type)) == 0) {
+ pr_warn("[%s][%s] already off\n", __func__, gAdieCtrlType[type]);
+ } else {
+ CONSYS_CLR_BIT(
+ CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_TOP_CK_EN_CTRL, (0x1 << type));
+
+ status = CONSYS_REG_READ(
+ CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_A_DIE_TOP_CK_EN_CTRL);
+ if (0 == (status & CONN_INFRA_SYSRAM__A_DIE_DIG_TOP_CK_EN_MASK)) {
+ ret = consys_adie_top_ck_en_ctrl(false);
+ }
+ }
+
+ consys_sema_release(CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX);
+ return ret;
+}
+
+int consys_spi_clock_switch(enum connsys_spi_speed_type type)
+{
+#define MAX_SPI_CLOCK_SWITCH_COUNT 100
+ unsigned int status;
+ unsigned int counter = 0;
+ int ret = 0;
+
+ /* Get semaphore before read */
+ if (consys_sema_acquire_timeout(CONN_SEMA_RFSPI_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) {
+ pr_err("[SPI CLOCK SWITCH] Require semaphore fail\n");
+ return -1;
+ }
+
+ if (type == CONNSYS_SPI_SPEED_26M) {
+ CONSYS_REG_WRITE_MASK(
+ CONN_REG_RFSPI_ADDR + CONN_RF_SPI_MST_REG_SPI_CRTL,
+ 0x0, 0x5);
+ status = CONSYS_REG_READ(CONN_REG_RFSPI_ADDR + CONN_RF_SPI_MST_REG_SPI_CRTL) & 0x18;
+ while (status != 0x8 && counter < MAX_SPI_CLOCK_SWITCH_COUNT) {
+ udelay(10);
+ status = CONSYS_REG_READ(CONN_REG_RFSPI_ADDR + CONN_RF_SPI_MST_REG_SPI_CRTL) & 0x18;
+ counter++;
+ }
+ if (counter == MAX_SPI_CLOCK_SWITCH_COUNT) {
+ pr_err("[%s] switch to 26M fail\n", __func__);
+ ret = -1;
+ }
+ } else if (type == CONNSYS_SPI_SPEED_64M) {
+ CONSYS_REG_WRITE_MASK(
+ CONN_REG_RFSPI_ADDR + CONN_RF_SPI_MST_REG_SPI_CRTL, 0x5, 0x5);
+ status = CONSYS_REG_READ(CONN_REG_RFSPI_ADDR + CONN_RF_SPI_MST_REG_SPI_CRTL) & 0x18;
+ while (status != 0x10 && counter < MAX_SPI_CLOCK_SWITCH_COUNT) {
+ udelay(10);
+ status = CONSYS_REG_READ(CONN_REG_RFSPI_ADDR + CONN_RF_SPI_MST_REG_SPI_CRTL) & 0x18;
+ counter++;
+ }
+ if (counter == MAX_SPI_CLOCK_SWITCH_COUNT) {
+ pr_err("[%s] switch to 64M fail\n", __func__);
+ ret = -1;
+ }
+ } else {
+ ret = -1;
+ pr_err("[%s] wrong parameter %d\n", __func__, type);
+ }
+
+ consys_sema_release(CONN_SEMA_RFSPI_INDEX);
+
+ return ret;
+}
+
+int consys_subsys_status_update(bool on, int radio)
+{
+ if (radio < CONNDRV_TYPE_BT || radio > CONNDRV_TYPE_WIFI) {
+ pr_err("[%s] wrong parameter: %d\n", __func__, radio);
+ return -1;
+ }
+
+ if (consys_sema_acquire_timeout(CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX, CONN_SEMA_TIMEOUT) == CONN_SEMA_GET_FAIL) {
+ pr_err("[%s] acquire semaphore (%d) timeout\n",
+ __func__, CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX);
+ return -1;
+ }
+
+ if (on) {
+ CONSYS_SET_BIT(
+ CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_RADIO_STATUS,
+ (0x1 << radio));
+ } else {
+ CONSYS_CLR_BIT(
+ CONN_INFRA_SYSRAM_BASE_ADDR + CONN_INFRA_SYSRAM_SW_CR_RADIO_STATUS,
+ (0x1 << radio));
+ }
+
+ consys_sema_release(CONN_SEMA_CONN_INFRA_COMMON_SYSRAM_INDEX);
+ return 0;
+}
+
+
+bool consys_is_rc_mode_enable(void)
+{
+ int ret;
+
+ ret = CONSYS_REG_READ_BIT(CON_REG_SPM_BASE_ADDR + SPM_RC_CENTRAL_CFG1, 0x1);
+
+ return ret;
+}
+
+void consys_config_setup(void)
+{
+ /* To access CR in conninfra off domain, Conninfra should be on state */
+ /* Enable conn_infra bus hang detect function
+ * Address: 0x1800_F000
+ * Data: 32'h32C8_001C
+ * Action: write
+ */
+ CONSYS_REG_WRITE(CONN_DEBUG_CTRL_ADDR + CONN_DEBUG_CTRL_REG_OFFSET, 0x32c8001c);
+}
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/pmic_mng.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/pmic_mng.c
new file mode 100755
index 0000000..39d7865
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/platform/pmic_mng.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#include "consys_hw.h"
+#include "pmic_mng.h"
+#include "osal.h"
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+const struct consys_platform_pmic_ops* consys_platform_pmic_ops = NULL;
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+int pmic_mng_init(
+ struct platform_device *pdev,
+ struct conninfra_dev_cb* dev_cb,
+ const struct conninfra_plat_data* plat_data)
+{
+ if (consys_platform_pmic_ops == NULL) {
+ consys_platform_pmic_ops =
+ (const struct consys_platform_pmic_ops*)plat_data->platform_pmic_ops;
+ }
+
+ if (consys_platform_pmic_ops && consys_platform_pmic_ops->consys_pmic_get_from_dts)
+ consys_platform_pmic_ops->consys_pmic_get_from_dts(pdev, dev_cb);
+
+ return 0;
+}
+
+int pmic_mng_deinit(void)
+{
+ return 0;
+}
+
+int pmic_mng_common_power_ctrl(unsigned int enable)
+{
+ int ret = 0;
+ if (consys_platform_pmic_ops &&
+ consys_platform_pmic_ops->consys_pmic_common_power_ctrl)
+ ret = consys_platform_pmic_ops->consys_pmic_common_power_ctrl(enable);
+ return ret;
+}
+
+int pmic_mng_wifi_power_ctrl(unsigned int enable)
+{
+ int ret = 0;
+ if (consys_platform_pmic_ops &&
+ consys_platform_pmic_ops->consys_pmic_wifi_power_ctrl)
+ ret = consys_platform_pmic_ops->consys_pmic_wifi_power_ctrl(enable);
+ return ret;
+
+}
+
+int pmic_mng_bt_power_ctrl(unsigned int enable)
+{
+ int ret = 0;
+ if (consys_platform_pmic_ops &&
+ consys_platform_pmic_ops->consys_pmic_bt_power_ctrl)
+ ret = consys_platform_pmic_ops->consys_pmic_bt_power_ctrl(enable);
+ return ret;
+}
+
+int pmic_mng_gps_power_ctrl(unsigned int enable)
+{
+ int ret = 0;
+ if (consys_platform_pmic_ops &&
+ consys_platform_pmic_ops->consys_pmic_gps_power_ctrl)
+ ret = consys_platform_pmic_ops->consys_pmic_gps_power_ctrl(enable);
+ return ret;
+}
+
+int pmic_mng_fm_power_ctrl(unsigned int enable)
+{
+ int ret = 0;
+ if (consys_platform_pmic_ops &&
+ consys_platform_pmic_ops->consys_pmic_fm_power_ctrl)
+ ret = consys_platform_pmic_ops->consys_pmic_fm_power_ctrl(enable);
+ return ret;
+}
+
+
+int pmic_mng_event_cb(unsigned int id, unsigned int event)
+{
+ if (consys_platform_pmic_ops &&
+ consys_platform_pmic_ops->consys_pmic_event_notifier)
+ consys_platform_pmic_ops->consys_pmic_event_notifier(id, event);
+ return 0;
+}
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/src/conninfra.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/src/conninfra.c
new file mode 100755
index 0000000..a4cf074
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/src/conninfra.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#define pr_fmt(fmt) KBUILD_MODNAME "@(%s:%d) " fmt, __func__, __LINE__
+
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/module.h>
+#include <linux/fb.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include "conninfra.h"
+#include "emi_mng.h"
+#include "conninfra_core.h"
+#include "consys_hw.h"
+
+#include <linux/ratelimit.h>
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+#define CONNINFRA_RST_RATE_LIMIT 0
+
+#if CONNINFRA_RST_RATE_LIMIT
+DEFINE_RATELIMIT_STATE(g_rs, HZ, 1);
+
+#define DUMP_LOG() if (__ratelimit(&g_rs)) \
+ pr_info("rst is ongoing")
+
+#else
+#define DUMP_LOG()
+#endif
+
+struct conninfra_rst_data {
+ struct work_struct rst_worker;
+ enum consys_drv_type drv;
+ char *reason;
+};
+
+struct conninfra_rst_data rst_data;
+
+int conninfra_get_clock_schematic(void)
+{
+ return consys_hw_get_clock_schematic();
+}
+EXPORT_SYMBOL(conninfra_get_clock_schematic);
+
+void conninfra_get_phy_addr(unsigned int *addr, unsigned int *size)
+{
+ phys_addr_t base;
+
+ conninfra_get_emi_phy_addr(CONNSYS_EMI_FW_WFDMA, &base, size);
+ if (addr)
+ *addr = (unsigned int)base;
+ return;
+}
+EXPORT_SYMBOL(conninfra_get_phy_addr);
+
+void conninfra_get_emi_phy_addr(enum connsys_emi_type type, phys_addr_t* base, unsigned int *size)
+{
+ struct consys_emi_addr_info* addr_info = emi_mng_get_phy_addr();
+
+ switch (type) {
+ case CONNSYS_EMI_FW_WFDMA:
+ if (base)
+ *base = addr_info->emi_ap_phy_addr;
+ if (size)
+ *size = addr_info->emi_size;
+ break;
+ case CONNSYS_EMI_FW:
+ if (base)
+ *base = addr_info->emi_ap_phy_addr;
+ if (size)
+ *size = addr_info->fw_emi_size;
+ break;
+ case CONNSYS_EMI_WFDMA:
+ if (base)
+ *base = addr_info->emi_ap_phy_addr + addr_info->fw_emi_size;
+ if (size)
+ *size = addr_info->wfdma_emi_size;
+ break;
+ case CONNSYS_EMI_MCIF:
+ if (base)
+ *base = addr_info->md_emi_phy_addr;
+ if (size)
+ *size = addr_info->md_emi_size;
+ break;
+ default:
+ pr_err("Wrong EMI type: %d\n", type);
+ if (base)
+ *base = 0x0;
+ if (size)
+ *size = 0;
+ }
+}
+EXPORT_SYMBOL(conninfra_get_emi_phy_addr);
+
+int conninfra_pwr_on(enum consys_drv_type drv_type)
+{
+ pr_info("[%s] drv=[%d]", __func__, drv_type);
+ if (conninfra_core_is_rst_locking()) {
+ DUMP_LOG();
+ return CONNINFRA_ERR_RST_ONGOING;
+ }
+
+#if CFG_CONNINFRA_PRE_CAL_BLOCKING
+ conninfra_core_pre_cal_blocking();
+#endif
+
+ return conninfra_core_power_on(drv_type);
+}
+EXPORT_SYMBOL(conninfra_pwr_on);
+
+int conninfra_pwr_off(enum consys_drv_type drv_type)
+{
+ if (conninfra_core_is_rst_locking()) {
+ DUMP_LOG();
+ return CONNINFRA_ERR_RST_ONGOING;
+ }
+
+#if CFG_CONNINFRA_PRE_CAL_BLOCKING
+ conninfra_core_pre_cal_blocking();
+#endif
+
+ return conninfra_core_power_off(drv_type);
+}
+EXPORT_SYMBOL(conninfra_pwr_off);
+
+
+int conninfra_reg_readable(void)
+{
+ return conninfra_core_reg_readable();
+}
+EXPORT_SYMBOL(conninfra_reg_readable);
+
+
+int conninfra_reg_readable_no_lock(void)
+{
+ return conninfra_core_reg_readable_no_lock();
+}
+EXPORT_SYMBOL(conninfra_reg_readable_no_lock);
+
+int conninfra_is_bus_hang(void)
+{
+ if (conninfra_core_is_rst_locking()) {
+ DUMP_LOG();
+ return CONNINFRA_ERR_RST_ONGOING;
+ }
+ return conninfra_core_is_bus_hang();
+}
+EXPORT_SYMBOL(conninfra_is_bus_hang);
+
+int conninfra_trigger_whole_chip_rst(enum consys_drv_type who, char *reason)
+{
+ /* use schedule worker to trigger ??? */
+ /* so that function can be returned immediately */
+ int r;
+
+ r = conninfra_core_lock_rst();
+ if (r >= CHIP_RST_START) {
+ /* reset is ongoing */
+ pr_warn("[%s] r=[%d] chip rst is ongoing\n", __func__, r);
+ return 1;
+ }
+ pr_info("[%s] rst lock [%d] [%d] reason=%s", __func__, r, who, reason);
+
+ conninfra_core_trg_chip_rst(who, reason);
+
+ return 0;
+}
+EXPORT_SYMBOL(conninfra_trigger_whole_chip_rst);
+
+int conninfra_sub_drv_ops_register(enum consys_drv_type type,
+ struct sub_drv_ops_cb *cb)
+{
+ /* type validation */
+ if (type < 0 || type >= CONNDRV_TYPE_MAX) {
+ pr_err("[%s] incorrect drv type [%d]", __func__, type);
+ return -EINVAL;
+ }
+ pr_info("[%s] ----", __func__);
+ conninfra_core_subsys_ops_reg(type, cb);
+ return 0;
+}
+EXPORT_SYMBOL(conninfra_sub_drv_ops_register);
+
+int conninfra_sub_drv_ops_unregister(enum consys_drv_type type)
+{
+ /* type validation */
+ if (type < 0 || type >= CONNDRV_TYPE_MAX) {
+ pr_err("[%s] incorrect drv type [%d]", __func__, type);
+ return -EINVAL;
+ }
+ pr_info("[%s] ----", __func__);
+ conninfra_core_subsys_ops_unreg(type);
+ return 0;
+}
+EXPORT_SYMBOL(conninfra_sub_drv_ops_unregister);
+
+
+int conninfra_spi_read(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int *data)
+{
+ if (conninfra_core_is_rst_locking()) {
+ DUMP_LOG();
+ return CONNINFRA_ERR_RST_ONGOING;
+ }
+ if (subsystem >= SYS_SPI_MAX) {
+ pr_err("[%s] wrong subsys %d", __func__, subsystem);
+ return -EINVAL;
+ }
+ conninfra_core_spi_read(subsystem, addr, data);
+ return 0;
+}
+EXPORT_SYMBOL(conninfra_spi_read);
+
+int conninfra_spi_write(enum sys_spi_subsystem subsystem, unsigned int addr, unsigned int data)
+{
+ if (conninfra_core_is_rst_locking()) {
+ DUMP_LOG();
+ return CONNINFRA_ERR_RST_ONGOING;
+ }
+
+ if (subsystem >= SYS_SPI_MAX) {
+ pr_err("[%s] wrong subsys %d", __func__, subsystem);
+ return -EINVAL;
+ }
+ conninfra_core_spi_write(subsystem, addr, data);
+ return 0;
+}
+EXPORT_SYMBOL(conninfra_spi_write);
+
+int conninfra_adie_top_ck_en_on(enum consys_adie_ctl_type type)
+{
+ if (conninfra_core_is_rst_locking()) {
+ DUMP_LOG();
+ return CONNINFRA_ERR_RST_ONGOING;
+ }
+
+ return conninfra_core_adie_top_ck_en_on(type);
+}
+EXPORT_SYMBOL(conninfra_adie_top_ck_en_on);
+
+int conninfra_adie_top_ck_en_off(enum consys_adie_ctl_type type)
+{
+ if (conninfra_core_is_rst_locking()) {
+ DUMP_LOG();
+ return CONNINFRA_ERR_RST_ONGOING;
+ }
+
+ return conninfra_core_adie_top_ck_en_off(type);
+}
+EXPORT_SYMBOL(conninfra_adie_top_ck_en_off);
+
+int conninfra_spi_clock_switch(enum connsys_spi_speed_type type)
+{
+ return conninfra_core_spi_clock_switch(type);
+}
+EXPORT_SYMBOL(conninfra_spi_clock_switch);
+
+void conninfra_config_setup(void)
+{
+ if (conninfra_core_is_rst_locking()) {
+ DUMP_LOG();
+ return;
+ }
+
+ conninfra_core_config_setup();
+}
+EXPORT_SYMBOL(conninfra_config_setup);
+
+int conninfra_bus_clock_ctrl(enum consys_drv_type drv_type, unsigned int bus_clock, int status)
+{
+ return conninfra_core_bus_clock_ctrl(drv_type, bus_clock, status);
+}
+EXPORT_SYMBOL(conninfra_bus_clock_ctrl);
+
+int conninfra_debug_dump(void)
+{
+ return conninfra_core_debug_dump();
+
+}
+EXPORT_SYMBOL(conninfra_debug_dump);
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/src/conninfra_dev.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/src/conninfra_dev.c
new file mode 100755
index 0000000..6ea97e3
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/src/conninfra_dev.c
@@ -0,0 +1,593 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#include <linux/cdev.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include "conninfra.h"
+#include "conninfra_conf.h"
+#include "conninfra_core.h"
+#include "conninfra_dbg.h"
+#include "consys_hw.h"
+#include "wmt_build_in_adapter.h"
+#include "emi_mng.h"
+
+#if CFG_CONNINFRA_STEP_SUPPORT
+#include "conninfra_step.h"
+#endif /* CFG_CONNINFRA_STEP_SUPPORT */
+
+#if CFG_CONNINFRA_UT_SUPPORT
+#include "conninfra_test.h"
+#endif /* CFG_CONNINFRA_UT_SUPPORT */
+
+#if CFG_CONNINFRA_DEVAPC_SUPPORT
+#include <devapc_public.h>
+#endif /* CFG_CONNINFRA_DEVAPC_SUPPORT */
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+#define CONNINFRA_DEV_MAJOR 164
+#define CONNINFRA_DEV_NUM 1
+#define CONNINFRA_DRVIER_NAME "conninfra_drv"
+#define CONNINFRA_DEVICE_NAME "conninfra_dev"
+
+#define CONNINFRA_DEV_IOC_MAGIC 0xc2
+#define CONNINFRA_IOCTL_GET_CHIP_ID _IOR(CONNINFRA_DEV_IOC_MAGIC, 0, int)
+#define CONNINFRA_IOCTL_SET_COREDUMP_MODE _IOW(CONNINFRA_DEV_IOC_MAGIC, 1, unsigned int)
+
+#define CONNINFRA_DEV_INIT_TO_MS (2 * 1000)
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+enum conninfra_init_status {
+ CONNINFRA_INIT_NOT_START,
+ CONNINFRA_INIT_START,
+ CONNINFRA_INIT_DONE,
+};
+static int g_conninfra_init_status = CONNINFRA_INIT_NOT_START;
+static wait_queue_head_t g_conninfra_init_wq;
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+static int conninfra_dev_fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data);
+static int conninfra_dev_open(struct inode *inode, struct file *file);
+static int conninfra_dev_close(struct inode *inode, struct file *file);
+static ssize_t conninfra_dev_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *f_pos);
+static ssize_t conninfra_dev_write(struct file *filp,
+ const char __user *buf, size_t count,
+ loff_t *f_pos);
+static long conninfra_dev_unlocked_ioctl(
+ struct file *filp, unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_COMPAT
+static long conninfra_dev_compat_ioctl(
+ struct file *filp, unsigned int cmd, unsigned long arg);
+#endif /* CONFIG_COMPAT */
+static int conninfra_mmap(struct file *pFile, struct vm_area_struct *pVma);
+
+static int conninfra_thermal_query_cb(void);
+static void conninfra_clock_fail_dump_cb(void);
+
+static int conninfra_conn_reg_readable(void);
+static int conninfra_conn_is_bus_hang(void);
+
+#if CFG_CONNINFRA_DEVAPC_SUPPORT
+static void conninfra_devapc_violation_cb(void);
+static void conninfra_register_devapc_callback(void);
+#endif /* CFG_CONNINFRA_DEVAPC_SUPPORT */
+
+static int conninfra_dev_suspend_cb(void);
+static int conninfra_dev_resume_cb(void);
+static int conninfra_dev_pmic_event_cb(unsigned int, unsigned int);
+static int conninfra_dev_thermal_query_cb(void*, int*);
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+struct class *pConninfraClass;
+struct device *pConninfraDev;
+static struct cdev gConninfraCdev;
+
+const struct file_operations gConninfraDevFops = {
+ .open = conninfra_dev_open,
+ .release = conninfra_dev_close,
+ .read = conninfra_dev_read,
+ .write = conninfra_dev_write,
+ .unlocked_ioctl = conninfra_dev_unlocked_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = conninfra_dev_compat_ioctl,
+#endif /* CONFIG_COMPAT */
+ .mmap = conninfra_mmap,
+};
+
+struct wmt_platform_bridge g_plat_bridge = {
+ .thermal_query_cb = conninfra_thermal_query_cb,
+ .clock_fail_dump_cb = conninfra_clock_fail_dump_cb,
+ .conninfra_reg_readable_cb = conninfra_conn_reg_readable,
+ .conninfra_reg_is_bus_hang_cb = conninfra_conn_is_bus_hang
+};
+
+static int gConnInfraMajor = CONNINFRA_DEV_MAJOR;
+
+/* screen on/off notification */
+static struct notifier_block conninfra_fb_notifier;
+static struct work_struct gPwrOnOffWork;
+static atomic_t g_es_lr_flag_for_blank = ATOMIC_INIT(0); /* for ctrl blank flag */
+static int last_thermal_value;
+static int g_temp_thermal_value;
+
+static struct conninfra_dev_cb g_conninfra_dev_cb = {
+ .conninfra_suspend_cb = conninfra_dev_suspend_cb,
+ .conninfra_resume_cb = conninfra_dev_resume_cb,
+ .conninfra_pmic_event_notifier = conninfra_dev_pmic_event_cb,
+ .conninfra_thermal_query_cb = conninfra_dev_thermal_query_cb,
+};
+
+/* For DEVAPC callback */
+#if CFG_CONNINFRA_DEVAPC_SUPPORT
+static struct work_struct g_conninfra_devapc_work;
+static struct devapc_vio_callbacks conninfra_devapc_handle = {
+ .id = INFRA_SUBSYS_CONN,
+ .debug_dump = conninfra_devapc_violation_cb,
+};
+#endif /* CFG_CONNINFRA_DEVAPC_SUPPORT */
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+int conninfra_dev_open(struct inode *inode, struct file *file)
+{
+ static DEFINE_RATELIMIT_STATE(_rs, HZ, 1);
+
+ if (!wait_event_timeout(
+ g_conninfra_init_wq,
+ g_conninfra_init_status == CONNINFRA_INIT_DONE,
+ msecs_to_jiffies(CONNINFRA_DEV_INIT_TO_MS))) {
+ if (__ratelimit(&_rs)) {
+ pr_warn("wait_event_timeout (%d)ms,(%lu)jiffies,return -EIO\n",
+ CONNINFRA_DEV_INIT_TO_MS, msecs_to_jiffies(CONNINFRA_DEV_INIT_TO_MS));
+ }
+ return -EIO;
+ }
+
+ pr_info("open major %d minor %d (pid %d)\n",
+ imajor(inode), iminor(inode), current->pid);
+
+ return 0;
+}
+
+int conninfra_dev_close(struct inode *inode, struct file *file)
+{
+ pr_info("close major %d minor %d (pid %d)\n",
+ imajor(inode), iminor(inode), current->pid);
+
+ return 0;
+}
+
+ssize_t conninfra_dev_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ return 0;
+}
+
+ssize_t conninfra_dev_write(struct file *filp,
+ const char __user *buf, size_t count, loff_t *f_pos)
+{
+ return 0;
+}
+
+static long conninfra_dev_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ int retval = 0;
+
+ pr_info("[%s] cmd (%d),arg(%ld)\n", __func__, cmd, arg);
+ switch (cmd) {
+ case CONNINFRA_IOCTL_GET_CHIP_ID:
+ retval = consys_hw_chipid_get();
+ break;
+ case CONNINFRA_IOCTL_SET_COREDUMP_MODE:
+ #if CFG_CONNINFRA_COREDUMP_SUPPORT
+ connsys_coredump_set_dump_mode(arg);
+ #else
+ pr_info("Coredump is not support");
+ #endif /* CFG_CONNINFRA_COREDUMP_SUPPORT */
+ break;
+ }
+ return retval;
+
+}
+
+#ifdef CONFIG_COMPAT
+static long conninfra_dev_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ long ret;
+
+ pr_info("[%s] cmd (%d)\n", __func__, cmd);
+ ret = conninfra_dev_unlocked_ioctl(filp, cmd, arg);
+ return ret;
+}
+#endif /* CONFIG_COMPAT */
+
+static int conninfra_mmap(struct file *pFile, struct vm_area_struct *pVma)
+{
+#if CFG_CONNINFRA_COREDUMP_SUPPORT
+ unsigned long bufId = pVma->vm_pgoff;
+ struct consys_emi_addr_info* addr_info = emi_mng_get_phy_addr();
+
+ pr_info("conninfra_mmap start:%lu end:%lu size: %lu buffer id=%lu\n",
+ pVma->vm_start, pVma->vm_end,
+ pVma->vm_end - pVma->vm_start, bufId);
+
+ if (bufId == 0) {
+ if (pVma->vm_end - pVma->vm_start > addr_info->emi_size)
+ return -1;
+ pr_info("conninfra_mmap size: %lu\n", pVma->vm_end - pVma->vm_start);
+ if (remap_pfn_range(pVma, pVma->vm_start, addr_info->emi_ap_phy_addr >> PAGE_SHIFT,
+ pVma->vm_end - pVma->vm_start, pVma->vm_page_prot))
+ return -EAGAIN;
+ } else if (bufId == 1) {
+ if (addr_info == NULL)
+ return -1;
+ if (addr_info->md_emi_size == 0 ||
+ pVma->vm_end - pVma->vm_start > addr_info->md_emi_size)
+ return -1;
+ pr_info("MD direct path size=%u map size=%lu\n",
+ addr_info->md_emi_size,
+ pVma->vm_end - pVma->vm_start);
+ if (remap_pfn_range(pVma, pVma->vm_start,
+ addr_info->md_emi_phy_addr >> PAGE_SHIFT,
+ pVma->vm_end - pVma->vm_start, pVma->vm_page_prot))
+ return -EAGAIN;
+ }
+#endif /* CFG_CONNINFRA_COREDUMP_SUPPORT */
+ return -EINVAL;
+}
+
+static int conninfra_dev_get_blank_state(void)
+{
+ return atomic_read(&g_es_lr_flag_for_blank);
+}
+
+int conninfra_dev_fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ struct fb_event *evdata = data;
+ int blank;
+
+ pr_debug("conninfra_dev_fb_notifier_callback event=[%lu]\n", event);
+
+ /* If we aren't interested in this event, skip it immediately ... */
+ if (event != FB_EARLY_EVENT_BLANK)
+ return 0;
+
+ blank = *(int *)evdata->data;
+
+ switch (blank) {
+ case FB_BLANK_UNBLANK:
+ atomic_set(&g_es_lr_flag_for_blank, 1);
+ pr_info("@@@@@@@@@@ Conninfra enter UNBLANK @@@@@@@@@@@@@@\n");
+ schedule_work(&gPwrOnOffWork);
+ break;
+ case FB_BLANK_POWERDOWN:
+ atomic_set(&g_es_lr_flag_for_blank, 0);
+ pr_info("@@@@@@@@@@ Conninfra enter early POWERDOWN @@@@@@@@@@@@@@\n");
+ schedule_work(&gPwrOnOffWork);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static void conninfra_dev_pwr_on_off_handler(struct work_struct *work)
+{
+ pr_debug("conninfra_dev_pwr_on_off_handler start to run\n");
+
+ /* Update blank on status after wmt power on */
+ if (conninfra_dev_get_blank_state() == 1) {
+ conninfra_core_screen_on();
+ } else {
+ conninfra_core_screen_off();
+ }
+}
+
+static int conninfra_thermal_query_cb(void)
+{
+ int ret;
+
+ /* if rst is ongoing, return thermal val got from last time */
+ if (conninfra_core_is_rst_locking()) {
+ pr_info("[%s] rst is locking, return last temp ", __func__);
+ return last_thermal_value;
+ }
+ ret = conninfra_core_thermal_query(&g_temp_thermal_value);
+ if (ret == 0)
+ last_thermal_value = g_temp_thermal_value;
+ else if (ret == CONNINFRA_ERR_WAKEUP_FAIL)
+ conninfra_trigger_whole_chip_rst(CONNDRV_TYPE_CONNINFRA, "Query thermal wakeup fail");
+
+ return last_thermal_value;
+}
+
+static void conninfra_clock_fail_dump_cb(void)
+{
+ conninfra_core_clock_fail_dump_cb();
+}
+
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+/* THIS FUNCTION IS ONLY FOR AUDIO DRIVER */
+/* this function go through consys_hw, skip conninfra_core */
+/* there is no lock and skip consys power on check */
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+static int conninfra_conn_reg_readable(void)
+{
+ return consys_hw_reg_readable();
+ /*return conninfra_core_reg_readable(); */
+}
+
+static int conninfra_conn_is_bus_hang(void)
+{
+ /* if rst is ongoing, don't dump */
+ if (conninfra_core_is_rst_locking()) {
+ pr_info("[%s] rst is locking, skip dump", __func__);
+ return CONNINFRA_ERR_RST_ONGOING;
+ }
+ return conninfra_core_is_bus_hang();
+}
+
+#if CFG_CONNINFRA_DEVAPC_SUPPORT
+static void conninfra_devapc_violation_cb(void)
+{
+ schedule_work(&g_conninfra_devapc_work);
+}
+
+static void conninfra_devapc_handler(struct work_struct *work)
+{
+ conninfra_trigger_whole_chip_rst(CONNDRV_TYPE_CONNINFRA, "CONNSYS DEVAPC");
+}
+
+static void conninfra_register_devapc_callback(void)
+{
+ INIT_WORK(&g_conninfra_devapc_work, conninfra_devapc_handler);
+ register_devapc_vio_callback(&conninfra_devapc_handle);
+}
+#endif /* CFG_CONNINFRA_DEVAPC_SUPPORT */
+
+static int conninfra_dev_suspend_cb(void)
+{
+ return 0;
+}
+
+static int conninfra_dev_resume_cb(void)
+{
+ conninfra_core_dump_power_state();
+ return 0;
+}
+
+static int conninfra_dev_pmic_event_cb(unsigned int id, unsigned int event)
+{
+ conninfra_core_pmic_event_cb(id, event);
+
+ return 0;
+}
+
+static int conninfra_dev_thermal_query_cb(void* data, int* temp)
+{
+ if (temp)
+ *temp = conninfra_thermal_query_cb();
+
+ return 0;
+}
+
+/************************************************************************/
+
+static int conninfra_dev_init(void)
+{
+ dev_t devID = MKDEV(gConnInfraMajor, 0);
+ int cdevErr = -1;
+ int iret = 0;
+
+ g_conninfra_init_status = CONNINFRA_INIT_START;
+ init_waitqueue_head((wait_queue_head_t *)&g_conninfra_init_wq);
+
+ iret = register_chrdev_region(devID, CONNINFRA_DEV_NUM,
+ CONNINFRA_DRVIER_NAME);
+ if (iret) {
+ pr_err("fail to register chrdev\n");
+ g_conninfra_init_status = CONNINFRA_INIT_NOT_START;
+ return -1;
+ }
+
+ cdev_init(&gConninfraCdev, &gConninfraDevFops);
+ gConninfraCdev.owner = THIS_MODULE;
+
+ cdevErr = cdev_add(&gConninfraCdev, devID, CONNINFRA_DEV_NUM);
+ if (cdevErr) {
+ pr_err("cdev_add() fails (%d)\n", cdevErr);
+ goto err1;
+ }
+
+ pConninfraClass = class_create(THIS_MODULE, CONNINFRA_DEVICE_NAME);
+ if (IS_ERR(pConninfraClass)) {
+ pr_err("class create fail, error code(%ld)\n",
+ PTR_ERR(pConninfraClass));
+ goto err1;
+ }
+
+ pConninfraDev = device_create(pConninfraClass, NULL, devID,
+ NULL, CONNINFRA_DEVICE_NAME);
+ if (IS_ERR(pConninfraDev)) {
+ pr_err("device create fail, error code(%ld)\n",
+ PTR_ERR(pConninfraDev));
+ goto err2;
+ }
+
+ /* init power on off handler */
+ INIT_WORK(&gPwrOnOffWork, conninfra_dev_pwr_on_off_handler);
+ conninfra_fb_notifier.notifier_call
+ = conninfra_dev_fb_notifier_callback;
+ iret = fb_register_client(&conninfra_fb_notifier);
+ if (iret)
+ pr_err("register fb_notifier fail");
+ else
+ pr_info("register fb_notifier success");
+
+#if CFG_CONNINFRA_UT_SUPPORT
+ iret = conninfra_test_setup();
+ if (iret)
+ pr_err("init conninfra_test fail, ret = %d\n", iret);
+#endif /* CFG_CONNINFRA_UT_SUPPORT */
+
+ iret = conninfra_conf_init();
+ if (iret)
+ pr_warn("init conf fail\n");
+
+ iret = mtk_conninfra_drv_init(&g_conninfra_dev_cb);
+ if (iret) {
+ pr_err("init consys_hw fail, ret = %d\n", iret);
+ g_conninfra_init_status = CONNINFRA_INIT_NOT_START;
+ return -2;
+ }
+
+ iret = conninfra_core_init();
+ if (iret) {
+ pr_err("conninfra init fail");
+ g_conninfra_init_status = CONNINFRA_INIT_NOT_START;
+ return -3;
+ }
+
+ conninfra_dev_dbg_init();
+
+#if CFG_CONNINFRA_STEP_SUPPORT
+ CONNINFRA_STEP_INIT_FUNC();
+#endif /* CFG_CONNINFRA_STEP_SUPPORT */
+
+ wmt_export_platform_bridge_register(&g_plat_bridge);
+
+#if CFG_CONNINFRA_DEVAPC_SUPPORT
+ conninfra_register_devapc_callback();
+#endif /* CFG_CONNINFRA_DEVAPC_SUPPORT */
+
+ pr_info("ConnInfra Dev: init (%d)\n", iret);
+ g_conninfra_init_status = CONNINFRA_INIT_DONE;
+ return 0;
+
+err2:
+
+ pr_err("[conninfra_dev_init] err2");
+ if (pConninfraClass) {
+ class_destroy(pConninfraClass);
+ pConninfraClass = NULL;
+ }
+err1:
+ pr_err("[conninfra_dev_init] err1");
+ if (cdevErr == 0)
+ cdev_del(&gConninfraCdev);
+
+ if (iret == 0) {
+ unregister_chrdev_region(devID, CONNINFRA_DEV_NUM);
+ gConnInfraMajor = -1;
+ }
+
+ g_conninfra_init_status = CONNINFRA_INIT_NOT_START;
+ return -2;
+}
+
+static void conninfra_dev_deinit(void)
+{
+ dev_t dev = MKDEV(gConnInfraMajor, 0);
+ int iret = 0;
+
+ g_conninfra_init_status = CONNINFRA_INIT_NOT_START;
+ fb_unregister_client(&conninfra_fb_notifier);
+
+ iret = conninfra_dev_dbg_deinit();
+#if CFG_CONNINFRA_UT_SUPPORT
+ iret = conninfra_test_remove();
+#endif /* CFG_CONNINFRA_UT_SUPPORT */
+
+#if CFG_CONNINFRA_STEP_SUPPORT
+ CONNINFRA_STEP_DEINIT_FUNC();
+#endif /* CFG_CONNINFRA_STEP_SUPPORT */
+
+ iret = conninfra_core_deinit();
+
+ iret = mtk_conninfra_drv_deinit();
+
+ iret = conninfra_conf_deinit();
+
+ if (pConninfraDev) {
+ device_destroy(pConninfraClass, dev);
+ pConninfraDev = NULL;
+ }
+
+ if (pConninfraClass) {
+ class_destroy(pConninfraClass);
+ pConninfraClass = NULL;
+ }
+
+ cdev_del(&gConninfraCdev);
+ unregister_chrdev_region(dev, CONNINFRA_DEV_NUM);
+
+ pr_info("ConnInfra: platform init (%d)\n", iret);
+}
+
+module_init(conninfra_dev_init);
+module_exit(conninfra_dev_deinit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Willy.Yu @ CTD/SE5/CS5");
+
+module_param(gConnInfraMajor, uint, 0644);
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/cal_test.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/cal_test.c
new file mode 100755
index 0000000..4ba3cc8
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/cal_test.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#include <linux/slab.h>
+#include <linux/gfp.h>
+#include <linux/mm.h>
+#include "conninfra.h"
+#include "conninfra_core.h"
+#include "osal.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+int pre_cal_power_on_handler(void)
+{
+ pr_info("[%s] ===========", __func__);
+ osal_sleep_ms(100);
+ return 0;
+}
+
+int pre_cal_do_cal_handler(void)
+{
+ pr_info("[%s] ===========", __func__);
+ return 0;
+}
+
+
+struct sub_drv_ops_cb g_cal_drv_ops_cb;
+
+int calibration_test(void)
+{
+ int ret;
+
+ memset(&g_cal_drv_ops_cb, 0, sizeof(struct sub_drv_ops_cb));
+
+ g_cal_drv_ops_cb.pre_cal_cb.pwr_on_cb = pre_cal_power_on_handler;
+ g_cal_drv_ops_cb.pre_cal_cb.do_cal_cb = pre_cal_do_cal_handler;
+
+
+ pr_info("[%s] cb init [%p][%p]", __func__,
+ g_cal_drv_ops_cb.pre_cal_cb.pwr_on_cb,
+ g_cal_drv_ops_cb.pre_cal_cb.do_cal_cb);
+
+ conninfra_sub_drv_ops_register(CONNDRV_TYPE_BT, &g_cal_drv_ops_cb);
+ conninfra_sub_drv_ops_register(CONNDRV_TYPE_WIFI, &g_cal_drv_ops_cb);
+
+ ret = conninfra_core_pre_cal_start();
+ if (ret)
+ pr_warn("[%s] fail [%d]", __func__, ret);
+
+ osal_sleep_ms(1000);
+
+ conninfra_core_screen_on();
+
+ conninfra_sub_drv_ops_unregister(CONNDRV_TYPE_BT);
+ conninfra_sub_drv_ops_unregister(CONNDRV_TYPE_WIFI);
+ pr_info("[%s] finish.", __func__);
+ return 0;
+}
+
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/chip_rst_test.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/chip_rst_test.c
new file mode 100755
index 0000000..bfd19b4
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/chip_rst_test.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#include <linux/slab.h>
+#include <linux/gfp.h>
+#include <linux/mm.h>
+#include "conninfra.h"
+#include "osal.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+int pre_chip_rst_handler(enum consys_drv_type drv, char* reason)
+{
+ pr_info("[%s] ===========", __func__);
+ osal_sleep_ms(100);
+ return 0;
+}
+
+int post_chip_rst_handler(void)
+{
+ pr_info("[%s] ===========", __func__);
+ return 0;
+}
+
+int pre_chip_rst_timeout_handler(enum consys_drv_type drv, char* reason)
+{
+ pr_info("[%s] ++++++++++++", __func__);
+ osal_sleep_ms(800);
+ pr_info("[%s] ------------", __func__);
+ return 0;
+}
+
+struct sub_drv_ops_cb g_drv_ops_cb;
+struct sub_drv_ops_cb g_drv_timeout_ops_cb;
+
+int chip_rst_test(void)
+{
+ int ret;
+
+ memset(&g_drv_ops_cb, 0, sizeof(struct sub_drv_ops_cb));
+ memset(&g_drv_timeout_ops_cb, 0, sizeof(struct sub_drv_ops_cb));
+
+ g_drv_ops_cb.rst_cb.pre_whole_chip_rst = pre_chip_rst_handler;
+ g_drv_ops_cb.rst_cb.post_whole_chip_rst = post_chip_rst_handler;
+
+ g_drv_timeout_ops_cb.rst_cb.pre_whole_chip_rst = pre_chip_rst_timeout_handler;
+ g_drv_timeout_ops_cb.rst_cb.post_whole_chip_rst = post_chip_rst_handler;
+
+ pr_info("[%s] cb init [%p][%p]", __func__,
+ g_drv_ops_cb.rst_cb.pre_whole_chip_rst,
+ g_drv_ops_cb.rst_cb.post_whole_chip_rst);
+
+ conninfra_sub_drv_ops_register(CONNDRV_TYPE_BT, &g_drv_ops_cb);
+ conninfra_sub_drv_ops_register(CONNDRV_TYPE_WIFI, &g_drv_ops_cb);
+ conninfra_sub_drv_ops_register(CONNDRV_TYPE_FM, &g_drv_timeout_ops_cb);
+
+ pr_info("[%s] ++++++++++++++++++++++", __func__);
+
+ ret = conninfra_trigger_whole_chip_rst(CONNDRV_TYPE_BT, "test reset");
+ if (ret)
+ pr_warn("[%s] fail [%d]", __func__, ret);
+ else
+ pr_info("Trigger chip reset success. Test pass.");
+ osal_sleep_ms(10);
+
+ pr_info("Try to trigger whole chip reset when reset is ongoing. It should be fail.");
+ ret = conninfra_trigger_whole_chip_rst(CONNDRV_TYPE_BT, "test reset");
+ pr_info("Test %s. ret = %d.", ret == 1? "pass": "fail", ret);
+
+ pr_info("Try to funcion on when reset is ongoing. It should be fail.");
+ ret = conninfra_pwr_on(CONNDRV_TYPE_WIFI);
+ pr_info("Test %s. ret = %d.", ret == CONNINFRA_ERR_RST_ONGOING ? "pass": "fail", ret);
+
+ osal_sleep_ms(3000);
+
+ conninfra_sub_drv_ops_unregister(CONNDRV_TYPE_BT);
+ conninfra_sub_drv_ops_unregister(CONNDRV_TYPE_WIFI);
+ pr_info("chip_rst_test finish");
+ return 0;
+}
+
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/conf_test.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/conf_test.c
new file mode 100755
index 0000000..4f39360
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/conf_test.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#include "conninfra_conf.h"
+#include "conf_test.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+
+int conninfra_conf_test(void)
+{
+ int ret;
+ const struct conninfra_conf *conf;
+
+#if 0
+ ret = conninfra_conf_set_cfg_file("WMT_SOC.cfg");
+ if (ret) {
+ pr_err("set cfg file fail [%d]", ret);
+ return -1;
+ }
+#endif
+
+ ret = conninfra_conf_init();
+ if (ret) {
+ pr_err("int conf fail [%d]", ret);
+ return -1;
+ }
+
+ conf = conninfra_conf_get_cfg();
+ if (NULL == conf) {
+ pr_err("int conf fail [%d]", ret);
+ return -1;
+ }
+ if (conf->tcxo_gpio != 0) {
+ pr_err("test tcxo gpio fail [%d]. For most case, it should be 0.",
+ conf->tcxo_gpio);
+ return -1;
+ }
+
+ pr_info("[%s] test PASS\n", __func__);
+ return 0;
+}
+
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/conninfra_step_test.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/conninfra_step_test.c
new file mode 100755
index 0000000..b4e5df5
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/conninfra_step_test.c
@@ -0,0 +1,4301 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include "osal.h"
+#include "conninfra_step_test.h"
+#include "conninfra_step.h"
+#include "emi_mng.h"
+#include "consys_hw.h"
+#include "consys_reg_mng.h"
+#include "consys_reg_util.h"
+
+
+#define TEST_WRITE_CR_TEST_CASE 0
+
+struct step_test_check g_conninfra_step_test_check;
+
+
+static void conninfra_step_test_create_emi_action(struct step_test_report *p_report);
+static void conninfra_step_test_create_cond_emi_action(struct step_test_report *p_report);
+static void conninfra_step_test_create_register_action(struct step_test_report *p_report);
+static void conninfra_step_test_create_cond_register_action(struct step_test_report *p_report);
+static void conninfra_step_test_check_register_symbol(struct step_test_report *p_report);
+static void conninfra_step_test_create_other_action(struct step_test_report *p_report);
+static void conninfra_step_test_do_emi_action(struct step_test_report *p_report);
+static void conninfra_step_test_do_cond_emi_action(struct step_test_report *p_report);
+static void conninfra_step_test_do_register_action(struct step_test_report *p_report);
+static void conninfra_step_test_do_cond_register_action(struct step_test_report *p_report);
+static void conninfra_step_test_do_gpio_action(struct step_test_report *p_report);
+static void conninfra_step_test_create_periodic_dump(struct step_test_report *p_report);
+static void conninfra_step_test_do_show_action(struct step_test_report *p_report);
+static void conninfra_step_test_do_sleep_action(struct step_test_report *p_report);
+static void conninfra_step_test_do_condition_action(struct step_test_report *p_report);
+static void conninfra_step_test_do_value_action(struct step_test_report *p_report);
+
+//static void conninfra_step_test_parse_data3(struct step_test_report *p_report);
+static void conninfra_step_test_parse_data1(struct step_test_report *p_report);
+static void conninfra_step_test_parse_data2(struct step_test_report *p_report);
+
+void conninfra_step_test_clear_parameter(char *params[])
+{
+ int i = 0;
+
+ for (i = 0; i < STEP_PARAMETER_SIZE; i++)
+ params[i] = NULL;
+}
+
+#define index_of_array(current_addr, base_addr, type) \
+ (((unsigned long)current_addr - (unsigned long)base_addr) / sizeof(type))
+
+
+int conninfra_step_test_check_write_tp2(struct step_action_list *p_act_list, enum step_drv_type drv_type,
+ enum step_action_id act_id, int param_num, char *params[])
+{
+ int index;
+ int i;
+ int tp_id;
+ struct step_test_scenario *cur_scn = g_conninfra_step_test_check.cur_test_scn;
+
+ if (cur_scn == NULL)
+ return 0;
+
+ if (g_conninfra_step_test_check.step_check_result == TEST_FAIL)
+ return 0;
+
+ index = cur_scn->test_idx;
+ cur_scn->test_idx++;
+
+ if (cur_scn->pt_acts[index].tp_id != -1) {
+
+ tp_id = index_of_array(p_act_list, g_step_drv_type_def[drv_type].action_list, struct step_action_list);
+
+ if (tp_id != cur_scn->pt_acts[index].tp_id) {
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ pr_err("STEP test failed: [%d] drvType=[%d] tp_id %d: expect %d\n", index,
+ drv_type, tp_id, cur_scn->pt_acts[index].tp_id);
+ return 0;
+ }
+ }
+
+ if (act_id != cur_scn->pt_acts[index].act_id) {
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ pr_err("STEP test failed: [%d] act_id %d: expect %d\n", index,
+ act_id, cur_scn->pt_acts[index].act_id);
+ return 0;
+ }
+
+ if (param_num != cur_scn->pt_acts[index].param_num) {
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ pr_err("STEP test failed: [%d] param num %d: expect %d\n", index,
+ param_num, cur_scn->pt_acts[index].param_num);
+ return 0;
+ }
+
+ for (i = 0; i < STEP_PARAMETER_SIZE; i++) {
+ if (cur_scn->pt_acts[index].params[i] == NULL || strcmp(cur_scn->pt_acts[index].params[i], "") == 0)
+ break;
+
+ if (params[i] == NULL || strcmp(params[i], cur_scn->pt_acts[index].params[i]) != 0) {
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ pr_err("STEP test failed: [%d] params[%d] %s: expect %s(%d)\n", index, i, params[i],
+ cur_scn->pt_acts[index].params[i]);
+ return 0;
+ }
+ }
+
+ g_conninfra_step_test_check.step_check_result = TEST_PASS;
+ return 0;
+}
+
+void __conninfra_step_test_parse_data2(const char *buf, struct step_test_report *p_report, char *err_result)
+{
+ struct step_test_scenario *cur_scn = g_conninfra_step_test_check.cur_test_scn;
+
+ conninfra_step_parse_data(buf, osal_strlen((char *)buf), conninfra_step_test_check_write_tp2);
+ if (cur_scn->total_test_sz != cur_scn->test_idx) {
+ pr_err("STEP test failed: index %d: expect total %d\n",
+ cur_scn->total_test_sz, cur_scn->test_idx);
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ }
+ conninfra_step_test_update_result(g_conninfra_step_test_check.step_check_result, p_report, err_result);
+}
+
+void conninfra_step_test_check_emi_act(unsigned int len, ...)
+{
+ unsigned int offset;
+ unsigned int check_result;
+ unsigned int value;
+ unsigned char *p_virtual_addr = NULL;
+ va_list args;
+
+ if (g_conninfra_step_test_check.step_check_result == TEST_FAIL)
+ return;
+
+ offset = g_conninfra_step_test_check.step_check_emi_offset[g_conninfra_step_test_check.step_check_index];
+
+ p_virtual_addr = conninfra_step_test_get_emi_virt_offset(offset);
+ if (!p_virtual_addr) {
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ pr_err("STEP test failed: p_virtual_addr offset(%d) is null", offset);
+ return;
+ }
+ check_result = CONSYS_REG_READ(p_virtual_addr);
+
+ va_start(args, len);
+ value = va_arg(args, unsigned int);
+ va_end(args);
+
+ conninfra_step_test_put_emi_virt_offset();
+
+ if (check_result == value) {
+ g_conninfra_step_test_check.step_check_result = TEST_PASS;
+ } else {
+ pr_err("STEP test failed: check index [%d] Value is %d, expect %d offset=[%x]",
+ g_conninfra_step_test_check.step_check_index,
+ value, check_result, offset);
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ return;
+ }
+
+ if (g_conninfra_step_test_check.step_check_temp_register_id != -1) {
+ if (g_infra_step_env.temp_register[g_conninfra_step_test_check.step_check_temp_register_id] !=
+ (check_result & g_conninfra_step_test_check.step_test_mask)) {
+ pr_err("STEP test failed: Register id(%d) value is %d, expect %d mask 0x%08x",
+ g_conninfra_step_test_check.step_check_temp_register_id,
+ g_infra_step_env.temp_register[g_conninfra_step_test_check.step_check_temp_register_id],
+ check_result, g_conninfra_step_test_check.step_test_mask);
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ }
+ }
+
+ g_conninfra_step_test_check.step_check_index++;
+}
+
+void conninfra_step_test_check_reg_read_act(unsigned int len, ...)
+{
+ unsigned int check_result;
+ unsigned int value;
+ va_list args;
+
+ if (g_conninfra_step_test_check.step_check_result == TEST_FAIL)
+ return;
+
+ va_start(args, len);
+ value = va_arg(args, unsigned int);
+ check_result = CONSYS_REG_READ(g_conninfra_step_test_check.step_check_register_addr);
+
+ if (check_result == value) {
+ g_conninfra_step_test_check.step_check_result = TEST_PASS;
+ } else {
+ pr_err("STEP test failed: Value is %d, expect %d(0x%08x)", value, check_result,
+ g_conninfra_step_test_check.step_check_register_addr);
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ }
+
+ if (g_conninfra_step_test_check.step_check_temp_register_id != -1) {
+ if (g_infra_step_env.temp_register[g_conninfra_step_test_check.step_check_temp_register_id] !=
+ (check_result & g_conninfra_step_test_check.step_test_mask)) {
+ pr_err("STEP test failed: Register id(%d) value is %d, expect %d",
+ g_conninfra_step_test_check.step_check_temp_register_id,
+ g_infra_step_env.temp_register[g_conninfra_step_test_check.step_check_temp_register_id],
+ check_result);
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ }
+ }
+
+ va_end(args);
+}
+
+void conninfra_step_test_check_reg_write_act(unsigned int len, ...)
+{
+ unsigned int value;
+ va_list args;
+ unsigned int mask = g_conninfra_step_test_check.step_test_mask;
+
+ va_start(args, len);
+ value = va_arg(args, unsigned int);
+
+ if (value == 0xdeadfeed) {
+ g_conninfra_step_test_check.step_check_result = TEST_PASS;
+ } else if (mask == 0xFFFFFFFF) {
+ if (g_conninfra_step_test_check.step_check_write_value == value) {
+ g_conninfra_step_test_check.step_check_result = TEST_PASS;
+ } else {
+ pr_err("STEP test failed: Value is %d, expect %d", value,
+ g_conninfra_step_test_check.step_check_write_value);
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ }
+ } else {
+ if ((mask & value) != (mask & g_conninfra_step_test_check.step_check_write_value)) {
+ pr_err("STEP test failed: Overrite value: %d, expect value %d origin %d mask %d",
+ value,
+ g_conninfra_step_test_check.step_check_write_value,
+ g_conninfra_step_test_check.step_recovery_value,
+ mask);
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ } else if ((~mask & value) != (~mask & g_conninfra_step_test_check.step_recovery_value)) {
+ pr_err("STEP test failed: No change value: %d, expect value %d origin %d mask %d",
+ value,
+ g_conninfra_step_test_check.step_check_write_value,
+ g_conninfra_step_test_check.step_recovery_value,
+ mask);
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ } else {
+ g_conninfra_step_test_check.step_check_result = TEST_PASS;
+ }
+ }
+
+ va_end(args);
+}
+
+void conninfra_step_test_check_show_act(unsigned int len, ...)
+{
+ char *content;
+ va_list args;
+
+ va_start(args, len);
+ content = va_arg(args, char*);
+ if (content == NULL || g_conninfra_step_test_check.step_check_result_string == NULL) {
+ pr_err("STEP test failed: content is NULL");
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ }
+ if (content != NULL && g_conninfra_step_test_check.step_check_result_string != NULL &&
+ osal_strcmp(content, g_conninfra_step_test_check.step_check_result_string) == 0) {
+ g_conninfra_step_test_check.step_check_result = TEST_PASS;
+ } else {
+ pr_err("STEP test failed: content(%s), expect(%s)",
+ content, g_conninfra_step_test_check.step_check_result_string);
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ }
+ va_end(args);
+}
+
+void conninfra_step_test_check_condition(unsigned int len, ...)
+{
+ int value;
+ va_list args;
+
+ va_start(args, len);
+ value = va_arg(args, int);
+ if (value == g_conninfra_step_test_check.step_check_result_value) {
+ g_conninfra_step_test_check.step_check_result = TEST_PASS;
+ } else {
+ pr_err("STEP test failed: value(%d), expect(%d)",
+ value, g_conninfra_step_test_check.step_check_result_value);
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ }
+ va_end(args);
+}
+
+void conninfra_step_test_check_value_act(unsigned int len, ...)
+{
+ int value;
+ va_list args;
+
+ va_start(args, len);
+ value = va_arg(args, int);
+ if (value == g_conninfra_step_test_check.step_check_result_value) {
+ g_conninfra_step_test_check.step_check_result = TEST_PASS;
+ } else {
+ pr_err("STEP test failed: value(%d), expect(%d)",
+ value, g_conninfra_step_test_check.step_check_result_value);
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ }
+ va_end(args);
+}
+
+void conninfra_step_test_clear_check_data(void)
+{
+ unsigned int i = 0, j = 0;
+
+ for (i = 0; i < STEP_TEST_ACTION_NUMBER; i++) {
+ g_conninfra_step_test_check.step_check_test_tp_id[i] = 0;
+ g_conninfra_step_test_check.step_check_test_act_id[i] = 0;
+ g_conninfra_step_test_check.step_check_params_num[i] = 0;
+ g_conninfra_step_test_check.step_check_emi_offset[i] = 0;
+ for (j = 0; j < STEP_PARAMETER_SIZE; j++)
+ g_conninfra_step_test_check.step_check_params[i][j] = "";
+ }
+
+ g_conninfra_step_test_check.step_check_total = 0;
+ g_conninfra_step_test_check.step_check_index = 0;
+ g_conninfra_step_test_check.step_check_result = TEST_PASS;
+ g_conninfra_step_test_check.step_check_register_addr = 0;
+ g_conninfra_step_test_check.step_test_mask = 0xFFFFFFFF;
+ g_conninfra_step_test_check.step_recovery_value = 0;
+ g_conninfra_step_test_check.step_check_result_value = 0;
+ g_conninfra_step_test_check.step_check_temp_register_id = -1;
+
+ g_conninfra_step_test_check.cur_test_scn = NULL;
+}
+
+void conninfra_step_test_clear_temp_register(void)
+{
+ int i;
+
+ for (i = 0; i < STEP_TEMP_REGISTER_SIZE; i++)
+ g_infra_step_env.temp_register[i] = 0;
+}
+
+#if 0
+void __conninfra_step_test_parse_data(const char *buf, struct step_test_report *p_report, char *err_result)
+{
+ conninfra_step_parse_data(buf, osal_strlen((char *)buf), conninfra_step_test_check_write_tp);
+ if (g_conninfra_step_test_check.step_check_total != g_conninfra_step_test_check.step_check_index) {
+ pr_err("STEP test failed: index %d: expect total %d\n", g_conninfra_step_test_check.step_check_index,
+ g_conninfra_step_test_check.step_check_total);
+ g_conninfra_step_test_check.step_check_result = TEST_FAIL;
+ }
+ conninfra_step_test_update_result(g_conninfra_step_test_check.step_check_result, p_report, err_result);
+}
+#endif
+
+void __conninfra_step_test_do_emi_action(enum step_action_id act_id, int param_num, char *params[], int result_of_action,
+ struct step_test_report *p_report, char *err_result)
+{
+ struct step_action *p_act = NULL;
+
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ if (conninfra_step_do_emi_action(p_act, conninfra_step_test_check_emi_act) ==
+ result_of_action) {
+ if (g_conninfra_step_test_check.step_check_total != g_conninfra_step_test_check.step_check_index) {
+ p_report->fail++;
+ pr_err("%s, index %d: expect total %d\n", err_result,
+ g_conninfra_step_test_check.step_check_index, g_conninfra_step_test_check.step_check_total);
+ } else if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ p_report->pass++;
+ } else {
+ p_report->fail++;
+ pr_err("%s\n", err_result);
+ }
+ } else {
+ pr_err("%s, expect result is %d\n", err_result, result_of_action);
+ p_report->fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ if (result_of_action == -1) {
+ p_report->pass++;
+ } else {
+ p_report->fail++;
+ pr_err("%s, Create failed\n", err_result);
+ }
+ }
+}
+
+void __conninfra_step_test_do_cond_emi_action(enum step_action_id act_id, int param_num, char *params[], int result_of_action,
+ struct step_test_report *p_report, char *err_result)
+{
+ struct step_action *p_act = NULL;
+
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ if (conninfra_step_do_condition_emi_action(p_act, conninfra_step_test_check_emi_act) ==
+ result_of_action) {
+ if (g_conninfra_step_test_check.step_check_total != g_conninfra_step_test_check.step_check_index) {
+ p_report->fail++;
+ pr_err("%s, index %d: expect total %d\n", err_result,
+ g_conninfra_step_test_check.step_check_index, g_conninfra_step_test_check.step_check_total);
+ } else if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ p_report->pass++;
+ } else {
+ p_report->fail++;
+ pr_err("%s\n", err_result);
+ }
+ } else {
+ pr_err("%s, expect result is %d\n", err_result, result_of_action);
+ p_report->fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ if (result_of_action == -1) {
+ p_report->pass++;
+ } else {
+ p_report->fail++;
+ pr_err("%s, Create failed\n", err_result);
+ }
+ }
+}
+
+void __conninfra_step_test_do_register_action(enum step_action_id act_id, int param_num, char *params[], int result_of_action,
+ struct step_test_report *p_report, char *err_result)
+{
+ struct step_action *p_act = NULL;
+ int result;
+
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ if (osal_strcmp(params[0], "1") == 0) {
+ /* Write register test */
+ if (g_conninfra_step_test_check.step_check_register_addr != 0) {
+ g_conninfra_step_test_check.step_recovery_value =
+ CONSYS_REG_READ(g_conninfra_step_test_check.step_check_register_addr);
+ }
+ result = conninfra_step_do_register_action(p_act, conninfra_step_test_check_reg_write_act);
+ if (result == result_of_action) {
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ p_report->pass++;
+ } else {
+ p_report->fail++;
+ pr_err("%s\n", err_result);
+ }
+ } else if (result == -2) {
+ p_report->check++;
+ pr_info("STEP check: %s, no clock is ok?\n", err_result);
+ } else {
+ pr_err("%s, expect result is %d\n", err_result,
+ result_of_action);
+ p_report->fail++;
+ }
+ if (g_conninfra_step_test_check.step_check_register_addr != 0) {
+ CONSYS_REG_WRITE(g_conninfra_step_test_check.step_check_register_addr,
+ g_conninfra_step_test_check.step_recovery_value);
+ }
+ } else {
+ /* Read register test */
+ g_conninfra_step_test_check.step_check_result = TEST_PASS;
+ result = conninfra_step_do_register_action(p_act, conninfra_step_test_check_reg_read_act);
+ if (result == result_of_action) {
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ p_report->pass++;
+ } else {
+ p_report->fail++;
+ pr_err("%s\n", err_result);
+ }
+ } else if (result == -2) {
+ p_report->check++;
+ pr_info("STEP check: %s, no clock is ok?\n", err_result);
+ } else {
+ pr_err("%s, expect result is %d\n", err_result,
+ result_of_action);
+ p_report->fail++;
+ }
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ if (result_of_action == -1) {
+ p_report->pass++;
+ } else {
+ p_report->fail++;
+ pr_err("%s, Create failed\n", err_result);
+ }
+ }
+}
+
+void __conninfra_step_test_do_cond_register_action(enum step_action_id act_id, int param_num,
+ char *params[], int result_of_action,
+ struct step_test_report *p_report, char *err_result)
+{
+ struct step_action *p_act = NULL;
+ int result;
+
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ pr_info("[%s] == ", __func__);
+ if (p_act != NULL) {
+ if (osal_strcmp(params[1], "1") == 0) {
+ /* Write register test */
+ if (g_conninfra_step_test_check.step_check_register_addr != 0) {
+ g_conninfra_step_test_check.step_recovery_value =
+ CONSYS_REG_READ(g_conninfra_step_test_check.step_check_register_addr);
+ }
+
+ result = conninfra_step_do_condition_register_action(p_act, conninfra_step_test_check_reg_write_act);
+ if (result == result_of_action) {
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ p_report->pass++;
+ } else {
+ p_report->fail++;
+ pr_err("%s\n", err_result);
+ }
+ } else if (result == -2) {
+ p_report->check++;
+ pr_info("STEP check: %s, no clock is ok?\n", err_result);
+ } else {
+ pr_err("%s, expect result is %d\n", err_result, result_of_action);
+ p_report->fail++;
+ }
+ if (g_conninfra_step_test_check.step_check_register_addr != 0) {
+ CONSYS_REG_WRITE(g_conninfra_step_test_check.step_check_register_addr,
+ g_conninfra_step_test_check.step_recovery_value);
+ }
+ } else {
+ pr_info("[%s] == read register test ", __func__);
+ /* Read register test */
+ g_conninfra_step_test_check.step_check_result = TEST_PASS;
+ result = conninfra_step_do_condition_register_action(p_act, conninfra_step_test_check_reg_read_act);
+ if (result == result_of_action) {
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ p_report->pass++;
+ } else {
+ p_report->fail++;
+ pr_err("%s\n", err_result);
+ }
+ } else if (result == -2) {
+ p_report->check++;
+ pr_info("STEP check: %s, no clock is ok?\n", err_result);
+ } else {
+ pr_err("%s, expect result is %d\n", err_result, result_of_action);
+ p_report->fail++;
+ }
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ if (result_of_action == -1) {
+ p_report->pass++;
+ } else {
+ p_report->fail++;
+ pr_err("%s, Create failed\n", err_result);
+ }
+ }
+}
+
+void conninfra_step_test_all(void)
+{
+ struct step_test_report report = {0, 0, 0};
+ //bool is_enable_step = g_infra_step_env.is_enable;
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+
+ conninfra_step_init();
+
+ report.pass = 0;
+ report.fail = 0;
+ report.check = 0;
+
+ pr_info("STEP test: All start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ g_infra_step_env.is_enable = 0;
+
+ conninfra_step_test_read_file(&report);
+
+ //conninfra_step_test_parse_data3(&report);
+
+ conninfra_step_test_parse_data1(&report);
+ conninfra_step_test_parse_data2(&report);
+
+ g_infra_step_env.is_enable = 1;
+ conninfra_step_test_create_emi_action(&report);
+ conninfra_step_test_create_cond_emi_action(&report);
+ conninfra_step_test_create_register_action(&report);
+ conninfra_step_test_create_cond_register_action(&report);
+ conninfra_step_test_check_register_symbol(&report);
+ conninfra_step_test_create_other_action(&report);
+ //conninfra_step_test_parse_data(&report);
+
+ if (true) {
+ conninfra_step_test_do_emi_action(&report);
+ conninfra_step_test_do_cond_emi_action(&report);
+ }
+
+ /* NOT test yet */
+ conninfra_step_test_do_register_action(&report);
+ /* NOT test yet */
+ conninfra_step_test_do_cond_register_action(&report);
+
+ conninfra_step_test_do_gpio_action(&report);
+ //wmt_step_test_do_wakeup_action(&report);
+ conninfra_step_test_create_periodic_dump(&report);
+ conninfra_step_test_do_show_action(&report);
+ conninfra_step_test_do_sleep_action(&report);
+ conninfra_step_test_do_condition_action(&report);
+ conninfra_step_test_do_value_action(&report);
+
+ //conninfra_step_test_do_chip_reset_action(&report);
+ //g_infra_step_env.is_enable = is_enable_step;
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: All result",
+ &report, sec_begin, usec_begin, sec_end, usec_end);
+
+ conninfra_step_deinit();
+}
+
+void conninfra_step_test_read_file(struct step_test_report *p_report)
+{
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+
+ pr_info("STEP test: Read file start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ /********************************
+ ******** Test case 1 ***********
+ ******* Wrong file name ********
+ ********************************/
+ if (-1 == conninfra_step_read_file("conninfra_wrong_file.cfg")) {
+ temp_report.pass++;
+ } else {
+ pr_err("STEP test failed: (Read file TC-1) expect no file\n");
+ temp_report.fail++;
+ }
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Read file result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+
+
+char *parse_data_buf_tc1 =
+ "// TEST NOW\r\n"
+ "\r\n"
+ "[TP CONNINFRA 1] Before Chip reset\r\n"
+ "[AT] _EMI 0 0x50 0x9c\r\n"
+ "[AT] _REG 0 0x08 5 2\r\n"
+ "[TP CONNINFRA 2] After Chip reset\r\n"
+ "[AT] _REG 1 0x08 30\r\n"
+ "[AT] GPIO 0 8\r\n"
+ "[AT] GPIO 1 6 3\r\n"
+ "[AT] _REG 1 0x08 30 0xFF00FF00\r\n"
+ "[TP CONNINFRA 3] Before read consys thermal\r\n"
+ "[AT] SHOW Hello_World\r\n"
+ "[AT] _SLP 1000\r\n"
+ "[AT] COND $1 $2 == $3\r\n"
+ "[AT] COND $1 $2 == 16\r\n"
+ "[AT] _VAL $0 0x66\r\n"
+ "[TP CONNINFRA 4] Power on sequence(0): Start power on\r\n"
+ "[AT] _EMI 0 0x50 0xFFFFFFFF $1\r\n"
+ "[AT] _REG 0 0x08 0xFFFFFFFF $1\r\n"
+ "[AT] CEMI $2 0 0x50 0xFFFFFFFF $1\r\n"
+ "[AT] CREG $2 0 0x08 0xFFFFFFFF $1\r\n"
+ "[TP WF 1] Command Timeout\r\n"
+ "[AT] _EMI 0 0x50 0xFFFFFFFF $1\r\n"
+ "[TP WF 2] Before Chip reset\r\n"
+ "[AT] _EMI 0 0x50 0xFFFFFFFF $1\r\n"
+ "[TP BT 1] Command Timeout\r\n"
+ "[AT] _EMI 0 0x50 0xFFFFFFFF $1\r\n"
+ "[TP BT 2] Before Chip reset\r\n"
+ "[AT] _EMI 0 0x50 0xFFFFFFFF $1\r\n"
+ "[TP GPS 1] Command timeout\r\n"
+ "[AT] _EMI 0 0x50 0xFFFFFFFF $1\r\n"
+ "[TP GPS 2] Before Chip reset\r\n"
+ "[AT] _EMI 0 0x50 0xFFFFFFFF $1\r\n"
+ "[TP FM 1] Command timeout\r\n"
+ "[AT] _EMI 0 0x50 0xFFFFFFFF $1\r\n"
+ "[TP FM 2] Before Chip reset\r\n"
+ "[AT] _EMI 0 0x50 0xFFFFFFFF $1\r\n"
+ "\r\n";
+
+
+struct step_test_scenario parse_data_buf_scn1 = {
+ "// TC1\r\n", 0, 23,
+ { /* array */
+ /* ----------------------------------------------------------------------- */
+ /* [TP CONNINFRA 1] */
+ /* tp_id, act_id */
+ /* params */
+ { STEP_CONNINFRA_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_EMI,
+ 3, {"0", "0x50", "0x9c"} },
+ { STEP_CONNINFRA_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_REGISTER,
+ 4, {"0", "0x08", "5", "2"} },
+ /* [TP CONNINFRA 2] */
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_REGISTER,
+ 3, {"1", "0x08", "30"}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_GPIO,
+ 2, {"0", "8"}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_GPIO,
+ 3, {"1", "6", "3"}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_REGISTER,
+ 4, {"1", "0x08", "30", "0xFF00FF00"}},
+ /* [TP CONNINFRA 3] */
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_SHOW_STRING,
+ 1, {"Hello_World"}},
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_SLEEP,
+ 1, {"1000"}},
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_CONDITION,
+ 4, {"$1", "$2", "==", "$3"}},
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_CONDITION,
+ 4, {"$1", "$2", "==", "16"}},
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_VALUE,
+ 2, {"$0", "0x66"}},
+ /* [TP CONNINFRA 4] */
+ { STEP_CONNINFRA_TP_POWER_ON_START, STEP_ACTION_INDEX_EMI,
+ 4, {"0", "0x50", "0xFFFFFFFF", "$1"}},
+ { STEP_CONNINFRA_TP_POWER_ON_START, STEP_ACTION_INDEX_REGISTER,
+ 4, {"0", "0x08", "0xFFFFFFFF", "$1"}},
+ { STEP_CONNINFRA_TP_POWER_ON_START, STEP_ACTION_INDEX_CONDITION_EMI,
+ 5, {"$2", "0", "0x50", "0xFFFFFFFF", "$1"}},
+ { STEP_CONNINFRA_TP_POWER_ON_START, STEP_ACTION_INDEX_CONDITION_REGISTER,
+ 5, {"$2", "0", "0x08", "0xFFFFFFFF", "$1"}},
+ /* ----------------------------------------------------------------------- */
+ /* [TP WF 1] */
+ { STEP_WF_TP_COMMAND_TIMEOUT, STEP_ACTION_INDEX_EMI,
+ 4, {"0", "0x50", "0xFFFFFFFF", "$1"}},
+ /* [TP WF 2] */
+ { STEP_WF_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_EMI,
+ 4, {"0", "0x50", "0xFFFFFFFF", "$1"}},
+ /* ----------------------------------------------------------------------- */
+ /* [TP BT 1] */
+ { STEP_BT_TP_COMMAND_TIMEOUT, STEP_ACTION_INDEX_EMI,
+ 4, {"0", "0x50", "0xFFFFFFFF", "$1"}},
+ /* [TP BT 2] */
+ { STEP_BT_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_EMI,
+ 4, {"0", "0x50", "0xFFFFFFFF", "$1"}},
+ /* ----------------------------------------------------------------------- */
+ /* [TP GPS 1] */
+ { STEP_GPS_TP_COMMAND_TIMEOUT, STEP_ACTION_INDEX_EMI,
+ 4, {"0", "0x50", "0xFFFFFFFF", "$1"}},
+ /* [TP GPS 2] */
+ { STEP_GPS_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_EMI,
+ 4, {"0", "0x50", "0xFFFFFFFF", "$1"}},
+ /* ----------------------------------------------------------------------- */
+ /* [TP FM 1] */
+ { STEP_FM_TP_COMMAND_TIMEOUT, STEP_ACTION_INDEX_EMI,
+ 4, {"0", "0x50", "0xFFFFFFFF", "$1"}},
+ /* [TP FM 2] */
+ { STEP_FM_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_EMI,
+ 4, {"0", "0x50", "0xFFFFFFFF", "$1"}},
+ }
+};
+
+static void conninfra_step_test_parse_data_tc1(struct step_test_report *temp_report)
+{
+ int i;
+
+ for (i = parse_data_buf_scn1.total_test_sz; i < STEP_TEST_ACTION_NUMBER; i++)
+ parse_data_buf_scn1.pt_acts[i].tp_id = -1;
+ parse_data_buf_scn1.test_idx = 0;
+
+ g_conninfra_step_test_check.cur_test_scn = &parse_data_buf_scn1;
+ __conninfra_step_test_parse_data2(parse_data_buf_tc1, temp_report,
+ "STEP test case failed: (Parse data TC-1) Normal case\n");
+
+}
+
+const char *parse_data_buf_tc2 =
+ "// TEST NOW\r\n"
+ "\r\n"
+ "[TP CONNINFRA 1] Before Chip reset\r\n"
+ "[AT] _EMI 0 0x50 0x9c \r\n"
+ "[AT] _REG 0 0x08 5 2\r\n"
+ " [PD+] 2\r\n"
+ " [AT] _EMI 0 0x50 0x9c\r\n"
+ " [PD-] \r\n"
+ " [TP CONNINFRA 2] After Chip reset\r\n"
+ "[AT] _REG 1 0x08 30\r\n"
+ "[AT] GPIO 0 8\r\n"
+ " [AT] GPIO 1 6 3\r\n"
+ " [PD+] 5\r\n"
+ " [AT] _EMI 0 0x50 0x9c\r\n"
+ " [PD-] \r\n"
+ "[TP CONNINFRA 3] Before read consys thermal\r\n"
+ " [AT] SHOW Hello\r\n"
+ "[AT] _SLP 1000\r\n"
+ " [AT] COND $1 $2 == $3\r\n"
+ " [AT] _VAL $0 0x66\r\n"
+ "[TP CONNINFRA 4] Power on sequence(0): Start power on\r\n"
+ "[AT] CEMI $2 0 0x50 0xFFFFFFFF $1\r\n"
+ " [AT] CREG $2 0 0x08 0xFFFFFFFF $1\r\n"
+ "\r\n";
+
+struct step_test_scenario parse_data_buf_scn_tc2 = {
+ "// TC1\r\n", 0, 15,
+ { /* array */
+ /* struct step_test_scn_tp_act */
+ /* tp_id, act_id */
+ /* [TP 1] */
+ /* params */
+ { STEP_CONNINFRA_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_EMI,
+ 3, {"0", "0x50", "0x9c"}},
+ { STEP_CONNINFRA_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_REGISTER,
+ 4, {"0", "0x08", "5", "2"}},
+ { -1, STEP_ACTION_INDEX_EMI,
+ 3, {"0", "0x50", "0x9c"}},
+ { STEP_CONNINFRA_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_PERIODIC_DUMP,
+ 0, {}},
+ /* [TP 2] */
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_REGISTER,
+ 3, {"1", "0x08", "30"}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_GPIO,
+ 2, {"0", "8"}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_GPIO,
+ 3, {"1", "6", "3"}},
+ { -1, STEP_ACTION_INDEX_EMI,
+ 3, {"0", "0x50", "0x9c"}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_PERIODIC_DUMP,
+ 0, {}
+ },
+ /* [TP 3] */
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_SHOW_STRING,
+ 1, {"Hello"}
+ },
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_SLEEP,
+ 1, {"1000"}
+ },
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_CONDITION,
+ 4, {"$1", "$2", "==", "$3"}
+ },
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_VALUE,
+ 2, {"$0", "0x66"}
+ },
+ /* [TP 4] */
+ { STEP_CONNINFRA_TP_POWER_ON_START, STEP_ACTION_INDEX_CONDITION_EMI,
+ 5, {"$2", "0", "0x50", "0xFFFFFFFF", "$1"}
+ },
+ { STEP_CONNINFRA_TP_POWER_ON_START, STEP_ACTION_INDEX_CONDITION_REGISTER,
+ 5, {"$2", "0", "0x08", "0xFFFFFFFF", "$1"}
+ },
+ }
+};
+
+static void conninfra_step_test_parse_data_tc2(struct step_test_report *temp_report)
+{
+ int i;
+
+ for (i = parse_data_buf_scn_tc2.total_test_sz; i < STEP_TEST_ACTION_NUMBER; i++)
+ parse_data_buf_scn_tc2.pt_acts[i].tp_id = -1;
+ parse_data_buf_scn_tc2.test_idx = 0;
+
+ g_conninfra_step_test_check.cur_test_scn = &parse_data_buf_scn_tc2;
+ __conninfra_step_test_parse_data2(parse_data_buf_tc2, temp_report,
+ "STEP test case failed: (Parse data TC-2) Normal case with some space\n");
+}
+
+char* parse_data_buf_tc3 =
+ "// TEST NOW\r\n"
+ "\r\n"
+ "[TP CONNINFRA 1] Before Chip reset\r\n"
+ "[AT] _EMI 0x50 0x9c\r\n"
+ "[AT] _REG 0 5 2\r\n"
+ "[TP CONNINFRA 2] After Chip reset\r\n"
+ "[AT] _REG 1 0x08\r\n"
+ "[AT] GPIO 0\r\n"
+ "[AT] GPIO 6 3\r\n"
+ "[TP CONNINFRA 3] Before read consys thermal\r\n"
+ "[AT] SHOW\r\n"
+ "[AT] _SLP\r\n"
+ "[AT] COND $1 $2 >\r\n"
+ "[AT] _VAL 0x66\r\n"
+ "\r\n";
+
+struct step_test_scenario parse_data_scn_tc3 = {
+ "// TC3 \r\n", 0, 9,
+ { /* array */
+ /* struct step_test_scn_tp_act */
+ /* tp_id */
+ /* [TP 1] */
+ /* act_id, params */
+ { STEP_CONNINFRA_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_EMI,
+ 2, {"0x50", "0x9c"}},
+ { STEP_CONNINFRA_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_REGISTER,
+ 3, {"0", "5", "2"}},
+ /* [TP 2] */
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_REGISTER,
+ 2, {"1", "0x08"}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_GPIO,
+ 1, {"0"}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_GPIO,
+ 2, {"6", "3"}},
+ /* [TP 3] */
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_SHOW_STRING,
+ 0, {}},
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_SLEEP,
+ 0, {}},
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_CONDITION,
+ 3, {"$1", "$2", ">"}},
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_VALUE,
+ 1, {"0x66"}},
+ }
+};
+
+static void conninfra_step_test_parse_data_tc3(struct step_test_report *temp_report)
+{
+ int i;
+
+ for (i = parse_data_scn_tc3.total_test_sz; i < STEP_TEST_ACTION_NUMBER; i++)
+ parse_data_scn_tc3.pt_acts[i].tp_id = -1;
+ parse_data_scn_tc3.test_idx = 0;
+
+ g_conninfra_step_test_check.cur_test_scn = &parse_data_scn_tc3;
+
+ __conninfra_step_test_parse_data2(parse_data_buf_tc3, temp_report,
+ "STEP test case failed: (Parse data TC-3) Not enough parameter\n");
+
+
+}
+
+static char *parse_data_buf_tc4 =
+ "// TEST NOW\r\n"
+ "\r\n"
+ "[Tp COnnINFRA 1] Before Chip reset\r\n"
+ "[aT] _emi 0 0x50 0x9c\r\n"
+ "[At] _reg 0 0x08 5 2\r\n"
+ "[tP CONNinfra 2] After Chip reset\r\n"
+ "[at] _reg 1 0x08 30\r\n"
+ "[at] gpio 0 8\r\n"
+ "[AT] gpio 1 6 3\r\n"
+ "[AT] _reg 1 0x08 30 0xFF00FF00\r\n"
+ "[pd+] 5\r\n"
+ "[At] gpio 0 8\r\n"
+ "[pd-]\r\n"
+ "[tp conninfra 3] Before read consys thermal\r\n"
+ "[AT] show Hello_World\r\n"
+ "[AT] _slp 1000\r\n"
+ "[AT] cond $1 $2 == $3\r\n"
+ "[AT] _val $0 0x66\r\n"
+ "[TP CONNINFRA 4] Power on sequence(0): Start power on\r\n"
+ "[AT] cemi $2 0 0x50 0xFFFFFFFF $1\r\n"
+ "[at] creg $2 0 0x08 0xffffffff $1\r\n"
+ "[TP wf 1] Command timeout\r\n"
+ "[AT] _EMI 0 0x50 0xFFFFFFFF $1\r\n"
+ "[tp WF 2] Before Chip reset\r\n"
+ "[AT] _EMI 0 0x50 0xFFFFFFFF $1\r\n"
+ "\r\n";
+
+static struct step_test_scenario parse_data_scn_tc4 = {
+ "// TC4 \r\n", 0, 16,
+ { /* array */
+ /* struct step_test_scn_tp_act */
+ /* tp_id */
+ /* act_id, params */
+ { STEP_CONNINFRA_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_EMI,
+ 3, {"0", "0x50", "0x9c"}},
+ { STEP_CONNINFRA_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_REGISTER,
+ 4, {"0", "0x08", "5", "2"}},
+ /* [TP 2] */
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_REGISTER,
+ 3, {"1", "0x08", "30"}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_GPIO,
+ 2, {"0", "8"}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_GPIO,
+ 3, {"1", "6", "3"}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_REGISTER,
+ 4, {"1", "0x08", "30", "0xFF00FF00"}},
+ { -1, STEP_ACTION_INDEX_GPIO,
+ 2, {"0", "8"}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_PERIODIC_DUMP,
+ 0, {}},
+ /* [TP 3] */
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_SHOW_STRING,
+ 1, {"Hello_World"}},
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_SLEEP,
+ 1, {"1000"}},
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_CONDITION,
+ 4, {"$1", "$2", "==", "$3"}},
+ { STEP_CONNINFRA_TP_BEFORE_READ_THERMAL, STEP_ACTION_INDEX_VALUE,
+ 2, {"$0", "0x66"}},
+ /* [TP 4] */
+ { STEP_CONNINFRA_TP_POWER_ON_START, STEP_ACTION_INDEX_CONDITION_EMI,
+ 5, {"$2", "0", "0x50", "0xFFFFFFFF", "$1"}},
+ { STEP_CONNINFRA_TP_POWER_ON_START, STEP_ACTION_INDEX_CONDITION_REGISTER,
+ 5, {"$2", "0", "0x08", "0xffffffff", "$1"}},
+ /* ----------------------------------------------------------------------- */
+ /* [TP WF 1] */
+ { STEP_WF_TP_COMMAND_TIMEOUT, STEP_ACTION_INDEX_EMI,
+ 4, {"0", "0x50", "0xFFFFFFFF", "$1"}},
+ /* [TP WF 2] */
+ { STEP_WF_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_EMI,
+ 4, {"0", "0x50", "0xFFFFFFFF", "$1"}},
+
+ }
+};
+
+static void conninfra_step_test_parse_data_tc4(struct step_test_report *temp_report)
+{
+ int i;
+
+ for (i = parse_data_scn_tc4.total_test_sz; i < STEP_TEST_ACTION_NUMBER; i++)
+ parse_data_scn_tc4.pt_acts[i].tp_id = -1;
+ parse_data_scn_tc4.test_idx = 0;
+
+ g_conninfra_step_test_check.cur_test_scn = &parse_data_scn_tc4;
+ __conninfra_step_test_parse_data2(parse_data_buf_tc4, temp_report,
+ "STEP test case failed: (Parse data TC-4) Upcase and lowercase\n");
+}
+
+char *parse_data_buf_tc5 =
+ "// TEST NOW\r\n"
+ "\r\n"
+ "[TP CONNINFRA 2] After Chip reset\r\n"
+ "[AT] _REG 1 0x08 30\r\n"
+ "[AT] GPIO 0 8\r\n"
+ "[AT] GPIO 1 6 3\r\n"
+ "[tp conninfra 3] Before read consys thermal\r\n"
+ "[TP CONNINFRA 1] Before Chip reset\r\n"
+ "[AT] _EMI 0 0x50 0x9c\r\n"
+ "[AT] _REG 0 0x08 5 2\r\n"
+ "\r\n";
+
+struct step_test_scenario parse_data_scn_tc5 = {
+ "// TC4 \r\n", 0, 5,
+ { /* array */
+ /* struct step_test_scn_tp_act */
+ /* tp_id */
+ /* act_id, params */
+ /* [TP 2] */
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_REGISTER,
+ 3, {"1", "0x08", "30"}
+ },
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_GPIO,
+ 2, {"0", "8"}
+ },
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_GPIO,
+ 3, {"1", "6", "3"}
+ },
+ { STEP_CONNINFRA_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_EMI,
+ 3, {"0", "0x50", "0x9c"}
+ },
+ { STEP_CONNINFRA_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_REGISTER,
+ 4, {"0", "0x08", "5", "2"}
+ },
+ }
+};
+
+static void conninfra_step_test_parse_data_tc5(struct step_test_report *temp_report)
+{
+ int i;
+
+ for (i = parse_data_scn_tc5.total_test_sz; i < STEP_TEST_ACTION_NUMBER; i++)
+ parse_data_scn_tc5.pt_acts[i].tp_id = -1;
+ parse_data_scn_tc5.test_idx = 0;
+
+ g_conninfra_step_test_check.cur_test_scn = &parse_data_scn_tc5;
+ __conninfra_step_test_parse_data2(parse_data_buf_tc5, temp_report,
+ "STEP test case failed: (Parse data TC-5) TP sequence switch\n");
+
+}
+
+char *parse_data_buf_tc6 =
+ "// TEST NOW\r\n"
+ "\r\n"
+ "[TP CONNINFRA 1] Before Chip reset\r\n"
+ "[AT] _EMI 0 0x50 0x9c // show emi 0x50~0x9c\r\n"
+ "// show cregister\r\n"
+ "[AT] _REG 0 0x08 5 2\r\n"
+ "// Do some action\r\n"
+ "[TP CONNINFRA 2] After Chip reset\r\n"
+ "[AT] _REG 1 0x08 30\r\n"
+ "[AT] GPIO 0 8\r\n"
+ "[AT] GPIO 1 6 3\r\n"
+ "[PD+] 5 // pd start\r\n"
+ "[AT] GPIO 0 8 // just do it\r\n"
+ "// Do some action\r\n"
+ "[PD-] // pd ned\r\n"
+ "\r\n";
+
+struct step_test_scenario parse_data_scn_tc6 = {
+ "// TC4 \r\n", 0, 7,
+ { /* array */
+ /* struct step_test_scn_tp_act */
+ /* tp_id */
+ /* act_id, params */
+ { STEP_CONNINFRA_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_EMI,
+ 3, {"0", "0x50", "0x9c"}},
+ { STEP_CONNINFRA_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_REGISTER,
+ 4, {"0", "0x08", "5", "2"}},
+ /* [TP 2] */
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_REGISTER,
+ 3, {"1", "0x08", "30"}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_GPIO,
+ 2, {"0", "8"}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_GPIO,
+ 3, {"1", "6", "3"}},
+ { -1, STEP_ACTION_INDEX_GPIO,
+ 2, {"0", "8"}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_PERIODIC_DUMP,
+ 0, {}},
+ }
+};
+
+static void conninfra_step_test_parse_data_tc6(struct step_test_report *temp_report)
+{
+ int i;
+
+ for (i = parse_data_scn_tc6.total_test_sz; i < STEP_TEST_ACTION_NUMBER; i++)
+ parse_data_scn_tc6.pt_acts[i].tp_id = -1;
+
+ parse_data_scn_tc6.test_idx = 0;
+ g_conninfra_step_test_check.cur_test_scn = &parse_data_scn_tc6;
+
+ __conninfra_step_test_parse_data2(parse_data_buf_tc6, temp_report,
+ "STEP test case failed: (Parse data TC-6) More comment\n");
+
+}
+
+char *parse_data_buf_tc7 =
+ "// TEST NOW\r\n"
+ "\r\n"
+ "[TP adfacdadf 1]When Command timeout\r\n"
+ "[AT] _EMI 0 0x50 0x9c\r\n"
+ "[TPCONNINFRA1] Before Chip reset\r\n"
+ "[TP-CONNINFRA-1] Before Chip reset\r\n"
+ "[T P 2] After Chip reset\r\n"
+ "[AT] _slp\r\n"
+ "[TP CONNINFRA 2 After Chip reset\r\n"
+ "[AT] _slp\r\n"
+ "[PD+]\r\n"
+ "[PD-]\r\n"
+ "[TP CONNINFRA 2] After Chip reset\r\n"
+ "[AT]_REG 1 0x08 30\r\n"
+ "[A T] GPIO 0 8\r\n"
+ "[ AT ] GPIO 1 6 3\r\n"
+ "AT GPIO 0 8\r\n"
+ "[AT WAK+\r\n"
+ "\r\n";
+
+struct step_test_scenario parse_data_scn_tc7 = {
+ "// TC7 \r\n", 0, 0,
+ {}
+};
+
+
+static void conninfra_step_test_parse_data_tc7(struct step_test_report *temp_report)
+{
+ int i;
+
+ for (i = parse_data_scn_tc7.total_test_sz; i < STEP_TEST_ACTION_NUMBER; i++)
+ parse_data_scn_tc7.pt_acts[i].tp_id = -1;
+
+ parse_data_scn_tc7.test_idx = 0;
+ g_conninfra_step_test_check.cur_test_scn = &parse_data_scn_tc7;
+
+ __conninfra_step_test_parse_data2(parse_data_buf_tc7, temp_report,
+ "STEP test case failed: (Parse data TC-7) Wrong format\n");
+
+}
+
+char *parse_data_buf_tc8 =
+ "// TEST NOW\r\n"
+ "\r\n"
+ "[TP CONNINFRA 1] Before Chip reset\r\n"
+ "[PD+] 5\r\n"
+ "[AT] _EMI 0 0x50 0x9c\r\n"
+ "[AT] _REG 0 0x08 5 2\r\n"
+ "[PD-]\r\n"
+ "[TP CONNINFRA 2] After Chip reset\r\n"
+ "[AT] _REG 1 0x08 30\r\n"
+ "[PD+] 3\r\n"
+ "[AT] GPIO 0 8\r\n"
+ "[PD-]\r\n"
+ "[AT] GPIO 1 6 3\r\n"
+ "\r\n";
+
+struct step_test_scenario parse_data_scn_tc8 = {
+ "// TC4 \r\n", 0, 7,
+ { /* array */
+ /* tp_id */
+ /* act_id, params */
+ { -1, STEP_ACTION_INDEX_EMI,
+ 3, {"0", "0x50", "0x9c"}},
+ { -1, STEP_ACTION_INDEX_REGISTER,
+ 4, {"0", "0x08", "5", "2"}},
+ { STEP_CONNINFRA_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_PERIODIC_DUMP,
+ 0, {}},
+ /* [TP 2] */
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_REGISTER,
+ 3, {"1", "0x08", "30"}},
+ { -1, STEP_ACTION_INDEX_GPIO,
+ 2, {"0", "8"}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_PERIODIC_DUMP,
+ 0, {}},
+ { STEP_CONNINFRA_TP_AFTER_CHIP_RESET, STEP_ACTION_INDEX_GPIO,
+ 3, {"1", "6", "3"}},
+ }
+};
+
+static void conninfra_step_test_parse_data_tc8(struct step_test_report *temp_report)
+{
+ int i;
+
+ for (i = parse_data_scn_tc8.total_test_sz; i < STEP_TEST_ACTION_NUMBER; i++)
+ parse_data_scn_tc8.pt_acts[i].tp_id = -1;
+
+ parse_data_scn_tc8.test_idx = 0;
+ g_conninfra_step_test_check.cur_test_scn = &parse_data_scn_tc8;
+
+ __conninfra_step_test_parse_data2(parse_data_buf_tc8, temp_report,
+ "STEP test case failed: (Parse data TC-8) Periodic dump\n");
+
+}
+
+char *parse_data_buf_tc9 =
+ "// TEST NOW\r\n"
+ "\r\n"
+ "[TP CONNINFRA 1] Before Chip reset\r\n"
+ "[AT] _EMI 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0x10 0x11 0x12 0x13\r\n"
+ "\r\n";
+
+struct step_test_scenario parse_data_scn_tc9 = {
+ "// TC4 \r\n", 0, 1,
+ { /* array */
+ /* struct step_test_scn_tp_act */
+ /* tp_id */
+ /* act_id, params */
+ { STEP_CONNINFRA_TP_BEFORE_CHIP_RESET, STEP_ACTION_INDEX_EMI,
+ 10, {"0x1", "0x2", "0x3", "0x4", "0x5", "0x6", "0x7", "0x8", "0x9", "0x10"}
+ },
+ }
+};
+
+static void conninfra_step_test_parse_data_tc9(struct step_test_report *temp_report)
+{
+ int i;
+
+ for (i = parse_data_scn_tc9.total_test_sz; i < STEP_TEST_ACTION_NUMBER; i++)
+ parse_data_scn_tc9.pt_acts[i].tp_id = -1;
+
+ parse_data_scn_tc9.test_idx = 0;
+ g_conninfra_step_test_check.cur_test_scn = &parse_data_scn_tc9;
+
+ __conninfra_step_test_parse_data2(parse_data_buf_tc9, temp_report,
+ "STEP test case failed: (Parse data TC-8) Periodic dump\n");
+
+}
+
+void conninfra_step_test_parse_data1(struct step_test_report *p_report)
+{
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+
+ pr_info("STEP test: Parse data start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ /********************************
+ ******** Test case 1 ***********
+ ******** Normal case ***********
+ ********************************/
+ pr_info("STEP test: TC 1\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_parse_data_tc1(&temp_report);
+
+ /*********************************
+ ******** Test case 2 ************
+ ** Normal case with some space **
+ *********************************/
+ pr_info("STEP test: TC 2\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_parse_data_tc2(&temp_report);
+
+ /***************************************************
+ ****************** Test case 3 ********************
+ ** Failed case not enough parameter (Can parser) **
+ ***************************************************/
+ pr_info("STEP test: TC 3\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_parse_data_tc3(&temp_report);
+
+ /***************************************************
+ ****************** Test case 4 ********************
+ ************** Upcase and lowercase ***************
+ ***************************************************/
+ pr_info("STEP test: TC 4\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_parse_data_tc4(&temp_report);
+
+ /*************************************************
+ ****************** Test case 5 ******************
+ ************** TP sequence switch ***************
+ *************************************************/
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Parse data result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+
+}
+void conninfra_step_test_parse_data2(struct step_test_report *p_report)
+{
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+
+ pr_info("STEP test: Parse data start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+
+ pr_info("STEP test: TC 5\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_parse_data_tc5(&temp_report);
+
+ /*********************************
+ ********* Test case 6 ***********
+ ********* More comment **********
+ *********************************/
+ pr_info("STEP test: TC 6\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_parse_data_tc6(&temp_report);
+
+ /*********************************
+ ********* Test case 7 ***********
+ ********* Wrong format **********
+ *********************************/
+ pr_info("STEP test: TC 7\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_parse_data_tc7(&temp_report);
+
+ /********************************
+ ******** Test case 8 ***********
+ ******* Periodic dump **********
+ ********************************/
+ pr_info("STEP test: TC 8\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_parse_data_tc8(&temp_report);
+
+ /*********************************
+ ******** Test case 9 ************
+ *** Boundary: Much parameter ****
+ *********************************/
+ pr_info("STEP test: TC 9\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_parse_data_tc9(&temp_report);
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Parse data result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+
+void conninfra_step_test_create_emi_action(struct step_test_report *p_report)
+{
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ int check_params[STEP_PARAMETER_SIZE];
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ int param_num = 0;
+
+ pr_info("STEP test: Create EMI action start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ act_id = STEP_ACTION_INDEX_EMI;
+
+ /*****************************
+ ******** Test case 1 ********
+ **** EMI create for read ****
+ *****************************/
+ pr_info("STEP test: TC 1\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ params[1] = "0x50";
+ params[2] = "0x9c";
+ param_num = 3;
+ check_params[0] = 0;
+ check_params[1] = 0x50;
+ check_params[2] = 0x9c;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-1) EMI create");
+
+ /************************************
+ ********** Test case 2 ************
+ **** EMI create fail less param ****
+ ************************************/
+ pr_info("STEP test: TC 2\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ params[1] = "0x50";
+ param_num = 2;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-2) EMI create fail");
+
+ /*************************************************
+ **************** Test case 3 *******************
+ ********** Save emi to temp register ************
+ *************************************************/
+ pr_info("STEP test: TC 3\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ params[1] = "0x50";
+ params[2] = "0x00000030";
+ params[3] = "$3";
+ param_num = 4;
+ check_params[0] = 0;
+ check_params[1] = 0x50;
+ check_params[2] = 0x00000030;
+ check_params[3] = 3;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-3) Save emi to temp register");
+
+ /*************************************************
+ **************** Test case 4 *******************
+ ** Boundary: Save emi to wrong temp register ****
+ *************************************************/
+ pr_info("STEP test: TC 4\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ params[1] = "0x50";
+ params[2] = "0x00000030";
+ params[3] = "$30";
+ param_num = 4;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-4) Boundary: Save emi to wrong temp register");
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Create EMI action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+
+void conninfra_step_test_create_cond_emi_action(struct step_test_report *p_report)
+{
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ int check_params[STEP_PARAMETER_SIZE];
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ int param_num = 0;
+
+ pr_info("STEP test: Create condition EMI action start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ act_id = STEP_ACTION_INDEX_CONDITION_EMI;
+
+ /*************************************************
+ **************** Test case 1 *******************
+ ************ Condition emi create ***************
+ *************************************************/
+ pr_info("STEP test: TC 1\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$1";
+ params[1] = "0";
+ params[2] = "0x50";
+ params[3] = "0x70";
+ param_num = 4;
+ check_params[0] = 1;
+ check_params[1] = 0;
+ check_params[2] = 0x50;
+ check_params[3] = 0x70;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-1) Condition emi create");
+
+ /*************************************************
+ **************** Test case 2 *******************
+ ****** Save condition emi to temp register ******
+ *************************************************/
+ pr_info("STEP test: TC 2\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$2";
+ params[1] = "0";
+ params[2] = "0x50";
+ params[3] = "0x00000030";
+ params[4] = "$3";
+ param_num = 5;
+ check_params[0] = 2;
+ check_params[1] = 0;
+ check_params[2] = 0x50;
+ check_params[3] = 0x00000030;
+ check_params[4] = 3;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-2) Save condition emi to temp register");
+
+ /***********************************************************
+ ******************** Test case 3 *************************
+ ** Boundary: Save condition emi to wrong temp register ****
+ ***********************************************************/
+ pr_info("STEP test: TC 3\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$1";
+ params[1] = "0";
+ params[2] = "0x50";
+ params[3] = "0x00000030";
+ params[4] = "$30";
+ param_num = 5;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-3) Boundary: Boundary: Save condition emi to wrong temp register");
+
+ /***********************************************************
+ ******************** Test case 4 *************************
+ ** Boundary: Save condition emi is wrong temp register ****
+ ***********************************************************/
+ pr_info("STEP test: TC 4\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$30";
+ params[1] = "0";
+ params[2] = "0x50";
+ params[3] = "0x00000030";
+ params[4] = "$1";
+ param_num = 5;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-4) Boundary: Boundary: Save condition emi is wrong temp register");
+
+ /*************************************************
+ **************** Test case 5 *******************
+ ******* Condition emi create less params ********
+ *************************************************/
+ pr_info("STEP test: TC 5\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$1";
+ params[1] = "0";
+ params[2] = "0x50";
+ param_num = 3;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-5) Condition emi create less params");
+
+ /*************************************************
+ **************** Test case 6 *******************
+ ******* Condition emi create wrong symbol *******
+ *************************************************/
+ pr_info("STEP test: TC 6\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "1";
+ params[1] = "0";
+ params[2] = "0x50";
+ params[3] = "0x00000030";
+ params[4] = "$1";
+ param_num = 5;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-6) Condition emi create wrong symbol");
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Create condition EMI action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+
+void conninfra_step_test_create_register_action(struct step_test_report *p_report)
+{
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ int check_params[STEP_PARAMETER_SIZE];
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ int param_num = 0;
+
+ pr_info("STEP test: Create Register action start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ act_id = STEP_ACTION_INDEX_REGISTER;
+
+ /****************************************
+ ************ Test case 1 ***************
+ **** REGISTER(Addr) create for read ****
+ ****************************************/
+ pr_info("STEP test: TC 1\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ params[1] = "0x124dfad";
+ params[2] = "0x9c";
+ params[3] = "2";
+ params[4] = "10";
+ param_num = 5;
+ check_params[0] = 0;
+ check_params[1] = 0x124dfad;
+ check_params[2] = 0x9c;
+ check_params[3] = 2;
+ check_params[4] = 10;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-1) REG create read");
+
+ /*****************************************
+ ************ Test case 2 ****************
+ **** REGISTER(Addr) create for write ****
+ *****************************************/
+ pr_info("STEP test: TC 2\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "1";
+ params[1] = "0x124dfad";
+ params[2] = "0x9c";
+ params[3] = "15";
+ param_num = 4;
+ check_params[0] = 1;
+ check_params[1] = 0x124dfad;
+ check_params[2] = 0x9c;
+ check_params[3] = 15;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-2) REG create write");
+
+ /******************************************
+ ************** Test case 3 ***************
+ ******* Boundary: read wrong symbol ******
+ ******************************************/
+ pr_info("STEP test: TC 3\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ params[1] = "#10000";
+ params[2] = "0x204";
+ params[3] = "1";
+ params[4] = "0";
+ param_num = 5;
+ check_params[0] = 0;
+ check_params[1] = 0x124dfad;
+ check_params[2] = 0x9c;
+ check_params[3] = 2;
+ check_params[4] = 10;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-3) Boundary: read wrong symbol");
+
+ /****************************************************
+ **************** Test case 4 **********************
+ **** REGISTER(Addr) create read fail less param ****
+ ****************************************************/
+ pr_info("STEP test: TC 4\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ params[1] = "0x124dfad";
+ params[2] = "0x9c";
+ param_num = 3;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-4) REG create read fail");
+
+ /*****************************************************
+ ************ Test case 5 ***************************
+ **** REGISTER(Addr) create write fail less param ****
+ *****************************************************/
+ pr_info("STEP test: TC 5\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "1";
+ params[1] = "0x124dfad";
+ params[2] = "0x9c";
+ param_num = 3;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-5) REG create write fail");
+
+ /*****************************************
+ ************ Test case 6 ****************
+ ** REGISTER(Addr) create for write bit ***
+ *****************************************/
+ pr_info("STEP test: TC 6\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "1";
+ params[1] = "0x124dfad";
+ params[2] = "0x9c";
+ params[3] = "15";
+ params[4] = "0xFF00FF00";
+ param_num = 5;
+ check_params[0] = 1;
+ check_params[1] = 0x124dfad;
+ check_params[2] = 0x9c;
+ check_params[3] = 15;
+ check_params[4] = 0xFF00FF00;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-6) REG create write");
+
+ /*********************************************************
+ ******************** Test case 7 ***********************
+ **** REGISTER(Addr) create for read to temp register ****
+ *********************************************************/
+ pr_info("STEP test: TC 7\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ params[1] = "0x124dfad";
+ params[2] = "0x9c";
+ params[3] = "0x00000030";
+ params[4] = "$5";
+ param_num = 5;
+ check_params[0] = 0;
+ check_params[1] = 0x124dfad;
+ check_params[2] = 0x9c;
+ check_params[3] = 0x00000030;
+ check_params[4] = 5;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-7) REGISTER(Addr) create for read to temp register");
+
+ /*********************************************************
+ ******************** Test case 8 ***********************
+ *** REGISTER(Symbol) create for read to temp register ***
+ *********************************************************/
+ pr_info("STEP test: TC 8\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ params[1] = "#1";
+ params[2] = "0x9c";
+ params[3] = "0x00000030";
+ params[4] = "$7";
+ param_num = 5;
+ check_params[0] = 0;
+ check_params[1] = 1;
+ check_params[2] = 0x9c;
+ check_params[3] = 0x00000030;
+ check_params[4] = 7;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-8) REGISTER(Symbol) create for read to temp register");
+
+ /*********************************************************
+ ******************** Test case 9 ***********************
+ ********** REGISTER(Symbol) create for read *************
+ *********************************************************/
+ pr_info("STEP test: TC 9\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ params[1] = "#1";
+ params[2] = "0x9c";
+ params[3] = "1";
+ params[4] = "10";
+ param_num = 5;
+ check_params[0] = 0;
+ check_params[1] = 1;
+ check_params[2] = 0x9c;
+ check_params[3] = 1;
+ check_params[4] = 10;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-9) REGISTER(Symbol) create for read");
+
+ /*********************************************************
+ ******************** Test case 10 ***********************
+ ************ REGISTER(Addr) less parameter **************
+ *********************************************************/
+ pr_info("STEP test: TC 10\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ params[1] = "0x124dfad";
+ params[2] = "0x9c";
+ params[3] = "0x555";
+ param_num = 4;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-10) REGISTER(Addr) less parameter");
+
+ /*********************************************************
+ ******************** Test case 11 ***********************
+ ************ REGISTER(Symbol) less parameter **************
+ *********************************************************/
+ pr_info("STEP test: TC 11\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ params[1] = "#1";
+ params[2] = "0x9c";
+ params[3] = "0x555";
+ param_num = 4;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-11) REGISTER(Symbol) less parameter");
+
+ /**********************************************************
+ *********************** Test case 12 *********************
+ ** Boundary: REGISTER(Addr) read to worng temp register **
+ **********************************************************/
+ pr_info("STEP test: TC 12\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ params[1] = "0x124dfad";
+ params[2] = "0x9c";
+ params[3] = "0x00000030";
+ params[4] = "$35";
+ param_num = 5;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-12) Boundary: REGISTER(Addr) read to worng temp registe");
+
+ /************************************************************
+ *********************** Test case 13 ***********************
+ ** Boundary: REGISTER(Symbol) read to worng temp register **
+ ************************************************************/
+ pr_info("STEP test: TC 13\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ params[1] = "#1";
+ params[2] = "0x9c";
+ params[3] = "0x00000030";
+ params[4] = "$35";
+ param_num = 5;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-13) Boundary: REGISTER(Symbol) read to worng temp registe");
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Create register action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+
+void conninfra_step_test_create_cond_register_action(struct step_test_report *p_report)
+{
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ int check_params[STEP_PARAMETER_SIZE];
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ int param_num = 0;
+
+ pr_info("STEP test: Create condition Register action start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ act_id = STEP_ACTION_INDEX_CONDITION_REGISTER;
+
+ /****************************************
+ ************ Test case 1 ***************
+ **** COND_REG(Addr) create for read ****
+ ****************************************/
+ pr_info("STEP test: TC 1\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$5";
+ params[1] = "0";
+ params[2] = "0x124dfad";
+ params[3] = "0x9c";
+ params[4] = "2";
+ params[5] = "10";
+ param_num = 6;
+ check_params[0] = 5;
+ check_params[1] = 0;
+ check_params[2] = 0x124dfad;
+ check_params[3] = 0x9c;
+ check_params[4] = 2;
+ check_params[5] = 10;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-1) COND_REG(Addr) create for read");
+
+ /*****************************************
+ ************ Test case 2 ****************
+ **** COND_REG(Addr) create for write ****
+ *****************************************/
+ pr_info("STEP test: TC 2\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$7";
+ params[1] = "1";
+ params[2] = "0x124dfad";
+ params[3] = "0x9c";
+ params[4] = "15";
+ param_num = 5;
+ check_params[0] = 7;
+ check_params[1] = 1;
+ check_params[2] = 0x124dfad;
+ check_params[3] = 0x9c;
+ check_params[4] = 15;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-2) COND_REG(Addr) create write");
+
+ /******************************************
+ ************** Test case 3 ***************
+ ******* Boundary: read wrong symbol ******
+ ******************************************/
+ pr_info("STEP test: TC 3\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$2";
+ params[1] = "0";
+ params[2] = "#10000";
+ params[3] = "0x204";
+ params[4] = "1";
+ params[5] = "0";
+ param_num = 6;
+ check_params[0] = 2;
+ check_params[1] = 0;
+ check_params[2] = 0x124dfad;
+ check_params[3] = 0x9c;
+ check_params[4] = 2;
+ check_params[5] = 10;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-3) Boundary: read wrong symbol");
+
+ /****************************************************
+ **************** Test case 4 **********************
+ **** COND_REG(Addr) create read fail less param ****
+ ****************************************************/
+ pr_info("STEP test: TC 4\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$3";
+ params[1] = "0";
+ params[2] = "0x124dfad";
+ params[3] = "0x9c";
+ param_num = 4;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-4) COND_REG create read fail");
+
+ /*****************************************************
+ ************ Test case 5 ***************************
+ **** COND_REG(Addr) create write fail less param ****
+ *****************************************************/
+ pr_info("STEP test: TC 5\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$4";
+ params[1] = "1";
+ params[2] = "0x124dfad";
+ params[3] = "0x9c";
+ param_num = 4;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-5) COND_REG create write fail");
+
+ /*****************************************
+ ************ Test case 6 ****************
+ ** COND_REG(Addr) create for write bit ***
+ *****************************************/
+ pr_info("STEP test: TC 6\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$9";
+ params[1] = "1";
+ params[2] = "0x124dfad";
+ params[3] = "0x9c";
+ params[4] = "15";
+ params[5] = "0xFF00FF00";
+ param_num = 6;
+ check_params[0] = 9;
+ check_params[1] = 1;
+ check_params[2] = 0x124dfad;
+ check_params[3] = 0x9c;
+ check_params[4] = 15;
+ check_params[5] = 0xFF00FF00;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-6) COND_REG create write");
+
+ /*********************************************************
+ ******************** Test case 7 ***********************
+ **** COND_REG(Addr) create for read to temp register ****
+ *********************************************************/
+ pr_info("STEP test: TC 7\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$9";
+ params[1] = "0";
+ params[2] = "0x124dfad";
+ params[3] = "0x9c";
+ params[4] = "0x00000030";
+ params[5] = "$5";
+ param_num = 6;
+ check_params[0] = 9;
+ check_params[1] = 0;
+ check_params[2] = 0x124dfad;
+ check_params[3] = 0x9c;
+ check_params[4] = 0x00000030;
+ check_params[5] = 5;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-7) COND_REG(Addr) create for read to temp register");
+
+ /*********************************************************
+ ******************** Test case 8 ***********************
+ *** COND_REG(Symbol) create for read to temp register ***
+ *********************************************************/
+ pr_info("STEP test: TC 8\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$1";
+ params[1] = "0";
+ params[2] = "#1";
+ params[3] = "0x9c";
+ params[4] = "0x00000030";
+ params[5] = "$7";
+ param_num = 6;
+ check_params[0] = 1;
+ check_params[1] = 0;
+ check_params[2] = 1;
+ check_params[3] = 0x9c;
+ check_params[4] = 0x00000030;
+ check_params[5] = 7;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-8) COND_REG(Symbol) create for read to temp register");
+
+ /*********************************************************
+ ******************** Test case 9 ***********************
+ ********** COND_REG(Symbol) create for read *************
+ *********************************************************/
+ pr_info("STEP test: TC 9\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$2";
+ params[1] = "0";
+ params[2] = "#1";
+ params[3] = "0x9c";
+ params[4] = "1";
+ params[5] = "10";
+ param_num = 6;
+ check_params[0] = 2;
+ check_params[1] = 0;
+ check_params[2] = 1;
+ check_params[3] = 0x9c;
+ check_params[4] = 1;
+ check_params[5] = 10;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-9) COND_REG(Symbol) create for read");
+
+ /*********************************************************
+ ******************** Test case 10 ***********************
+ ************ COND_REG(Addr) less parameter **************
+ *********************************************************/
+ pr_info("STEP test: TC 10\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$3";
+ params[1] = "0";
+ params[2] = "0x124dfad";
+ params[3] = "0x9c";
+ params[4] = "0x555";
+ param_num = 5;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-10) COND_REG(Addr) less parameter");
+
+ /*********************************************************
+ ******************** Test case 11 ***********************
+ ************ COND_REG(Symbol) less parameter **************
+ *********************************************************/
+ pr_info("STEP test: TC 11\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$4";
+ params[1] = "0";
+ params[2] = "#1";
+ params[3] = "0x9c";
+ params[4] = "0x555";
+ param_num = 5;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-11) COND_REG(Symbol) less parameter");
+
+ /**********************************************************
+ *********************** Test case 12 *********************
+ ** Boundary: COND_REG(Addr) read to worng temp register **
+ **********************************************************/
+ pr_info("STEP test: TC 12\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$5";
+ params[1] = "0";
+ params[2] = "0x124dfad";
+ params[3] = "0x9c";
+ params[4] = "0x00000030";
+ params[5] = "$35";
+ param_num = 6;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-12) Boundary: COND_REG(Addr) read to worng temp registe");
+
+ /************************************************************
+ *********************** Test case 13 ***********************
+ ** Boundary: COND_REG(Symbol) read to worng temp register **
+ ************************************************************/
+ pr_info("STEP test: TC 13\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$6";
+ params[1] = "0";
+ params[2] = "#1";
+ params[3] = "0x9c";
+ params[4] = "0x00000030";
+ params[5] = "$35";
+ param_num = 6;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-13) Boundary: COND_REG(Symbol) read to worng temp registe");
+
+ /*********************************************************
+ ******************** Test case 14 ***********************
+ ************* COND_REG(Symbol) worng symbol *************
+ *********************************************************/
+ pr_info("STEP test: TC 14\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "8";
+ params[1] = "0";
+ params[2] = "#1";
+ params[3] = "0x9c";
+ params[4] = "1";
+ params[5] = "10";
+ param_num = 6;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-14) Boundary: COND_REG(Symbol) worng symbol");
+
+ /*********************************************************
+ ******************** Test case 15 ***********************
+ ********* COND_REG(Symbol) worng temp register id *******
+ *********************************************************/
+ pr_info("STEP test: TC 15\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$88";
+ params[1] = "0";
+ params[2] = "#1";
+ params[3] = "0x9c";
+ params[4] = "1";
+ params[5] = "10";
+ param_num = 6;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-15) Boundary: COND_REG(Symbol) read to worng temp registe");
+
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Create condition register action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+
+
+#if 0
+int conninfra_step_test_get_symbol_num(void)
+{
+ int len;
+ struct device_node *node = NULL;
+
+ if (g_pdev != NULL) {
+ node = g_pdev->dev.of_node;
+ if (node) {
+ of_get_property(node, "reg", &len);
+ len /= (of_n_addr_cells(node) + of_n_size_cells(node));
+ len /= (sizeof(int));
+ } else {
+ pr_err("STEP test failed: node null");
+ return -1;
+ }
+ } else {
+ pr_err("STEP test failed: gdev null");
+ return -1;
+ }
+
+ return len;
+}
+#endif
+
+void conninfra_step_test_check_register_symbol(struct step_test_report *p_report)
+{
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ int check_params[STEP_PARAMETER_SIZE];
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ int param_num = 0;
+ int i = 0;
+ /* use CONSYS_BASE_ADDR_MAX directly */
+ //int symbol_num = conninfra_step_test_get_symbol_num();
+ int symbol_num = consys_reg_mng_get_reg_symbol_num();
+ unsigned char buf[4];
+
+ pr_info("STEP test: Check Register symbol start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ act_id = STEP_ACTION_INDEX_REGISTER;
+ /*********************************************************
+ ******************** Test case 1 ***********************
+ ********** REGISTER(Symbol) create for read *************
+ *********************************************************/
+ pr_info("STEP test: TC 1\n");
+ if (symbol_num < 0) {
+ temp_report.fail++;
+ } else {
+ pr_info("STEP test: symbol_num = [%d]\n", symbol_num);
+ for (i = 1; i <= symbol_num; i++) {
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ snprintf(buf, 4, "#%d", i);
+ params[1] = buf;
+ params[2] = "0x9c";
+ params[3] = "1";
+ params[4] = "10";
+ param_num = 5;
+ check_params[0] = 0;
+ check_params[1] = i;
+ check_params[2] = 0x9c;
+ check_params[3] = 1;
+ check_params[4] = 10;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Check Register symbol TC-1) REGISTER(Symbol) create for read");
+ }
+ }
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Check Register symbol result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+
+void conninfra_step_test_create_other_action(struct step_test_report *p_report)
+{
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ int check_params[STEP_PARAMETER_SIZE];
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ struct step_pd_entry fack_pd_entry;
+ int param_num = 0;
+
+ pr_info("STEP test: Create other action start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ /******************************************
+ ************ Test case 1 *****************
+ ********** GPIO create for read **********
+ ******************************************/
+ pr_info("STEP test: TC 1\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_GPIO;
+ params[0] = "0";
+ params[1] = "8";
+ param_num = 2;
+ check_params[0] = 0;
+ check_params[1] = 8;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-1) GPIO create read");
+
+ /*************************************************
+ **************** Test case 6 *******************
+ ********** GPIO create fail less param **********
+ *************************************************/
+ pr_info("STEP test: TC 6\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_GPIO;
+ params[0] = "0";
+ param_num = 1;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-6) GPIO create fail");
+
+ /*************************************************
+ **************** Test case 7 *******************
+ ************** Periodic dump create *************
+ *************************************************/
+ pr_info("STEP test: TC 7\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_PERIODIC_DUMP;
+ params[0] = (char*)&fack_pd_entry;
+ param_num = 1;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-7) Periodic dump create fail");
+
+ /*************************************************
+ **************** Test case 8 *******************
+ ****** Periodic dump create fail no param *******
+ *************************************************/
+ pr_info("STEP test: TC 8\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_PERIODIC_DUMP;
+ param_num = 0;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-8) Periodic dump create fail");
+
+ /*************************************************
+ **************** Test case 9 *******************
+ **************** Show create ********************
+ *************************************************/
+ pr_info("STEP test: TC 9\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_SHOW_STRING;
+ params[0] = "Hello";
+ param_num = 1;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-9) Show create");
+
+ /*************************************************
+ **************** Test case 10 *******************
+ ******** Show create failed no param ************
+ *************************************************/
+ pr_info("STEP test: TC 10\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_SHOW_STRING;
+ param_num = 0;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-10) Show create failed no param");
+
+ /*************************************************
+ **************** Test case 11 *******************
+ **************** Sleep create *******************
+ *************************************************/
+ pr_info("STEP test: TC 11\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_SLEEP;
+ params[0] = "1000";
+ param_num = 1;
+ check_params[0] = 1000;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-11) Sleep create");
+
+ /*************************************************
+ **************** Test case 12 *******************
+ ********* Sleep create failed no param **********
+ *************************************************/
+ pr_info("STEP test: TC 12\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_SLEEP;
+ param_num = 0;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-12) Sleep create failed no param");
+
+ /*************************************************
+ **************** Test case 13 *******************
+ ************** Condition create *****************
+ *************************************************/
+ pr_info("STEP test: TC 13\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_CONDITION;
+ params[0] = "$0";
+ params[1] = "$1";
+ params[2] = "==";
+ params[3] = "$2";
+ param_num = 4;
+ check_params[0] = 0;
+ check_params[1] = 1;
+ check_params[2] = STEP_OPERATOR_EQUAL;
+ check_params[3] = 2;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-13) Condition create");
+
+ /*************************************************
+ **************** Test case 14 *******************
+ *********** Condition create value **************
+ *************************************************/
+ pr_info("STEP test: TC 14\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_CONDITION;
+ params[0] = "$0";
+ params[1] = "$1";
+ params[2] = "==";
+ params[3] = "16";
+ param_num = 4;
+ check_params[0] = 0;
+ check_params[1] = 1;
+ check_params[2] = STEP_OPERATOR_EQUAL;
+ check_params[3] = 16;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-14) Condition create");
+
+ /*************************************************
+ **************** Test case 15 *******************
+ ****** Condition create failed less param *******
+ *************************************************/
+ pr_info("STEP test: TC 15\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_CONDITION;
+ params[0] = "$0";
+ params[1] = "$1";
+ params[2] = "$2";
+ param_num = 3;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-15) Condition create failed less param");
+
+ /*************************************************
+ **************** Test case 16 *******************
+ ******** Condition create failed no value********
+ *************************************************/
+ pr_info("STEP test: TC 16\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_CONDITION;
+ params[0] = "==";
+ param_num = 1;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-16) Condition create failed no value");
+
+ /*************************************************
+ **************** Test case 17 *******************
+ * Boundary: Condition create failed over reg id *
+ *************************************************/
+ pr_info("STEP test: TC 17\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_CONDITION;
+ params[0] = "$25";
+ params[1] = "$1";
+ params[2] = "==";
+ params[3] = "$2";
+ param_num = 4;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-17) Boundary: Condition create failed over reg id");
+
+ /*************************************************
+ **************** Test case 18 *******************
+ * Boundary: Condition create failed over reg id *
+ *************************************************/
+ pr_info("STEP test: TC 18\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_CONDITION;
+ params[0] = "$0";
+ params[1] = "$1";
+ params[2] = "==";
+ params[3] = "$20";
+ param_num = 4;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-18) Boundary: Condition create failed over reg id");
+
+ /*************************************************
+ **************** Test case 19 *******************
+ ******** Condition create failed operator********
+ *************************************************/
+ pr_info("STEP test: TC 19\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_CONDITION;
+ params[0] = "$0";
+ params[1] = "$1";
+ params[2] = "&";
+ params[3] = "$2";
+ param_num = 4;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-19) Condition create failed operator");
+
+ /*************************************************
+ **************** Test case 20 *******************
+ **************** Value create *******************
+ *************************************************/
+ pr_info("STEP test: TC 20\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_VALUE;
+ params[0] = "$0";
+ params[1] = "0x123";
+ param_num = 2;
+ check_params[0] = 0;
+ check_params[1] = 0x123;
+ conninfra_step_test_create_action(act_id, param_num, params, 0, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-20) Condition create");
+
+ /*************************************************
+ **************** Test case 21 *******************
+ ******* Value create failed wrong order *********
+ *************************************************/
+ pr_info("STEP test: TC 21\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_VALUE;
+ params[0] = "0x123";
+ params[1] = "$1";
+ param_num = 2;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-21) Value create failed wrong order");
+
+ /*************************************************
+ **************** Test case 22 *******************
+ ********* Value create failed no value **********
+ *************************************************/
+ pr_info("STEP test: TC 22\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_VALUE;
+ params[0] = "$1";
+ param_num = 1;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-22) Value create failed no value");
+
+ /*************************************************
+ **************** Test case 23 *******************
+ *** Boundary: Value create failed over reg id ***
+ *************************************************/
+ pr_info("STEP test: TC 23\n");
+ conninfra_step_test_clear_parameter(params);
+ act_id = STEP_ACTION_INDEX_VALUE;
+ params[0] = "$25";
+ params[1] = "0x123";
+ param_num = 2;
+ conninfra_step_test_create_action(act_id, param_num, params, -1, check_params, &temp_report,
+ "STEP test case failed: (Create action TC-23) Boundary: Value create failed over reg id");
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Create other action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+
+#if 0
+/* this offset only for FPGA */
+#define CONNINFRA_STEP_TEST_EMI_COREDUMP_OFFSET 0x4f000
+/* formal chip use this offset*/
+//#define CONNINFRA_STEP_TEST_EMI_COREDUMP_OFFSET 0x27f000
+
+int conninfra_step_test_get_emi_offset(unsigned char buf[], int offset)
+{
+ P_CONSYS_EMI_ADDR_INFO emi_phy_addr = NULL;
+
+ emi_phy_addr = emi_mng_get_phy_addr();
+ if (emi_phy_addr != NULL) {
+ /* TODO: fix this, change the region to coredump */
+
+ snprintf(buf, 11, "0x%08x", (CONNINFRA_STEP_TEST_EMI_COREDUMP_OFFSET /*->emi_core_dump_offset*/ + offset));
+ //snprintf(buf, 11, "0x%08x", ((unsigned int)emi_phy_addr->emi_ap_phy_addr /*->emi_core_dump_offset*/ + offset));
+ } else {
+ pr_err("STEP test failed: emi_phy_addr is NULL\n");
+ return -1;
+ }
+
+ return 0;
+}
+#endif
+
+void conninfra_step_test_do_emi_action(struct step_test_report *p_report)
+{
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ unsigned char buf_begin[11];
+ unsigned char buf_end[11];
+ int param_num;
+ struct consys_emi_addr_info* emi_phy_addr = NULL;
+
+ pr_info("STEP test: Do EMI action start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ act_id = STEP_ACTION_INDEX_EMI;
+
+ emi_phy_addr = emi_mng_get_phy_addr();
+ if (emi_phy_addr == NULL) {
+ temp_report.fail++;
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Do EMI action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+ return;
+ }
+
+ if (conninfra_step_test_get_emi_offset(buf_begin, 0x0) != 0) {
+ temp_report.fail++;
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Do EMI action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+ return;
+ }
+
+ /*****************************************
+ ************ Test case 1 ****************
+ ********** EMI dump 32 bit **************
+ *****************************************/
+ pr_info("STEP test: TC 1\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ conninfra_step_test_get_emi_offset(buf_begin, 0x44);
+ params[1] = buf_begin;
+ conninfra_step_test_get_emi_offset(buf_end, 0x48);
+ params[2] = buf_end;
+ param_num = 3;
+ g_conninfra_step_test_check.step_check_total = 1;
+ g_conninfra_step_test_check.step_check_emi_offset[0] = 0x44;
+ __conninfra_step_test_do_emi_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do EMI action TC-1) dump 32bit");
+
+
+ /*****************************************
+ ************ Test case 2 ****************
+ ****** EMI dump check for address *******
+ *****************************************/
+ pr_info("STEP test: TC 2\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ conninfra_step_test_get_emi_offset(buf_begin, 0x24);
+ params[1] = buf_begin;
+ conninfra_step_test_get_emi_offset(buf_end, 0x44);
+ params[2] = buf_end;
+ param_num = 3;
+ g_conninfra_step_test_check.step_check_total = 8;
+ g_conninfra_step_test_check.step_check_emi_offset[0] = 0x24;
+ g_conninfra_step_test_check.step_check_emi_offset[1] = 0x28;
+ g_conninfra_step_test_check.step_check_emi_offset[2] = 0x2c;
+ g_conninfra_step_test_check.step_check_emi_offset[3] = 0x30;
+ g_conninfra_step_test_check.step_check_emi_offset[4] = 0x34;
+ g_conninfra_step_test_check.step_check_emi_offset[5] = 0x38;
+ g_conninfra_step_test_check.step_check_emi_offset[6] = 0x3c;
+ g_conninfra_step_test_check.step_check_emi_offset[7] = 0x40;
+ __conninfra_step_test_do_emi_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do EMI action TC-2) more address");
+
+ /*****************************************
+ ************ Test case 3 ****************
+ **** EMI dump begin larger than end *****
+ *****************************************/
+ pr_info("STEP test: TC 3\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ conninfra_step_test_get_emi_offset(buf_begin, 0x20);
+ params[1] = buf_begin;
+ conninfra_step_test_get_emi_offset(buf_end, 0x08);
+ params[2] = buf_end;
+ param_num = 3;
+ g_conninfra_step_test_check.step_check_total = 6;
+ g_conninfra_step_test_check.step_check_emi_offset[0] = 0x08;
+ g_conninfra_step_test_check.step_check_emi_offset[1] = 0x0c;
+ g_conninfra_step_test_check.step_check_emi_offset[2] = 0x10;
+ g_conninfra_step_test_check.step_check_emi_offset[3] = 0x14;
+ g_conninfra_step_test_check.step_check_emi_offset[4] = 0x18;
+ g_conninfra_step_test_check.step_check_emi_offset[5] = 0x1c;
+ __conninfra_step_test_do_emi_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do EMI action TC-3) begin larger than end");
+
+ /****************************************
+ ************ Test case 4 ***************
+ ******** EMI only support read *********
+ ****************************************/
+ pr_info("STEP test: TC 4\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "1";
+ conninfra_step_test_get_emi_offset(buf_begin, 0x08);
+ params[1] = buf_begin;
+ conninfra_step_test_get_emi_offset(buf_end, 0x20);
+ params[2] = buf_end;
+ param_num = 3;
+ __conninfra_step_test_do_emi_action(act_id, param_num, params, -1, &temp_report,
+ "STEP test case failed: (Do EMI action TC-4) only support read");
+
+ /****************************************
+ ************ Test case 5 ***************
+ ********* EMI dump not 32bit ***********
+ ****************************************/
+ pr_info("STEP test: TC 5\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ conninfra_step_test_get_emi_offset(buf_begin, 0x08);
+ params[1] = buf_begin;
+ conninfra_step_test_get_emi_offset(buf_end, 0x0e);
+ params[2] = buf_end;
+ param_num = 3;
+ g_conninfra_step_test_check.step_check_total = 2;
+ g_conninfra_step_test_check.step_check_emi_offset[0] = 0x08;
+ g_conninfra_step_test_check.step_check_emi_offset[1] = 0x0c;
+ __conninfra_step_test_do_emi_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do EMI action TC-5) not 32bit");
+
+ /*****************************************
+ ************ Test case 6 ****************
+ ***** EMI dump over emi max size ********
+ *****************************************/
+ pr_info("STEP test: TC 6\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ conninfra_step_test_get_emi_offset(buf_begin, (emi_phy_addr->emi_size + 0x08));
+ params[1] = buf_begin;
+ conninfra_step_test_get_emi_offset(buf_end, (emi_phy_addr->emi_size+ 0x0e));
+ params[2] = buf_end;
+ param_num = 3;
+ __conninfra_step_test_do_emi_action(act_id, param_num, params, -1, &temp_report,
+ "STEP test case failed: (Do EMI action TC-6) over emi max size");
+
+ /*****************************************
+ ************ Test case 7 ****************
+ ************* page fault ****************
+ *****************************************/
+ pr_info("STEP test: TC 7\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ conninfra_step_test_get_emi_offset(buf_begin, 0x02);
+ params[1] = buf_begin;
+ conninfra_step_test_get_emi_offset(buf_end, 0x08);
+ params[2] = buf_end;
+ param_num = 3;
+ __conninfra_step_test_do_emi_action(act_id, param_num, params, -1, &temp_report,
+ "STEP test case failed: (Do EMI action TC-7) page fault");
+
+ /*****************************************
+ ************ Test case 8 ****************
+ ********** save to temp reg *************
+ *****************************************/
+ pr_info("STEP test: TC 8\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "0";
+ conninfra_step_test_get_emi_offset(buf_begin, 0x08);
+ params[1] = buf_begin;
+ params[2] = "0x0F0F0F0F";
+ params[3] = "$1";
+ param_num = 4;
+ g_conninfra_step_test_check.step_check_total = 1;
+ g_conninfra_step_test_check.step_check_emi_offset[0] = 0x08;
+ g_conninfra_step_test_check.step_test_mask = 0x0F0F0F0F;
+ g_conninfra_step_test_check.step_check_temp_register_id = 1;
+ __conninfra_step_test_do_emi_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do EMI action TC-8) save to temp reg");
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Do EMI action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+
+void conninfra_step_test_do_cond_emi_action(struct step_test_report *p_report)
+{
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ unsigned char buf_begin[11];
+ unsigned char buf_end[11];
+ int param_num;
+ struct consys_emi_addr_info* emi_phy_addr = NULL;
+
+ pr_info("STEP test: Do condition EMI action start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ act_id = STEP_ACTION_INDEX_CONDITION_EMI;
+
+ emi_phy_addr = emi_mng_get_phy_addr();
+ if (emi_phy_addr == NULL) {
+ temp_report.fail++;
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Do Condition EMI action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+ return;
+ }
+
+ /*****************************************
+ ************ Test case 1 ****************
+ ********** EMI dump 32 bit **************
+ *****************************************/
+ pr_info("STEP test: TC 1\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$0";
+ params[1] = "0";
+ conninfra_step_test_get_emi_offset(buf_begin, 0x44);
+ params[2] = buf_begin;
+ conninfra_step_test_get_emi_offset(buf_end, 0x48);
+ params[3] = buf_end;
+ param_num = 4;
+ g_infra_step_env.temp_register[0] = 1;
+
+ g_conninfra_step_test_check.step_check_total = 1;
+ g_conninfra_step_test_check.step_check_emi_offset[0] = 0x44;
+ __conninfra_step_test_do_cond_emi_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do COND EMI action TC-1) dump 32bit");
+
+ /*****************************************
+ ************ Test case 2 ****************
+ ****** EMI dump check for address *******
+ *****************************************/
+ pr_info("STEP test: TC 2\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$1";
+ params[1] = "0";
+ conninfra_step_test_get_emi_offset(buf_begin, 0x24);
+ params[2] = buf_begin;
+ conninfra_step_test_get_emi_offset(buf_end, 0x44);
+ params[3] = buf_end;
+ param_num = 4;
+ g_infra_step_env.temp_register[1] = 1;
+
+ g_conninfra_step_test_check.step_check_total = 8;
+ g_conninfra_step_test_check.step_check_emi_offset[0] = 0x24;
+ g_conninfra_step_test_check.step_check_emi_offset[1] = 0x28;
+ g_conninfra_step_test_check.step_check_emi_offset[2] = 0x2c;
+ g_conninfra_step_test_check.step_check_emi_offset[3] = 0x30;
+ g_conninfra_step_test_check.step_check_emi_offset[4] = 0x34;
+ g_conninfra_step_test_check.step_check_emi_offset[5] = 0x38;
+ g_conninfra_step_test_check.step_check_emi_offset[6] = 0x3c;
+ g_conninfra_step_test_check.step_check_emi_offset[7] = 0x40;
+ __conninfra_step_test_do_cond_emi_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do COND EMI action TC-2) more address");
+
+ /*****************************************
+ ************ Test case 3 ****************
+ **** EMI dump begin larger than end *****
+ *****************************************/
+ pr_info("STEP test: TC 3\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$0";
+ params[1] = "0";
+ conninfra_step_test_get_emi_offset(buf_begin, 0x20);
+ params[2] = buf_begin;
+ conninfra_step_test_get_emi_offset(buf_end, 0x08);
+ params[3] = buf_end;
+ param_num = 4;
+ g_infra_step_env.temp_register[0] = 15;
+
+ g_conninfra_step_test_check.step_check_total = 6;
+ g_conninfra_step_test_check.step_check_emi_offset[0] = 0x08;
+ g_conninfra_step_test_check.step_check_emi_offset[1] = 0x0c;
+ g_conninfra_step_test_check.step_check_emi_offset[2] = 0x10;
+ g_conninfra_step_test_check.step_check_emi_offset[3] = 0x14;
+ g_conninfra_step_test_check.step_check_emi_offset[4] = 0x18;
+ g_conninfra_step_test_check.step_check_emi_offset[5] = 0x1c;
+ __conninfra_step_test_do_cond_emi_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do COND EMI action TC-3) begin larger than end");
+
+ /****************************************
+ ************ Test case 4 ***************
+ ******** EMI only support read *********
+ ****************************************/
+ pr_info("STEP test: TC 4\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$1";
+ params[1] = "1";
+ conninfra_step_test_get_emi_offset(buf_begin, 0x08);
+ params[2] = buf_begin;
+ conninfra_step_test_get_emi_offset(buf_end, 0x20);
+ params[3] = buf_end;
+ param_num = 4;
+ g_infra_step_env.temp_register[1] = 1;
+
+ __conninfra_step_test_do_cond_emi_action(act_id, param_num, params, -1, &temp_report,
+ "STEP test case failed: (Do COND EMI action TC-4) only support read");
+
+ /****************************************
+ ************ Test case 5 ***************
+ ********* EMI dump not 32bit ***********
+ ****************************************/
+ pr_info("STEP test: TC 5\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$0";
+ params[1] = "0";
+ conninfra_step_test_get_emi_offset(buf_begin, 0x08);
+ params[2] = buf_begin;
+ conninfra_step_test_get_emi_offset(buf_end, 0x0e);
+ params[3] = buf_end;
+ param_num = 4;
+ g_infra_step_env.temp_register[0] = 1;
+
+ g_conninfra_step_test_check.step_check_total = 2;
+ g_conninfra_step_test_check.step_check_emi_offset[0] = 0x08;
+ g_conninfra_step_test_check.step_check_emi_offset[1] = 0x0c;
+ __conninfra_step_test_do_cond_emi_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do COND EMI action TC-5) not 32bit");
+
+ /*****************************************
+ ************ Test case 6 ****************
+ ***** EMI dump over emi max size ********
+ *****************************************/
+ pr_info("STEP test: TC 6\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$9";
+ params[1] = "0";
+ conninfra_step_test_get_emi_offset(buf_begin, (emi_phy_addr->emi_size + 0x08));
+ params[2] = buf_begin;
+ conninfra_step_test_get_emi_offset(buf_end, (emi_phy_addr->emi_size + 0x0e));
+ params[3] = buf_end;
+ param_num = 4;
+ g_infra_step_env.temp_register[9] = 1;
+
+ __conninfra_step_test_do_cond_emi_action(act_id, param_num, params, -1, &temp_report,
+ "STEP test case failed: (Do COND EMI action TC-6) over emi max size");
+
+ /*****************************************
+ ************ Test case 7 ****************
+ ************* page fault ****************
+ *****************************************/
+ pr_info("STEP test: TC 7\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$0";
+ params[1] = "0";
+ conninfra_step_test_get_emi_offset(buf_begin, 0x02);
+ params[2] = buf_begin;
+ conninfra_step_test_get_emi_offset(buf_end, 0x08);
+ params[3] = buf_end;
+ param_num = 4;
+ g_infra_step_env.temp_register[0] = 1;
+
+ __conninfra_step_test_do_cond_emi_action(act_id, param_num, params, -1, &temp_report,
+ "STEP test case failed: (Do COND EMI action TC-7) page fault");
+
+ /*****************************************
+ ************ Test case 8 ****************
+ ********** save to temp reg *************
+ *****************************************/
+ pr_info("STEP test: TC 8\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$0";
+ params[1] = "0";
+ conninfra_step_test_get_emi_offset(buf_begin, 0x08);
+ params[2] = buf_begin;
+ params[3] = "0x0F0F0F0F";
+ params[4] = "$1";
+ param_num = 5;
+ g_conninfra_step_test_check.step_check_total = 1;
+ g_conninfra_step_test_check.step_check_emi_offset[0] = 0x08;
+ g_conninfra_step_test_check.step_test_mask = 0x0F0F0F0F;
+ g_conninfra_step_test_check.step_check_temp_register_id = 1;
+ g_infra_step_env.temp_register[0] = 1;
+ __conninfra_step_test_do_cond_emi_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do EMI action TC-8) save to temp reg");
+
+
+ /*****************************************
+ ************ Test case 9 ****************
+ ******** condition invalid **************
+ *****************************************/
+ pr_info("STEP test: TC 9\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$0";
+ params[1] = "0";
+ conninfra_step_test_get_emi_offset(buf_begin, 0x08);
+ params[2] = buf_begin;
+ conninfra_step_test_get_emi_offset(buf_end, 0x0e);
+ params[3] = buf_end;
+ param_num = 4;
+ g_infra_step_env.temp_register[0] = 0;
+
+ __conninfra_step_test_do_cond_emi_action(act_id, param_num, params, -1, &temp_report,
+ "STEP test case failed: (Do COND EMI action TC-9) condition invalid");
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Do condition EMI action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+
+void conninfra_step_test_do_register_action(struct step_test_report *p_report)
+{
+#define TEST_BUF_LEN 12
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ unsigned char buf[TEST_BUF_LEN], buf2[TEST_BUF_LEN];
+ int param_num;
+ unsigned int can_write_idx = 0, chip_id_idx = 0;
+ unsigned long can_write_offset = 0, chip_id_offset = 0;
+ unsigned long can_write_vir_addr = 0, can_write_phy_addr = 0;
+ unsigned long chip_id_vir_addr = 0, chip_id_phy_addr = 0;
+ unsigned long first_idx_vir_addr = 0, first_idx_phy_addr = 0;
+ unsigned char can_write_offset_char[11];
+
+ pr_info("STEP test: Do register action start\n");
+
+ /* TODO: need to redefine the test case */
+#if TEST_WRITE_CR_TEST_CASE
+ if (consys_reg_mng_find_can_write_reg(&can_write_idx, &can_write_offset)) {
+ p_report->fail++;
+ pr_err("STEP test: Do register action init can_write_offset failed\n");
+ return;
+ }
+#endif
+ snprintf(can_write_offset_char, 11, "0x%08lx", can_write_offset);
+
+ if (consys_reg_mng_get_chip_id_idx_offset(&chip_id_idx, &chip_id_offset)) {
+ p_report->fail++;
+ pr_err("STEP test: Do register action init chip id idx and offset fail \n");
+ return;
+ }
+ can_write_vir_addr = consys_reg_mng_get_virt_addr_by_idx(can_write_idx);
+ can_write_phy_addr = consys_reg_mng_get_phy_addr_by_idx(can_write_idx);
+
+ chip_id_vir_addr = consys_reg_mng_get_virt_addr_by_idx(chip_id_idx);
+ chip_id_phy_addr = consys_reg_mng_get_phy_addr_by_idx(chip_id_idx);
+
+ pr_info("[%s] chipId idx=[%d] vir=[%p] phy=[%p] offset=[%x]", __func__,
+ chip_id_idx, chip_id_vir_addr, chip_id_phy_addr, chip_id_offset);
+
+ if (can_write_vir_addr == 0 || can_write_phy_addr == 0 ||
+ chip_id_vir_addr == 0 || chip_id_phy_addr == 0) {
+ p_report->fail++;
+ pr_err("STEP test: Do register action init vir/phy addr fail [%x][%x] [%x][%x] chipidIdx=[%d]\n",
+ can_write_vir_addr, can_write_phy_addr,
+ chip_id_vir_addr, chip_id_phy_addr, chip_id_idx);
+ return;
+ }
+
+ pr_info("[%s] offset=[%s]", __func__, can_write_offset_char);
+
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ act_id = STEP_ACTION_INDEX_REGISTER;
+ /****************************************
+ ************ Test case 1 ***************
+ ******** REG read HW chip id **********
+ ****************************************/
+ pr_info("STEP test: TC 1\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+
+ snprintf(buf, TEST_BUF_LEN, "#%d", chip_id_idx+1);
+ snprintf(buf2, TEST_BUF_LEN, "0x%lx", chip_id_offset);
+
+ params[0] = "0";
+ //params[1] = "#1";
+ params[1] = buf;
+ //params[2] = "0x04";
+ params[2] = buf2;
+ params[3] = "1";
+ params[4] = "0";
+ param_num = 5;
+ /* Chip id may different by projects, TODO: the address should be define on consys_hw */
+ //g_conninfra_step_test_check.step_check_register_addr = (CON_REG_INFRA_CFG_ADDR + 0x04);
+ g_conninfra_step_test_check.step_check_register_addr = (chip_id_vir_addr + chip_id_offset);
+ __conninfra_step_test_do_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do register action TC-1) MCU chip id");
+
+ /**********************************************
+ *************** Test case 2 ******************
+ ** REG read MCU chip id by physical address **
+ **********************************************/
+ pr_info("STEP test: TC 2\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ snprintf(buf, TEST_BUF_LEN, "0x%08lx", chip_id_phy_addr);
+ params[1] = buf;
+ //params[2] = "0x04";
+ params[2] = buf2;
+ params[3] = "1";
+ params[4] = "0";
+ param_num = 5;
+ g_conninfra_step_test_check.step_check_register_addr = (chip_id_vir_addr + chip_id_offset);
+ __conninfra_step_test_do_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do register action TC-3) MCU chip id by phy");
+
+ /*****************************************
+ ************* Test case 3 ***************
+ ******** REG read over base size ********
+ *****************************************/
+ pr_info("STEP test: TC 3 >>>> \n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ params[1] = "#1";
+ params[2] = "0x11204";
+ params[3] = "1";
+ params[4] = "0";
+ param_num = 5;
+ __conninfra_step_test_do_register_action(act_id, param_num, params, -1, &temp_report,
+ "STEP test case failed: (Do register action TC-5) Over size");
+
+ /******************************************
+ ************** Test case 4 ***************
+ ***** REG read over base size by phy *****
+ ******************************************/
+ pr_info("STEP test: TC 6\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+
+ first_idx_phy_addr = consys_reg_mng_get_phy_addr_by_idx(0);
+ first_idx_vir_addr = consys_reg_mng_get_virt_addr_by_idx(0);
+ if (first_idx_phy_addr != 0 && first_idx_vir_addr != 0) {
+ snprintf(buf, TEST_BUF_LEN, "0x%08lx", first_idx_phy_addr);
+ params[1] = buf;
+ params[2] = "0x204";
+ params[3] = "1";
+ params[4] = "0";
+ param_num = 5;
+ g_conninfra_step_test_check.step_check_register_addr = (first_idx_vir_addr + 0x204);
+ __conninfra_step_test_do_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do register action TC-6) Over size by phy");
+ } else {
+ p_report->fail++;
+ pr_err("STEP test case failed: get physical address failed\n");
+ }
+
+ /******************************************
+ ************** Test case 5 ***************
+ *************** REG write ****************
+ ******************************************/
+#if TEST_WRITE_CR_TEST_CASE
+ pr_info("STEP test: TC 5\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+
+ snprintf(buf, TEST_BUF_LEN, "#%d", can_write_idx+1);
+ params[0] = "1";
+ //params[1] = "#0";
+ params[1] = buf;
+ params[2] = can_write_offset_char;
+ params[3] = "0x2";
+ param_num = 4;
+ g_conninfra_step_test_check.step_check_register_addr = (can_write_vir_addr + can_write_offset);
+ g_conninfra_step_test_check.step_check_write_value = 0x2;
+ __conninfra_step_test_do_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do register action TC-7) REG write");
+#endif
+
+ /******************************************
+ ************** Test case 6 ***************
+ *********** REG write by phy *************
+ ******************************************/
+#if TEST_WRITE_CR_TEST_CASE
+ pr_info("STEP test: TC 6\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "1";
+
+ snprintf(buf, TEST_BUF_LEN, "0x%08x", can_write_phy_addr);
+ params[1] = buf;
+ params[2] = can_write_offset_char;
+ params[3] = "0x7";
+ param_num = 4;
+ g_conninfra_step_test_check.step_check_register_addr = (can_write_vir_addr + can_write_offset);
+ g_conninfra_step_test_check.step_check_write_value = 0x7;
+ __conninfra_step_test_do_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do register action TC-8) REG write by phy");
+#endif
+
+ /******************************************
+ ************** Test case 7 ***************
+ ************* REG write bit **************
+ ******************************************/
+#if TEST_WRITE_CR_TEST_CASE
+ pr_info("STEP test: TC 7\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+
+ snprintf(buf, TEST_BUF_LEN, "#%d", can_write_idx+1);
+
+ params[0] = "1";
+ //params[1] = "#0";
+ params[1] = buf;
+ params[2] = can_write_offset_char;
+ params[3] = "0x321";
+ params[4] = "0x00F";
+ param_num = 5;
+ g_conninfra_step_test_check.step_check_register_addr = (can_write_vir_addr + can_write_offset);
+ g_conninfra_step_test_check.step_check_write_value = 0x001;
+ g_conninfra_step_test_check.step_test_mask = 0x00F;
+ __conninfra_step_test_do_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do register action TC-9) REG write bit");
+#endif
+
+ /******************************************
+ ************** Test case 8 **************
+ ********* REG write bit by phy ***********
+ ******************************************/
+#if TEST_WRITE_CR_TEST_CASE
+ pr_info("STEP test: TC 8\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "1";
+ //if (conninfra_step_test_get_reg_base_phy_addr(buf, 0) == 0) {
+ snprintf(buf, TEST_BUF_LEN, "0x%08x", can_write_phy_addr);
+ params[1] = buf;
+ params[2] = can_write_offset_char;
+ params[3] = "0x32f";
+ params[4] = "0x002";
+ param_num = 5;
+ g_conninfra_step_test_check.step_check_register_addr = (can_write_vir_addr + can_write_offset);
+ g_conninfra_step_test_check.step_check_write_value = 0x002;
+ g_conninfra_step_test_check.step_test_mask = 0x002;
+ __conninfra_step_test_do_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do register action TC-10) REG write bit by phy");
+#endif
+
+ /******************************************
+ ************** Test case 9 **************
+ ********* REG read to temp reg ***********
+ ******************************************/
+ pr_info("STEP test: TC 9\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "0";
+ params[1] = "#1";
+ params[2] = "0x08";
+ params[3] = "0x0F0F0F0F";
+ params[4] = "$2";
+ param_num = 5;
+ g_conninfra_step_test_check.step_check_register_addr = (first_idx_vir_addr + 0x08);
+ g_conninfra_step_test_check.step_test_mask = 0x0F0F0F0F;
+ g_conninfra_step_test_check.step_check_temp_register_id = 2;
+ __conninfra_step_test_do_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do register action TC-11) REG read to temp reg");
+
+ /******************************************
+ ************** Test case 10 **************
+ ******* REG read phy to temp reg *********
+ ******************************************/
+ pr_info("STEP test: TC 10\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "0";
+
+ snprintf(buf, TEST_BUF_LEN, "0x%08lx", first_idx_phy_addr);
+ params[1] = buf;
+ params[2] = "0x08";
+ params[3] = "0x0F0F0F0F";
+ params[4] = "$3";
+ param_num = 5;
+ g_conninfra_step_test_check.step_check_register_addr = (first_idx_vir_addr + 0x08);
+ g_conninfra_step_test_check.step_test_mask = 0x0F0F0F0F;
+ g_conninfra_step_test_check.step_check_temp_register_id = 3;
+ __conninfra_step_test_do_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do register action TC-12) REG read phy to temp reg");
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Do register action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+
+void conninfra_step_test_do_cond_register_action(struct step_test_report *p_report)
+{
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ unsigned char buf[TEST_BUF_LEN], buf2[TEST_BUF_LEN];
+ int param_num;
+ unsigned int can_write_idx = 0, chip_id_idx = 0;
+ unsigned long can_write_offset = 0, chip_id_offset = 0;
+ unsigned long can_write_vir_addr = 0, can_write_phy_addr = 0;
+ unsigned long chip_id_vir_addr, chip_id_phy_addr;
+ unsigned long first_idx_vir_addr, first_idx_phy_addr;
+ unsigned char can_write_offset_char[11];
+
+ pr_info("STEP test: Do condition register action start\n");
+
+#if TEST_WRITE_CR_TEST_CASE
+ if (consys_reg_mng_find_can_write_reg(&can_write_idx, &can_write_offset)) {
+ p_report->fail++;
+ pr_err("STEP test: Do register action init can_write_offset failed\n");
+ return;
+ }
+#endif
+ snprintf(can_write_offset_char, 11, "0x%08lx", can_write_offset);
+
+ if (consys_reg_mng_get_chip_id_idx_offset(&chip_id_idx, &chip_id_offset)) {
+ p_report->fail++;
+ pr_err("STEP test: Do register action init chip id idx and offset fail \n");
+ return;
+ }
+ can_write_vir_addr = consys_reg_mng_get_virt_addr_by_idx(can_write_idx);
+ can_write_phy_addr = consys_reg_mng_get_phy_addr_by_idx(can_write_idx);
+
+ chip_id_vir_addr = consys_reg_mng_get_virt_addr_by_idx(chip_id_idx);
+ chip_id_phy_addr = consys_reg_mng_get_phy_addr_by_idx(chip_id_idx);
+
+ if (can_write_vir_addr == 0 || can_write_phy_addr == 0 ||
+ chip_id_vir_addr == 0 || chip_id_phy_addr == 0) {
+ p_report->fail++;
+ pr_err("STEP test: Do register action init vir/phy addr fail [%x][%x][%x] \n"
+ , can_write_vir_addr, chip_id_vir_addr, chip_id_phy_addr);
+ return;
+ }
+
+ pr_info("STEP test: chipId=[%d] [%x][%x] offset=[%x] canWrite=[%d] [%x][%x]",
+ chip_id_idx, chip_id_vir_addr, chip_id_phy_addr, chip_id_offset,
+ can_write_idx, can_write_vir_addr, can_write_phy_addr);
+
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ act_id = STEP_ACTION_INDEX_CONDITION_REGISTER;
+ /****************************************
+ ************ Test case 1 ***************
+ ******** REG read MCU chip id **********
+ ****************************************/
+ pr_info("STEP test: TC 1\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+
+ snprintf(buf, TEST_BUF_LEN, "#%d", chip_id_idx+1);
+ snprintf(buf2, TEST_BUF_LEN, "0x%08lx", chip_id_offset);
+
+ params[0] = "$0";
+ params[1] = "0";
+ //params[2] = "#1";
+ params[2] = buf;
+ //params[3] = "0x04";
+ params[3] = buf2;
+ params[4] = "1";
+ params[5] = "0";
+ param_num = 6;
+ g_infra_step_env.temp_register[0] = 1;
+
+ g_conninfra_step_test_check.step_check_register_addr = (chip_id_vir_addr + chip_id_offset);
+ __conninfra_step_test_do_cond_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do cond register action TC-1) MCU chip id");
+
+ /**********************************************
+ *************** Test case 2 ******************
+ ** REG read chip id by physical address **
+ **********************************************/
+ pr_info("STEP test: TC 2\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$2";
+ params[1] = "0";
+
+ snprintf(buf, TEST_BUF_LEN, "0x%08lx", chip_id_phy_addr);
+ params[2] = buf;
+ //params[3] = "0x04";
+ params[3] = buf2;
+ params[4] = "1";
+ params[5] = "0";
+ param_num = 6;
+ g_infra_step_env.temp_register[2] = 1;
+
+ g_conninfra_step_test_check.step_check_register_addr = (chip_id_vir_addr + chip_id_offset);
+ __conninfra_step_test_do_cond_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do cond register action TC-3) MCU chip id by phy");
+
+ /*****************************************
+ ************* Test case 3 ***************
+ ******** REG read over base size ********
+ *****************************************/
+ pr_info("STEP test: TC 3\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$4";
+ params[1] = "0";
+ params[2] = "#1";
+ params[3] = "0x11204";
+ params[4] = "1";
+ params[5] = "0";
+ param_num = 6;
+ g_infra_step_env.temp_register[4] = 10;
+
+ __conninfra_step_test_do_cond_register_action(act_id, param_num, params, -1, &temp_report,
+ "STEP test case failed: (Do cond register action TC-5) Over size");
+
+ /******************************************
+ ************** Test case 4 ***************
+ ***** REG read over base size by phy *****
+ ******************************************/
+ pr_info("STEP test: TC 4\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$5";
+ params[1] = "0";
+
+ first_idx_phy_addr = consys_reg_mng_get_phy_addr_by_idx(0);
+ first_idx_vir_addr = consys_reg_mng_get_virt_addr_by_idx(0);
+
+ if (first_idx_phy_addr != 0 && first_idx_vir_addr != 0) {
+ snprintf(buf, TEST_BUF_LEN, "0x%08lx", first_idx_phy_addr);
+ params[2] = buf;
+ params[3] = "0x204";
+ params[4] = "1";
+ params[5] = "0";
+ param_num = 6;
+ g_infra_step_env.temp_register[5] = 1;
+
+ g_conninfra_step_test_check.step_check_register_addr = (first_idx_vir_addr + 0x204);
+ __conninfra_step_test_do_cond_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do cond register action TC-6) Over size by phy");
+ } else {
+ p_report->fail++;
+ pr_err("STEP test case failed: get physical address failed\n");
+ }
+
+ /******************************************
+ ************** Test case 5 ***************
+ *************** REG write ****************
+ ******************************************/
+#if TEST_WRITE_CR_TEST_CASE
+ pr_info("STEP test: TC 5\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+
+ snprintf(buf, TEST_BUF_LEN, "#%d", can_write_idx+1);
+ params[0] = "$6";
+ params[1] = "1";
+ params[2] = buf;
+ params[3] = can_write_offset_char;
+ params[4] = "0x2";
+ param_num = 5;
+ g_infra_step_env.temp_register[6] = 1;
+
+ //g_conninfra_step_test_check.step_check_register_addr = (CON_REG_INFRA_RGU_ADDR + can_write_offset);
+ g_conninfra_step_test_check.step_check_register_addr = (can_write_vir_addr + can_write_offset);
+ g_conninfra_step_test_check.step_check_write_value = 0x2;
+ __conninfra_step_test_do_cond_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do cond register action TC-7) REG write");
+#endif
+
+ /******************************************
+ ************** Test case 6 ***************
+ *********** REG write by phy *************
+ ******************************************/
+#if TEST_WRITE_CR_TEST_CASE
+ pr_info("STEP test: TC 6\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$7";
+ params[1] = "1";
+ //if (conninfra_step_test_get_reg_base_phy_addr(buf, 0) == 0) {
+
+ snprintf(buf, TEST_BUF_LEN, "0x%08x", can_write_phy_addr);
+ params[2] = buf;
+ params[3] = can_write_offset_char;
+ params[4] = "0x7";
+ param_num = 5;
+ g_infra_step_env.temp_register[7] = 1;
+
+ //g_conninfra_step_test_check.step_check_register_addr = (CON_REG_INFRA_RGU_ADDR + can_write_offset);
+ g_conninfra_step_test_check.step_check_register_addr = (can_write_vir_addr + can_write_offset);
+ g_conninfra_step_test_check.step_check_write_value = 0x7;
+ __conninfra_step_test_do_cond_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do cond register action TC-8) REG write by phy");
+#endif
+ //} else {
+ // p_report->fail++;
+ // pr_err("STEP test case failed: get physical address failed\n");
+ //}
+
+ /******************************************
+ ************** Test case 7 ***************
+ ************* REG write bit **************
+ ******************************************/
+#if TEST_WRITE_CR_TEST_CASE
+ pr_info("STEP test: TC 7\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+
+ snprintf(buf, TEST_BUF_LEN, "#%d", can_write_idx+1);
+ params[0] = "$8";
+ params[1] = "1";
+ params[2] = buf;
+ params[3] = can_write_offset_char;
+ params[4] = "0x321";
+ params[5] = "0x00F";
+ param_num = 6;
+ g_infra_step_env.temp_register[8] = 1;
+
+ g_conninfra_step_test_check.step_check_register_addr = (can_write_vir_addr + can_write_offset);
+ //g_conninfra_step_test_check.step_check_register_addr = (CON_REG_INFRA_RGU_ADDR + can_write_offset);
+ g_conninfra_step_test_check.step_check_write_value = 0x001;
+ g_conninfra_step_test_check.step_test_mask = 0x00F;
+ __conninfra_step_test_do_cond_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do cond register action TC-9) REG write bit");
+#endif
+
+ /******************************************
+ ************** Test case 8 **************
+ ********* REG write bit by phy ***********
+ ******************************************/
+#if TEST_WRITE_CR_TEST_CASE
+ pr_info("STEP test: TC 8\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$9";
+ params[1] = "1";
+ snprintf(buf, TEST_BUF_LEN, "0x%08x", can_write_phy_addr);
+ params[2] = buf;
+ params[3] = can_write_offset_char;
+ params[4] = "0x32f";
+ params[5] = "0x002";
+ param_num = 6;
+ g_infra_step_env.temp_register[9] = 1;
+
+ g_conninfra_step_test_check.step_check_register_addr = (can_write_vir_addr + can_write_offset);
+ g_conninfra_step_test_check.step_check_write_value = 0x002;
+ g_conninfra_step_test_check.step_test_mask = 0x002;
+ __conninfra_step_test_do_cond_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do cond register action TC-10) REG write bit by phy");
+#endif
+
+ /******************************************
+ ************** Test case 9 **************
+ ********* REG read to temp reg ***********
+ ******************************************/
+ pr_info("STEP test: TC 9\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$8";
+ params[1] = "0";
+ params[2] = "#1";
+ params[3] = "0x08";
+ params[4] = "0x0F0F0F0F";
+ params[5] = "$2";
+ param_num = 6;
+ g_conninfra_step_test_check.step_check_register_addr = (first_idx_vir_addr + 0x08);
+ g_conninfra_step_test_check.step_test_mask = 0x0F0F0F0F;
+ g_conninfra_step_test_check.step_check_temp_register_id = 2;
+ g_infra_step_env.temp_register[8] = 1;
+ __conninfra_step_test_do_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do register action TC-11) REG read to temp reg");
+
+ /******************************************
+ ************** Test case 10 **************
+ ******* REG read phy to temp reg *********
+ ******************************************/
+ pr_info("STEP test: TC 12\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$8";
+ params[1] = "0";
+ snprintf(buf, TEST_BUF_LEN, "0x%08lx", first_idx_phy_addr);
+ params[2] = buf;
+ params[3] = "0x08";
+ params[4] = "0x0F0F0F0F";
+ params[5] = "$3";
+ param_num = 6;
+ g_conninfra_step_test_check.step_check_register_addr = (first_idx_vir_addr + 0x08);
+ g_conninfra_step_test_check.step_test_mask = 0x0F0F0F0F;
+ g_conninfra_step_test_check.step_check_temp_register_id = 3;
+ g_infra_step_env.temp_register[8] = 1;
+ __conninfra_step_test_do_register_action(act_id, param_num, params, 0, &temp_report,
+ "STEP test case failed: (Do register action TC-12) REG read phy to temp reg");
+
+ /******************************************
+ ************** Test case 11 **************
+ ************* condition invalid **********
+ ******************************************/
+ pr_info("STEP test: TC 13\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$8";
+ params[1] = "1";
+ params[2] = "#1";
+ params[3] = "0x160";
+ params[4] = "0x123";
+ params[5] = "0xF00";
+ param_num = 6;
+ g_infra_step_env.temp_register[8] = 0;
+
+ __conninfra_step_test_do_cond_register_action(act_id, param_num, params, -1, &temp_report,
+ "STEP test case failed: (Do cond register action TC-13) condition invalid");
+
+ /******************************************
+ ************** Test case 12 **************
+ ********** condition invalid write *******
+ ******************************************/
+ pr_info("STEP test: TC 12\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$6";
+ params[1] = "1";
+ params[2] = "#1";
+ params[3] = "0x110";
+ params[4] = "0x200";
+ param_num = 5;
+ g_infra_step_env.temp_register[6] = 0;
+
+ __conninfra_step_test_do_cond_register_action(act_id, param_num, params, -1, &temp_report,
+ "STEP test case failed: (Do cond register action TC-14) condition invalid write");
+
+ /******************************************
+ ************** Test case 13 **************
+ ********** condition invalid read *******
+ ******************************************/
+ pr_info("STEP test: TC 13\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ conninfra_step_test_clear_temp_register();
+ params[0] = "$0";
+ params[1] = "0";
+ params[2] = "#1";
+ params[3] = "0x08";
+ params[4] = "1";
+ params[5] = "0";
+ param_num = 6;
+ g_infra_step_env.temp_register[0] = 0;
+
+ __conninfra_step_test_do_cond_register_action(act_id, param_num, params, -1, &temp_report,
+ "STEP test case failed: (Do cond register action TC-15) REG write");
+
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Do condition register action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+
+void conninfra_step_test_do_gpio_action(struct step_test_report *p_report)
+{
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ struct step_action *p_act = NULL;
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ int param_num;
+
+ pr_info("STEP test: Do GPIO action start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ act_id = STEP_ACTION_INDEX_GPIO;
+ /****************************************
+ ************* Test case 1 **************
+ ************* GPIO read #8 *************
+ ****************************************/
+ pr_info("STEP test: TC 1\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "0";
+ params[1] = "8";
+ param_num = 2;
+
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ if (conninfra_step_do_gpio_action(p_act, NULL) == 0) {
+ pr_info("STEP check: Do gpio action TC-1(Read #8): search(8: )");
+ temp_report.check++;
+ } else {
+ pr_err("STEP test case failed: (Do gpio action TC-1) Read #8\n");
+ temp_report.fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: (Do gpio action TC-1) Create failed\n");
+ }
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Do GPIO action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+
+#if 0
+void conninfra_step_test_do_chip_reset_action(struct step_test_report *p_report)
+{
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ struct step_action *p_act = NULL;
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ int param_num;
+
+ pr_info("STEP test: Do chip reset action start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ act_id = STEP_ACTION_INDEX_CHIP_RESET;
+ /****************************************
+ ************* Test case 1 **************
+ ************* chip reset ***************
+ ****************************************/
+ pr_info("STEP test: TC 1\n");
+ param_num = 0;
+
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ if (wmt_step_do_chip_reset_action(p_act, NULL) == 0) {
+ pr_info("STEP check: Do chip reset TC-1(chip reset): Trigger AEE");
+ temp_report.check++;
+ } else {
+ pr_err("STEP test case failed: (Do chip reset action TC-1) chip reset\n");
+ temp_report.fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: (Do chip reset action TC-1) Create failed\n");
+ }
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Do chip reset action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+#endif
+
+#if 0
+void wmt_step_test_do_wakeup_action(struct step_test_report *p_report)
+{
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ struct step_action *p_act = NULL;
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ int param_num;
+
+ pr_info("STEP test: Do wakeup action start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ /****************************************
+ ************* Test case 1 **************
+ ***** Wakeup then read/write reg *******
+ ****************************************/
+ pr_info("STEP test: TC 1\n");
+ act_id = STEP_ACTION_INDEX_KEEP_WAKEUP;
+ param_num = 0;
+
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ wmt_step_do_keep_wakeup_action(p_act, NULL);
+ conninfra_step_test_do_register_action(&temp_report);
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: (Do wakeup) Create failed\n");
+ }
+
+ act_id = STEP_ACTION_INDEX_CANCEL_WAKEUP;
+ param_num = 0;
+
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ wmt_step_do_cancel_wakeup_action(p_act, NULL);
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: (Do cancel wakeup) Create failed\n");
+ }
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Do wakeup action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+#endif
+
+void conninfra_step_test_do_show_action(struct step_test_report *p_report)
+{
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ struct step_action *p_act = NULL;
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ int param_num;
+
+ pr_info("STEP test: Do show action start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ act_id = STEP_ACTION_INDEX_SHOW_STRING;
+ /****************************************
+ ************* Test case 1 **************
+ ********** Show Hello world ************
+ ****************************************/
+ pr_info("STEP test: TC 1\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "Hello_World";
+ param_num = 1;
+
+ g_conninfra_step_test_check.step_check_result_string = "Hello_World";
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ conninfra_step_do_show_string_action(p_act, conninfra_step_test_check_show_act);
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ temp_report.pass++;
+ } else {
+ pr_err("STEP test case failed: Do show TC-1(Show Hello world)\n");
+ temp_report.fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: Do show TC-1(Show Hello world) Create failed\n");
+ }
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Do show action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+
+#if 1
+void conninfra_step_test_do_sleep_action(struct step_test_report *p_report)
+{
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ struct step_action *p_act = NULL;
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ int check_sec_b, check_sec_e;
+ int check_usec_b, check_usec_e;
+ int param_num;
+
+ pr_info("STEP test: Do sleep action start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ act_id = STEP_ACTION_INDEX_SLEEP;
+ /****************************************
+ ************* Test case 1 **************
+ *************** Sleep 1s ***************
+ ****************************************/
+ pr_info("STEP test: TC 1\n");
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "1000";
+ param_num = 1;
+
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ osal_gettimeofday(&check_sec_b, &check_usec_b);
+ conninfra_step_do_sleep_action(p_act, NULL);
+ osal_gettimeofday(&check_sec_e, &check_usec_e);
+ if (check_sec_e > check_sec_b) {
+ temp_report.pass++;
+ } else {
+ pr_err("STEP test case failed: Do show TC-1(Sleep 1s), begin(%d.%d) end(%d.%d)\n",
+ check_sec_b, check_usec_b, check_sec_e, check_usec_e);
+ temp_report.fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: Do show TC-1(Sleep 1s) Create failed\n");
+ }
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Do sleep action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+#endif
+
+#if 1
+void conninfra_step_test_do_condition_action(struct step_test_report *p_report)
+{
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ struct step_action *p_act = NULL;
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ int param_num;
+
+ pr_info("STEP test: Do condition action start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ act_id = STEP_ACTION_INDEX_CONDITION;
+ /****************************************
+ ************* Test case 1 **************
+ *********** Condition equal ************
+ ****************************************/
+ pr_info("STEP test: TC 1\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_temp_register();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$0";
+ params[1] = "$1";
+ params[2] = "==";
+ params[3] = "$2";
+ param_num = 4;
+
+ g_conninfra_step_test_check.step_check_result_value = 1;
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ conninfra_step_do_condition_action(p_act, conninfra_step_test_check_condition);
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ temp_report.pass++;
+ } else {
+ pr_err("STEP test case failed: Do condition TC-1(equal)\n");
+ temp_report.fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: Do condition TC-1(equal) Create failed\n");
+ }
+
+ /****************************************
+ ************* Test case 2 **************
+ ********** Condition greater ***********
+ ****************************************/
+ pr_info("STEP test: TC 2\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_temp_register();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$0";
+ params[1] = "$1";
+ params[2] = ">";
+ params[3] = "$2";
+ param_num = 4;
+ g_infra_step_env.temp_register[1] = 0;
+ g_infra_step_env.temp_register[2] = 1;
+
+ g_conninfra_step_test_check.step_check_result_value = 0;
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ conninfra_step_do_condition_action(p_act, conninfra_step_test_check_condition);
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ temp_report.pass++;
+ } else {
+ pr_err("STEP test case failed: Do condition TC-2(greater)\n");
+ temp_report.fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: Do condition TC-2(greater) Create failed\n");
+ }
+
+ /****************************************
+ ************* Test case 3 **************
+ ******* Condition greater equal ********
+ ****************************************/
+ pr_info("STEP test: TC 3\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_temp_register();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$0";
+ params[1] = "$1";
+ params[2] = ">=";
+ params[3] = "$2";
+ param_num = 4;
+ g_infra_step_env.temp_register[1] = 2;
+ g_infra_step_env.temp_register[2] = 2;
+
+ g_conninfra_step_test_check.step_check_result_value = 1;
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ conninfra_step_do_condition_action(p_act, conninfra_step_test_check_condition);
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ temp_report.pass++;
+ } else {
+ pr_err("STEP test case failed: Do condition TC-3(greater equal)\n");
+ temp_report.fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: Do condition TC-3(greater equal) Create failed\n");
+ }
+
+ /****************************************
+ ************* Test case 4 **************
+ ************ Condition less ************
+ ****************************************/
+ pr_info("STEP test: TC 4\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_temp_register();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$0";
+ params[1] = "$1";
+ params[2] = "<";
+ params[3] = "$2";
+ param_num = 4;
+ g_infra_step_env.temp_register[1] = 10;
+ g_infra_step_env.temp_register[2] = 0;
+
+ g_conninfra_step_test_check.step_check_result_value = 0;
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ conninfra_step_do_condition_action(p_act, conninfra_step_test_check_condition);
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ temp_report.pass++;
+ } else {
+ pr_err("STEP test case failed: Do condition TC-4(less)\n");
+ temp_report.fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: Do condition TC-4(less) Create failed\n");
+ }
+
+ /****************************************
+ ************* Test case 5 **************
+ ********* Condition less equal *********
+ ****************************************/
+ pr_info("STEP test: TC 5\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_temp_register();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$0";
+ params[1] = "$1";
+ params[2] = "<=";
+ params[3] = "$2";
+ param_num = 4;
+ g_infra_step_env.temp_register[1] = 0;
+ g_infra_step_env.temp_register[2] = 10;
+
+ g_conninfra_step_test_check.step_check_result_value = 1;
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ conninfra_step_do_condition_action(p_act, conninfra_step_test_check_condition);
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ temp_report.pass++;
+ } else {
+ pr_err("STEP test case failed: Do condition TC-5(less equal)\n");
+ temp_report.fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: Do condition TC-5(less equal) Create failed\n");
+ }
+
+ /****************************************
+ ************* Test case 6 **************
+ ********* Condition not equal **********
+ ****************************************/
+ pr_info("STEP test: TC 6\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_temp_register();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$1";
+ params[1] = "$2";
+ params[2] = "!=";
+ params[3] = "$3";
+ param_num = 4;
+ g_infra_step_env.temp_register[2] = 3;
+ g_infra_step_env.temp_register[3] = 3;
+
+ g_conninfra_step_test_check.step_check_result_value = 0;
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ conninfra_step_do_condition_action(p_act, conninfra_step_test_check_condition);
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ temp_report.pass++;
+ } else {
+ pr_err("STEP test case failed: Do condition TC-6(not equal)\n");
+ temp_report.fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: Do condition TC-6(not equal) Create failed\n");
+ }
+
+ /****************************************
+ ************* Test case 7 **************
+ ************ Condition and *************
+ ****************************************/
+ pr_info("STEP test: TC 7\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_temp_register();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$1";
+ params[1] = "$2";
+ params[2] = "&&";
+ params[3] = "$3";
+ param_num = 4;
+ g_infra_step_env.temp_register[2] = 0x10;
+ g_infra_step_env.temp_register[3] = 0x00;
+
+ g_conninfra_step_test_check.step_check_result_value = 0;
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ conninfra_step_do_condition_action(p_act, conninfra_step_test_check_condition);
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ temp_report.pass++;
+ } else {
+ pr_err("STEP test case failed: Do condition TC-7(and)\n");
+ temp_report.fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: Do condition TC-7(and) Create failed\n");
+ }
+
+ /****************************************
+ ************* Test case 8 **************
+ ************* Condition or *************
+ ****************************************/
+ pr_info("STEP test: TC 8\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_temp_register();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$1";
+ params[1] = "$2";
+ params[2] = "||";
+ params[3] = "$3";
+ param_num = 4;
+ g_infra_step_env.temp_register[2] = 0x10;
+ g_infra_step_env.temp_register[3] = 0x00;
+
+ g_conninfra_step_test_check.step_check_result_value = 1;
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ conninfra_step_do_condition_action(p_act, conninfra_step_test_check_condition);
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ temp_report.pass++;
+ } else {
+ pr_err("STEP test case failed: Do condition TC-8(or)\n");
+ temp_report.fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: Do condition TC-8(or) Create failed\n");
+ }
+
+ /****************************************
+ ************* Test case 9 **************
+ ****** Condition not equal value *******
+ ****************************************/
+ pr_info("STEP test: TC 9\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_temp_register();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$1";
+ params[1] = "$2";
+ params[2] = "!=";
+ params[3] = "99";
+ param_num = 4;
+ g_infra_step_env.temp_register[2] = 99;
+
+ g_conninfra_step_test_check.step_check_result_value = 0;
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ conninfra_step_do_condition_action(p_act, conninfra_step_test_check_condition);
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ temp_report.pass++;
+ } else {
+ pr_err("STEP test case failed: Do condition TC-9(not equal value)\n");
+ temp_report.fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: Do condition TC-9(not equal value) Create failed\n");
+ }
+
+ /****************************************
+ ************* Test case 10 *************
+ ********* Condition equal value ********
+ ****************************************/
+ pr_info("STEP test: TC 10\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_temp_register();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$1";
+ params[1] = "$2";
+ params[2] = "==";
+ params[3] = "18";
+ param_num = 4;
+ g_infra_step_env.temp_register[2] = 18;
+
+ g_conninfra_step_test_check.step_check_result_value = 1;
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ conninfra_step_do_condition_action(p_act, conninfra_step_test_check_condition);
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ temp_report.pass++;
+ } else {
+ pr_err("STEP test case failed: Do condition TC-10(equal value)\n");
+ temp_report.fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: Do condition TC-10(equal value) Create failed\n");
+ }
+
+ /****************************************
+ ************* Test case 11 *************
+ ****** Condition equal value (HEX) *****
+ ****************************************/
+ pr_info("STEP test: TC 10\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_temp_register();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$1";
+ params[1] = "$2";
+ params[2] = "==";
+ params[3] = "0x18";
+ param_num = 4;
+ g_infra_step_env.temp_register[2] = 24;
+
+ g_conninfra_step_test_check.step_check_result_value = 1;
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ conninfra_step_do_condition_action(p_act, conninfra_step_test_check_condition);
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ temp_report.pass++;
+ } else {
+ pr_err("STEP test case failed: Do condition TC-11(equal value HEX)\n");
+ temp_report.fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: Do condition TC-11(equal value HEX) Create failed\n");
+ }
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Do condition action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+#endif
+
+#if 1
+void conninfra_step_test_do_value_action(struct step_test_report *p_report)
+{
+ enum step_action_id act_id;
+ char *params[STEP_PARAMETER_SIZE];
+ struct step_action *p_act = NULL;
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ int param_num;
+
+ pr_info("STEP test: Do value action start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+ act_id = STEP_ACTION_INDEX_VALUE;
+ /****************************************
+ ************* Test case 1 **************
+ ******* Save value to register *********
+ ****************************************/
+ pr_info("STEP test: TC 1\n");
+ conninfra_step_test_clear_check_data();
+ conninfra_step_test_clear_temp_register();
+ conninfra_step_test_clear_parameter(params);
+ params[0] = "$2";
+ params[1] = "0x66";
+ param_num = 2;
+
+ g_conninfra_step_test_check.step_check_result_value = 0x66;
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ conninfra_step_do_value_action(p_act, conninfra_step_test_check_value_act);
+ if (g_conninfra_step_test_check.step_check_result == TEST_PASS) {
+ temp_report.pass++;
+ } else {
+ pr_err("STEP test case failed: Do show TC-1(Save value to register)");
+ temp_report.fail++;
+ }
+ conninfra_step_remove_action(p_act);
+ } else {
+ temp_report.fail++;
+ pr_err("STEP test case failed: Do show TC-1(Save value to register) Create failed\n");
+ }
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Do value action result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+#endif
+
+#if 1
+void conninfra_step_test_create_periodic_dump(struct step_test_report *p_report)
+{
+ int expires_ms;
+ struct step_test_report temp_report = {0, 0, 0};
+ int sec_begin = 0;
+ int usec_begin = 0;
+ int sec_end = 0;
+ int usec_end = 0;
+ struct step_pd_entry *p_current;
+ bool is_thread_run_for_test = 0;
+
+ pr_info("STEP test: Create periodic dump start\n");
+ osal_gettimeofday(&sec_begin, &usec_begin);
+
+ if (g_infra_step_env.pd_struct.step_pd_wq == NULL) {
+ if (conninfra_step_init_pd_env() != 0) {
+ pr_err("STEP test case failed: Start thread failed\n");
+ return;
+ }
+ is_thread_run_for_test = 1;
+ }
+
+ /****************************************
+ ************* Test case 1 **************
+ *************** Normal *****************
+ ****************************************/
+ pr_info("STEP test: TC 1\n");
+ expires_ms = 5;
+ p_current = conninfra_step_get_periodic_dump_entry(expires_ms);
+ if (p_current == NULL) {
+ pr_err("STEP test case failed: (Create periodic dump TC-1) No entry\n");
+ temp_report.fail++;
+ } else {
+ if (p_current->expires_ms == expires_ms) {
+ temp_report.pass++;
+ } else {
+ pr_err("STEP test case failed: (Create periodic dump TC-1) Currect %d not %d\n",
+ p_current->expires_ms, expires_ms);
+ temp_report.fail++;
+ }
+ list_del_init(&p_current->list);
+ kfree(p_current);
+ }
+
+ if (is_thread_run_for_test == 1)
+ conninfra_step_deinit_pd_env();
+
+ osal_gettimeofday(&sec_end, &usec_end);
+ conninfra_step_test_show_result_report("STEP result: Create periodic dump result",
+ &temp_report, sec_begin, usec_begin, sec_end, usec_end);
+ conninfra_step_test_update_result_report(p_report, &temp_report);
+}
+#endif
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/conninfra_step_test_util.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/conninfra_step_test_util.c
new file mode 100755
index 0000000..b1c59b6
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/conninfra_step_test_util.c
@@ -0,0 +1,577 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#include "conninfra_step.h"
+#include "conninfra_step_test.h"
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <asm/io.h>
+#include "emi_mng.h"
+#include "consys_hw.h"
+#include "consys_reg_mng.h"
+#include "consys_reg_util.h"
+
+
+void conninfra_step_test_update_result(int result, struct step_test_report *p_report, char *err_result)
+{
+ if (result != TEST_FAIL) {
+ p_report->pass++;
+ } else {
+ pr_err("%s", err_result);
+ p_report->fail++;
+ }
+}
+
+void conninfra_step_test_update_result_report(struct step_test_report *p_dest_report,
+ struct step_test_report *p_src_report)
+{
+ p_dest_report->pass += p_src_report->pass;
+ p_dest_report->fail += p_src_report->fail;
+ p_dest_report->check += p_src_report->check;
+}
+
+void conninfra_step_test_show_result_report(char *test_name, struct step_test_report *p_report, int sec_begin, int usec_begin,
+ int sec_end, int usec_end)
+{
+ unsigned int total = 0;
+ unsigned int pass = 0;
+ unsigned int fail = 0;
+ unsigned int check = 0;
+ int sec = 0;
+ int usec = 0;
+
+ pass = p_report->pass;
+ fail = p_report->fail;
+ check = p_report->check;
+
+ if (usec_end >= usec_begin) {
+ sec = sec_end - sec_begin;
+ usec = usec_end - usec_begin;
+ } else {
+ sec = sec_end - sec_begin - 1;
+ usec = usec_end - usec_begin + 1000000;
+ }
+
+ total = pass + fail + check;
+ pr_info("%s Total: %d, PASS: %d, FAIL: %d, CHECK: %d, Spend Time: %d.%.6d\n",
+ test_name, total, pass, fail, check, sec, usec);
+}
+
+static int conninfra_step_test_check_create_read_reg(struct step_register_info *p_reg_info,
+ int check_params[], char *err_result, int check_index)
+{
+ int result = TEST_FAIL;
+
+ if (p_reg_info->address_type == 0 /*STEP_REGISTER_PHYSICAL_ADDRESS*/) {
+ if (p_reg_info->address != check_params[check_index + 1] ||
+ p_reg_info->offset != check_params[check_index + 2]) {
+ pr_err(
+ "%s, C1 reg params: %d, %p, %d\n",
+ err_result, p_reg_info->is_write, p_reg_info->address,
+ p_reg_info->offset);
+ return TEST_FAIL;
+ }
+ } else {
+ if (p_reg_info->address_type != check_params[check_index + 1] ||
+ p_reg_info->offset != check_params[check_index + 2]) {
+ pr_err(
+ "%s, C2 reg params: %d, %p, %d\n",
+ err_result, p_reg_info->is_write, p_reg_info->address,
+ p_reg_info->offset);
+ return TEST_FAIL;
+ }
+ }
+
+ if (p_reg_info->output_mode == STEP_OUTPUT_LOG) {
+ if (p_reg_info->times != check_params[check_index + 3] ||
+ p_reg_info->delay_time != check_params[check_index + 4]) {
+ pr_err(
+ "%s, C3 reg params: %d, %p, %d, %d, %d\n",
+ err_result, p_reg_info->is_write, p_reg_info->address,
+ p_reg_info->offset, p_reg_info->times, p_reg_info->delay_time);
+ result = TEST_FAIL;
+ } else {
+ result = TEST_PASS;
+ }
+ } else if (p_reg_info->output_mode == STEP_OUTPUT_REGISTER) {
+ if (p_reg_info->mask != check_params[check_index + 3] ||
+ p_reg_info->temp_reg_id != check_params[check_index + 4]) {
+ pr_err(
+ "%s, C4 reg params: %d, %p, %d, %d, %d\n",
+ err_result, p_reg_info->is_write, p_reg_info->address,
+ p_reg_info->offset, p_reg_info->mask, p_reg_info->temp_reg_id);
+ result = TEST_FAIL;
+ } else {
+ result = TEST_PASS;
+ }
+ } else {
+ result = TEST_FAIL;
+ }
+
+ return result;
+}
+
+static int conninfra_step_test_check_create_write_reg(struct step_register_info *p_reg_info,
+ int check_params[], char *err_result, int check_index)
+{
+ int result = TEST_FAIL;
+
+ if (p_reg_info->address_type == 0 /*STEP_REGISTER_PHYSICAL_ADDRESS*/) {
+ if (p_reg_info->address != check_params[check_index + 1] ||
+ p_reg_info->offset != check_params[check_index + 2] ||
+ p_reg_info->value != check_params[check_index + 3]) {
+ pr_err(
+ "%s, C1 reg params: %d, %p, %d, %d\n",
+ err_result, p_reg_info->is_write, p_reg_info->address,
+ p_reg_info->offset, p_reg_info->value);
+ result = TEST_FAIL;
+ } else {
+ result = TEST_PASS;
+ }
+ } else {
+ if (p_reg_info->address_type != check_params[check_index + 1] ||
+ p_reg_info->offset != check_params[check_index + 2] ||
+ p_reg_info->value != check_params[check_index + 3]) {
+ pr_err(
+ "%s, C2 reg params: %d, %p, %d, %d\n",
+ err_result, p_reg_info->is_write, p_reg_info->address_type,
+ p_reg_info->offset, p_reg_info->value);
+ result = TEST_FAIL;
+ } else {
+ result = TEST_PASS;
+ }
+ }
+
+ return result;
+}
+
+int conninfra_step_test_check_create_emi(struct step_emi_action *p_emi_act, int check_params[],
+ char *err_result)
+{
+ struct step_emi_info *p_emi_info = NULL;
+ int result = TEST_FAIL;
+
+ p_emi_info = &p_emi_act->info;
+ if (p_emi_act->base.action_id != STEP_ACTION_INDEX_EMI) {
+ pr_err("%s, id wrong: %d\n", err_result, p_emi_act->base.action_id);
+ result = TEST_FAIL;
+ } else if (p_emi_info->output_mode == STEP_OUTPUT_LOG) {
+ if (p_emi_info->is_write != check_params[0] ||
+ p_emi_info->begin_offset != check_params[1] ||
+ p_emi_info->end_offset != check_params[2]) {
+ pr_err("%s, C1 emi log params: %d, %d, %d\n",
+ err_result, p_emi_info->is_write, p_emi_info->begin_offset,
+ p_emi_info->end_offset);
+ result = TEST_FAIL;
+ } else {
+ result = TEST_PASS;
+ }
+ } else if (p_emi_info->output_mode == STEP_OUTPUT_REGISTER) {
+ if (p_emi_info->is_write != check_params[0] ||
+ p_emi_info->begin_offset != check_params[1] ||
+ p_emi_info->mask != check_params[2] ||
+ p_emi_info->temp_reg_id != check_params[3]) {
+ pr_err("%s, C2 emi reg params: %d, %d, %d, %d\n",
+ err_result, p_emi_info->is_write, p_emi_info->begin_offset,
+ p_emi_info->mask, p_emi_info->temp_reg_id);
+ result = TEST_FAIL;
+ } else {
+ result = TEST_PASS;
+ }
+ } else {
+ result = TEST_FAIL;
+ }
+
+ return result;
+}
+
+int conninfra_step_test_check_create_reg(struct step_register_action *p_reg_act, int check_params[],
+ char *err_result)
+{
+ struct step_register_info *p_reg_info = NULL;
+ int result = TEST_FAIL;
+
+ p_reg_info = &p_reg_act->info;
+ if (p_reg_act->base.action_id != STEP_ACTION_INDEX_REGISTER) {
+ pr_err("%s, id wrong: %d\n", err_result, p_reg_act->base.action_id);
+ result = TEST_FAIL;
+ } else if (p_reg_info->is_write != check_params[0]) {
+ pr_err("%s, write failed: %d expect(%d)", err_result, p_reg_info->is_write, check_params[0]);
+ result = TEST_FAIL;
+ } else {
+ if (p_reg_info->is_write == 0)
+ result = conninfra_step_test_check_create_read_reg(p_reg_info, check_params, err_result, 0);
+ else
+ result = conninfra_step_test_check_create_write_reg(p_reg_info, check_params, err_result, 0);
+ }
+
+ return result;
+}
+
+
+
+int conninfra_step_test_check_create_condition_emi(struct step_condition_emi_action *p_cond_emi_act, int check_params[],
+ char *err_result)
+{
+ struct step_emi_info *p_emi_info = NULL;
+ int result = TEST_FAIL;
+
+ p_emi_info = &p_cond_emi_act->info;
+ if (p_cond_emi_act->base.action_id != STEP_ACTION_INDEX_CONDITION_EMI) {
+ pr_err("%s, id wrong: %d\n", err_result, p_cond_emi_act->base.action_id);
+ result = TEST_FAIL;
+ } else if (p_emi_info->output_mode == STEP_OUTPUT_LOG) {
+ if (p_cond_emi_act->cond_reg_id != check_params[0] ||
+ p_emi_info->is_write != check_params[1] ||
+ p_emi_info->begin_offset != check_params[2] ||
+ p_emi_info->end_offset != check_params[3]) {
+ pr_err("%s, C1 emi log params: %d, %d, %d, %d\n",
+ err_result, p_cond_emi_act->cond_reg_id, p_emi_info->is_write,
+ p_emi_info->begin_offset, p_emi_info->end_offset);
+ result = TEST_FAIL;
+ } else {
+ result = TEST_PASS;
+ }
+ } else if (p_emi_info->output_mode == STEP_OUTPUT_REGISTER) {
+ if (p_cond_emi_act->cond_reg_id != check_params[0] ||
+ p_emi_info->is_write != check_params[1] ||
+ p_emi_info->begin_offset != check_params[2] ||
+ p_emi_info->mask != check_params[3] ||
+ p_emi_info->temp_reg_id != check_params[4]) {
+ pr_err("%s, C2 emi reg params: %d, %d, %d, %d, %d\n",
+ err_result, p_cond_emi_act->cond_reg_id, p_emi_info->is_write,
+ p_emi_info->begin_offset, p_emi_info->mask, p_emi_info->temp_reg_id);
+ result = TEST_FAIL;
+ } else {
+ result = TEST_PASS;
+ }
+ } else {
+ result = TEST_FAIL;
+ }
+
+ return result;
+}
+
+int conninfra_step_test_check_create_condition_reg(struct step_condition_register_action *p_cond_reg_act, int check_params[],
+ char *err_result)
+{
+ struct step_register_info *p_reg_info = NULL;
+ int result = TEST_FAIL;
+
+ p_reg_info = &p_cond_reg_act->info;
+ if (p_cond_reg_act->base.action_id != STEP_ACTION_INDEX_CONDITION_REGISTER) {
+ pr_err("%s, id wrong: %d\n", err_result, p_cond_reg_act->base.action_id);
+ result = TEST_FAIL;
+ } else if (p_cond_reg_act->cond_reg_id != check_params[0]) {
+ pr_err("%s, reg id failed: %d expect(%d)", err_result,
+ p_cond_reg_act->cond_reg_id, check_params[0]);
+ result = TEST_FAIL;
+ } else if (p_reg_info->is_write != check_params[1]) {
+ pr_err("%s, write failed: %d expect(%d)", err_result,
+ p_reg_info->is_write, check_params[1]);
+ result = TEST_FAIL;
+ } else {
+ if (p_reg_info->is_write == 0)
+ result = conninfra_step_test_check_create_read_reg(p_reg_info, check_params, err_result, 1);
+ else
+ result = conninfra_step_test_check_create_write_reg(p_reg_info, check_params, err_result, 1);
+ }
+
+ return result;
+}
+
+int conninfra_step_test_check_create_gpio(struct step_gpio_action *p_gpio_act, int check_params[],
+ char *err_result)
+{
+ int result = TEST_FAIL;
+
+ if (p_gpio_act->base.action_id != STEP_ACTION_INDEX_GPIO) {
+ pr_err("%s, id wrong: %d\n", err_result, p_gpio_act->base.action_id);
+ result = TEST_FAIL;
+ } else if (p_gpio_act->is_write != check_params[0]) {
+ pr_err("%s, write failed: %d", err_result, p_gpio_act->is_write);
+ result = TEST_FAIL;
+ } else {
+ if (p_gpio_act->pin_symbol != check_params[1]) {
+ pr_err("%s, gpio params: %d, %d\n",
+ err_result, p_gpio_act->is_write, p_gpio_act->pin_symbol);
+ result = TEST_FAIL;
+ } else {
+ result = TEST_PASS;
+ }
+ }
+
+ return result;
+}
+
+int conninfra_step_test_check_create_periodic_dump(struct step_periodic_dump_action *p_pd_act,
+ int check_params[], char *err_result)
+{
+ int result = TEST_FAIL;
+
+ if (p_pd_act->base.action_id != STEP_ACTION_INDEX_PERIODIC_DUMP) {
+ pr_err("%s, id wrong: %d\n", err_result, p_pd_act->base.action_id);
+ result = TEST_FAIL;
+ } else {
+ result = TEST_PASS;
+ }
+
+ return result;
+}
+
+int conninfra_step_test_check_create_show_string(struct step_show_string_action *p_show_act,
+ int check_params[], char *err_result)
+{
+ int result = TEST_FAIL;
+
+ if (p_show_act->base.action_id != STEP_ACTION_INDEX_SHOW_STRING) {
+ pr_err("%s, id wrong: %d\n", err_result, p_show_act->base.action_id);
+ result = TEST_FAIL;
+ } else {
+ result = TEST_PASS;
+ }
+
+ return result;
+}
+
+int conninfra_step_test_check_create_sleep(struct step_sleep_action *p_sleep_act,
+ int check_params[], char *err_result)
+{
+ int result = TEST_FAIL;
+
+ if (p_sleep_act->base.action_id != STEP_ACTION_INDEX_SLEEP) {
+ pr_err("%s, id wrong: %d\n", err_result, p_sleep_act->base.action_id);
+ result = TEST_FAIL;
+ } else if (p_sleep_act->ms != check_params[0]) {
+ pr_err("%s, param failed: %d expect(%d)", err_result, p_sleep_act->ms, check_params[0]);
+ result = TEST_FAIL;
+ } else {
+ result = TEST_PASS;
+ }
+
+ return result;
+}
+
+int conninfra_step_test_check_create_condition(struct step_condition_action *p_cond_act,
+ int check_params[], char *err_result)
+{
+ int result = TEST_FAIL;
+
+ if (p_cond_act->base.action_id != STEP_ACTION_INDEX_CONDITION) {
+ pr_err("%s, id wrong: %d\n", err_result, p_cond_act->base.action_id);
+ result = TEST_FAIL;
+ } else if (p_cond_act->result_temp_reg_id != check_params[0] ||
+ p_cond_act->l_temp_reg_id != check_params[1] ||
+ p_cond_act->operator_id != check_params[2]) {
+ pr_err("%s, C1 param failed: %d %d %d %d expect(%d %d %d %d)",
+ err_result, p_cond_act->result_temp_reg_id, p_cond_act->l_temp_reg_id,
+ p_cond_act->operator_id, p_cond_act->r_temp_reg_id,
+ check_params[0], check_params[1], check_params[2], check_params[3]);
+ result = TEST_FAIL;
+ } else {
+ if (p_cond_act->mode == STEP_CONDITION_RIGHT_REGISTER && p_cond_act->r_temp_reg_id != check_params[3]) {
+ pr_err("%s, C2 param failed: %d %d %d %d expect(%d %d %d %d)",
+ err_result, p_cond_act->result_temp_reg_id, p_cond_act->l_temp_reg_id,
+ p_cond_act->operator_id, p_cond_act->r_temp_reg_id,
+ check_params[0], check_params[1], check_params[2], check_params[3]);
+ result = TEST_FAIL;
+ } else if (p_cond_act->mode == STEP_CONDITION_RIGHT_VALUE && p_cond_act->value != check_params[3]) {
+ pr_err("%s, C3 param failed: %d %d %d %d expect(%d %d %d %d)",
+ err_result, p_cond_act->result_temp_reg_id, p_cond_act->l_temp_reg_id,
+ p_cond_act->operator_id, p_cond_act->value,
+ check_params[0], check_params[1], check_params[2], check_params[3]);
+ result = TEST_FAIL;
+ } else {
+ result = TEST_PASS;
+ }
+ }
+
+ return result;
+}
+
+int conninfra_step_test_check_create_value(struct step_value_action *p_val_act,
+ int check_params[], char *err_result)
+{
+ int result = TEST_FAIL;
+
+ if (p_val_act->base.action_id != STEP_ACTION_INDEX_VALUE) {
+ pr_err("%s, id wrong: %d\n", err_result, p_val_act->base.action_id);
+ result = TEST_FAIL;
+ } else if (p_val_act->temp_reg_id != check_params[0] ||
+ p_val_act->value != check_params[1]) {
+ pr_err("%s, param failed: %d %d expect(%d %d)",
+ err_result, p_val_act->temp_reg_id, p_val_act->value,
+ check_params[0], check_params[1]);
+ result = TEST_FAIL;
+ } else {
+ result = TEST_PASS;
+ }
+
+ return result;
+}
+
+void conninfra_step_test_create_action(enum step_action_id act_id, int param_num, char *params[], int result_of_action,
+ int check_params[], struct step_test_report *p_report, char *err_result)
+{
+ struct step_action *p_act = NULL;
+ int result = TEST_FAIL;
+
+ p_act = conninfra_step_create_action(STEP_DRV_TYPE_CONNINFRA, act_id, param_num, params);
+ if (p_act != NULL) {
+ switch (p_act->action_id) {
+ case STEP_ACTION_INDEX_EMI:
+ {
+ struct step_emi_action *p_emi_act = NULL;
+
+ p_emi_act = clist_entry_action(emi, p_act);
+ result = conninfra_step_test_check_create_emi(p_emi_act, check_params,
+ err_result);
+ }
+ break;
+ case STEP_ACTION_INDEX_REGISTER:
+ {
+ struct step_register_action *p_reg_act = NULL;
+
+ p_reg_act = clist_entry_action(register, p_act);
+ result = conninfra_step_test_check_create_reg(p_reg_act, check_params,
+ err_result);
+ }
+ break;
+ case STEP_ACTION_INDEX_GPIO:
+ {
+ struct step_gpio_action *p_gpio_act = NULL;
+
+ p_gpio_act = clist_entry_action(gpio, p_act);
+ result = conninfra_step_test_check_create_gpio(p_gpio_act, check_params,
+ err_result);
+ }
+ break;
+ case STEP_ACTION_INDEX_PERIODIC_DUMP:
+ {
+ struct step_periodic_dump_action *p_pd_act = NULL;
+
+ p_pd_act = clist_entry_action(periodic_dump, p_act);
+ result = conninfra_step_test_check_create_periodic_dump(p_pd_act,
+ check_params, err_result);
+ }
+ break;
+ case STEP_ACTION_INDEX_SHOW_STRING:
+ {
+ struct step_show_string_action *p_show_act = NULL;
+
+ p_show_act = clist_entry_action(show_string, p_act);
+ result = conninfra_step_test_check_create_show_string(p_show_act,
+ check_params, err_result);
+ }
+ break;
+ case STEP_ACTION_INDEX_SLEEP:
+ {
+ struct step_sleep_action *p_sleep_act = NULL;
+
+ p_sleep_act = clist_entry_action(sleep, p_act);
+ result = conninfra_step_test_check_create_sleep(p_sleep_act,
+ check_params, err_result);
+ }
+ break;
+ case STEP_ACTION_INDEX_CONDITION:
+ {
+ struct step_condition_action *p_cond_act = NULL;
+
+ p_cond_act = clist_entry_action(condition, p_act);
+ result = conninfra_step_test_check_create_condition(p_cond_act,
+ check_params, err_result);
+ }
+ break;
+ case STEP_ACTION_INDEX_VALUE:
+ {
+ struct step_value_action *p_val_act = NULL;
+
+ p_val_act = clist_entry_action(value, p_act);
+ result = conninfra_step_test_check_create_value(p_val_act,
+ check_params, err_result);
+ }
+ break;
+ case STEP_ACTION_INDEX_CONDITION_EMI:
+ {
+ struct step_condition_emi_action *p_cond_emi_act = NULL;
+
+ p_cond_emi_act = clist_entry_action(condition_emi, p_act);
+ result = conninfra_step_test_check_create_condition_emi(p_cond_emi_act, check_params,
+ err_result);
+ }
+ break;
+ case STEP_ACTION_INDEX_CONDITION_REGISTER:
+ {
+ struct step_condition_register_action *p_cond_reg_act = NULL;
+
+ p_cond_reg_act = clist_entry_action(condition_register, p_act);
+ result = conninfra_step_test_check_create_condition_reg(p_cond_reg_act, check_params,
+ err_result);
+ }
+ break;
+ default:
+ result = TEST_FAIL;
+ break;
+ }
+
+ if (result_of_action == -1)
+ result = TEST_FAIL;
+
+ conninfra_step_remove_action(p_act);
+ } else {
+ if (result_of_action == -1)
+ result = TEST_PASS;
+ else
+ result = TEST_FAIL;
+ }
+ conninfra_step_test_update_result(result, p_report, err_result);
+}
+
+/* this offset only for FPGA */
+#define CONNINFRA_STEP_TEST_EMI_COREDUMP_OFFSET 0x4f000
+/* formal chip use this offset*/
+//#define CONNINFRA_STEP_TEST_EMI_COREDUMP_OFFSET 0x27f000
+
+int conninfra_step_test_get_emi_offset(unsigned char buf[], int offset)
+{
+ struct consys_emi_addr_info *emi_phy_addr = NULL;
+
+ emi_phy_addr = emi_mng_get_phy_addr();
+ if (emi_phy_addr != NULL) {
+ /* TODO: fix this, change the region to coredump */
+ snprintf(buf, 11, "0x%08x", (CONNINFRA_STEP_TEST_EMI_COREDUMP_OFFSET + offset));
+ } else {
+ pr_err("STEP test failed: emi_phy_addr is NULL\n");
+ return -1;
+ }
+ return 0;
+}
+
+static unsigned char __iomem *emi_map_addr = NULL;
+
+unsigned char* conninfra_step_test_get_emi_virt_offset(unsigned int offset)
+{
+ struct consys_emi_addr_info *emi_addr_info = NULL;
+
+ if (emi_map_addr == NULL) {
+ emi_addr_info = emi_mng_get_phy_addr();
+ if (emi_addr_info != NULL) {
+ emi_map_addr = ioremap_nocache(emi_addr_info->emi_ap_phy_addr +
+ CONNINFRA_STEP_TEST_EMI_COREDUMP_OFFSET + offset,
+ 0x100);
+ }
+ }
+ return emi_map_addr;
+}
+
+void conninfra_step_test_put_emi_virt_offset(void)
+{
+ if (emi_map_addr != NULL) {
+ iounmap(emi_map_addr);
+ emi_map_addr = NULL;
+ }
+}
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/conninfra_test.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/conninfra_test.c
new file mode 100755
index 0000000..12ec2fa
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/conninfra_test.c
@@ -0,0 +1,512 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#define pr_fmt(fmt) "conninfra_test@(%s:%d) " fmt, __func__, __LINE__
+
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/proc_fs.h>
+#include "conninfra_test.h"
+#include "osal.h"
+
+#include "conninfra.h"
+#include "conninfra_core.h"
+#include "consys_reg_mng.h"
+
+#include "connsyslog_test.h"
+#include "conf_test.h"
+#include "cal_test.h"
+#include "msg_evt_test.h"
+#include "chip_rst_test.h"
+#include "mailbox_test.h"
+#include "conninfra_step_test.h"
+#include "coredump_test.h"
+#include "consys_hw.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+#define CONNINFRA_TEST_PROCNAME "driver/conninfra_test"
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+static ssize_t conninfra_test_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos);
+static ssize_t conninfra_test_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos);
+
+static int core_tc(int par1, int par2, int par3);
+static int conf_tc(int par1, int par2, int par3);
+static int cal_tc(int par1, int par2, int par3);
+static int msg_evt_tc(int par1, int par2, int par3);
+static int chip_rst_tc(int par1, int par2, int par3);
+static int mailbox_tc(int par1, int par2, int par3);
+static int emi_tc(int par1, int par2, int par3);
+static int log_tc(int par1, int par2, int par3);
+static int thermal_tc(int par1, int par2, int par3);
+static int step_tc(int par1, int par2, int par3);
+static int bus_hang_tc(int par1, int par2, int par3);
+static int dump_tc(int par1, int par2, int par3);
+static int is_bus_hang_tc(int par1, int par2, int par3);
+static int ap_resume_tc(int par1, int par2, int par3);
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+static struct proc_dir_entry *gConninfraTestEntry;
+
+static const CONNINFRA_TEST_FUNC conninfra_test_func[] = {
+ [0x01] = core_tc,
+ [0x02] = conf_tc,
+ [0x03] = msg_evt_tc,
+ [0x04] = chip_rst_tc,
+ [0x05] = cal_tc,
+ [0x06] = mailbox_tc,
+ [0x07] = emi_tc,
+ [0x08] = log_tc,
+ [0x09] = thermal_tc,
+ [0x0a] = step_tc,
+ [0x0b] = bus_hang_tc,
+ [0x0c] = dump_tc,
+ [0x0d] = is_bus_hang_tc,
+ [0x0e] = ap_resume_tc,
+};
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+int core_tc_pwr_on(void)
+{
+ int iret = 0;
+
+ pr_info("Power on test start");
+ iret = conninfra_core_power_on(CONNDRV_TYPE_BT);
+ pr_info("BT power on %s (result = %d)", iret? "fail" : "pass", iret);
+ osal_sleep_ms(100);
+ iret = conninfra_core_power_on(CONNDRV_TYPE_FM);
+ pr_info("FM power on %s (result = %d)", iret? "fail" : "pass", iret);
+ osal_sleep_ms(100);
+ iret = conninfra_core_power_on(CONNDRV_TYPE_GPS);
+ pr_info("GPS power on %s (result = %d)", iret? "fail" : "pass", iret);
+ osal_sleep_ms(100);
+ iret = conninfra_core_power_on(CONNDRV_TYPE_WIFI);
+ pr_info("Wi-Fi power on %s (result = %d)", iret? "fail" : "pass", iret);
+ osal_sleep_ms(200);
+
+ return iret;
+}
+
+int core_tc_pwr_off(void)
+{
+ int iret = 0;
+
+ iret = conninfra_core_power_off(CONNDRV_TYPE_WIFI);
+ pr_info("Wi-Fi power off %s (result = %d)", iret? "fail" : "pass", iret);
+ osal_sleep_ms(100);
+ iret = conninfra_core_power_off(CONNDRV_TYPE_GPS);
+ pr_info("GPS power off %s (result = %d)", iret? "fail" : "pass", iret);
+ osal_sleep_ms(100);
+ iret = conninfra_core_power_off(CONNDRV_TYPE_BT);
+ pr_info("BT power off %s (result = %d)", iret? "fail" : "pass", iret);
+ osal_sleep_ms(100);
+ iret = conninfra_core_power_off(CONNDRV_TYPE_FM);
+ pr_info("FM power off %s (result = %d)", iret? "fail" : "pass", iret);
+
+ return iret;
+}
+
+
+int core_tc(int par1, int par2, int par3)
+{
+ int iret = 0;
+ char* driver_name[CONNDRV_TYPE_MAX] = {
+ "BT",
+ "FM",
+ "GPS",
+ "Wi-Fi",
+ };
+
+ if (par2 == 0) {
+ iret = core_tc_pwr_on();
+ iret = core_tc_pwr_off();
+ } else if (par2 == 1) {
+ if (par3 == 15) {
+ iret = core_tc_pwr_on();
+ } else if (par3 >= CONNDRV_TYPE_BT && par3 <= CONNDRV_TYPE_WIFI) {
+ pr_info("Power on %s test start\n", driver_name[par3]);
+ iret = conninfra_core_power_on(par3);
+ pr_info("Power on %s test, return = %d\n", driver_name[par3], iret);
+ } else {
+ pr_info("No support parameter\n");
+ }
+ } else if (par2 == 2) {
+ if (par3 == 15) {
+ iret = core_tc_pwr_off();
+ } else if (par3 >= CONNDRV_TYPE_BT && par3 <= CONNDRV_TYPE_WIFI) {
+ pr_info("Power off %s test start\n", driver_name[par3]);
+ iret = conninfra_core_power_off(par3);
+ pr_info("Power off %s test, return = %d\n", driver_name[par3], iret);
+ } else {
+ pr_info("No support parameter\n");
+ }
+ } else if (par2 == 3) {
+ if (par3 == 1) {
+ iret = conninfra_core_adie_top_ck_en_on(CONNSYS_ADIE_CTL_FW_WIFI);
+ pr_info(
+ "Turn on adie top ck en (ret=%d), please check 0x1805_2830[6] should be 1\n",
+ iret);
+ } else if (par3 == 0) {
+ iret = conninfra_core_adie_top_ck_en_off(CONNSYS_ADIE_CTL_FW_WIFI);
+ pr_info(
+ "Turn off adie top ck en (ret=%d), please check 0x1805_2830[6] should be 1\n",
+ iret);
+ }
+ }
+ //pr_info("core_tc %s (result = %d)", iret? "fail" : "pass", iret);
+ return 0;
+}
+
+static int conf_tc(int par1, int par2, int par3)
+{
+ return conninfra_conf_test();
+}
+
+static int msg_evt_tc(int par1, int par2, int par3)
+{
+ return msg_evt_test();
+}
+
+static int chip_rst_tc(int par1, int par2, int par3)
+{
+ pr_info("test start");
+ return chip_rst_test();
+}
+
+static int cal_tc(int par1, int par2, int par3)
+{
+ pr_info("test start");
+ return calibration_test();
+}
+
+
+static int mailbox_tc(int par1, int par2, int par3)
+{
+ return mailbox_test();
+}
+
+static int emi_tc(int par1, int par2, int par3)
+{
+#if CFG_CONNINFRA_EMI_SUPPORT
+ unsigned int addr = 0;
+ unsigned int size = 0;
+ int ret = 0;
+
+ pr_info("[%s] start", __func__);
+ conninfra_get_phy_addr(&addr, &size);
+ if (addr == 0 || size == 0) {
+ pr_err("[%s] fail! addr=[0x%x] size=[%u]", __func__, addr, size);
+ ret = -1;
+ } else
+ pr_info("[%s] pass. addr=[0x%x] size=[%u]", __func__, addr, size);
+
+ pr_info("[%s] end", __func__);
+
+ return ret;
+#else
+ pr_info("[%s] EMI function is not supported", __func__);
+ return 0;
+#endif
+}
+
+static int thermal_tc(int par1, int par2, int par3)
+{
+#if CFG_CONNINFRA_THERMAL_SUPPORT
+ int ret, temp;
+
+ ret = core_tc_pwr_on();
+ if (ret) {
+ pr_err("pwr on fail");
+ return -1;
+ }
+ ret = conninfra_core_thermal_query(&temp);
+ pr_info("[%s] thermal res=[%d][%d]", __func__, ret, temp);
+
+ return ret;
+#else
+ pr_info("[%s] Thermal function is not supported", __func__);
+ return 0;
+#endif
+}
+
+static int step_tc(int par1, int par2, int par3)
+{
+#if CFG_CONNINFRA_STEP_SUPPORT
+ int ret;
+
+ ret = core_tc_pwr_on();
+ if (ret) {
+ pr_err("pwr on fail");
+ return -1;
+ }
+
+ conninfra_core_force_conninfra_wakeup();
+ conninfra_step_test_all();
+ conninfra_core_force_conninfra_sleep();
+#else
+ pr_info("[%s] function not support", __func__);
+#endif
+ return 0;
+}
+
+static int log_tc(int par1, int par2, int par3)
+{
+#if CFG_CONNINFRA_FW_LOG_SUPPORT
+ /* 0: initial state
+ * 1: log has been init.
+ */
+ static int log_status = 0;
+ int ret = 0;
+
+ if (par2 == 0) {
+ if (log_status != 0) {
+ pr_info("log has been init.\n");
+ return 0;
+ }
+ /* init */
+ ret = connlog_test_init();
+ if (ret)
+ pr_err("FW log init fail! ret=%d\n", ret);
+ else {
+ log_status = 1;
+ pr_info("FW log init finish. Check result on EMI.\n");
+ }
+ } else if (par2 == 1) {
+ /* add fake log */
+ /* read log */
+ connlog_test_read();
+ } else if (par2 == 2) {
+ /* deinit */
+ if (log_status == 0) {
+ pr_info("log didn't init\n");
+ return 0;
+ }
+ ret = connlog_test_deinit();
+ if (ret)
+ pr_err("FW log deinit fail! ret=%d\n", ret);
+ else
+ log_status = 0;
+ }
+ return ret;
+#else
+ pr_info("[%s] function not support", __func__);
+ return 0;
+#endif
+}
+
+
+static int bus_hang_tc(int par1, int par2, int par3)
+{
+#if CFG_CONNINFRA_BUS_HANG_DEBUG_SUPPORT
+ int r;
+ r = conninfra_core_is_bus_hang();
+
+ pr_info("[%s] r=[%d]\n", __func__, r);
+#else
+ pr_info("[%s] function not support", __func__);
+#endif
+ return 0;
+}
+
+static int dump_tc(int par1, int par2, int par3)
+{
+#if CFG_CONNINFRA_COREDUMP_SUPPORT
+ return coredump_test(par1, par2, par3);
+#else
+ pr_info("[%s] function not support", __func__);
+ return 0;
+#endif
+}
+
+static int is_bus_hang_tc(int par1, int par2, int par3)
+{
+#if CFG_CONNINFRA_BUS_HANG_DEBUG_SUPPORT
+ int r;
+
+ r = consys_reg_mng_reg_readable();
+ pr_info("[%s] r=[%d]", __func__, r);
+ r = consys_reg_mng_is_bus_hang();
+ pr_info("[%s] r=[%d]", __func__, r);
+#else
+ pr_info("[%s] function not support", __func__);
+#endif
+ return 0;
+}
+
+static int ap_resume_tc(int par1, int par2, int par3)
+{
+ return 0;
+}
+
+ssize_t conninfra_test_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ return 0;
+}
+
+ssize_t conninfra_test_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos)
+{
+ size_t len = count;
+ char buf[256];
+ char *pBuf;
+ char *pDelimiter = " \t";
+ int x = 0, y = 0, z = 0;
+ char *pToken = NULL;
+ long res = 0;
+ static bool test_enabled = false;
+
+ pr_info("write parameter len = %d\n\r", (int) len);
+ if (len >= osal_sizeof(buf)) {
+ pr_err("input handling fail!\n");
+ len = osal_sizeof(buf) - 1;
+ return -1;
+ }
+
+ if (copy_from_user(buf, buffer, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ pr_info("write parameter data = %s\n\r", buf);
+
+ pBuf = buf;
+ pToken = osal_strsep(&pBuf, pDelimiter);
+ if (pToken != NULL) {
+ osal_strtol(pToken, 16, &res);
+ x = (int)res;
+ } else {
+ x = 0;
+ }
+
+ pToken = osal_strsep(&pBuf, "\t\n ");
+ if (pToken != NULL) {
+ osal_strtol(pToken, 16, &res);
+ y = (int)res;
+ pr_info("y = 0x%08x\n\r", y);
+ } else {
+ y = 3000;
+ /*efuse, register read write default value */
+ if (0x11 == x || 0x12 == x || 0x13 == x)
+ y = 0x80000000;
+ }
+
+ pToken = osal_strsep(&pBuf, "\t\n ");
+ if (pToken != NULL) {
+ osal_strtol(pToken, 16, &res);
+ z = (int)res;
+ } else {
+ z = 10;
+ /*efuse, register read write default value */
+ if (0x11 == x || 0x12 == x || 0x13 == x)
+ z = 0xffffffff;
+ }
+
+ pr_info("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z);
+
+ /* For eng and userdebug load, have to enable conninfra_test by
+ * writing 0xDB9DB9 to * "/proc/driver/conninfra_test" to avoid
+ * some malicious use
+ */
+ if (x == 0xDB9DB9) {
+ test_enabled = true;
+ return len;
+ }
+
+ if (!test_enabled) {
+ pr_err("Please enable conninfra test first");
+ return len;
+ }
+
+ if (osal_array_size(conninfra_test_func) > x &&
+ NULL != conninfra_test_func[x])
+ (*conninfra_test_func[x]) (x, y, z);
+ else
+ pr_warn("no handler defined for command id(0x%08x)\n\r", x);
+
+ return len;
+
+}
+
+
+int conninfra_test_setup(void)
+{
+ static const struct file_operations conninfra_test_fops = {
+ .owner = THIS_MODULE,
+ .read = conninfra_test_read,
+ .write = conninfra_test_write,
+ };
+ int i_ret = 0;
+
+ gConninfraTestEntry = proc_create(CONNINFRA_TEST_PROCNAME,
+ 0664, NULL, &conninfra_test_fops);
+ if (gConninfraTestEntry == NULL) {
+ pr_err("Unable to create / wmt_aee proc entry\n\r");
+ i_ret = -1;
+ }
+
+ return i_ret;
+}
+
+int conninfra_test_remove(void)
+{
+ if (gConninfraTestEntry != NULL)
+ proc_remove(gConninfraTestEntry);
+ return 0;
+}
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/connsyslog_test.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/connsyslog_test.c
new file mode 100644
index 0000000..eabcdc3
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/connsyslog_test.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+#define pr_fmt(fmt) "connlog_test@(%s:%d) " fmt, __func__, __LINE__
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+#include <linux/printk.h>
+
+#include "conninfra.h"
+#include "connsys_debug_utility.h"
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+static void connlog_test_event_handler(void);
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+#define TEST_LOG_BUF_SIZE 1*2014
+
+static char test_buf[TEST_LOG_BUF_SIZE];
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+static void connlog_test_event_handler(void)
+{
+ ssize_t read = 0;
+ pr_info("connlog_test_event_handler\n");
+
+ read = connsys_log_read(CONN_DEBUG_TYPE_WIFI, test_buf, TEST_LOG_BUF_SIZE);
+ pr_info("Read %u:\n", read);
+ connsys_log_dump_buf("log_test", test_buf, read);
+ pr_info("============================================\n");
+}
+
+int connlog_test_init(void)
+{
+ unsigned int emi_addr = 0;
+ unsigned int emi_size = 0;
+ int ret;
+
+ conninfra_get_phy_addr(&emi_addr, &emi_size);
+ if (!emi_addr || !emi_size) {
+ pr_err("EMI init fail.\n");
+ return 1;
+ }
+
+ ret = connsys_dedicated_log_path_apsoc_init(emi_addr);
+ if (ret) {
+ pr_err("connsys_dedicated_log_path_apsoc_init should fail\n");
+ return 2;
+ } else {
+ pr_info("connsys_dedicated_log_path_apsoc_init return fail as expection\n");
+ }
+
+ ret = connsys_log_init(CONN_DEBUG_TYPE_WIFI);
+ if (ret) {
+ pr_err("Init connsys log failed\n");
+ return 3;
+ }
+ connsys_log_register_event_cb(CONN_DEBUG_TYPE_WIFI, connlog_test_event_handler);
+ return 0;
+}
+
+int connlog_test_read(void)
+{
+ connsys_log_irq_handler(CONN_DEBUG_TYPE_WIFI);
+ return 0;
+}
+
+int connlog_test_deinit(void)
+{
+ connsys_log_deinit(CONN_DEBUG_TYPE_WIFI);
+ return 0;
+}
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/dump_test.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/dump_test.c
new file mode 100755
index 0000000..c1719f7
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/dump_test.c
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+#define pr_fmt(fmt) "dump_test@(%s:%d) " fmt, __func__, __LINE__
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+#include <linux/delay.h>
+#include <linux/printk.h>
+
+#include "conninfra.h"
+#include "connsys_debug_utility.h"
+
+#include "coredump_test.h"
+#include "coredump/conndump_netlink.h"
+
+#include "msg_thread.h"
+
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+static int coredump_test_init(void);
+static int coredump_test_start(void);
+static int coredump_test_deinit(void);
+
+static int dump_test_reg_readable(void);
+static void dump_test_poll_cpu_pcr(unsigned int times, unsigned int sleep);
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+static void* g_dumpCtx = 0;
+static int nl_init = 0;
+struct msg_thread_ctx g_msg_ctx;
+
+static int init = 0;
+
+typedef enum {
+ DUMP_TEST_OPID_1 = 0,
+ DUMP_TEST_OPID_2 = 1,
+ DUMP_TEST_OPID_MAX
+} test_opid;
+
+
+static int opfunc_test_1(struct msg_op_data *op);
+static int opfunc_test_2(struct msg_op_data *op);
+
+static const msg_opid_func test_op_func[] = {
+ [DUMP_TEST_OPID_1] = opfunc_test_1,
+ [DUMP_TEST_OPID_2] = opfunc_test_2,
+};
+
+struct coredump_event_cb g_cb = {
+ .reg_readable = dump_test_reg_readable,
+ .poll_cpupcr = dump_test_poll_cpu_pcr,
+};
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+static int dump_test_reg_readable(void)
+{
+ return 1;
+}
+
+static void dump_test_poll_cpu_pcr(unsigned int times, unsigned int sleep)
+{
+ pr_info("[%s]\n", __func__);
+}
+
+#define TEST_STRING "this is coredump test"
+
+static int coredump_test_start(void)
+{
+
+ if (!g_dumpCtx) {
+ pr_err("coredump contxt is not init\n");
+ return 1;
+ }
+#if 0
+ pr_info("[%s] tc[0] test case\n", __func__);
+ /* Trigger interrupt */
+ connsys_coredump_setup_tc(g_dumpCtx, 0);
+
+ /* Start to dump */
+ connsys_coredump_start(g_dumpCtx, 0);
+
+ pr_info("[%s] sleep\n", __func__);
+ msleep(5000);
+
+ pr_info("[%s] tc[1] test case\n", __func__);
+ /* Trigger interrupt */
+ connsys_coredump_setup_tc(g_dumpCtx, 1);
+ /* Start to dump */
+ connsys_coredump_start(g_dumpCtx, 0);
+
+ pr_info("[%s] tc[2] test case\n", __func__);
+ /* Trigger interrupt */
+ connsys_coredump_setup_tc(g_dumpCtx, 2);
+ /* Start to dump */
+ connsys_coredump_start(g_dumpCtx, 0);
+#endif
+
+ pr_info("[%s] end\n", __func__);
+ return 0;
+
+}
+
+static int coredump_nl_start(void)
+{
+ int ret;
+
+
+ ret = conndump_netlink_send_to_native(CONN_DEBUG_TYPE_WIFI, "[M]", TEST_STRING, osal_strlen(TEST_STRING));
+ pr_info("send ret=%d", ret);
+ ret = conndump_netlink_send_to_native(CONN_DEBUG_TYPE_WIFI, "[EMI]", NULL, 0);
+ pr_info("send emi dump ret=%d", ret);
+ return 0;
+}
+
+static int coredump_test_init(void)
+{
+ unsigned int emi_addr = 0;
+ unsigned int emi_size = 0;
+
+ if (g_dumpCtx) {
+ pr_err("log handler has been init. Need to deinit.\n");
+ return 1;
+ }
+
+ conninfra_get_phy_addr(&emi_addr, &emi_size);
+ if (!emi_addr || !emi_size) {
+ pr_err("EMI init fail.\n");
+ return 2;
+ }
+
+ pr_info("emi_addr=0x%08x, size=%d", emi_addr, emi_size);
+
+ g_dumpCtx = connsys_coredump_init(
+ CONN_DEBUG_TYPE_WIFI, &g_cb);
+
+ if (!g_dumpCtx) {
+ pr_err("Coredump init fail.\n");
+ return 3;
+ }
+
+ return 0;
+
+}
+
+static void coredump_end_cb(void* ctx) {
+ pr_info("Get dump end");
+}
+
+static int coredump_nl_init(void)
+{
+ int ret;
+ struct netlink_event_cb nl_cb;
+
+ if (!nl_init) {
+ nl_cb.coredump_end = coredump_end_cb;
+ ret = conndump_netlink_init(CONN_DEBUG_TYPE_WIFI, NULL, &nl_cb);
+ pr_info("init get %d", ret);
+ nl_init = 1;
+ }
+ return 0;
+}
+
+static int coredump_test_deinit(void)
+{
+ if (!g_dumpCtx) {
+ pr_err("coredump contxt is not init\n");
+ return 1;
+ }
+
+ connsys_coredump_deinit(g_dumpCtx);
+ return 0;
+}
+
+static int coredump_nl_deinit(void)
+{
+ nl_init = 0;
+ return 0;
+}
+
+int opfunc_test_1(struct msg_op_data *op)
+{
+ int tc = op->op_data[0];
+ int ret = 0;
+
+ pr_info("[%s] param=[%d]", __func__, tc);
+ switch (tc) {
+ case 0:
+ ret = coredump_test_init();
+ break;
+ case 1:
+ ret = coredump_test_start();
+ break;
+ case 2:
+ ret = coredump_test_deinit();
+ break;
+ }
+ pr_info("ret = %d", ret);
+ return 0;
+}
+
+int opfunc_test_2(struct msg_op_data *op)
+{
+ int tc = op->op_data[0];
+ int ret = 0;
+
+ pr_info("[%s] param=[%d]", __func__, tc);
+
+ switch (tc) {
+ case 0:
+ ret = coredump_nl_init();
+ break;
+ case 1:
+ ret = coredump_nl_start();
+ break;
+ case 2:
+ ret = coredump_nl_deinit();
+ break;
+ }
+ pr_info("ret = %d", ret);
+ return 0;
+}
+
+int coredump_test(int par1, int par2, int par3)
+{
+ pr_info("Disable coredump test in SQC\n");
+ init = 1;
+ return 0;
+#if 0
+ int ret = 0;
+
+ if (init == 0) {
+ ret = msg_thread_init(
+ &g_msg_ctx, "DumptestThread", test_op_func, DUMP_TEST_OPID_MAX);
+ init = 1;
+ }
+ if (par2 == 0xff && par3 == 0xff && init) {
+ pr_info("End test");
+ msg_thread_deinit(&g_msg_ctx);
+ init = 0;
+ }
+
+ msg_thread_send_1(&g_msg_ctx, par2, par3);
+
+ return 0;
+#endif
+}
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/cal_test.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/cal_test.h
new file mode 100755
index 0000000..da917ca
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/cal_test.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _CAL_TEST_H_
+#define _CAL_TEST_H_
+
+#include "osal.h"
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+int calibration_test(void);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _CAL_TEST_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/chip_rst_test.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/chip_rst_test.h
new file mode 100755
index 0000000..b9b413a
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/chip_rst_test.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _CHIP_RST_TEST_H_
+#define _CHIP_RST_TEST_H_
+
+#include "osal.h"
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+int chip_rst_test(void);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _CHIP_RST_TEST_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/conf_test.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/conf_test.h
new file mode 100755
index 0000000..a5aa7bd
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/conf_test.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _CONF_TEST_H_
+#define _CONF_TEST_H_
+
+#include "osal.h"
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+int conninfra_conf_test(void);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _CONF_TEST_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/conninfra_core_test.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/conninfra_core_test.h
new file mode 100755
index 0000000..fcc964a
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/conninfra_core_test.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _CONNINFRA_CORE_TEST_H_
+#define _CONNINFRA_CORE_TEST_H_
+
+#include "osal.h"
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+#define WMT_FUNC_CTRL_ON (MTK_WCN_BOOL_TRUE)
+#define WMT_FUNC_CTRL_OFF (MTK_WCN_BOOL_FALSE)
+
+#define INIT_CMD(c, e, s) {.cmd = c, .cmdSz = sizeof(c), .evt = e, .evtSz = sizeof(e), .str = s}
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _CONNINFRA_CORE_TEST_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/conninfra_step_test.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/conninfra_step_test.h
new file mode 100755
index 0000000..43d1ea3
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/conninfra_step_test.h
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#ifndef _CONNINFRA_STEP_TEST_H_
+#define _CONNINFRA_STEP_TEST_H_
+
+#include "osal.h"
+#include "conninfra_step.h"
+
+#define STEP_TEST_CONSYS_EMI_WMT_OFFSET 0x68000
+
+#define TEST_FAIL -1
+#define TEST_PASS 0
+#define TEST_CHECK 1
+#define STEP_TEST_ACTION_NUMBER 30
+
+extern struct step_env_struct g_infra_step_env;
+extern struct platform_device *g_pdev;
+
+struct step_test_report {
+ unsigned int pass;
+ unsigned int fail;
+ unsigned int check;
+};
+
+struct step_test_scn_tp_act {
+ int tp_id;
+ int act_id;
+ int param_num;
+ const char* params[STEP_PARAMETER_SIZE];
+};
+struct step_test_scenario {
+ const char* title;
+ int test_idx;
+ int total_test_sz;
+ struct step_test_scn_tp_act pt_acts[STEP_TEST_ACTION_NUMBER];
+};
+
+struct step_test_check {
+ unsigned int step_check_total;
+ int step_check_test_tp_id[STEP_TEST_ACTION_NUMBER];
+ int step_check_test_act_id[STEP_TEST_ACTION_NUMBER];
+ char *step_check_params[STEP_TEST_ACTION_NUMBER][STEP_PARAMETER_SIZE];
+ int step_check_params_num[STEP_TEST_ACTION_NUMBER];
+ unsigned int step_check_index;
+ int step_check_result;
+ char *step_check_result_string;
+ int step_check_result_value;
+ unsigned int step_check_emi_offset[STEP_TEST_ACTION_NUMBER];
+ size_t step_check_register_addr;
+ size_t step_check_write_value;
+ unsigned int step_test_mask;
+ unsigned int step_recovery_value;
+ int step_check_temp_register_id;
+
+ struct step_test_scenario* cur_test_scn;
+};
+
+
+
+/* step test utility ++++ */
+
+void conninfra_step_test_show_result_report(char *test_name, struct step_test_report *p_report, int sec_begin, int usec_begin,
+ int sec_end, int usec_end);
+void conninfra_step_test_update_result_report(struct step_test_report *p_dest_report,
+ struct step_test_report *p_src_report);
+
+void conninfra_step_test_create_action(enum step_action_id act_id, int param_num, char *params[], int result_of_action,
+ int check_params[], struct step_test_report *p_report, char *err_result);
+
+void conninfra_step_test_update_result(int result, struct step_test_report *p_report, char *err_result);
+/* step test utility ---- */
+
+void conninfra_step_test_all(void);
+void conninfra_step_test_read_file(struct step_test_report *p_report);
+//void conninfra_step_test_parse_data1(struct step_test_report *p_report);
+//void conninfra_step_test_parse_data1(struct step_test_report *p_report);
+
+/* EMI test utility */
+int conninfra_step_test_get_emi_offset(unsigned char buf[], int offset);
+unsigned char* conninfra_step_test_get_emi_virt_offset(unsigned int offset);
+void conninfra_step_test_put_emi_virt_offset(void);
+
+/* reg test utility */
+//int conninfra_step_test_find_can_write_register(void);
+//int conninfra_step_test_get_reg_base_phy_addr(unsigned char buf[], unsigned int index);
+
+/* unchecked ++++ */
+//void wmt_step_test_create_emi_action(struct step_test_report *p_report);
+//void wmt_step_test_create_cond_emi_action(struct step_test_report *p_report);
+//void wmt_step_test_create_register_action(struct step_test_report *p_report);
+//void wmt_step_test_create_cond_register_action(struct step_test_report *p_report);
+//void wmt_step_test_check_register_symbol(struct step_test_report *p_report);
+//void wmt_step_test_create_other_action(struct step_test_report *p_report);
+//void wmt_step_test_do_emi_action(struct step_test_report *p_report);
+//void wmt_step_test_do_cond_emi_action(struct step_test_report *p_report);
+//void wmt_step_test_do_register_action(struct step_test_report *p_report);
+//void wmt_step_test_do_cond_register_action(struct step_test_report *p_report);
+//void conninfra_step_test_do_gpio_action(struct step_test_report *p_report);
+//void conninfra_step_test_do_chip_reset_action(struct step_test_report *p_report);
+//void conninfra_step_test_create_periodic_dump(struct step_test_report *p_report);
+//void conninfra_step_test_do_show_action(struct step_test_report *p_report);
+//void conninfra_step_test_do_sleep_action(struct step_test_report *p_report);
+//void conninfra_step_test_do_condition_action(struct step_test_report *p_report);
+//void conninfra_step_test_do_value_action(struct step_test_report *p_report);
+
+/* No need */
+//void wmt_step_test_do_disable_reset_action(struct step_test_report *p_report);
+//void wmt_step_test_do_wakeup_action(struct step_test_report *p_report);
+
+/* unchecked ---- */
+
+
+#endif /* end of _CONNINFRA_STEP_TEST_H_ */
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/conninfra_test.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/conninfra_test.h
new file mode 100755
index 0000000..4710e67
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/conninfra_test.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _CONNINFRA_TEST_H_
+#define _CONNINFRA_TEST_H_
+
+#include "osal.h"
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+#define INIT_CMD(c, e, s) {.cmd = c, .cmdSz = sizeof(c), .evt = e, .evtSz = sizeof(e), .str = s}
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+typedef int(*CONNINFRA_TEST_FUNC) (int par1, int par2, int par3);
+
+int conninfra_test_setup(void);
+int conninfra_test_remove(void);
+
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _CONNINFRA_CORE_TEST_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/connsyslog_test.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/connsyslog_test.h
new file mode 100644
index 0000000..f6e6988
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/connsyslog_test.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+#ifndef _CONNLOG_TEST_H_
+#define _CONNLOG_TEST_H_
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+int connlog_test_init(void);
+int connlog_test_read(void);
+int connlog_test_deinit(void);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _CONNLOG_TEST_H_ */
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/coredump_test.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/coredump_test.h
new file mode 100755
index 0000000..3934ca7
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/coredump_test.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#ifndef _COREDUMP_TEST_H_
+#define _COREDUMP_TEST_H_
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+int coredump_test(int par1, int par2, int par3);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _COREDUMP_TEST_H_ */
+
+
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/mailbox_test.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/mailbox_test.h
new file mode 100755
index 0000000..9935352
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/mailbox_test.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _MAILBOX_TEST_H_
+#define _MAILBOX_TEST_H_
+
+#include "osal.h"
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+int mailbox_test(void);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _MAILBOX_TEST_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/msg_evt_test.h b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/msg_evt_test.h
new file mode 100755
index 0000000..617c657
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/include/msg_evt_test.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#ifndef _MSG_EVT_TEST_H_
+#define _MSG_EVT_TEST_H_
+
+#include "osal.h"
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+int msg_evt_test(void);
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+#endif /* _MSG_EVT_TEST_H_ */
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/mailbox_test.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/mailbox_test.c
new file mode 100755
index 0000000..38c48d2
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/mailbox_test.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+#include <linux/mailbox_client.h>
+#include "consys_hw.h"
+#include "conninfra_core_test.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+struct demo_client {
+ struct mbox_client cl;
+ struct mbox_chan *mbox;
+ struct completion c;
+ bool async;
+};
+
+
+static void message_from_remote(struct mbox_client *cl, void *msg)
+{
+ struct demo_client *dc = container_of(cl, struct demo_client, cl);
+ if (dc->async) {
+ pr_info("AAAAsync");
+ } else {
+ pr_info("SSSSSSSync");
+ }
+}
+
+static void sample_sent(struct mbox_client *cl, void *msg, int r)
+{
+ struct demo_client *dc = container_of(cl, struct demo_client, cl);
+ complete(&dc->c);
+}
+
+int mailbox_test(void)
+{
+ struct demo_client *dc_sync;
+ struct platform_device *pdev = get_consys_device();
+
+ dc_sync = kzalloc(sizeof(*dc_sync), GFP_KERNEL);
+ dc_sync->cl.dev = &pdev->dev;
+ dc_sync->cl.rx_callback = message_from_remote;
+ dc_sync->cl.tx_done = sample_sent;
+ dc_sync->cl.tx_block = true;
+ dc_sync->cl.tx_tout = 500;
+ dc_sync->cl.knows_txdone = false;
+ dc_sync->async = false;
+
+ dc_sync->mbox = mbox_request_channel(&dc_sync->cl, 0);
+
+ if (IS_ERR(dc_sync->mbox)) {
+ kfree(dc_sync);
+ pr_err("request channel fail [%ld]", PTR_ERR(dc_sync->mbox));
+ return -1;
+ }
+ mbox_send_message(dc_sync->mbox, 0);
+
+ wait_for_completion(&dc_sync->c);
+ kfree(dc_sync);
+
+ return 0;
+}
diff --git a/src/kernel/modules/connectivity/2.0/conninfra_driver/test/msg_evt_test.c b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/msg_evt_test.c
new file mode 100755
index 0000000..6efd310
--- /dev/null
+++ b/src/kernel/modules/connectivity/2.0/conninfra_driver/test/msg_evt_test.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2016 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+/*! \file
+* \brief Declaration of library functions
+*
+* Any definitions in this file will be shared among GLUE Layer and internal Driver Stack.
+*/
+
+#define pr_fmt(fmt) "msg_evt_test@(%s:%d) " fmt, __func__, __LINE__
+
+#include <linux/slab.h>
+#include <linux/gfp.h>
+#include <linux/mm.h>
+#include "msg_thread.h"
+#include "msg_evt_test.h"
+
+/*******************************************************************************
+* C O M P I L E R F L A G S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* M A C R O S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* E X T E R N A L R E F E R E N C E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* C O N S T A N T S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* D A T A T Y P E S
+********************************************************************************
+*/
+
+/*******************************************************************************
+* F U N C T I O N D E C L A R A T I O N S
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P U B L I C D A T A
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* P R I V A T E D A T A
+********************************************************************************
+*/
+
+
+/*******************************************************************************
+* F U N C T I O N S
+********************************************************************************
+*/
+
+struct work_struct rst_worker;
+struct msg_thread_ctx g_ctx;
+
+typedef enum {
+ INFRA_TEST_OPID_1 = 0,
+ INFRA_TEST_OPID_2 = 1,
+ INFRA_TEST_OPID_MAX
+} test_opid;
+
+
+static int opfunc_test_1(struct msg_op_data *op);
+static int opfunc_test_2(struct msg_op_data *op);
+
+static const msg_opid_func test_op_func[] = {
+ [INFRA_TEST_OPID_1] = opfunc_test_1,
+ [INFRA_TEST_OPID_2] = opfunc_test_2,
+};
+
+int opfunc_test_1(struct msg_op_data *op)
+{
+ pr_info("[%s]", __func__);
+ return 0;
+}
+
+int opfunc_test_2(struct msg_op_data *op)
+{
+ unsigned int drv_type = op->op_data[0];
+
+ pr_info("[%s] param=[%d]", __func__, drv_type);
+ return 0;
+}
+
+
+static void msg_thrd_handler(struct work_struct *work)
+{
+ msg_thread_send_1(&g_ctx, INFRA_TEST_OPID_2, 2011);
+ osal_sleep_ms(5);
+ msg_thread_send_wait_1(&g_ctx, INFRA_TEST_OPID_2, 0, 2022);
+ msg_thread_send_wait_1(&g_ctx, INFRA_TEST_OPID_2, 0, 2033);
+}
+
+int msg_evt_test(void)
+{
+ int ret;
+
+ INIT_WORK(&rst_worker, msg_thrd_handler);
+
+ ret = msg_thread_init(&g_ctx, "TestThread",
+ test_op_func, INFRA_TEST_OPID_MAX);
+ if (ret) {
+ pr_err("inti msg_thread fail ret=[%d]\n", ret);
+ return -2;
+ }
+
+ schedule_work(&rst_worker);
+
+ msg_thread_send_wait_1(&g_ctx, INFRA_TEST_OPID_2, 0, 1011);
+ //osal_sleep_ms(10);
+ msg_thread_send_1(&g_ctx, INFRA_TEST_OPID_2, 1022);
+ osal_sleep_ms(10);
+ msg_thread_send_wait_1(&g_ctx, INFRA_TEST_OPID_2, 0, 1033);
+
+ osal_sleep_ms(1000);
+
+ pr_info("<<<<<>>>>>>> freeOpq=[%u][%u] ActiveQ=[%u][%u]",
+ g_ctx.free_op_q.write, g_ctx.free_op_q.read,
+ g_ctx.active_op_q.write, g_ctx.active_op_q.read);
+ osal_sleep_ms(500);
+
+ ret = msg_thread_deinit(&g_ctx);
+ pr_info("[%s] msg_thread_deinit\n", __func__);
+
+ pr_info("[%s] test PASS\n", __func__);
+ return 0;
+}
+
+