[Feature][Modem]Update MTK MODEM V1.6 baseline version: MOLY.NR15.R3.MD700.IVT.MP1MR3.MP.V1.6
MTK modem version: MT2735_IVT_MOLY.NR15.R3.MD700.IVT.MP1MR3.MP.V1.6.tar.gz
RF modem version: NA
Change-Id: I45a4c2752fa9d1a618beacd5d40737fb39ab64fb
diff --git a/mcu/driver/devdrv/spmi/src/dcl_spmi.c b/mcu/driver/devdrv/spmi/src/dcl_spmi.c
new file mode 100644
index 0000000..e0a2cfe
--- /dev/null
+++ b/mcu/driver/devdrv/spmi/src/dcl_spmi.c
@@ -0,0 +1,480 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2005
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ * dcl_pmu.c
+ *
+ * Project:
+ * --------
+ * MOLY
+ *
+ * Description:
+ * ------------
+ * This Module defines DCL (Driver Common Layer) of the PMIC driver.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ * HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+#include "kal_debug.h"
+#include "kal_public_api.h"
+#include "kal_hrt_api.h"
+#include "intrCtrl.h"
+#include "dcl.h"
+#include "pmif.h"
+#include "spmi.h"
+#include "pmif_sw.h"
+#include "spmi_sw.h"
+#include "us_timer.h"
+#include "drv_features.h"
+
+#if defined (DRV_SPMI_OFF) || DRV_SPMI_NOT_SUPPORT
+
+DCL_STATUS DclSPMI_Initialize(void)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_HANDLE DclSPMI_Open(DCL_DEV dev, DCL_FLAGS flags)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSPMI_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSPMI_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSPMI_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSPMI_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSPMI_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSPMI_Close(DCL_HANDLE handle)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+#else /* DRV_SPMI_OFF */
+SPMI_CONTROL_HANDLER spmi_control_handler = 0;
+static DCL_UINT32 dcl_spmi_handle_count = 0;
+
+/*************************************************************************
+* FUNCTION
+* DclSPMI_Initialize
+*
+* DESCRIPTION
+* This function is to initialize SPMI module
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* STATUS_OK
+*
+*************************************************************************/
+DCL_STATUS DclSPMI_Initialize(void)
+{
+#if defined(MT6885) || defined(MT6873) || defined(MERCURY)
+ pmif_spmi_init(SPMI_MASTER_0);
+#elif defined(MT6853)
+#if defined(MT6315)
+ pmif_spmi_init(SPMI_MASTER_1);
+#else
+ pmif_spmi_init(SPMI_MASTER_1);
+ pmif_spmi_init(SPMI_MASTER_P_1);
+#endif
+#else
+ pmif_spmi_init(SPMI_MASTER_1);
+ pmif_spmi_init(SPMI_MASTER_P_1);
+#endif
+
+ return STATUS_OK;
+}
+
+/*************************************************************************
+* FUNCTION
+* DclSPMI_Open
+*
+* DESCRIPTION
+* This function is to open the SPMI module and return a handle
+*
+* PARAMETERS
+* dev: only valid for DCL_SPMI
+* flags: no sepcial flags is needed. Please use FLAGS_NONE
+*
+* RETURNS
+* DCL_HANDLE_INVALID: Open failed.
+* other value: a valid handle
+*
+*************************************************************************/
+DCL_HANDLE DclSPMI_Open(DCL_DEV dev, DCL_FLAGS flags)
+{
+ kal_uint32 handle;
+
+ if (dev != DCL_SPMI) {
+ /* Incorrecr device ID */
+ return DCL_HANDLE_INVALID;
+ }
+ kal_hrt_take_itc_lock(KAL_ITC_SPMI_LOCK, KAL_INFINITE_WAIT);
+ dcl_spmi_handle_count++;
+ handle = dcl_spmi_handle_count;
+ kal_hrt_give_itc_lock(KAL_ITC_SPMI_LOCK);
+
+ /* Register DCL default lisr */
+ return handle;
+}
+
+/*************************************************************************
+* FUNCTION
+* DclSPMI_ReadData
+*
+* DESCRIPTION
+* This function is not supported for the SPMI module now.
+*
+* PARAMETERS
+* N/A
+*
+* RETURNS
+* STATUS_UNSUPPORTED
+*
+*************************************************************************/
+DCL_STATUS DclSPMI_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
+{
+
+ return STATUS_UNSUPPORTED;
+}
+
+/*************************************************************************
+* FUNCTION
+* DclSPMI_WriteData
+*
+* DESCRIPTION
+* This function is not supported for the SPMI module now.
+*
+* PARAMETERS
+* N/A
+*
+* RETURNS
+* STATUS_UNSUPPORTED
+*
+*************************************************************************/
+DCL_STATUS DclSPMI_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
+{
+
+ return STATUS_UNSUPPORTED;
+}
+
+/*************************************************************************
+* FUNCTION
+* DclSPMI_Configure
+*
+* DESCRIPTION
+* This function is not supported for the SPMI module now.
+*
+* PARAMETERS
+* N/A
+*
+* RETURNS
+* STATUS_UNSUPPORTED
+*
+*************************************************************************/
+DCL_STATUS DclSPMI_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
+{
+
+ return STATUS_UNSUPPORTED;
+}
+
+/*************************************************************************
+* FUNCTION
+* DclSPMI_RegisterCallback
+*
+* DESCRIPTION
+* This function is not supported for the SPMI module now.
+*
+* PARAMETERS
+* N/A
+*
+* RETURNS
+* STATUS_UNSUPPORTED
+*
+*************************************************************************/
+DCL_STATUS DclSPMI_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
+{
+ return STATUS_UNSUPPORTED;
+}
+
+/*************************************************************************
+* FUNCTION
+* DclSPMI_Control
+*
+* DESCRIPTION
+* This function is to send command to control the SPMI module.
+*
+* PARAMETERS
+* handle: The handle value returned from DclSPMI_Open
+* cmd: a control command for SPMI module
+* RETURNS
+* STATUS_OK: command is executed successfully.
+* STATUS_FAIL: command is failed.
+* STATUS_INVALID_CMD: It's a invalid command.
+* STATUS_UNSUPPORTED: It's a unsupported command.
+*
+*************************************************************************/
+DCL_STATUS DclSPMI_Control_Priv(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ struct spmi_device *md_dev;
+ DCL_INT32 ret = STATUS_OK, cmd_ret = 0;
+
+ switch(cmd) {
+ case EXT_REGISTER_READL:
+ {
+ SPMI_CTRL_EXT_REGISTER_READL *cmd = &(data->rSPMIExtRegisterReadL);
+ unsigned char rdata = 0;
+
+ md_dev = get_spmi_device(SPMI_MASTER_0, (unsigned int)cmd->type);
+ //TBD md_dev = get_spmi_device(SPMI_MASTER_0, slaveid);
+ cmd_ret = spmi_ext_register_readl(md_dev, cmd->addr,
+ &rdata, cmd->len);
+ if (cmd_ret)
+ ret = STATUS_FAIL;
+ cmd->value = rdata;
+ }
+ break;
+
+ case EXT_REGISTER_WRITEL:
+ {
+ SPMI_CTRL_EXT_REGISTER_WRITEL *cmd = &(data->rSPMIExtRegisterWriteL);
+ unsigned char wdata = 0;
+
+ md_dev = get_spmi_device(SPMI_MASTER_0, (unsigned int)cmd->type);
+ wdata = (unsigned char)cmd->value;
+ cmd_ret = spmi_ext_register_writel(md_dev, cmd->addr,
+ &wdata, cmd->len);
+ if (cmd_ret)
+ ret = STATUS_FAIL;
+ }
+ break;
+
+ case EXT_REGISTER_READL_FIELD:
+ {
+ SPMI_CTRL_EXT_REGISTER_READL_FIELD *cmd = &(data->rSPMIExtRegisterReadLField);
+ unsigned char rdata = 0;
+
+ md_dev = get_spmi_device(SPMI_MASTER_0, (unsigned int)cmd->type);
+ cmd_ret = spmi_ext_register_readl_field(md_dev, cmd->addr,
+ &rdata, cmd->len, cmd->mask, cmd->shift);
+ if (cmd_ret)
+ ret = STATUS_FAIL;
+ cmd->value = rdata;
+ }
+ break;
+
+ case EXT_REGISTER_WRITEL_FIELD:
+ {
+ SPMI_CTRL_EXT_REGISTER_WRITEL_FIELD *cmd = &(data->rSPMIExtRegisterWriteLField);
+ unsigned char wdata = 0;
+
+ md_dev = get_spmi_device(SPMI_MASTER_0, (unsigned int)cmd->type);
+ wdata = (unsigned char)cmd->value;
+ cmd_ret = spmi_ext_register_writel_field(md_dev, cmd->addr,
+ &wdata, cmd->len, cmd->mask, cmd->shift);
+ if (cmd_ret)
+ ret = STATUS_FAIL;
+ }
+ break;
+
+ case REGISTER_READ:
+ {
+ SPMI_CTRL_EXT_REGISTER_READL *cmd = &(data->rSPMIExtRegisterReadL);
+ unsigned char rdata = 0;
+
+ md_dev = get_spmi_device(SPMI_MASTER_0, (unsigned int)cmd->type);
+ cmd_ret = spmi_register_read(md_dev, cmd->addr, &rdata);
+ if (cmd_ret)
+ ret = STATUS_FAIL;
+ cmd->value = rdata;
+ }
+ break;
+
+ case REGISTER_WRITE:
+ {
+ SPMI_CTRL_EXT_REGISTER_WRITEL *cmd = &(data->rSPMIExtRegisterWriteL);
+ unsigned char wdata = 0;
+
+ md_dev = get_spmi_device(SPMI_MASTER_0, (unsigned int)cmd->type);
+ wdata = (unsigned char)cmd->value;
+ cmd_ret = spmi_register_write(md_dev, cmd->addr, wdata);
+ if (cmd_ret)
+ ret = STATUS_FAIL;
+ }
+ break;
+
+ case EXT_REGISTER_READ:
+ {
+ SPMI_CTRL_EXT_REGISTER_READL *cmd = &(data->rSPMIExtRegisterReadL);
+ unsigned char rdata = 0;
+
+ md_dev = get_spmi_device(SPMI_MASTER_0, (unsigned int)cmd->type);
+ cmd_ret = spmi_ext_register_read(md_dev, cmd->addr,
+ &rdata, cmd->len);
+ if (cmd_ret)
+ ret = STATUS_FAIL;
+ cmd->value = rdata;
+ }
+ break;
+
+ case EXT_REGISTER_WRITE:
+ {
+ SPMI_CTRL_EXT_REGISTER_WRITEL *cmd = &(data->rSPMIExtRegisterWriteL);
+ unsigned char wdata = 0;
+
+ md_dev = get_spmi_device(SPMI_MASTER_0, (unsigned int)cmd->type);
+ wdata = (unsigned char)cmd->value;
+ cmd_ret = spmi_ext_register_write(md_dev, cmd->addr,
+ &wdata, cmd->len);
+ if (cmd_ret)
+ ret = STATUS_FAIL;
+ }
+ break;
+ }
+
+ return ret;
+}
+
+DCL_STATUS DclSPMI_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+ return DclSPMI_Control_Priv(handle, cmd, data);
+}
+/*************************************************************************
+* FUNCTION
+* DclSPMI_Close
+*
+* DESCRIPTION
+* This function is to close the SPMI module.
+*
+* PARAMETERS
+* handle: the returned handle value of DclSPMI_Close
+*
+* RETURNS
+* STATUS_OK
+*
+*************************************************************************/
+DCL_STATUS DclSPMI_Close(DCL_HANDLE handle)
+{
+ return STATUS_OK;
+}
+
+#endif /* endif DRV_SPMI_OFF */
+
diff --git a/mcu/driver/devdrv/spmi/src/pmif.c b/mcu/driver/devdrv/spmi/src/pmif.c
new file mode 100644
index 0000000..7ef3e76
--- /dev/null
+++ b/mcu/driver/devdrv/spmi/src/pmif.c
@@ -0,0 +1,753 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+ * the prior written permission of MediaTek inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of MediaTek Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * MediaTek Inc. (C) 2019. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+ * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+ * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek
+ * Software") have been modified by MediaTek Inc. All revisions are subject to
+ * any receiver's applicable license agreements with MediaTek Inc.
+ */
+/*
+ * MTK PMIF Driver
+ *
+ * Copyright 2019 MediaTek Co.,Ltd.
+ *
+ * DESCRIPTION:
+ * This file provides API for other drivers to access PMIC registers
+ *
+ */
+
+#include <pmif.h>
+#include <spmi.h>
+#include <pmif_sw.h>
+#include <spmi_sw.h>
+
+#define GET_SWINF_0_FSM(x) ((x>>1) & 0x00000007)
+#define GET_PMIF_INIT_DONE(x) ((x>>15) & 0x00000001)
+#define TIMEOUT_WAIT_IDLE (1000000) /* ap latency concern 1ms */
+
+#define PMIF_CMD_PER_3 (0x1 << PMIF_CMD_EXT_REG_LONG)
+#define PMIF_CMD_PER_1_3 \
+ ((0x1 << PMIF_CMD_REG) | (0x1 << PMIF_CMD_EXT_REG_LONG))
+#define PMIF_CMD_PER_2_3 \
+ ((0x1 << PMIF_CMD_EXT_REG) | (0x1 << PMIF_CMD_EXT_REG_LONG))
+
+static int pmif_spmi_read_cmd(struct pmif *arb, unsigned char opc,
+ unsigned char sid, unsigned short addr, unsigned char *buf,
+ unsigned short len);
+static int pmif_spmi_write_cmd(struct pmif *arb, unsigned char opc,
+ unsigned char sid, unsigned short addr, const unsigned char *buf,
+ unsigned short len);
+#if PMIF_NO_PMIC
+static int pmif_spmi_read_cmd(struct pmif *arb, unsigned char opc,
+ unsigned char sid, unsigned short addr, unsigned char *buf,
+ unsigned short len)
+{
+ PMIF_INFO("do Nothing.\n");
+ return 0;
+}
+
+static int pmif_spmi_write_cmd(struct pmif *arb, unsigned char opc,
+ unsigned char sid, unsigned short addr, const unsigned char *buf,
+ unsigned short len)
+{
+ PMIF_INFO("do Nothing.\n");
+ return 0;
+}
+
+/* init interface */
+int pmif_spmi_init(int mstid)
+{
+ PMIF_INFO("do Nothing.\n");
+ return 0;
+}
+#else /* #if PMIF_NO_PMIC */
+/* pmif internal API declaration */
+#if PMIF_TIMEOUT
+static unsigned long long pmif_get_current_time(void);
+static int pmif_timeout_ns(unsigned long long start_time_ns,
+ unsigned long long timeout_time_ns);
+static unsigned long long pmif_time2ns(unsigned long long time_us);
+#endif
+static void pmif_enable_soft_reset(int mstid);
+static void pmif_spmi_enable_clk_set(int mstid);
+static void pmif_spmi_force_normal_mode(int mstid);
+static void pmif_spmi_enable_swinf(int mstid, unsigned int chan_no,
+ unsigned int swinf_no);
+static void pmif_spmi_enable_cmdIssue(int mstid, kal_bool en);
+static void pmif_spmi_enable(int mstid);
+
+
+enum pmif_regs {
+ PMIF_INIT_DONE,
+ PMIF_INF_EN,
+ PMIF_INF_CMD_PER_0,
+ PMIF_INF_CMD_PER_1,
+ PMIF_INF_CMD_PER_2,
+ PMIF_INF_CMD_PER_3,
+ PMIF_INF_MAX_BYTECNT_PER_0,
+ PMIF_INF_MAX_BYTECNT_PER_1,
+ PMIF_INF_MAX_BYTECNT_PER_2,
+ PMIF_INF_MAX_BYTECNT_PER_3,
+ PMIF_ARB_EN,
+ PMIF_CMDISSUE_EN,
+ PMIF_TIMER_CTRL,
+ PMIF_SPI_MODE_CTRL,
+ PMIF_IRQ_EVENT_EN_0,
+ PMIF_IRQ_FLAG_0,
+ PMIF_IRQ_CLR_0,
+ PMIF_SWINF_0_ACC,
+ PMIF_SWINF_0_WDATA_31_0,
+ PMIF_SWINF_0_WDATA_63_32,
+ PMIF_SWINF_0_RDATA_31_0,
+ PMIF_SWINF_0_RDATA_63_32,
+ PMIF_SWINF_0_VLD_CLR,
+ PMIF_SWINF_0_STA,
+ PMIF_SWINF_1_ACC,
+ PMIF_SWINF_1_WDATA_31_0,
+ PMIF_SWINF_1_WDATA_63_32,
+ PMIF_SWINF_1_RDATA_31_0,
+ PMIF_SWINF_1_RDATA_63_32,
+ PMIF_SWINF_1_VLD_CLR,
+ PMIF_SWINF_1_STA,
+ PMIF_SWINF_2_ACC,
+ PMIF_SWINF_2_WDATA_31_0,
+ PMIF_SWINF_2_WDATA_63_32,
+ PMIF_SWINF_2_RDATA_31_0,
+ PMIF_SWINF_2_RDATA_63_32,
+ PMIF_SWINF_2_VLD_CLR,
+ PMIF_SWINF_2_STA,
+ PMIF_SWINF_3_ACC,
+ PMIF_SWINF_3_WDATA_31_0,
+ PMIF_SWINF_3_WDATA_63_32,
+ PMIF_SWINF_3_RDATA_31_0,
+ PMIF_SWINF_3_RDATA_63_32,
+ PMIF_SWINF_3_VLD_CLR,
+ PMIF_SWINF_3_STA,
+};
+
+static int mt6885_regs[] = {
+ [PMIF_INIT_DONE] = 0x0000,
+ [PMIF_INF_EN] = 0x0024,
+ [PMIF_INF_CMD_PER_0] = 0x002c,
+ [PMIF_INF_CMD_PER_1] = 0x0030,
+ [PMIF_INF_CMD_PER_2] = 0x0034,
+ [PMIF_INF_CMD_PER_3] = 0x0038,
+ [PMIF_INF_MAX_BYTECNT_PER_0] = 0x003c,
+ [PMIF_INF_MAX_BYTECNT_PER_1] = 0x0040,
+ [PMIF_INF_MAX_BYTECNT_PER_2] = 0x0044,
+ [PMIF_INF_MAX_BYTECNT_PER_3] = 0x0048,
+ [PMIF_ARB_EN] = 0x0150,
+ [PMIF_CMDISSUE_EN] = 0x03B4,
+ [PMIF_TIMER_CTRL] = 0x03E0,
+ [PMIF_SPI_MODE_CTRL] = 0x0400,
+ [PMIF_IRQ_EVENT_EN_0] = 0x0418,
+ [PMIF_IRQ_FLAG_0] = 0x0420,
+ [PMIF_IRQ_CLR_0] = 0x0424,
+ [PMIF_SWINF_0_ACC] = 0x0C00,
+ [PMIF_SWINF_0_WDATA_31_0] = 0x0C04,
+ [PMIF_SWINF_0_WDATA_63_32] = 0x0C08,
+ [PMIF_SWINF_0_RDATA_31_0] = 0x0C14,
+ [PMIF_SWINF_0_RDATA_63_32] = 0x0C18,
+ [PMIF_SWINF_0_VLD_CLR] = 0x0C24,
+ [PMIF_SWINF_0_STA] = 0x0C28,
+ [PMIF_SWINF_1_ACC] = 0x0C40,
+ [PMIF_SWINF_1_WDATA_31_0] = 0x0C44,
+ [PMIF_SWINF_1_WDATA_63_32] = 0x0C48,
+ [PMIF_SWINF_1_RDATA_31_0] = 0x0C54,
+ [PMIF_SWINF_1_RDATA_63_32] = 0x0C58,
+ [PMIF_SWINF_1_VLD_CLR] = 0x0C64,
+ [PMIF_SWINF_1_STA] = 0x0C68,
+ [PMIF_SWINF_2_ACC] = 0x0C80,
+ [PMIF_SWINF_2_WDATA_31_0] = 0x0C84,
+ [PMIF_SWINF_2_WDATA_63_32] = 0x0C88,
+ [PMIF_SWINF_2_RDATA_31_0] = 0x0C94,
+ [PMIF_SWINF_2_RDATA_63_32] = 0x0C98,
+ [PMIF_SWINF_2_VLD_CLR] = 0x0CA4,
+ [PMIF_SWINF_2_STA] = 0x0CA8,
+ [PMIF_SWINF_3_ACC] = 0x0CC0,
+ [PMIF_SWINF_3_WDATA_31_0] = 0x0CC4,
+ [PMIF_SWINF_3_WDATA_63_32] = 0x0CC8,
+ [PMIF_SWINF_3_RDATA_31_0] = 0x0CD4,
+ [PMIF_SWINF_3_RDATA_63_32] = 0x0CD8,
+ [PMIF_SWINF_3_VLD_CLR] = 0x0CE4,
+ [PMIF_SWINF_3_STA] = 0x0CE8,
+};
+
+#if defined(CHIP10992)
+static int mt6880_regs[] = {
+ [PMIF_INIT_DONE] = 0x0000,
+ [PMIF_INF_EN] = 0x0024,
+ [PMIF_INF_CMD_PER_0] = 0x002c,
+ [PMIF_INF_CMD_PER_1] = 0x0030,
+ [PMIF_INF_CMD_PER_2] = 0x0034,
+ [PMIF_INF_CMD_PER_3] = 0x0038,
+ [PMIF_INF_MAX_BYTECNT_PER_0] = 0x003c,
+ [PMIF_INF_MAX_BYTECNT_PER_1] = 0x0040,
+ [PMIF_INF_MAX_BYTECNT_PER_2] = 0x0044,
+ [PMIF_INF_MAX_BYTECNT_PER_3] = 0x0048,
+ [PMIF_ARB_EN] = 0x0150,
+ [PMIF_CMDISSUE_EN] = 0x03B8,
+ [PMIF_TIMER_CTRL] = 0x03E4,
+ [PMIF_SPI_MODE_CTRL] = 0x0408,
+ [PMIF_IRQ_EVENT_EN_0] = 0x0420,
+ [PMIF_IRQ_FLAG_0] = 0x0428,
+ [PMIF_IRQ_CLR_0] = 0x042C,
+ [PMIF_SWINF_0_ACC] = 0x0800,
+ [PMIF_SWINF_0_WDATA_31_0] = 0x0804,
+ [PMIF_SWINF_0_RDATA_31_0] = 0x0814,
+ [PMIF_SWINF_0_VLD_CLR] = 0x0824,
+ [PMIF_SWINF_0_STA] = 0x0828,
+ [PMIF_SWINF_1_ACC] = 0x0840,
+ [PMIF_SWINF_1_WDATA_31_0] = 0x0844,
+ [PMIF_SWINF_1_RDATA_31_0] = 0x0854,
+ [PMIF_SWINF_1_VLD_CLR] = 0x0864,
+ [PMIF_SWINF_1_STA] = 0x0868,
+ [PMIF_SWINF_2_ACC] = 0x0880,
+ [PMIF_SWINF_2_WDATA_31_0] = 0x0884,
+ [PMIF_SWINF_2_RDATA_31_0] = 0x0894,
+ [PMIF_SWINF_2_VLD_CLR] = 0x08A4,
+ [PMIF_SWINF_2_STA] = 0x08A8,
+ [PMIF_SWINF_3_ACC] = 0x08C0,
+ [PMIF_SWINF_3_WDATA_31_0] = 0x08C4,
+ [PMIF_SWINF_3_RDATA_31_0] = 0x08D4,
+ [PMIF_SWINF_3_VLD_CLR] = 0x08E4,
+ [PMIF_SWINF_3_STA] = 0x08E8,
+};
+#else
+static int mt6853_regs[] = {
+ [PMIF_INIT_DONE] = 0x0000,
+ [PMIF_INF_EN] = 0x0024,
+ [PMIF_INF_CMD_PER_0] = 0x002c,
+ [PMIF_INF_CMD_PER_1] = 0x0030,
+ [PMIF_INF_CMD_PER_2] = 0x0034,
+ [PMIF_INF_CMD_PER_3] = 0x0038,
+ [PMIF_INF_MAX_BYTECNT_PER_0] = 0x003c,
+ [PMIF_INF_MAX_BYTECNT_PER_1] = 0x0040,
+ [PMIF_INF_MAX_BYTECNT_PER_2] = 0x0044,
+ [PMIF_INF_MAX_BYTECNT_PER_3] = 0x0048,
+ [PMIF_ARB_EN] = 0x0150,
+ [PMIF_CMDISSUE_EN] = 0x03B8,
+ [PMIF_TIMER_CTRL] = 0x03E4,
+ [PMIF_SPI_MODE_CTRL] = 0x0408,
+ [PMIF_IRQ_EVENT_EN_0] = 0x0420,
+ [PMIF_IRQ_FLAG_0] = 0x0428,
+ [PMIF_IRQ_CLR_0] = 0x042C,
+ [PMIF_SWINF_0_ACC] = 0x0C00,
+ [PMIF_SWINF_0_WDATA_31_0] = 0x0C04,
+ [PMIF_SWINF_0_WDATA_63_32] = 0x0C08,
+ [PMIF_SWINF_0_RDATA_31_0] = 0x0C14,
+ [PMIF_SWINF_0_RDATA_63_32] = 0x0C18,
+ [PMIF_SWINF_0_VLD_CLR] = 0x0C24,
+ [PMIF_SWINF_0_STA] = 0x0C28,
+ [PMIF_SWINF_1_ACC] = 0x0C40,
+ [PMIF_SWINF_1_WDATA_31_0] = 0x0C44,
+ [PMIF_SWINF_1_WDATA_63_32] = 0x0C48,
+ [PMIF_SWINF_1_RDATA_31_0] = 0x0C54,
+ [PMIF_SWINF_1_RDATA_63_32] = 0x0C58,
+ [PMIF_SWINF_1_VLD_CLR] = 0x0C64,
+ [PMIF_SWINF_1_STA] = 0x0C68,
+ [PMIF_SWINF_2_ACC] = 0x0C80,
+ [PMIF_SWINF_2_WDATA_31_0] = 0x0C84,
+ [PMIF_SWINF_2_WDATA_63_32] = 0x0C88,
+ [PMIF_SWINF_2_RDATA_31_0] = 0x0C94,
+ [PMIF_SWINF_2_RDATA_63_32] = 0x0C98,
+ [PMIF_SWINF_2_VLD_CLR] = 0x0CA4,
+ [PMIF_SWINF_2_STA] = 0x0CA8,
+ [PMIF_SWINF_3_ACC] = 0x0CC0,
+ [PMIF_SWINF_3_WDATA_31_0] = 0x0CC4,
+ [PMIF_SWINF_3_WDATA_63_32] = 0x0CC8,
+ [PMIF_SWINF_3_RDATA_31_0] = 0x0CD4,
+ [PMIF_SWINF_3_RDATA_63_32] = 0x0CD8,
+ [PMIF_SWINF_3_VLD_CLR] = 0x0CE4,
+ [PMIF_SWINF_3_STA] = 0x0CE8,
+};
+#endif
+
+static struct pmif pmif_spmi_arb[] = {
+ {
+ .base = (unsigned int *)PMIF_SPMI_BASE,
+ .regs = mt6885_regs,
+ .spmimst_base = (unsigned int *)SPMI_MST_BASE,
+ .swinf_ch_start = PMIF_SWINF_0_CHAN_NO,
+ .swinf_no = PMIF_AP_SWINF_NO,
+ .write = 0x0,
+ .mstid = SPMI_MASTER_0,
+ .pmifid = PMIF_PMIFID,
+ .read_cmd = pmif_spmi_read_cmd,
+ .write_cmd = pmif_spmi_write_cmd,
+ .pmif_enable_clk_set = pmif_spmi_enable_clk_set,
+ .pmif_force_normal_mode = pmif_spmi_force_normal_mode,
+ .pmif_enable_swinf = pmif_spmi_enable_swinf,
+ .pmif_enable_cmdIssue = pmif_spmi_enable_cmdIssue,
+ .pmif_enable = pmif_spmi_enable,
+ .is_pmif_init_done = is_pmif_spmi_init_done,
+ },
+ {
+ .base = (unsigned int *)PMIF_SPMI_BASE,
+#if defined(CHIP10992)
+ .regs = mt6880_regs,
+#else
+ .regs = mt6853_regs,
+#endif
+ .spmimst_base = (unsigned int *)SPMI_MST_BASE,
+ .swinf_ch_start = PMIF_SWINF_0_CHAN_NO,
+ .swinf_no = PMIF_AP_SWINF_NO,
+ .write = 0x0,
+ .mstid = SPMI_MASTER_1,
+ .pmifid = PMIF_PMIFID,
+ .read_cmd = pmif_spmi_read_cmd,
+ .write_cmd = pmif_spmi_write_cmd,
+ .pmif_enable_clk_set = pmif_spmi_enable_clk_set,
+ .pmif_force_normal_mode = pmif_spmi_force_normal_mode,
+ .pmif_enable_swinf = pmif_spmi_enable_swinf,
+ .pmif_enable_cmdIssue = pmif_spmi_enable_cmdIssue,
+ .pmif_enable = pmif_spmi_enable,
+ .is_pmif_init_done = is_pmif_spmi_init_done,
+ },
+#if !defined(MT6885) && !defined(MT6873)
+ {
+ .base = (unsigned int *)PMIF_SPMI_P_BASE,
+#if defined(CHIP10992)
+ .regs = mt6880_regs,
+#else
+ .regs = mt6853_regs,
+#endif
+ .spmimst_base = (unsigned int *)SPMI_MST_P_BASE,
+ .swinf_ch_start = PMIF_SWINF_0_CHAN_NO_P,
+ .swinf_no = PMIF_AP_SWINF_NO_P,
+ .write = 0x0,
+ .mstid = SPMI_MASTER_P_1,
+ .pmifid = PMIF_PMIFID_2,
+ .read_cmd = pmif_spmi_read_cmd,
+ .write_cmd = pmif_spmi_write_cmd,
+ .pmif_enable_clk_set = pmif_spmi_enable_clk_set,
+ .pmif_force_normal_mode = pmif_spmi_force_normal_mode,
+ .pmif_enable_swinf = pmif_spmi_enable_swinf,
+ .pmif_enable_cmdIssue = pmif_spmi_enable_cmdIssue,
+ .pmif_enable = pmif_spmi_enable,
+ .is_pmif_init_done = is_pmif_spmi_init_done,
+ },
+#endif
+};
+/* static struct pmif pmif_spi_arb[0]; */
+
+/* pmif timeout */
+#if PMIF_TIMEOUT
+static unsigned long long pmif_get_current_time(void)
+{
+ return gpt4_get_current_tick();
+}
+
+static int pmif_timeout_ns(unsigned long long start_time_ns,
+ unsigned long long timeout_time_ns)
+{
+ return gpt4_timeout_tick(start_time_ns, timeout_time_ns);
+}
+
+static unsigned long long pmif_time2ns(unsigned long long time_us)
+{
+ return gpt4_time2tick_us(time_us);
+}
+#endif
+static inline unsigned int pmif_check_idle(int mstid) {
+ struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
+ unsigned int reg_rdata, offset = 0;
+#if PMIF_TIMEOUT
+ unsigned long long start_time_ns = 0, end_time_ns = 0, timeout_ns = 0;
+ unsigned long time_cnt = 100000;
+
+ start_time_ns = pmif_get_current_time();
+ timeout_ns = pmif_time2ns(TIMEOUT_WAIT_IDLE);
+#endif
+
+ do {
+#if PMIF_TIMEOUT
+ if (pmif_timeout_ns(start_time_ns, timeout_ns)) {
+ end_time_ns = pmif_get_current_time();
+ PMIF_ERR("%s timeout %d %d\n", __func__, start_time_ns,
+ end_time_ns - start_time_ns);
+ return -ETIMEDOUT;
+ }
+ if ((time_cnt--) == 0) {
+ PMIF_ERR("%s timeout %d %d\n", __func__, start_time_ns,
+ end_time_ns - start_time_ns);
+ return -ETIMEDOUT;
+ }
+#endif
+ offset = arb->regs[PMIF_SWINF_0_STA] + (0x40 * arb->swinf_no);
+ reg_rdata = DRV_Reg32(arb->base + offset);
+ } while(GET_SWINF_0_FSM(reg_rdata) != SWINF_FSM_IDLE);
+
+ return 0;
+}
+
+static inline unsigned int pmif_check_vldclr(int mstid) {
+ struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
+ unsigned int reg_rdata, offset = 0;
+#if PMIF_TIMEOUT
+ unsigned long long start_time_ns = 0, end_time_ns = 0, timeout_ns = 0;
+ unsigned long time_cnt = 100000;
+
+ start_time_ns = pmif_get_current_time();
+ timeout_ns = pmif_time2ns(TIMEOUT_WAIT_IDLE);
+#endif
+
+ do {
+#if PMIF_TIMEOUT
+ if (pmif_timeout_ns(start_time_ns, timeout_ns)) {
+ end_time_ns = pmif_get_current_time();
+ PMIF_ERR("%s timeout %d %d\n", __func__, start_time_ns,
+ end_time_ns - start_time_ns);
+ return -ETIMEDOUT;
+ }
+ if ((time_cnt--) == 0) {
+ PMIF_ERR("%s timeout %d %d\n", __func__, start_time_ns,
+ end_time_ns - start_time_ns);
+ return -ETIMEDOUT;
+ }
+#endif
+ offset = arb->regs[PMIF_SWINF_0_STA] + (0x40 * arb->swinf_no);
+ reg_rdata = DRV_Reg32(arb->base + offset);
+ } while(GET_SWINF_0_FSM(reg_rdata) != SWINF_FSM_WFVLDCLR);
+
+ return 0;
+}
+static void pmif_enable_soft_reset(int mstid)
+{
+ DRV_WriteReg32(INFRA_GLOBALCON_RST2_SET, 0x1 << 14);
+ DRV_WriteReg32(INFRA_GLOBALCON_RST2_CLR, 0x1 << 14);
+
+ PMIF_INFO("%s done\n", __func__);
+}
+
+static void pmif_spmi_enable_clk_set(int mstid)
+{
+#if !defined(CONFIG_FPGA_EARLY_PORTING)
+ /* TBD */
+ DRV_WriteReg32(CLK_CFG_8_CLR, (0x1 << 15) | (0x1 << 12) | (0x7 << 8));
+ DRV_WriteReg32(CLK_CFG_UPDATE1, 0x1 << 2);
+#endif
+
+ /* sys_ck cg enable, turn off clock */
+ DRV_WriteReg32(MODULE_SW_CG_0_SET, 0x0000000f);
+ /* turn off clock */
+ DRV_WriteReg32(MODULE_SW_CG_2_SET, 0x00000100);
+
+ /* toggle SPMI sw reset */
+ pmif_enable_soft_reset(mstid);
+
+ /* sys_ck cg enable, turn on clock */
+ DRV_WriteReg32(MODULE_SW_CG_0_CLR, 0x0000000f);
+ /* turn on clock */
+ DRV_WriteReg32(MODULE_SW_CG_2_CLR, 0x00000100);
+
+ PMIF_INFO("%s done\n", __func__);
+}
+
+static void pmif_spmi_force_normal_mode(int mstid)
+{
+ struct pmif *arb = get_pmif_controller(PMIF_SPMI, SPMI_MASTER_0);
+ unsigned int offset = 0;
+
+ /* Force SPMI in normal mode. */
+ offset = arb->regs[PMIF_SPI_MODE_CTRL];
+ DRV_WriteReg32(arb->base + offset,
+ DRV_Reg32(arb->base + offset) & (~(0x3 << 9)));
+ DRV_WriteReg32(arb->base + offset,
+ DRV_Reg32(arb->base + offset) | (0x1 << 9));
+
+ PMIF_INFO("%s done\n", __func__);
+}
+
+static void pmif_spmi_enable_swinf(int mstid, unsigned int chan_no,
+ unsigned int swinf_no)
+{
+ struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
+ unsigned int offset = 0;
+
+ /* Enable swinf */
+ offset = arb->regs[PMIF_INF_EN];
+ DRV_WriteReg32(arb->base + offset,
+ 0x1 << (arb->swinf_ch_start + arb->swinf_no));
+
+ /* Enable arbitration */
+ offset = arb->regs[PMIF_ARB_EN];
+ DRV_WriteReg32(arb->base + offset,
+ 0x1 << (arb->swinf_ch_start + arb->swinf_no));
+
+ PMIF_INFO("%s done\n", __func__);
+}
+
+static void pmif_spmi_enable_cmdIssue(int mstid, kal_bool en)
+{
+ struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
+
+ /* Enable cmdIssue */
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_CMDISSUE_EN], en);
+
+ PMIF_INFO("%s done\n", __func__);
+}
+
+static void pmif_spmi_enable(int mstid)
+{
+ struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
+#if PMIF_NORMAL_BOOT
+ unsigned int bytecnt_per = 0, hw_bytecnt = 0;
+ unsigned int cmd_per = 0;
+
+ /* clear all cmd permission for per channel */
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_CMD_PER_0], 0);
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_CMD_PER_1], 0);
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_CMD_PER_2], 0);
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_CMD_PER_3], 0);
+ /* enable if we need cmd 0~3 permission for per channel */
+ cmd_per = PMIF_CMD_PER_3 << 28 | PMIF_CMD_PER_3 << 24 |
+ PMIF_CMD_PER_3 << 20 | PMIF_CMD_PER_1_3 << 16 |
+ PMIF_CMD_PER_3 << 8 | PMIF_CMD_PER_1_3 << 0;
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_CMD_PER_0], cmd_per);
+ cmd_per = PMIF_CMD_PER_3 << 4;
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_CMD_PER_1], cmd_per);
+
+ /* set bytecnt max limitation*/
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_MAX_BYTECNT_PER_0], 0);
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_MAX_BYTECNT_PER_1], 0);
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_MAX_BYTECNT_PER_2], 0);
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_MAX_BYTECNT_PER_3], 0);
+ /* hw bytecnt indicate when we set 0, it can send 1 byte;
+ * set 1, it can send 2 byte.
+ */
+ hw_bytecnt = PMIF_BYTECNT_MAX -1;
+ if (hw_bytecnt > 0) {
+ bytecnt_per = hw_bytecnt << 28 | hw_bytecnt << 24 |
+ hw_bytecnt << 20 | hw_bytecnt << 16 |
+ hw_bytecnt << 12 | hw_bytecnt << 8 |
+ hw_bytecnt << 4 | hw_bytecnt << 0;
+ }
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_MAX_BYTECNT_PER_0],
+ bytecnt_per);
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_MAX_BYTECNT_PER_1],
+ bytecnt_per);
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_MAX_BYTECNT_PER_2],
+ bytecnt_per);
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_MAX_BYTECNT_PER_3],
+ bytecnt_per);
+#endif /* end of #if PMIF_NORMAL_BOOT */
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_EN], 0x2F5);
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_ARB_EN], 0x2F5);
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_TIMER_CTRL], 0x3);
+ DRV_WriteReg32(arb->base + arb->regs[PMIF_INIT_DONE], 0x1);
+
+ PMIF_INFO("%s done\n", __func__);
+}
+
+static int pmif_spmi_read_cmd(struct pmif *arb, unsigned char opc,
+ unsigned char sid, unsigned short addr, unsigned char *buf,
+ unsigned short len)
+{
+ int write = 0x0;
+ unsigned int ret = 0, offset = 0, data = 0;
+ unsigned char bc = len - 1;
+
+ if ((sid & ~(0xf)) != 0x0)
+ return -EINVAL;
+
+ if (len > PMIF_BYTECNT_MAX)
+ return -EINVAL;
+
+ /* Check the opcode */
+ if (opc >= 0x60 && opc <= 0x7F)
+ opc = PMIF_CMD_REG;
+ else if (opc >= 0x20 && opc <= 0x2F)
+ opc = PMIF_CMD_EXT_REG;
+ else if (opc >= 0x38 && opc <= 0x3F)
+ opc = PMIF_CMD_EXT_REG_LONG;
+ else
+ return -EINVAL;
+
+ /* ENTER_CRITICAL(); */
+ kal_hrt_take_itc_lock(KAL_ITC_SPMI_LOCK, KAL_INFINITE_WAIT);
+
+ /* Wait for Software Interface FSM state to be IDLE. */
+ ret = pmif_check_idle(arb->mstid);
+ if(ret)
+ return ret;
+
+ /* Send the command. */
+ offset = arb->regs[PMIF_SWINF_0_ACC] + (0x40 * arb->swinf_no);
+ DRV_WriteReg32(arb->base + offset,
+ (opc << 30) | (write << 29) | (sid << 24) | (bc << 16) | addr);
+
+ /* Wait for Software Interface FSM state to be WFVLDCLR,
+ *
+ * read the data and clear the valid flag.
+ */
+ if(write == 0)
+ {
+ ret = pmif_check_vldclr(arb->mstid);
+ if(ret)
+ return ret;
+
+ offset =
+ arb->regs[PMIF_SWINF_0_RDATA_31_0] + (0x40 * arb->swinf_no);
+ data = DRV_Reg32(arb->base + offset);
+ memcpy(buf, &data, (bc & 3) + 1);
+ offset =
+ arb->regs[PMIF_SWINF_0_VLD_CLR] + (0x40 * arb->swinf_no);
+ DRV_WriteReg32(arb->base + offset, 0x1);
+ }
+ kal_hrt_give_itc_lock(KAL_ITC_SPMI_LOCK);
+ /* EXIT_CRITICAL(); */
+
+ return 0x0;
+}
+
+static int pmif_spmi_write_cmd(struct pmif *arb, unsigned char opc,
+ unsigned char sid, unsigned short addr, const unsigned char *buf,
+ unsigned short len)
+{
+ int write = 0x1;
+ unsigned int ret = 0, offset = 0, data = 0;
+ unsigned char bc = len - 1;
+
+ if ((sid & ~(0xf)) != 0x0)
+ return -EINVAL;
+
+ if (len > PMIF_BYTECNT_MAX)
+ return -EINVAL;
+
+ /* Check the opcode */
+ if (opc >= 0x40 && opc <= 0x5F)
+ opc = PMIF_CMD_REG;
+ else if (opc <= 0x0F)
+ opc = PMIF_CMD_EXT_REG;
+ else if (opc >= 0x30 && opc <= 0x37)
+ opc = PMIF_CMD_EXT_REG_LONG;
+ else if (opc >= 0x80)
+ opc = PMIF_CMD_REG_0;
+ else
+ return -EINVAL;
+
+ /* ENTER_CRITICAL(); */
+ kal_hrt_take_itc_lock(KAL_ITC_SPMI_LOCK, KAL_INFINITE_WAIT);
+
+ /* Wait for Software Interface FSM state to be IDLE. */
+ ret = pmif_check_idle(arb->mstid);
+ if(ret)
+ return ret;
+
+ /* Set the write data. */
+ if (write == 1)
+ {
+ offset =
+ arb->regs[PMIF_SWINF_0_WDATA_31_0] + (0x40 * arb->swinf_no);
+ memcpy(&data, buf, (bc & 3) + 1);
+ DRV_WriteReg32(arb->base + offset, data);
+ }
+ /* Send the command. */
+ offset = arb->regs[PMIF_SWINF_0_ACC] + (0x40 * arb->swinf_no);
+ DRV_WriteReg32(arb->base + offset,
+ (opc << 30) | (write << 29) | (sid << 24) |
+ (bc << 16) | addr);
+
+ kal_hrt_give_itc_lock(KAL_ITC_SPMI_LOCK);
+ /* EXIT_CRITICAL(); */
+
+ return 0x0;
+}
+
+struct pmif *get_pmif_controller(int inf, int mstid)
+{
+ if (inf == PMIF_SPMI) {
+ return &pmif_spmi_arb[mstid];
+ } else if (inf == PMIF_SPI) {
+ /* TBD
+ *pmif_spi_arb[mstid].base = (unsigned int *)PMIF_SPI_BASE;
+ *pmif_spi_arb[mstid].swinf_no = 0x0;
+ *pmif_spi_arb[mstid].write = 0x0;
+ *pmif_spi_arb[mstid].pmifid = 0x0;
+ *pmif_spi_arb[mstid].read_cmd = pmif_spi_read_cmd;
+ *pmif_spi_arb[mstid].write_cmd = pmif_spi_write_cmd;
+ *pmif_spi_arb[mstid].read_cmd_nochk = pmif_spi_read_cmd_nochk;
+ *pmif_spi_arb[mstid].write_cmd_nochk =
+ * pmif_spi_write_cmd_nochk;
+ *return &pmif_spi_arb[mstid];
+ */
+ }
+
+ return 0;
+}
+int is_pmif_spmi_init_done(int mstid)
+{
+ int ret = 0;
+
+ struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
+
+ ret = DRV_Reg32(arb->base + arb->regs[PMIF_INIT_DONE]);
+ PMIF_INFO("%s ret = %d\n", __func__, ret);
+ if ((ret & 0x1) == 1)
+ return 0;
+
+ return -ENODEV;
+}
+
+int pmif_spmi_init(int mstid)
+{
+ struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
+ int ret = 0;
+
+ INIT_CRITICAL();
+
+ if (is_pmif_spmi_init_done(mstid) != 0) {
+ arb->pmif_enable_clk_set(mstid);
+ arb->pmif_force_normal_mode(mstid);
+ /* Enable SWINF and arbitration for AP. */
+ arb->pmif_enable_swinf(mstid, PMIF_SWINF_0_CHAN_NO,
+ PMIF_AP_SWINF_NO);
+ arb->pmif_enable_cmdIssue(mstid,KAL_TRUE);
+
+ arb->pmif_enable(mstid);
+ ret = arb->is_pmif_init_done(mstid);
+ if(ret) {
+ PMIF_ERR("init done check fail\n");
+ return -ENODEV;
+ }
+ }
+
+ ret = spmi_init(arb);
+ if(ret) {
+ PMIF_ERR("init fail\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+#endif /* endif PMIF_NO_PMIC */
diff --git a/mcu/driver/devdrv/spmi/src/spmi.c b/mcu/driver/devdrv/spmi/src/spmi.c
new file mode 100644
index 0000000..f982a47
--- /dev/null
+++ b/mcu/driver/devdrv/spmi/src/spmi.c
@@ -0,0 +1,992 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+ * the prior written permission of MediaTek inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of MediaTek Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * MediaTek Inc. (C) 2019. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+ * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+ * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek
+ * Software") have been modified by MediaTek Inc. All revisions are subject to
+ * any receiver's applicable license agreements with MediaTek Inc.
+ */
+/*
+ * MTK SPMI Driver
+ *
+ * Copyright 2018 MediaTek Co.,Ltd.
+ *
+ * DESCRIPTION:
+ * This file provides API for other drivers to access PMIC registers
+ *
+ */
+
+#include <spmi.h>
+#include <pmif.h>
+#include <pmif_sw.h>
+#include <spmi_sw.h>
+#include <mt6315_upmu_hw.h>
+
+static int mt6885_spmi_regs[] = {
+ [SPMI_OP_ST_CTRL] = 0x0000,
+ [SPMI_GRP_ID_EN] = 0x0004,
+ [SPMI_OP_ST_STA] = 0x0008,
+ [SPMI_MST_SAMPL] = 0x000c,
+ [SPMI_MST_REQ_EN] = 0x0010,
+#if SPMI_RCS_SUPPORT
+ [SPMI_RCS_CTRL] = 0x0014,
+ [SPMI_SLV_3_0_EINT] = 0x0020,
+ [SPMI_SLV_7_4_EINT] = 0x0024,
+ [SPMI_SLV_B_8_EINT] = 0x0028,
+ [SPMI_SLV_F_C_EINT] = 0x002c,
+#endif /* #if SPMI_RCS_SUPPORT */
+ [SPMI_REC_CTRL] = 0x0040,
+ [SPMI_REC0] = 0x0044,
+ [SPMI_REC1] = 0x0048,
+ [SPMI_REC2] = 0x004c,
+ [SPMI_REC3] = 0x0050,
+ [SPMI_REC4] = 0x0054,
+#if SPMI_RCS_SUPPORT
+ [SPMI_REC_CMD_DEC] = 0x005c,
+ [SPMI_DEC_DBG] = 0x00f8,
+#endif
+ [SPMI_MST_DBG] = 0x00fc,
+};
+
+static struct pmif *pmif_spmi_arb_ctrl[SPMI_MASTER_MAX];
+#if MT63xx_EVB
+#if defined(MT6885) || defined(MT6873)
+struct spmi_device spmi_dev[] = {
+ {
+ .slvid = SPMI_SLAVE_3,
+ .grpiden = 0x800,
+ .type = BUCK_MD,
+ .type_id = BUCK_MD_ID,
+ .mstid = SPMI_MASTER_0,/* spmi-m */
+ .hwcid_addr = 0x09,
+ .hwcid_val = 0x15,
+ .swcid_addr = 0x0b,
+ .swcid_val = 0x15,
+ .pmif_arb = NULL,
+ }, {
+ .slvid = SPMI_SLAVE_6,
+ .grpiden = 0x800,
+ .type = BUCK_CPU,
+ .type_id = BUCK_CPU_ID,
+ .mstid = SPMI_MASTER_0,/* spmi-m */
+ .hwcid_addr = 0x09,
+ .hwcid_val = 0x15,
+ .swcid_addr = 0x0b,
+ .swcid_val = 0x15,
+ .pmif_arb = NULL,
+ }, {
+ .slvid = SPMI_SLAVE_7,
+ .grpiden = 0x800,
+ .type = BUCK_GPU,
+ .type_id = BUCK_GPU_ID,
+ .mstid = SPMI_MASTER_0,/* spmi-m */
+ .hwcid_addr = 0x09,
+ .hwcid_val = 0x15,
+ .swcid_addr = 0x0b,
+ .swcid_val = 0x15,
+ .pmif_arb = NULL,
+ },
+};
+#elif defined(MT6853)
+#if defined(MT6315)
+struct spmi_device spmi_dev[] = {
+ {
+ .slvid = SPMI_SLAVE_3,
+ .grpiden = 0x800,
+ .type = BUCK_MD,
+ .type_id = BUCK_MD_ID,
+ .mstid = SPMI_MASTER_1,/* spmi-m */
+ .hwcid_addr = 0x09,
+ .hwcid_val = 0x15,
+ .swcid_addr = 0x0b,
+ .swcid_val = 0x15,
+ .pmif_arb = NULL,
+ },
+};
+#else
+struct spmi_device spmi_dev[] = {
+ {
+ .slvid = SPMI_SLAVE_9,
+ .grpiden = 0x0,
+ .type = SUB_PMIC,
+ .type_id = SUB_PMIC_ID,
+ .mstid = SPMI_MASTER_1,/* spmi-m */
+ .hwcid_addr = 0x0000,
+ .hwcid_val = 0x70,/* check [7:4] */
+ .swcid_addr = 0x0001,
+ .swcid_val = 0x08,/* check [3:0] */
+ .pmif_arb = NULL,
+ }, {
+ .slvid = SPMI_SLAVE_8,
+ .grpiden = 0x0,
+ .type = BUCK_MD,
+ .type_id = BUCK_MD_ID,
+ .mstid = SPMI_MASTER_P_1, /* spmi-p */
+ .hwcid_addr = 0x0706,
+ .hwcid_val = 0x00,
+ .swcid_addr = 0x0706,
+ .swcid_val = 0x00,
+ .pmif_arb = NULL,
+ },
+};
+#endif
+#elif defined(CHIP10992)
+struct spmi_device spmi_dev[] = {
+ {
+ .slvid = SPMI_SLAVE_4,
+ .grpiden = 0x1 << 0xB,
+ .type = MAIN_PMIC,
+ .type_id = MAIN_PMIC_ID,
+ .mstid = SPMI_MASTER_1,/* spmi-m */
+ .hwcid_addr = 0x09,
+ .hwcid_val = 0x30,
+ .swcid_addr = 0x0b,
+ .swcid_val = 0x30,
+ .pmif_arb = NULL,
+ }, {
+ .slvid = SPMI_SLAVE_4,
+ .grpiden = 0x1 << 0xB,
+ .type = BUCK_MD,
+ .type_id = BUCK_MD_ID,
+ .mstid = SPMI_MASTER_P_1,/* spmi-p */
+ .hwcid_addr = 0x01A0, /* TOP_VRCTL_VR0_EN */
+ .hwcid_val = 0xFF, /* All BUCK EN = 0xFF */
+ .pmif_arb = NULL,
+ },
+};
+#endif /* end of #if defined(MT6885) || defined(MT6873) */
+#else
+struct spmi_device spmi_dev[] = {
+ {
+ .slvid = SPMI_SLAVE_12,
+ .grpiden = 0x100,
+ .type = BUCK_MD,
+ .type_id = BUCK_MD_ID,
+ .pmif_arb = NULL,
+ }, {
+ .slvid = SPMI_SLAVE_10,
+ .grpiden = 0x100,
+ .type = BUCK_CPU,
+ .type_id = BUCK_CPU_ID,
+ .pmif_arb = NULL,
+ }, {
+ .slvid = SPMI_SLAVE_11,
+ .grpiden = 0x100,
+ .type = BUCK_GPU,
+ .type_id = BUCK_GPU_ID,
+ .pmif_arb = NULL,
+ },
+};
+#endif
+unsigned char spmi_device_cnt;
+
+/* spmi internal API declaration */
+static int spmi_config_master(unsigned int mstid, kal_bool en);
+static int spmi_config_slave(struct spmi_device *dev);
+static int spmi_cali_rd_clock_polarity(struct spmi_device *dev,
+ unsigned int mstid);
+static int spmi_ctrl_op_st(int mstid, unsigned int grpiden,
+ unsigned int sid, unsigned int cmd);
+#if SPMI_RCS_SUPPORT
+static int spmi_enable_rcs(struct spmi_device *dev, unsigned int mstid);
+int spmi_read_eint_sta(unsigned char *slv_eint_sta);
+#endif
+#if SPMI_DEBUG
+static int spmi_rw_test(struct spmi_device *dev);
+static int spmi_read_check(struct spmi_device *dev);
+static int spmi_drv_ut(struct spmi_device *dev, unsigned int ut);
+#endif
+int spmi_enable_group_id(int mstid, unsigned int grpiden);
+int spmi_lock_slave_reg(struct spmi_device *dev);
+int spmi_unlock_slave_reg(struct spmi_device *dev);
+
+#if SPMI_NO_PMIC
+int spmi_init(struct pmif *pmif_arb)
+{
+ SPMI_INFO("do Nothing.\n");
+ return 0;
+}
+
+#else /* #ifdef SPMI_NO_PMIC */
+/*
+ * Function : mtk_spmi_readl()
+ * Description : mtk spmi controller read api
+ * Parameter :
+ * Return :
+ */
+unsigned int spmi_readl(int mstid, enum spmi_regs reg)
+{
+ struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
+
+ return DRV_Reg32(arb->spmimst_base + arb->spmimst_regs[reg]);
+}
+
+/*
+ * Function : mtk_spmi_writel()
+ * Description : mtk spmi controller write api
+ * Parameter :
+ * Return :
+ */
+void spmi_writel(int mstid, enum spmi_regs reg, unsigned int val)
+{
+ struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
+
+ DRV_WriteReg32(arb->spmimst_base + arb->spmimst_regs[reg], val);
+}
+
+/*
+ * Function : spmi_lock_slave_reg()
+ * Description : protect spmi slv register to be write
+ * Parameter :
+ * Return :
+ */
+int spmi_lock_slave_reg(struct spmi_device *dev)
+{
+ const unsigned char wpk_key = 0x0;
+ const unsigned char wpk_key_h = 0x0;
+
+ if ((dev->slvid == SPMI_SLAVE_6) ||
+ (dev->slvid == SPMI_SLAVE_7) ||
+ (dev->slvid == SPMI_SLAVE_3)) {
+ /* enable dig_wpk key, write 0x0*/
+ spmi_ext_register_writel(dev, MT6315_PMIC_DIG_WPK_KEY_ADDR,
+ &wpk_key, 1);
+ spmi_ext_register_writel(dev, MT6315_PMIC_DIG_WPK_KEY_H_ADDR,
+ &wpk_key_h, 1);
+ }
+
+ return 0;
+}
+
+/*
+ * Function : spmi_unlock_slave_reg()
+ * Description : unlock spmi slv register to write
+ * Parameter :
+ * Return :
+ */
+int spmi_unlock_slave_reg(struct spmi_device *dev)
+{
+ const unsigned char wpk_key = 0x15;
+ const unsigned char wpk_key_h = 0x63;
+
+ if ((dev->slvid == SPMI_SLAVE_6) ||
+ (dev->slvid == SPMI_SLAVE_7) ||
+ (dev->slvid == SPMI_SLAVE_3)) {
+ /* disable dig_wpk key, write 0x6315*/
+ spmi_ext_register_writel(dev, MT6315_PMIC_DIG_WPK_KEY_ADDR,
+ &wpk_key, 1);
+ spmi_ext_register_writel(dev, MT6315_PMIC_DIG_WPK_KEY_H_ADDR,
+ &wpk_key_h, 1);
+ }
+
+ return 0;
+}
+
+static int spmi_config_master(unsigned int mstid, kal_bool en)
+{
+ /* Software reset */
+ DRV_WriteReg32(WDT_SWSYSRST2, 0x85 << 24 | 0x1 << 4);
+
+#if !defined(CONFIG_FPGA_EARLY_PORTING)
+ /* TBD */
+ DRV_WriteReg32(CLK_CFG_16_CLR, 0x7 | (0x1 << 4) | (0x1 << 7));
+ DRV_WriteReg32(CLK_CFG_UPDATE2, 0x1 << 2);
+#endif
+
+ /* Software reset */
+ DRV_WriteReg32(WDT_SWSYSRST2, 0x85 << 24);
+
+ /* Enable SPMI */
+ spmi_writel(mstid, SPMI_MST_REQ_EN, en);
+
+ SPMI_INFO("%s done\n", __func__);
+
+ return 0;
+}
+
+static int spmi_config_slave(struct spmi_device *dev)
+{
+ return 0;
+}
+
+static int spmi_cali_rd_clock_polarity(struct spmi_device *dev,
+ unsigned int mstid)
+{
+ unsigned int i = 0;
+#if 0 //TBD
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+ struct cali cali_data[] = {
+ {SPMI_CK_DLY_1T, SPMI_CK_POL_POS},
+ {SPMI_CK_NO_DLY, SPMI_CK_POL_POS},
+ {SPMI_CK_NO_DLY, SPMI_CK_POL_NEG}
+ };
+
+ /* Indicate sampling clock polarity, 1: Positive 0: Negative */
+ for (i = 0;i < 3; i++) {
+ spmi_writel(mstid, SPMI_MST_SAMPL,
+ (cali_data[i].dly << 0x1) | cali_data[i].pol);
+ /* for exception reboot, we only call UT/spmi_read_check w/o
+ * write test. It avoid to affect exception record.
+ */
+#if SPMI_DEBUG
+ if (spmi_read_check(dev) == 0) {
+ SPMI_DBG("dly:%d, pol:%d\n", cali_data[i].dly,
+ cali_data[i].pol);
+ break;
+ }
+#endif
+ }
+ if (i == 3) {
+ SPMI_ERR("FATAL ERROR");
+ ASSERT(0);
+ }
+
+#if 0 //TBD
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+ return 0;
+}
+
+#if SPMI_RCS_SUPPORT
+static int spmi_enable_rcs(struct spmi_device *dev, unsigned int mstid)
+{
+ unsigned char wdata = 0, rdata = 0, i = 0;
+
+ /* clear int status */
+ wdata = 0xc0;
+ spmi_ext_register_writel(dev, MT6315_PMIC_RG_INT_STATUS_RCS0_ADDR,
+ &wdata, 1);
+
+ /* config match mode */
+ wdata = 0x2;
+ spmi_ext_register_writel(dev, MT6315_PMIC_RG_INT_RCS1_ADDR, &wdata, 1);
+ spmi_ext_register_readl(dev, MT6315_PMIC_RG_INT_RCS1_ADDR, &rdata, 1);
+ SPMI_DBG("slvid:%x After set RG_INT_RCS1[0x%x]=0x%x\n", dev->slvid,
+ MT6315_PMIC_RG_INT_RCS1_ADDR, rdata);
+
+ /* set
+ * RG_RCS_ABIT[1] = 1
+ * RG_RCS_CMD[3:2] = 1
+ * RG_RCS_ID[7:4] = 0
+ */
+ spmi_ext_register_readl(dev, MT6315_PMIC_RG_RCS_ABIT_ADDR, &rdata, 1);
+ wdata = rdata |
+ (0x1 << MT6315_PMIC_RG_RCS_ABIT_SHIFT) |
+ (0x1 << MT6315_PMIC_RG_RCS_CMD_SHIFT);
+ wdata &= ~(0xf << MT6315_PMIC_RG_RCS_ID_SHIFT);
+ spmi_ext_register_writel(dev, MT6315_PMIC_RG_RCS_ABIT_ADDR, &wdata, 1);
+ spmi_ext_register_readl(dev, MT6315_PMIC_RG_RCS_ABIT_ADDR, &rdata, 1);
+ SPMI_DBG("slvid:%x After set SPMI_RCS_FUN0[0x%x]=0x%x\n", dev->slvid,
+ MT6315_PMIC_RG_RCS_ABIT_ADDR, rdata);
+
+ /* set rcs_addr = slvid */
+ wdata = dev->slvid;
+ spmi_ext_register_writel(dev, MT6315_PMIC_RG_RCS_ADDR_ADDR, &wdata, 1);
+ spmi_ext_register_readl(dev, MT6315_PMIC_RG_RCS_ADDR_ADDR, &rdata, 1);
+ SPMI_DBG("slvid:%x After set RCS_ADDR[0x%x]=0x%x\n", dev->slvid,
+ MT6315_PMIC_RG_RCS_ADDR_ADDR, rdata);
+
+ /* set mask */
+ wdata = 0x0;
+ spmi_ext_register_writel(dev, MT6315_PMIC_RG_INT_MASK_RCS0_ADDR,
+ &wdata, 1);
+ spmi_ext_register_readl(dev, MT6315_PMIC_RG_INT_MASK_RCS0_ADDR,
+ &rdata, 1);
+ SPMI_DBG("slvid:%x After set RG_INT_MASK[0x%x]=0x%x\n", dev->slvid,
+ MT6315_PMIC_RG_INT_MASK_RCS0_ADDR, rdata);
+
+ /* set top rcs0/rcs1 interrupt enable */
+ wdata = (0x1 << MT6315_PMIC_RG_INT_EN_RCS0_SHIFT) |
+ (0x1 << MT6315_PMIC_RG_INT_EN_RCS1_SHIFT);
+ spmi_ext_register_writel(dev, MT6315_PMIC_RG_INT_EN_RCS0_ADDR,
+ &wdata, 1);
+ spmi_ext_register_readl(dev, MT6315_PMIC_RG_INT_EN_RCS0_ADDR,
+ &rdata, 1);
+ SPMI_DBG("slvid:%x After set RG_INT_EN[0x%x]=0x%x\n", dev->slvid,
+ MT6315_PMIC_RG_INT_EN_RCS0_ADDR, rdata);
+
+ /* enable rcs function */
+ spmi_ext_register_readl(dev, MT6315_PMIC_RG_RCS_ENABLE_ADDR,
+ &rdata, 1);
+ wdata = rdata | (0x1 << MT6315_PMIC_RG_RCS_ENABLE_SHIFT);
+ spmi_ext_register_writel(dev, MT6315_PMIC_RG_RCS_ENABLE_ADDR,
+ &wdata, 1);
+ spmi_ext_register_readl(dev, MT6315_PMIC_RG_RCS_ENABLE_ADDR,
+ &rdata, 1);
+ SPMI_DBG("slvid:%x After set Enable[0x%x]=0x%x\n", dev->slvid,
+ MT6315_PMIC_RG_RCS_ENABLE_ADDR, rdata);
+
+}
+
+int spmi_read_eint_sta(unsigned char *slv_eint_sta)
+{
+ struct pmif *arb = get_pmif_controller(PMIF_SPMI, SPMI_MASTER_0);
+ unsigned char offset = 0, j = 0, rdata = 0;
+ unsigned int regs = 0;
+
+ for (offset = 0; offset < 4; offset++) {
+ regs = arb->spmimst_regs[SPMI_SLV_3_0_EINT] + (offset*4);
+ rdata = DRV_Reg32(arb->spmimst_base + regs);
+ *(slv_eint_sta + j) = rdata & 0xff;
+ *(slv_eint_sta + j+1) = (rdata >> 8) & 0xff;
+ *(slv_eint_sta + j+2) = (rdata >> 16) & 0xff;
+ *(slv_eint_sta + j+3) = (rdata >> 24) & 0xff;
+ j += 4;
+ }
+
+ for (offset = 0; offset < 16; offset++) {
+ SPMI_INFO("%d, slv_eint_sta[0x%x]\n", offset,
+ *(slv_eint_sta + offset));
+ }
+ spmi_writel(mstid, SPMI_SLV_3_0_EINT, 0xffffffff);
+ spmi_writel(mstid, SPMI_SLV_7_4_EINT, 0xffffffff);
+ spmi_writel(mstid, SPMI_SLV_B_8_EINT, 0xffffffff);
+ spmi_writel(mstid, SPMI_SLV_F_C_EINT, 0xffffffff);
+
+ SPMI_INFO("%s, [0x%x]=0x%x\n", __func__,
+ arb->spmimst_base + arb->spmimst_regs[SPMI_DEC_DBG],
+ spmi_readl(mstid, SPMI_DEC_DBG));
+}
+#endif
+
+#if SPMI_EXTADDR_SUPPORT
+int spmi_register_zero_write_extaddr(struct spmi_device *dev,
+ unsigned int addr, unsigned char data)
+{
+ unsigned char wdata = 0;
+
+ spmi_unlock_slave_reg(dev);
+
+ if ((dev->slvid == SPMI_SLAVE_6) ||
+ (dev->slvid == SPMI_SLAVE_7) ||
+ (dev->slvid == SPMI_SLAVE_3)) {
+ /* assign specific addr */
+ wdata = (addr&0xff);
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_REG0_W_ADDR, &wdata, 1);
+ wdata = (addr>>8)&0xff;
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_REG0_W_H_ADDR, &wdata, 1);
+ }
+
+ spmi_lock_slave_reg(dev);
+
+ return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_ZERO_WRITE,
+ dev->slvid, addr, &data, 1);
+}
+
+int spmi_register_zero_write_set_extaddr(struct spmi_device *dev,
+ unsigned int addr, kal_bool en)
+{
+ unsigned char wdata = 0;
+
+ spmi_unlock_slave_reg(dev);
+
+ if ((dev->slvid == SPMI_SLAVE_6) ||
+ (dev->slvid == SPMI_SLAVE_7) ||
+ (dev->slvid == SPMI_SLAVE_3)) {
+ if (en == KAL_TRUE) {
+ /* assign specific addr */
+ wdata = (addr&0xff);
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_REG0_W_ADDR, &wdata, 1);
+ wdata = (addr>>8)&0xff;
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_REG0_W_H_ADDR,
+ &wdata, 1);
+ } else {
+ /* assign specific addr */
+ wdata = 0;
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_REG0_W_ADDR,
+ &wdata, 1);
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_REG0_W_H_ADDR,
+ &wdata, 1);
+ }
+ }
+
+ spmi_lock_slave_reg(dev);
+
+ return 0;
+}
+
+int spmi_register_read_extaddr(struct spmi_device *dev, unsigned int addr,
+ unsigned char *buf)
+{
+ unsigned char wdata = 0;
+
+ spmi_unlock_slave_reg(dev);
+
+ if ((dev->slvid == SPMI_SLAVE_6) ||
+ (dev->slvid == SPMI_SLAVE_7) ||
+ (dev->slvid == SPMI_SLAVE_3)) {
+ /* assign specific addr */
+ wdata = ((addr >> 5) & 0xff);
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_REG_RW_ADDR, &wdata, 1);
+ wdata = ((addr >> 5) & 0xff00);
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_REG_RW_H_ADDR, &wdata, 1);
+ }
+
+ spmi_lock_slave_reg(dev);
+
+ return dev->pmif_arb->read_cmd(dev->pmif_arb, SPMI_CMD_READ,
+ dev->slvid, addr, buf, 1);
+}
+
+int spmi_register_write_extaddr(struct spmi_device *dev, unsigned int addr,
+ unsigned char data)
+{
+ unsigned char wdata = 0;
+
+ spmi_unlock_slave_reg(dev);
+
+ if ((dev->slvid == SPMI_SLAVE_6) ||
+ (dev->slvid == SPMI_SLAVE_7) ||
+ (dev->slvid == SPMI_SLAVE_3)) {
+ /* assign specific addr */
+ wdata = ((addr >> 5) & 0xff);
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_REG_RW_ADDR, &wdata, 1);
+ wdata = ((addr >> 5) & 0xff00);
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_REG_RW_H_ADDR,
+ &wdata, 1);
+ }
+
+ spmi_lock_slave_reg(dev);
+
+ return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_WRITE,
+ dev->slvid, addr, &data, 1);
+}
+
+int spmi_register_rw_set_extaddr(struct spmi_device *dev, unsigned int addr,
+ kal_bool en)
+{
+ unsigned char wdata = 0;
+
+ spmi_unlock_slave_reg(dev);
+
+ if ((dev->slvid == SPMI_SLAVE_6) ||
+ (dev->slvid == SPMI_SLAVE_7) ||
+ (dev->slvid == SPMI_SLAVE_3)) {
+ if (en == KAL_TRUE) {
+ /* assign specific addr */
+ wdata = ((addr >> 5) & 0xff);
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_REG_RW_ADDR,
+ &wdata, 1);
+ wdata = ((addr >> 5) & 0xff00);
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_REG_RW_H_ADDR,
+ &wdata, 1);
+ } else {
+ /* assign specific addr */
+ wdata = 0;
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_REG_RW_ADDR,
+ &wdata, 1);
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_REG_RW_H_ADDR,
+ &wdata, 1);
+ }
+ }
+
+ spmi_lock_slave_reg(dev);
+
+ return 0;
+}
+
+int spmi_ext_register_read_extaddr(struct spmi_device *dev, unsigned int addr,
+ unsigned char *buf, unsigned short len)
+{
+ unsigned char wdata = 0;
+
+ spmi_unlock_slave_reg(dev);
+
+ if ((dev->slvid == SPMI_SLAVE_6) ||
+ (dev->slvid == SPMI_SLAVE_7) ||
+ (dev->slvid == SPMI_SLAVE_3)) {
+ /* assign specific addr */
+ wdata = ((addr >> 8) & 0xff);
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_EXT_REG_RW_ADDR,
+ &wdata, 1);
+ }
+
+ spmi_lock_slave_reg(dev);
+
+ return dev->pmif_arb->read_cmd(dev->pmif_arb, SPMI_CMD_EXT_READ,
+ dev->slvid, addr, buf, len);
+}
+
+int spmi_ext_register_write_extaddr(struct spmi_device *dev, unsigned int addr,
+ const unsigned char *buf, unsigned short len)
+{
+ unsigned char wdata = 0;
+
+ spmi_unlock_slave_reg(dev);
+
+ if ((dev->slvid == SPMI_SLAVE_6) ||
+ (dev->slvid == SPMI_SLAVE_7) ||
+ (dev->slvid == SPMI_SLAVE_3)) {
+ /* assign specific addr */
+ wdata = ((addr >> 8) & 0xff);
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_EXT_REG_RW_ADDR, &wdata, 1);
+ }
+
+ spmi_lock_slave_reg(dev);
+
+ return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_EXT_WRITE,
+ dev->slvid, addr, buf, len);
+}
+
+int spmi_ext_register_rw_set_extaddr(struct spmi_device *dev,
+ unsigned int addr, kal_bool en)
+{
+ unsigned char wdata = 0;
+
+ spmi_unlock_slave_reg(dev);
+
+ if ((dev->slvid == SPMI_SLAVE_6) ||
+ (dev->slvid == SPMI_SLAVE_7) ||
+ (dev->slvid == SPMI_SLAVE_3)) {
+ /* assign specific addr */
+ if (en == KAL_TRUE) {
+ wdata = ((addr >> 8) & 0xff);
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_EXT_REG_RW_ADDR,
+ &wdata, 1);
+ } else {
+ wdata = 0;
+ spmi_ext_register_writel(dev,
+ MT6315_PMIC_RG_EXTADR_EXT_REG_RW_ADDR,
+ &wdata, 1);
+ }
+ }
+
+ spmi_lock_slave_reg(dev);
+
+ return 0;
+}
+#endif /* end of SPMI_EXTADDR_SUPPORT */
+
+static int spmi_ctrl_op_st(int mstid, unsigned int grpiden, unsigned int sid,
+ unsigned int cmd)
+{
+ unsigned int rdata = 0x0;
+
+ /* gid is 0x800 */
+ spmi_writel(mstid, SPMI_GRP_ID_EN, grpiden);
+#if MT63xx_EVB
+ if (grpiden == (1 << SPMI_GROUP_ID))
+ spmi_writel(mstid, SPMI_OP_ST_CTRL,
+ (cmd << 0x4) | SPMI_GROUP_ID);
+#else
+ if (grpiden == 0x100)
+ spmi_writel(mstid, SPMI_OP_ST_CTRL, (cmd << 0x4) | 0x8);
+#endif
+ else
+ spmi_writel(mstid, SPMI_OP_ST_CTRL, (cmd << 0x4) | sid);
+
+ SPMI_WARN("spmi_ctrl_op_st 0x%x\n", spmi_readl(mstid, SPMI_OP_ST_CTRL));
+
+ do
+ {
+ rdata = spmi_readl(mstid, SPMI_OP_ST_STA);
+ SPMI_DBG("spmi_ctrl_op_st 0x%x\n", rdata);
+
+ if (((rdata >> 0x1) & SPMI_OP_ST_NACK) == SPMI_OP_ST_NACK) {
+ break;
+ }
+ }while((rdata & SPMI_OP_ST_BUSY) == SPMI_OP_ST_BUSY);
+
+ return 0;
+}
+
+int spmi_command_reset(int mstid, struct spmi_device *dev, unsigned int grpiden)
+{
+#if MT63xx_EVB
+ if (grpiden != (1 << SPMI_GROUP_ID))
+ dev->slvid = grpiden;
+#else
+ if (grpiden != 0x100)
+ dev->slvid = grpiden;
+#endif
+ return spmi_ctrl_op_st(mstid, grpiden, dev->slvid, SPMI_RESET);
+}
+int spmi_command_sleep(int mstid, struct spmi_device *dev, unsigned int grpiden)
+{
+#if MT63xx_EVB
+ if (grpiden != (1 << SPMI_GROUP_ID))
+ dev->slvid = grpiden;
+#else
+ if (grpiden != 0x100)
+ dev->slvid = grpiden;
+#endif
+ return spmi_ctrl_op_st(mstid, grpiden, dev->slvid, SPMI_SLEEP);
+}
+int spmi_command_wakeup(int mstid, struct spmi_device *dev, unsigned int grpiden)
+{
+#if MT63xx_EVB
+ if (grpiden != (1 << SPMI_GROUP_ID))
+ dev->slvid = grpiden;
+#else
+ if (grpiden != 0x100)
+ dev->slvid = grpiden;
+#endif
+ return spmi_ctrl_op_st(mstid, grpiden, dev->slvid, SPMI_WAKEUP);
+}
+int spmi_command_shutdown(int mstid, struct spmi_device *dev, unsigned int grpiden)
+{
+#if MT63xx_EVB
+ if (grpiden != (1 << SPMI_GROUP_ID))
+ dev->slvid = grpiden;
+#else
+ if (grpiden != 0x100)
+ dev->slvid = grpiden;
+#endif
+ return spmi_ctrl_op_st(mstid, grpiden, dev->slvid, SPMI_SHUTDOWN);
+}
+
+int spmi_enable_group_id(int mstid, unsigned int grpiden)
+{
+ spmi_writel(mstid, SPMI_GRP_ID_EN, grpiden);
+
+ return 0;
+}
+
+#if SPMI_DEBUG
+static int spmi_rw_test(struct spmi_device *dev)
+{
+ unsigned char wdata = 0, rdata = 0;
+
+ if (dev->mstid == SPMI_MASTER_P_1) {
+ SPMI_INFO("SPMI-P doesn't do %s\n", __func__);
+ return 0;
+ }
+ switch (dev->slvid) {
+ case SPMI_SLAVE_3:
+ case SPMI_SLAVE_6:
+ case SPMI_SLAVE_7:
+ wdata = DEFAULT_VALUE_READ_TEST;
+ spmi_ext_register_writel(dev, MT6315_PMIC_TOP_MDB_RSV1_ADDR,
+ &wdata, 1);
+ spmi_ext_register_readl(dev, MT6315_PMIC_TOP_MDB_RSV1_ADDR,
+ &rdata, 1);
+ if (rdata != DEFAULT_VALUE_READ_TEST) {
+ SPMI_ERR("%s fail_r, slvid:%d rdata = 0x%x.\n",
+ __func__, dev->slvid, rdata);
+ return -EIO;
+ } else
+ SPMI_DBG("%s pass_r, slvid:%d\n", __func__, dev->slvid);
+
+ wdata = DEFAULT_VALUE_WRITE_TEST;
+ spmi_ext_register_writel(dev, MT6315_PMIC_TOP_MDB_RSV1_H_ADDR,
+ &wdata, 1);
+
+ spmi_ext_register_readl(dev, MT6315_PMIC_TOP_MDB_RSV1_H_ADDR,
+ &rdata, 1);
+ if (rdata != DEFAULT_VALUE_WRITE_TEST) {
+ SPMI_ERR("%s fail_w, slvid:%d rdata = 0x%x.\n",
+ __func__, dev->slvid, rdata);
+ return -EIO;
+ } else
+ SPMI_DBG("%s pass_w, slvid:%d\n", __func__, dev->slvid);
+
+ break;
+ case SPMI_SLAVE_9:
+ spmi_read_check(dev);
+ break;
+ case SPMI_SLAVE_8:
+ default:
+ SPMI_ERR("%s not be here, slvid:%d\n", __func__, dev->slvid);
+ break;
+ }
+ return 0;
+}
+
+static int spmi_read_check(struct spmi_device *dev)
+{
+ unsigned char rdata = 0;
+
+ spmi_ext_register_readl(dev, dev->hwcid_addr, &rdata, 1);
+ /* mt6362 can only check 0x00[7:4], other mt63xx can align the rule */
+ if ((rdata & 0xF0) != (dev->hwcid_val & 0xF0)) {
+ SPMI_ERR("%s next, slvid:%d rdata = 0x%x.\n",
+ __func__, dev->slvid, rdata);
+ return -EIO;
+ } else
+ SPMI_DBG("%s done, slvid:%d\n", __func__, dev->slvid);
+
+ return 0;
+}
+
+static int spmi_drv_ut(struct spmi_device *dev, unsigned int ut)
+{
+ int ret = 0;
+
+ switch (ut) {
+ case 1:
+ ret = spmi_rw_test(dev);
+ break;
+ case 2:
+ ret = spmi_read_check(dev);
+ break;
+ case 3:
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+#endif /* end of #if SPMI_DEBUG */
+
+struct spmi_device *get_spmi_device(int mstid, unsigned int slv_type)
+{
+ unsigned int i;
+
+ for (i = 0; i < spmi_device_cnt; i++) {
+ if (slv_type == spmi_dev[i].type) {
+ return &spmi_dev[i];
+ }
+ }
+
+ return NULL;
+}
+
+int spmi_init(struct pmif *pmif_arb)
+{
+ int i = 0;
+#if SPMI_DEBUG
+ int ret = 0;
+#endif
+
+ if (pmif_arb == NULL) /* null check */ {
+ SPMI_ERR("arguments err\n");
+ return -EINVAL;
+ }
+
+ pmif_arb->spmimst_regs = mt6885_spmi_regs;
+ pmif_spmi_arb_ctrl[pmif_arb->mstid] = pmif_arb;
+ spmi_device_cnt = sizeof(spmi_dev)/sizeof(spmi_dev[0]);
+
+ if (is_pmif_spmi_init_done(pmif_arb->mstid) != 0)
+ spmi_config_master(pmif_arb->mstid, KAL_TRUE);
+
+ for (i = 0; i < spmi_device_cnt; i++) {
+ if (pmif_arb->mstid == spmi_dev[i].mstid) {
+ spmi_dev[i].pmif_arb = pmif_spmi_arb_ctrl[pmif_arb->mstid];
+ if (is_pmif_spmi_init_done(pmif_arb->mstid) != 0) {
+ spmi_config_slave(&spmi_dev[i]);
+ spmi_cali_rd_clock_polarity(&spmi_dev[i],
+ pmif_arb->mstid);
+ }
+#if SPMI_MONITOR_SUPPORT
+ /* dump 1st time slave debug register when booting */
+ spmi_dump_slv_record_reg(&spmi_dev[i]);
+#endif
+#if SPMI_RCS_SUPPORT
+ if (is_pmif_spmi_init_done() != 0) {
+ /* enable master rcs support */
+ spmi_writel(pmif_arb->mstid, SPMI_MST_RCS_CTRL, 0x15);
+ spmi_enable_rcs(&spmi_dev[i], pmif_arb->mstid);
+ }
+#endif
+
+#if SPMI_DEBUG
+ /* shouldn't enable at here*/
+ ret = spmi_drv_ut(&spmi_dev[i], 1);
+ if(ret) {
+ SPMI_ERR("EIO err\n");
+ return ret;
+ }
+#endif
+ /*TBD spmi_lock_slave_reg(&spmi_dev[i]); */
+ }
+ }
+ SPMI_INFO("%s done\n", __func__);
+
+ return 0;
+}
+
+#endif /* #ifdef SPMI_NO_PMIC */
diff --git a/mcu/driver/devdrv/spmi/src/spmi_common.c b/mcu/driver/devdrv/spmi/src/spmi_common.c
new file mode 100644
index 0000000..e7fb4e1
--- /dev/null
+++ b/mcu/driver/devdrv/spmi/src/spmi_common.c
@@ -0,0 +1,154 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+ * the prior written permission of MediaTek inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of MediaTek Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * MediaTek Inc. (C) 2019. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+ * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+ * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek
+ * Software") have been modified by MediaTek Inc. All revisions are subject to
+ * any receiver's applicable license agreements with MediaTek Inc.
+ */
+/*
+ * MTK SPMI Common Driver
+ *
+ * Copyright 2018 MediaTek Co.,Ltd.
+ *
+ * DESCRIPTION:
+ * This file provides API for other drivers to access PMIC registers
+ *
+ */
+
+#include <pmif.h>
+#include <spmi.h>
+#include <pmif_sw.h>
+#include <spmi_sw.h>
+
+#if SPMI_NO_PMIC
+int spmi_ext_register_readl(struct spmi_device *dev, unsigned int addr,
+ unsigned char *buf, unsigned short len)
+{
+ SPMI_INFO("%s do Nothing.\n", __func__);
+ return 0;
+}
+int spmi_ext_register_writel(struct spmi_device *dev, unsigned int addr,
+ const unsigned char *buf, unsigned short len)
+{
+ SPMI_INFO("%s do Nothing.\n", __func__);
+ return 0;
+}
+#else /* #ifdef SPMI_NO_PMIC */
+int spmi_register_zero_write(struct spmi_device *dev, unsigned int addr,
+ unsigned char data)
+{
+ return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_ZERO_WRITE,
+ dev->slvid, addr, &data, 1);
+}
+
+int spmi_register_read(struct spmi_device *dev, unsigned int addr,
+ unsigned char *buf)
+{
+ return dev->pmif_arb->read_cmd(dev->pmif_arb, SPMI_CMD_READ,
+ dev->slvid, addr, buf, 1);
+}
+
+int spmi_register_write(struct spmi_device *dev, unsigned int addr,
+ unsigned char data)
+{
+ return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_WRITE,
+ dev->slvid, addr, &data, 1);
+}
+
+int spmi_ext_register_read(struct spmi_device *dev, unsigned int addr,
+ unsigned char *buf, unsigned short len)
+{
+ return dev->pmif_arb->read_cmd(dev->pmif_arb, SPMI_CMD_EXT_READ,
+ dev->slvid, addr, buf, len);
+}
+
+int spmi_ext_register_write(struct spmi_device *dev, unsigned int addr,
+ const unsigned char *buf, unsigned short len)
+{
+ return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_EXT_WRITE,
+ dev->slvid, addr, buf, len);
+}
+
+int spmi_ext_register_readl(struct spmi_device *dev, unsigned int addr,
+ unsigned char *buf, unsigned short len)
+{
+ return dev->pmif_arb->read_cmd(dev->pmif_arb, SPMI_CMD_EXT_READL,
+ dev->slvid, addr, buf, len);
+}
+
+int spmi_ext_register_writel(struct spmi_device *dev, unsigned int addr,
+ const unsigned char *buf, unsigned short len)
+{
+ return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_EXT_WRITEL,
+ dev->slvid, addr, buf, len);
+}
+
+int spmi_ext_register_readl_field(struct spmi_device *dev, unsigned int addr,
+ unsigned char *buf, unsigned short len,
+ unsigned short mask, unsigned short shift)
+{
+ unsigned int ret = 0;
+ unsigned char rdata = 0;
+
+ if (len > 1)
+ return -2;
+
+ ret = dev->pmif_arb->read_cmd(dev->pmif_arb, SPMI_CMD_EXT_READL,
+ dev->slvid, addr, &rdata, len);
+ if (ret != 0)
+ return ret;
+
+ *buf = (rdata >> shift) & mask;
+
+ return 0;
+}
+
+int spmi_ext_register_writel_field(struct spmi_device *dev, unsigned int addr,
+ const unsigned char *buf, unsigned short len,
+ unsigned short mask, unsigned short shift)
+{
+ unsigned char data = 0x0;
+ unsigned int ret = 0;
+
+ if (len > 1)
+ return -2;
+
+ ret = spmi_ext_register_readl(dev, addr, &data, 1);
+ if (ret != 0)
+ return ret;
+
+ data = data & ~(mask << shift);
+ data |= (*buf << shift);
+ return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_EXT_WRITEL,
+ dev->slvid, addr, &data, len);
+}
+#endif /* endif SPMI_NO_PMIC */
diff --git a/mcu/driver/devdrv/spmi/src/spmi_dbg.c b/mcu/driver/devdrv/spmi/src/spmi_dbg.c
new file mode 100644
index 0000000..2924204
--- /dev/null
+++ b/mcu/driver/devdrv/spmi/src/spmi_dbg.c
@@ -0,0 +1,918 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+ * the prior written permission of MediaTek inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of MediaTek Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * MediaTek Inc. (C) 2019. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+ * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+ * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek
+ * Software") have been modified by MediaTek Inc. All revisions are subject to
+ * any receiver's applicable license agreements with MediaTek Inc.
+ */
+/*
+ * MTK SPMI Driver
+ *
+ * Copyright 2018 MediaTek Co.,Ltd.
+ *
+ * DESCRIPTION:
+ * This file provides API for other drivers to access PMIC registers
+ *
+ */
+#include <pmif.h>
+#include <spmi.h>
+#include <spmi_sw.h>
+#include <pmif_sw.h>
+#include <mt6315_upmu_hw.h>
+
+#if !SPMI_NO_PMIC
+
+#if (SPMI_CTP)
+#define sprintf FormatString
+#endif
+
+enum pmif_dbg_regs {
+ PMIF_INIT_DONE,
+ PMIF_INF_BUSY_STA,
+ PMIF_OTHER_BUSY_STA_0,
+ PMIF_OTHER_BUSY_STA_1,
+ PMIF_IRQ_EVENT_EN_0,
+ PMIF_IRQ_FLAG_0,
+ PMIF_IRQ_CLR_0,
+ PMIF_IRQ_EVENT_EN_1,
+ PMIF_IRQ_FLAG_1,
+ PMIF_IRQ_CLR_1,
+ PMIF_IRQ_EVENT_EN_2,
+ PMIF_IRQ_FLAG_2,
+ PMIF_IRQ_CLR_2,
+ PMIF_IRQ_EVENT_EN_3,
+ PMIF_IRQ_FLAG_3,
+ PMIF_IRQ_CLR_3,
+ PMIF_IRQ_EVENT_EN_4,
+ PMIF_IRQ_FLAG_4,
+ PMIF_IRQ_CLR_4,
+ PMIF_WDT_EVENT_EN_0,
+ PMIF_WDT_FLAG_0,
+ PMIF_WDT_EVENT_EN_1,
+ PMIF_WDT_FLAG_1,
+ PMIF_MONITOR_CTRL,
+ PMIF_MONITOR_TARGET_CHAN_0,
+ PMIF_MONITOR_TARGET_CHAN_1,
+ PMIF_MONITOR_TARGET_CHAN_2,
+ PMIF_MONITOR_TARGET_CHAN_3,
+ PMIF_MONITOR_TARGET_CHAN_4,
+ PMIF_MONITOR_TARGET_CHAN_5,
+ PMIF_MONITOR_TARGET_CHAN_6,
+ PMIF_MONITOR_TARGET_CHAN_7,
+ PMIF_MONITOR_TARGET_WRITE,
+ PMIF_MONITOR_TARGET_ADDR_0,
+ PMIF_MONITOR_TARGET_ADDR_1,
+ PMIF_MONITOR_TARGET_ADDR_2,
+ PMIF_MONITOR_TARGET_ADDR_3,
+ PMIF_MONITOR_TARGET_ADDR_4,
+ PMIF_MONITOR_TARGET_ADDR_5,
+ PMIF_MONITOR_TARGET_ADDR_6,
+ PMIF_MONITOR_TARGET_ADDR_7,
+ PMIF_MONITOR_TARGET_WDATA_0,
+ PMIF_MONITOR_TARGET_WDATA_1,
+ PMIF_MONITOR_TARGET_WDATA_2,
+ PMIF_MONITOR_TARGET_WDATA_3,
+ PMIF_MONITOR_TARGET_WDATA_4,
+ PMIF_MONITOR_TARGET_WDATA_5,
+ PMIF_MONITOR_TARGET_WDATA_6,
+ PMIF_MONITOR_TARGET_WDATA_7,
+ PMIF_MONITOR_STA,
+ PMIF_MONITOR_RECORD_0_0,
+ PMIF_MONITOR_RECORD_0_1,
+ PMIF_MONITOR_RECORD_0_2,
+ PMIF_MONITOR_RECORD_0_3,
+ PMIF_MONITOR_RECORD_0_4,
+ PMIF_MONITOR_RECORD_1_0,
+ PMIF_MONITOR_RECORD_1_1,
+ PMIF_MONITOR_RECORD_1_2,
+ PMIF_MONITOR_RECORD_1_3,
+ PMIF_MONITOR_RECORD_1_4,
+ PMIF_MONITOR_RECORD_2_0,
+ PMIF_MONITOR_RECORD_2_1,
+ PMIF_MONITOR_RECORD_2_2,
+ PMIF_MONITOR_RECORD_2_3,
+ PMIF_MONITOR_RECORD_2_4,
+ PMIF_MONITOR_RECORD_3_0,
+ PMIF_MONITOR_RECORD_3_1,
+ PMIF_MONITOR_RECORD_3_2,
+ PMIF_MONITOR_RECORD_3_3,
+ PMIF_MONITOR_RECORD_3_4,
+ PMIF_MONITOR_RECORD_4_0,
+ PMIF_MONITOR_RECORD_4_1,
+ PMIF_MONITOR_RECORD_4_2,
+ PMIF_MONITOR_RECORD_4_3,
+ PMIF_MONITOR_RECORD_4_4,
+ PMIF_MONITOR_RECORD_5_0,
+ PMIF_MONITOR_RECORD_5_1,
+ PMIF_MONITOR_RECORD_5_2,
+ PMIF_MONITOR_RECORD_5_3,
+ PMIF_MONITOR_RECORD_5_4,
+ PMIF_MONITOR_RECORD_6_0,
+ PMIF_MONITOR_RECORD_6_1,
+ PMIF_MONITOR_RECORD_6_2,
+ PMIF_MONITOR_RECORD_6_3,
+ PMIF_MONITOR_RECORD_6_4,
+ PMIF_MONITOR_RECORD_7_0,
+ PMIF_MONITOR_RECORD_7_1,
+ PMIF_MONITOR_RECORD_7_2,
+ PMIF_MONITOR_RECORD_7_3,
+ PMIF_MONITOR_RECORD_7_4,
+ PMIF_MONITOR_RECORD_8_0,
+ PMIF_MONITOR_RECORD_8_1,
+ PMIF_MONITOR_RECORD_8_2,
+ PMIF_MONITOR_RECORD_8_3,
+ PMIF_MONITOR_RECORD_8_4,
+ PMIF_MONITOR_RECORD_9_0,
+ PMIF_MONITOR_RECORD_9_1,
+ PMIF_MONITOR_RECORD_9_2,
+ PMIF_MONITOR_RECORD_9_3,
+ PMIF_MONITOR_RECORD_9_4,
+ PMIF_MONITOR_RECORD_10_0,
+ PMIF_MONITOR_RECORD_10_1,
+ PMIF_MONITOR_RECORD_10_2,
+ PMIF_MONITOR_RECORD_10_3,
+ PMIF_MONITOR_RECORD_10_4,
+ PMIF_MONITOR_RECORD_11_0,
+ PMIF_MONITOR_RECORD_11_1,
+ PMIF_MONITOR_RECORD_11_2,
+ PMIF_MONITOR_RECORD_11_3,
+ PMIF_MONITOR_RECORD_11_4,
+ PMIF_MONITOR_RECORD_12_0,
+ PMIF_MONITOR_RECORD_12_1,
+ PMIF_MONITOR_RECORD_12_2,
+ PMIF_MONITOR_RECORD_12_3,
+ PMIF_MONITOR_RECORD_12_4,
+ PMIF_MONITOR_RECORD_13_0,
+ PMIF_MONITOR_RECORD_13_1,
+ PMIF_MONITOR_RECORD_13_2,
+ PMIF_MONITOR_RECORD_13_3,
+ PMIF_MONITOR_RECORD_13_4,
+ PMIF_MONITOR_RECORD_14_0,
+ PMIF_MONITOR_RECORD_14_1,
+ PMIF_MONITOR_RECORD_14_2,
+ PMIF_MONITOR_RECORD_14_3,
+ PMIF_MONITOR_RECORD_14_4,
+ PMIF_MONITOR_RECORD_15_0,
+ PMIF_MONITOR_RECORD_15_1,
+ PMIF_MONITOR_RECORD_15_2,
+ PMIF_MONITOR_RECORD_15_3,
+ PMIF_MONITOR_RECORD_15_4,
+ PMIF_MONITOR_RECORD_16_0,
+ PMIF_MONITOR_RECORD_16_1,
+ PMIF_MONITOR_RECORD_16_2,
+ PMIF_MONITOR_RECORD_16_3,
+ PMIF_MONITOR_RECORD_16_4,
+ PMIF_MONITOR_RECORD_17_0,
+ PMIF_MONITOR_RECORD_17_1,
+ PMIF_MONITOR_RECORD_17_2,
+ PMIF_MONITOR_RECORD_17_3,
+ PMIF_MONITOR_RECORD_17_4,
+ PMIF_MONITOR_RECORD_18_0,
+ PMIF_MONITOR_RECORD_18_1,
+ PMIF_MONITOR_RECORD_18_2,
+ PMIF_MONITOR_RECORD_18_3,
+ PMIF_MONITOR_RECORD_18_4,
+ PMIF_MONITOR_RECORD_19_0,
+ PMIF_MONITOR_RECORD_19_1,
+ PMIF_MONITOR_RECORD_19_2,
+ PMIF_MONITOR_RECORD_19_3,
+ PMIF_MONITOR_RECORD_19_4,
+ PMIF_MONITOR_RECORD_20_0,
+ PMIF_MONITOR_RECORD_20_1,
+ PMIF_MONITOR_RECORD_20_2,
+ PMIF_MONITOR_RECORD_20_3,
+ PMIF_MONITOR_RECORD_20_4,
+ PMIF_MONITOR_RECORD_21_0,
+ PMIF_MONITOR_RECORD_21_1,
+ PMIF_MONITOR_RECORD_21_2,
+ PMIF_MONITOR_RECORD_21_3,
+ PMIF_MONITOR_RECORD_21_4,
+ PMIF_MONITOR_RECORD_22_0,
+ PMIF_MONITOR_RECORD_22_1,
+ PMIF_MONITOR_RECORD_22_2,
+ PMIF_MONITOR_RECORD_22_3,
+ PMIF_MONITOR_RECORD_22_4,
+ PMIF_MONITOR_RECORD_23_0,
+ PMIF_MONITOR_RECORD_23_1,
+ PMIF_MONITOR_RECORD_23_2,
+ PMIF_MONITOR_RECORD_23_3,
+ PMIF_MONITOR_RECORD_23_4,
+ PMIF_MONITOR_RECORD_24_0,
+ PMIF_MONITOR_RECORD_24_1,
+ PMIF_MONITOR_RECORD_24_2,
+ PMIF_MONITOR_RECORD_24_3,
+ PMIF_MONITOR_RECORD_24_4,
+ PMIF_MONITOR_RECORD_25_0,
+ PMIF_MONITOR_RECORD_25_1,
+ PMIF_MONITOR_RECORD_25_2,
+ PMIF_MONITOR_RECORD_25_3,
+ PMIF_MONITOR_RECORD_25_4,
+ PMIF_MONITOR_RECORD_26_0,
+ PMIF_MONITOR_RECORD_26_1,
+ PMIF_MONITOR_RECORD_26_2,
+ PMIF_MONITOR_RECORD_26_3,
+ PMIF_MONITOR_RECORD_26_4,
+ PMIF_MONITOR_RECORD_27_0,
+ PMIF_MONITOR_RECORD_27_1,
+ PMIF_MONITOR_RECORD_27_2,
+ PMIF_MONITOR_RECORD_27_3,
+ PMIF_MONITOR_RECORD_27_4,
+ PMIF_MONITOR_RECORD_28_0,
+ PMIF_MONITOR_RECORD_28_1,
+ PMIF_MONITOR_RECORD_28_2,
+ PMIF_MONITOR_RECORD_28_3,
+ PMIF_MONITOR_RECORD_28_4,
+ PMIF_MONITOR_RECORD_29_0,
+ PMIF_MONITOR_RECORD_29_1,
+ PMIF_MONITOR_RECORD_29_2,
+ PMIF_MONITOR_RECORD_29_3,
+ PMIF_MONITOR_RECORD_29_4,
+ PMIF_MONITOR_RECORD_30_0,
+ PMIF_MONITOR_RECORD_30_1,
+ PMIF_MONITOR_RECORD_30_2,
+ PMIF_MONITOR_RECORD_30_3,
+ PMIF_MONITOR_RECORD_30_4,
+ PMIF_MONITOR_RECORD_31_0,
+ PMIF_MONITOR_RECORD_31_1,
+ PMIF_MONITOR_RECORD_31_2,
+ PMIF_MONITOR_RECORD_31_3,
+ PMIF_MONITOR_RECORD_31_4,
+ PMIF_DEBUG_CTRL,
+ PMIF_RESERVED_0,
+ PMIF_SWINF_0_ACC,
+ PMIF_SWINF_0_WDATA_31_0,
+ PMIF_SWINF_0_WDATA_63_32,
+ PMIF_SWINF_0_RDATA_31_0,
+ PMIF_SWINF_0_RDATA_63_32,
+ PMIF_SWINF_0_VLD_CLR,
+ PMIF_SWINF_0_STA,
+ PMIF_SWINF_1_ACC,
+ PMIF_SWINF_1_WDATA_31_0,
+ PMIF_SWINF_1_WDATA_63_32,
+ PMIF_SWINF_1_RDATA_31_0,
+ PMIF_SWINF_1_RDATA_63_32,
+ PMIF_SWINF_1_VLD_CLR,
+ PMIF_SWINF_1_STA,
+ PMIF_SWINF_2_ACC,
+ PMIF_SWINF_2_WDATA_31_0,
+ PMIF_SWINF_2_WDATA_63_32,
+ PMIF_SWINF_2_RDATA_31_0,
+ PMIF_SWINF_2_RDATA_63_32,
+ PMIF_SWINF_2_VLD_CLR,
+ PMIF_SWINF_2_STA,
+ PMIF_SWINF_3_ACC,
+ PMIF_SWINF_3_WDATA_31_0,
+ PMIF_SWINF_3_WDATA_63_32,
+ PMIF_SWINF_3_RDATA_31_0,
+ PMIF_SWINF_3_RDATA_63_32,
+ PMIF_SWINF_3_VLD_CLR,
+ PMIF_SWINF_3_STA,
+};
+
+static int mt6xxx_pmif_dbg_regs[] = {
+ [PMIF_INIT_DONE] = 0x0000,
+ [PMIF_INF_BUSY_STA] = 0x0018,
+ [PMIF_OTHER_BUSY_STA_0] = 0x001C,
+ [PMIF_OTHER_BUSY_STA_1] = 0x0020,
+ [PMIF_IRQ_EVENT_EN_0] = 0x0418,
+ [PMIF_IRQ_FLAG_0] = 0x0420,
+ [PMIF_IRQ_CLR_0] = 0x0424,
+ [PMIF_IRQ_EVENT_EN_1] = 0x0428,
+ [PMIF_IRQ_FLAG_1] = 0x0430,
+ [PMIF_IRQ_CLR_1] = 0x0434,
+ [PMIF_IRQ_EVENT_EN_2] = 0x0438,
+ [PMIF_IRQ_FLAG_2] = 0x0440,
+ [PMIF_IRQ_CLR_2] = 0x0444,
+ [PMIF_IRQ_EVENT_EN_3] = 0x0448,
+ [PMIF_IRQ_FLAG_3] = 0x0450,
+ [PMIF_IRQ_CLR_3] = 0x0454,
+ [PMIF_IRQ_EVENT_EN_4] = 0x0458,
+ [PMIF_IRQ_FLAG_4] = 0x0460,
+ [PMIF_IRQ_CLR_4] = 0x0464,
+ [PMIF_WDT_EVENT_EN_0] = 0x046C,
+ [PMIF_WDT_FLAG_0] = 0x0470,
+ [PMIF_WDT_EVENT_EN_1] = 0x0474,
+ [PMIF_WDT_FLAG_1] = 0x0478,
+ [PMIF_MONITOR_CTRL] = 0x047C,
+ [PMIF_MONITOR_TARGET_CHAN_0] = 0x0480,
+ [PMIF_MONITOR_TARGET_CHAN_1] = 0x0484,
+ [PMIF_MONITOR_TARGET_CHAN_2] = 0x0488,
+ [PMIF_MONITOR_TARGET_CHAN_3] = 0x048C,
+ [PMIF_MONITOR_TARGET_CHAN_4] = 0x0490,
+ [PMIF_MONITOR_TARGET_CHAN_5] = 0x0494,
+ [PMIF_MONITOR_TARGET_CHAN_6] = 0x0498,
+ [PMIF_MONITOR_TARGET_CHAN_7] = 0x049C,
+ [PMIF_MONITOR_TARGET_WRITE] = 0x04A0,
+ [PMIF_MONITOR_TARGET_ADDR_0] = 0x04A4,
+ [PMIF_MONITOR_TARGET_ADDR_1] = 0x04A8,
+ [PMIF_MONITOR_TARGET_ADDR_2] = 0x04AC,
+ [PMIF_MONITOR_TARGET_ADDR_3] = 0x04B0,
+ [PMIF_MONITOR_TARGET_ADDR_4] = 0x04B4,
+ [PMIF_MONITOR_TARGET_ADDR_5] = 0x04B8,
+ [PMIF_MONITOR_TARGET_ADDR_6] = 0x04BC,
+ [PMIF_MONITOR_TARGET_ADDR_7] = 0x04C0,
+ [PMIF_MONITOR_TARGET_WDATA_0] = 0x04C4,
+ [PMIF_MONITOR_TARGET_WDATA_1] = 0x04C8,
+ [PMIF_MONITOR_TARGET_WDATA_2] = 0x04CC,
+ [PMIF_MONITOR_TARGET_WDATA_3] = 0x04D0,
+ [PMIF_MONITOR_TARGET_WDATA_4] = 0x04D4,
+ [PMIF_MONITOR_TARGET_WDATA_5] = 0x04D8,
+ [PMIF_MONITOR_TARGET_WDATA_6] = 0x04DC,
+ [PMIF_MONITOR_TARGET_WDATA_7] = 0x04E0,
+ [PMIF_MONITOR_STA] = 0x04E4,
+ [PMIF_MONITOR_RECORD_0_0] = 0x04E8,
+ [PMIF_MONITOR_RECORD_0_1] = 0x04EC,
+ [PMIF_MONITOR_RECORD_0_2] = 0x04F0,
+ [PMIF_MONITOR_RECORD_0_3] = 0x04F4,
+ [PMIF_MONITOR_RECORD_0_4] = 0x04F8,
+ [PMIF_MONITOR_RECORD_1_0] = 0x04FC,
+ [PMIF_MONITOR_RECORD_1_1] = 0x0500,
+ [PMIF_MONITOR_RECORD_1_2] = 0x0504,
+ [PMIF_MONITOR_RECORD_1_3] = 0x0508,
+ [PMIF_MONITOR_RECORD_1_4] = 0x050C,
+ [PMIF_MONITOR_RECORD_2_0] = 0x0510,
+ [PMIF_MONITOR_RECORD_2_1] = 0x0514,
+ [PMIF_MONITOR_RECORD_2_2] = 0x0518,
+ [PMIF_MONITOR_RECORD_2_3] = 0x051C,
+ [PMIF_MONITOR_RECORD_2_4] = 0x0520,
+ [PMIF_MONITOR_RECORD_3_0] = 0x0524,
+ [PMIF_MONITOR_RECORD_3_1] = 0x0528,
+ [PMIF_MONITOR_RECORD_3_2] = 0x052C,
+ [PMIF_MONITOR_RECORD_3_3] = 0x0530,
+ [PMIF_MONITOR_RECORD_3_4] = 0x0534,
+ [PMIF_MONITOR_RECORD_4_0] = 0x0538,
+ [PMIF_MONITOR_RECORD_4_1] = 0x053C,
+ [PMIF_MONITOR_RECORD_4_2] = 0x0540,
+ [PMIF_MONITOR_RECORD_4_3] = 0x0544,
+ [PMIF_MONITOR_RECORD_4_4] = 0x0548,
+ [PMIF_MONITOR_RECORD_5_0] = 0x054C,
+ [PMIF_MONITOR_RECORD_5_1] = 0x0550,
+ [PMIF_MONITOR_RECORD_5_2] = 0x0554,
+ [PMIF_MONITOR_RECORD_5_3] = 0x0558,
+ [PMIF_MONITOR_RECORD_5_4] = 0x055C,
+ [PMIF_MONITOR_RECORD_6_0] = 0x0560,
+ [PMIF_MONITOR_RECORD_6_1] = 0x0564,
+ [PMIF_MONITOR_RECORD_6_2] = 0x0568,
+ [PMIF_MONITOR_RECORD_6_3] = 0x056C,
+ [PMIF_MONITOR_RECORD_6_4] = 0x0570,
+ [PMIF_MONITOR_RECORD_7_0] = 0x0574,
+ [PMIF_MONITOR_RECORD_7_1] = 0x0578,
+ [PMIF_MONITOR_RECORD_7_2] = 0x057C,
+ [PMIF_MONITOR_RECORD_7_3] = 0x0580,
+ [PMIF_MONITOR_RECORD_7_4] = 0x0584,
+ [PMIF_MONITOR_RECORD_8_0] = 0x0588,
+ [PMIF_MONITOR_RECORD_8_1] = 0x058C,
+ [PMIF_MONITOR_RECORD_8_2] = 0x0590,
+ [PMIF_MONITOR_RECORD_8_3] = 0x0594,
+ [PMIF_MONITOR_RECORD_8_4] = 0x0598,
+ [PMIF_MONITOR_RECORD_9_0] = 0x059C,
+ [PMIF_MONITOR_RECORD_9_1] = 0x05A0,
+ [PMIF_MONITOR_RECORD_9_2] = 0x05A4,
+ [PMIF_MONITOR_RECORD_9_3] = 0x05A8,
+ [PMIF_MONITOR_RECORD_9_4] = 0x05AC,
+ [PMIF_MONITOR_RECORD_10_0] = 0x05B0,
+ [PMIF_MONITOR_RECORD_10_1] = 0x05B4,
+ [PMIF_MONITOR_RECORD_10_2] = 0x05B8,
+ [PMIF_MONITOR_RECORD_10_3] = 0x05BC,
+ [PMIF_MONITOR_RECORD_10_4] = 0x05C0,
+ [PMIF_MONITOR_RECORD_11_0] = 0x05C4,
+ [PMIF_MONITOR_RECORD_11_1] = 0x05C8,
+ [PMIF_MONITOR_RECORD_11_2] = 0x05CC,
+ [PMIF_MONITOR_RECORD_11_3] = 0x05D0,
+ [PMIF_MONITOR_RECORD_11_4] = 0x05D4,
+ [PMIF_MONITOR_RECORD_12_0] = 0x05D8,
+ [PMIF_MONITOR_RECORD_12_1] = 0x05DC,
+ [PMIF_MONITOR_RECORD_12_2] = 0x05E0,
+ [PMIF_MONITOR_RECORD_12_3] = 0x05E4,
+ [PMIF_MONITOR_RECORD_12_4] = 0x05E8,
+ [PMIF_MONITOR_RECORD_13_0] = 0x05EC,
+ [PMIF_MONITOR_RECORD_13_1] = 0x05F0,
+ [PMIF_MONITOR_RECORD_13_2] = 0x05F4,
+ [PMIF_MONITOR_RECORD_13_3] = 0x05F8,
+ [PMIF_MONITOR_RECORD_13_4] = 0x05FC,
+ [PMIF_MONITOR_RECORD_14_0] = 0x0600,
+ [PMIF_MONITOR_RECORD_14_1] = 0x0604,
+ [PMIF_MONITOR_RECORD_14_2] = 0x0608,
+ [PMIF_MONITOR_RECORD_14_3] = 0x060C,
+ [PMIF_MONITOR_RECORD_14_4] = 0x0610,
+ [PMIF_MONITOR_RECORD_15_0] = 0x0614,
+ [PMIF_MONITOR_RECORD_15_1] = 0x0618,
+ [PMIF_MONITOR_RECORD_15_2] = 0x061C,
+ [PMIF_MONITOR_RECORD_15_3] = 0x0620,
+ [PMIF_MONITOR_RECORD_15_4] = 0x0624,
+ [PMIF_MONITOR_RECORD_16_0] = 0x0628,
+ [PMIF_MONITOR_RECORD_16_1] = 0x062C,
+ [PMIF_MONITOR_RECORD_16_2] = 0x0630,
+ [PMIF_MONITOR_RECORD_16_3] = 0x0634,
+ [PMIF_MONITOR_RECORD_16_4] = 0x0638,
+ [PMIF_MONITOR_RECORD_17_0] = 0x063C,
+ [PMIF_MONITOR_RECORD_17_1] = 0x0640,
+ [PMIF_MONITOR_RECORD_17_2] = 0x0644,
+ [PMIF_MONITOR_RECORD_17_3] = 0x0648,
+ [PMIF_MONITOR_RECORD_17_4] = 0x064C,
+ [PMIF_MONITOR_RECORD_18_0] = 0x0650,
+ [PMIF_MONITOR_RECORD_18_1] = 0x0654,
+ [PMIF_MONITOR_RECORD_18_2] = 0x0658,
+ [PMIF_MONITOR_RECORD_18_3] = 0x065C,
+ [PMIF_MONITOR_RECORD_18_4] = 0x0660,
+ [PMIF_MONITOR_RECORD_19_0] = 0x0664,
+ [PMIF_MONITOR_RECORD_19_1] = 0x0668,
+ [PMIF_MONITOR_RECORD_19_2] = 0x066C,
+ [PMIF_MONITOR_RECORD_19_3] = 0x0670,
+ [PMIF_MONITOR_RECORD_19_4] = 0x0674,
+ [PMIF_MONITOR_RECORD_20_0] = 0x0678,
+ [PMIF_MONITOR_RECORD_20_1] = 0x067C,
+ [PMIF_MONITOR_RECORD_20_2] = 0x0680,
+ [PMIF_MONITOR_RECORD_20_3] = 0x0684,
+ [PMIF_MONITOR_RECORD_20_4] = 0x0688,
+ [PMIF_MONITOR_RECORD_21_0] = 0x068C,
+ [PMIF_MONITOR_RECORD_21_1] = 0x0690,
+ [PMIF_MONITOR_RECORD_21_2] = 0x0694,
+ [PMIF_MONITOR_RECORD_21_3] = 0x0698,
+ [PMIF_MONITOR_RECORD_21_4] = 0x069C,
+ [PMIF_MONITOR_RECORD_22_0] = 0x06A0,
+ [PMIF_MONITOR_RECORD_22_1] = 0x06A4,
+ [PMIF_MONITOR_RECORD_22_2] = 0x06A8,
+ [PMIF_MONITOR_RECORD_22_3] = 0x06AC,
+ [PMIF_MONITOR_RECORD_22_4] = 0x06B0,
+ [PMIF_MONITOR_RECORD_23_0] = 0x06B4,
+ [PMIF_MONITOR_RECORD_23_1] = 0x06B8,
+ [PMIF_MONITOR_RECORD_23_2] = 0x06BC,
+ [PMIF_MONITOR_RECORD_23_3] = 0x06C0,
+ [PMIF_MONITOR_RECORD_23_4] = 0x06C4,
+ [PMIF_MONITOR_RECORD_24_0] = 0x06C8,
+ [PMIF_MONITOR_RECORD_24_1] = 0x06CC,
+ [PMIF_MONITOR_RECORD_24_2] = 0x06D0,
+ [PMIF_MONITOR_RECORD_24_3] = 0x06D4,
+ [PMIF_MONITOR_RECORD_24_4] = 0x06D8,
+ [PMIF_MONITOR_RECORD_25_0] = 0x06DC,
+ [PMIF_MONITOR_RECORD_25_1] = 0x06E0,
+ [PMIF_MONITOR_RECORD_25_2] = 0x06E4,
+ [PMIF_MONITOR_RECORD_25_3] = 0x06E8,
+ [PMIF_MONITOR_RECORD_25_4] = 0x06EC,
+ [PMIF_MONITOR_RECORD_26_0] = 0x06F0,
+ [PMIF_MONITOR_RECORD_26_1] = 0x06F4,
+ [PMIF_MONITOR_RECORD_26_2] = 0x06F8,
+ [PMIF_MONITOR_RECORD_26_3] = 0x06FC,
+ [PMIF_MONITOR_RECORD_26_4] = 0x0700,
+ [PMIF_MONITOR_RECORD_27_0] = 0x0704,
+ [PMIF_MONITOR_RECORD_27_1] = 0x0708,
+ [PMIF_MONITOR_RECORD_27_2] = 0x070C,
+ [PMIF_MONITOR_RECORD_27_3] = 0x0710,
+ [PMIF_MONITOR_RECORD_27_4] = 0x0714,
+ [PMIF_MONITOR_RECORD_28_0] = 0x0718,
+ [PMIF_MONITOR_RECORD_28_1] = 0x071C,
+ [PMIF_MONITOR_RECORD_28_2] = 0x0720,
+ [PMIF_MONITOR_RECORD_28_3] = 0x0724,
+ [PMIF_MONITOR_RECORD_28_4] = 0x0728,
+ [PMIF_MONITOR_RECORD_29_0] = 0x072C,
+ [PMIF_MONITOR_RECORD_29_1] = 0x0730,
+ [PMIF_MONITOR_RECORD_29_2] = 0x0734,
+ [PMIF_MONITOR_RECORD_29_3] = 0x0738,
+ [PMIF_MONITOR_RECORD_29_4] = 0x073C,
+ [PMIF_MONITOR_RECORD_30_0] = 0x0740,
+ [PMIF_MONITOR_RECORD_30_1] = 0x0744,
+ [PMIF_MONITOR_RECORD_30_2] = 0x0748,
+ [PMIF_MONITOR_RECORD_30_3] = 0x074C,
+ [PMIF_MONITOR_RECORD_30_4] = 0x0750,
+ [PMIF_MONITOR_RECORD_31_0] = 0x0754,
+ [PMIF_MONITOR_RECORD_31_1] = 0x0758,
+ [PMIF_MONITOR_RECORD_31_2] = 0x075C,
+ [PMIF_MONITOR_RECORD_31_3] = 0x0760,
+ [PMIF_MONITOR_RECORD_31_4] = 0x0764,
+ [PMIF_DEBUG_CTRL] = 0x0768,
+ [PMIF_RESERVED_0] = 0x0770,
+ [PMIF_SWINF_0_ACC] = 0x0C00,
+ [PMIF_SWINF_0_WDATA_31_0] = 0x0C04,
+ [PMIF_SWINF_0_WDATA_63_32] = 0x0C08,
+ [PMIF_SWINF_0_RDATA_31_0] = 0x0C14,
+ [PMIF_SWINF_0_RDATA_63_32] = 0x0C18,
+ [PMIF_SWINF_0_VLD_CLR] = 0x0C24,
+ [PMIF_SWINF_0_STA] = 0x0C28,
+ [PMIF_SWINF_1_ACC] = 0x0C40,
+ [PMIF_SWINF_1_WDATA_31_0] = 0x0C44,
+ [PMIF_SWINF_1_WDATA_63_32] = 0x0C48,
+ [PMIF_SWINF_1_RDATA_31_0] = 0x0C54,
+ [PMIF_SWINF_1_RDATA_63_32] = 0x0C58,
+ [PMIF_SWINF_1_VLD_CLR] = 0x0C64,
+ [PMIF_SWINF_1_STA] = 0x0C68,
+ [PMIF_SWINF_2_ACC] = 0x0C80,
+ [PMIF_SWINF_2_WDATA_31_0] = 0x0C84,
+ [PMIF_SWINF_2_WDATA_63_32] = 0x0C88,
+ [PMIF_SWINF_2_RDATA_31_0] = 0x0C94,
+ [PMIF_SWINF_2_RDATA_63_32] = 0x0C98,
+ [PMIF_SWINF_2_VLD_CLR] = 0x0CA4,
+ [PMIF_SWINF_2_STA] = 0x0CA8,
+ [PMIF_SWINF_3_ACC] = 0x0CC0,
+ [PMIF_SWINF_3_WDATA_31_0] = 0x0CC4,
+ [PMIF_SWINF_3_WDATA_63_32] = 0x0CC8,
+ [PMIF_SWINF_3_RDATA_31_0] = 0x0CD4,
+ [PMIF_SWINF_3_RDATA_63_32] = 0x0CD8,
+ [PMIF_SWINF_3_VLD_CLR] = 0x0CE4,
+ [PMIF_SWINF_3_STA] = 0x0CE8,
+};
+#if SPMI_KERNEL
+static unsigned char spmi_pmif_log_buf[1280];
+#endif
+
+/* spmi & pmif debug mechanism */
+void spmi_dump_pmif_busy_reg(int mstid)
+{
+ struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
+ unsigned int i = 0, offset = 0, tmp_dat = 0;
+ unsigned int start = 0, end = 0;
+
+ start = arb->dbgregs[PMIF_INF_BUSY_STA]/4;
+ end = arb->dbgregs[PMIF_OTHER_BUSY_STA_1]/4;
+
+ PMIF_CRI("");
+ for (i = start; i <= end; i++) {
+ offset = arb->dbgregs[PMIF_INF_BUSY_STA] + (i * 4);
+ tmp_dat = DRV_Reg32(arb->base + offset);
+ PMIF_CRIL("(0x%x)=0x%x ", offset, tmp_dat);
+
+ if (i == 0)
+ continue;
+ }
+ PMIF_CRIL("\r\n");
+ spmi_dump_pmif_swinf_reg(mstid);
+
+}
+void spmi_dump_pmif_swinf_reg(int mstid)
+{
+ struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
+ unsigned int i = 0, offset = 0, j = 0, tmp_dat = 0;
+ unsigned int swinf[4] = {0}, cmd[4] = {0}, rw[4] = {0};
+ unsigned int slvid[4] = {0}, bytecnt[4] = {0}, adr[4] = {0};
+#if 0
+/* under construction !*/
+/* under construction !*/
+#endif
+ unsigned int wd_31_0[4] = {0}, rd_31_0[4] = {0};
+ unsigned int err[4] = {0}, sbusy[4] = {0}, done[4] = {0};
+ unsigned int qfillcnt[4] = {0}, qfreecnt[4] = {0}, qempty[4] = {0};
+ unsigned int qfull[4] = {0}, req[4] = {0}, fsm[4] = {0}, en[4] = {0};
+
+ for (i = 0; i < 4; i++) {
+ offset = arb->dbgregs[PMIF_SWINF_0_ACC] + (i * 0x40);
+ tmp_dat = DRV_Reg32(arb->base + offset);
+ swinf[j] = i;
+ cmd[j] = (tmp_dat & (0x3 << 30)) >> 30;
+ rw[j] = (tmp_dat & (0x1 << 29)) >> 29;
+ slvid[j] = (tmp_dat & (0xf << 24)) >> 24;
+ bytecnt[j] = (tmp_dat & (0xf << 16)) >> 16;
+ adr[j] = (tmp_dat & (0xffff << 0)) >> 0;
+ j += 1;
+ }
+ j = 0;
+ for (i = 0; i < 4; i++) {
+ offset = arb->dbgregs[PMIF_SWINF_0_WDATA_31_0] + (i * 0x40);
+ tmp_dat = DRV_Reg32(arb->base + offset);
+ wd_31_0[j] = tmp_dat;
+ j += 1;
+ }
+ j = 0;
+ for (i = 0; i < 4; i++) {
+ offset = arb->dbgregs[PMIF_SWINF_0_RDATA_31_0] + (i * 0x40);
+ tmp_dat = DRV_Reg32(arb->base + offset);
+ rd_31_0[j] = tmp_dat;
+ j += 1;
+ }
+ j = 0;
+ for (i = 0; i < 4; i++) {
+ offset = arb->dbgregs[PMIF_SWINF_0_STA] + (i * 0x40);
+ tmp_dat = DRV_Reg32(arb->base + offset);
+ err[j] = (tmp_dat & (0x1 << 18)) >> 18;
+ sbusy[j] = (tmp_dat & (0x1 << 17)) >> 17;
+ done[j] = (tmp_dat & (0x1 << 15)) >> 15;
+ qfillcnt[j] = (tmp_dat & (0xf << 11)) >> 11;
+ qfreecnt[j] = (tmp_dat & (0xf << 7)) >> 7;
+ qempty[j] = (tmp_dat & (0x1 << 6)) >> 6;
+ qfull[j] = (tmp_dat & (0x1 << 5)) >> 5;
+ req[j] = (tmp_dat & (0x1 << 4)) >> 4;
+ fsm[j] = (tmp_dat & (0x7 << 1)) >> 1;
+ en[j] = (tmp_dat & (0x1 << 0)) >> 0;
+ j += 1;
+ }
+ for (i = 0; i < 4; i++) {
+ if (rw[i] == 0) {
+ PMIF_CRI("[swinf:%d, cmd:0x%x, rw:0x%x, slvid:%d ",
+ swinf[i], cmd[i], rw[i], slvid[i]);
+ PMIF_CRIL("bytecnt:%d (read adr 0x%04x=0x%x)]\r\n",
+ bytecnt[i], adr[i], rd_31_0[i]);
+ PMIF_CRI("[err:%d, sbusy:%d, done:%d, qfillcnt:%d ",
+ err[i], sbusy[i], done[i], qfillcnt[i]);
+ PMIF_CRIL("qfreecnt:%d, qempty:%d, qfull:%d, req:%d ",
+ qfreecnt[i], qempty[i], qfull[i], req[i]);
+ PMIF_CRIL("fsm:%d, en:%d]\r\n", fsm[i], en[i]);
+ } else {
+ PMIF_CRI("[swinf:%d, cmd:0x%x, rw:0x%x, slvid:%d ",
+ swinf[i], cmd[i], rw[i], slvid[i]);
+ PMIF_CRIL("bytecnt:%d (write adr 0x%04x=0x%x)]\r\n",
+ bytecnt[i], adr[i], wd_31_0[i]);
+ PMIF_CRI("[err:%d, sbusy:%d, done:%d, qfillcnt:%d ",
+ err[i], sbusy[i], done[i], qfillcnt[i]);
+ PMIF_CRIL("qfreecnt:%d, qempty:%d, qfull:%d, req:%d ",
+ qfreecnt[i], qempty[i], qfull[i], req[i]);
+ PMIF_CRIL("fsm:%d, en:%d]\r\n", fsm[i], en[i]);
+ }
+ }
+}
+
+void spmi_dump_pmif_reg(int mstid)
+{
+ struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
+ unsigned int i = 0, offset = 0, tmp_dat = 0;
+ unsigned int start = 0, end = 0;
+
+ start = arb->dbgregs[PMIF_INIT_DONE]/4;
+ end = arb->dbgregs[PMIF_RESERVED_0]/4;
+
+ PMIF_CRI("");
+ for (i = start; i <= end; i++) {
+ offset = arb->dbgregs[PMIF_INIT_DONE] + (i * 4);
+ tmp_dat = DRV_Reg32(arb->base + offset);
+ PMIF_CRIL("(0x%x)=0x%x ", offset, tmp_dat);
+
+ if (i == 0)
+ continue;
+ if (i % 8 == 0) {
+ PMIF_CRIL("\r\n[PMIF] ");
+ }
+ }
+ PMIF_CRIL("\r\n");
+ spmi_dump_pmif_swinf_reg(mstid);
+}
+
+void spmi_dump_pmif_record_reg(int mstid)
+{
+ struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
+ unsigned int i = 0, offset = 0, j = 0, tmp_dat = 0;
+ unsigned int chan[32] = {0}, cmd[32] = {0}, rw[32] = {0};
+ unsigned int slvid[32] = {0}, bytecnt[32] = {0}, adr[32] = {0};
+#if 0
+/* under construction !*/
+#endif
+ unsigned int wd_31_0[32] = {0};
+
+ for (i = 0; i < 32; i++) {
+ offset = arb->dbgregs[PMIF_MONITOR_RECORD_0_0] + (i * 0x14);
+ tmp_dat = DRV_Reg32(arb->base + offset);
+ chan[j] = (tmp_dat & (0xf8000000)) >> 27;
+ cmd[j] = (tmp_dat & (0x3 << 25)) >> 25;
+ rw[j] = (tmp_dat & (0x1 << 24)) >> 24;
+ slvid[j] = (tmp_dat & (0xf << 20)) >> 20;
+ bytecnt[j] = (tmp_dat & (0xf << 16)) >> 16;
+ adr[j] = (tmp_dat & (0xffff << 0)) >> 0;
+ j += 1;
+ }
+ j = 0;
+ for (i = 0; i < 32; i++) {
+ offset = arb->dbgregs[PMIF_MONITOR_RECORD_0_1] + (i * 0x14);
+ tmp_dat = DRV_Reg32(arb->base + offset);
+ wd_31_0[j] = tmp_dat;
+ j += 1;
+ }
+
+ for (i = 0; i < 32; i++) {
+ SPMI_CRI("[swinf:%d, cmd:0x%x, rw:0x%x, slvid:%d ",
+ chan[i], cmd[i], rw[i], slvid[i]);
+ SPMI_CRIL("bytecnt:%d (adr 0x%04x=0x%x)]\r\n",
+ bytecnt[i], adr[i], wd_31_0[i]);
+ }
+ spmi_dump_pmif_swinf_reg(mstid);
+
+ /* clear record data and re-enable */
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_MONITOR_CTRL], 0x800);
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_MONITOR_CTRL], 0x5);
+}
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+/* under construction !*/
+#endif
+void spmi_dump_spmimst_reg(int mstid)
+{
+ struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
+ unsigned int i = 0, offset = 0, tmp_dat = 0;
+ unsigned int start = 0, end = 0;
+
+ start = arb->spmimst_regs[SPMI_OP_ST_CTRL]/4;
+ end = arb->spmimst_regs[SPMI_REC4]/4;
+
+ SPMI_CRI("");
+ for (i = start; i <= end; i++) {
+ offset = arb->spmimst_regs[SPMI_OP_ST_CTRL] + (i * 4);
+ tmp_dat = DRV_Reg32(arb->spmimst_base + offset);
+ SPMI_CRIL("(0x%x)=0x%x ", offset, tmp_dat);
+
+ if (i == 0)
+ continue;
+ if (i % 8 == 0) {
+ SPMI_CRIL("\r\n[SPMI] ");
+ }
+ }
+#if SPMI_RCS_SUPPORT
+ offset = arb->spmimst_regs[SPMI_DEC_DBG];
+ tmp_dat = DRV_Reg32(arb->spmimst_base + offset);
+ SPMI_CRIL("(0x%x)=0x%x ", offset, tmp_dat);
+#endif
+ offset = arb->spmimst_regs[SPMI_MST_DBG];
+ tmp_dat = DRV_Reg32(arb->spmimst_base + offset);
+ SPMI_CRIL("(0x%x)=0x%x ", offset, tmp_dat);
+ SPMI_CRIL("\r\n");
+}
+
+void spmi_dump_slv_record_reg(struct spmi_device *dev)
+{
+ unsigned char rdata1 = 0, rdata2 = 0, rdata3 = 0, rdata4 = 0;
+ unsigned int offset, i, j = 0;
+
+ /* log sequence, idx 0->1->2->3->0 */
+ for (offset = 0x34; offset < 0x50; offset += 4)
+ {
+ spmi_ext_register_readl(dev,
+ (MT6315_PLT0_ID_ANA_ID + offset), &rdata1, 1);
+ spmi_ext_register_readl(dev,
+ (MT6315_PLT0_ID_ANA_ID + offset + 1), &rdata2, 1);
+ spmi_ext_register_readl(dev,
+ (MT6315_PLT0_ID_ANA_ID + offset + 2), &rdata3, 1);
+ spmi_ext_register_readl(dev,
+ (MT6315_PLT0_ID_ANA_ID + offset + 3), &rdata4, 1);
+ if ((offset + 3) == 0x37) {
+ i = (rdata4 & 0xc) >> 2;
+ if (i == 0)
+ SPMI_CRI("slvid:%d DBG. Last cmd idx:0x3\r\n",
+ dev->slvid);
+ else {
+ SPMI_CRI("slvid:%d DBG. Last cmd idx:0x%x\r\n",
+ dev->slvid, ((rdata4 & 0xc) >> 2) - 1);
+ }
+
+ }
+ /*
+ *SPMI_CRI("[0x%x]=0x%x [0x%x]=0x%x [0x%x]=0x%x [0x%x]=0x%x ",
+ * offset, rdata1, (offset + 1), rdata2,
+ * (offset + 2), rdata3, (offset + 3), rdata4);
+ */
+
+ SPMI_CRI("Idx:%d slvid:%d Type:0x%x, [0x%x]=0x%x\r\n", j,
+ dev->slvid, (rdata4 & 0x3),
+ (rdata2 << 0x8) | rdata1, rdata3);
+ if (j <= 3)
+ j++;
+
+ }
+}
+
+int spmi_pmif_dbg_init(struct pmif *arb)
+{
+#if PMIF_MATCH_SUPPORT
+ unsigned int int_en = 0;
+#endif
+ arb->dbgregs = mt6xxx_pmif_dbg_regs;
+#if PMIF_MATCH_SUPPORT
+ /* enable matching mode */
+ PMIF_CRI("PMIF Matching Mode\n");
+
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_IRQ_CLR_0], 0xffffffff);
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_IRQ_CLR_1], 0xffffffff);
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_IRQ_CLR_2], 0xffffffff);
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_IRQ_CLR_3], 0xffffffff);
+
+ int_en = DRV_Reg32(arb->base + arb->dbgregs[PMIF_IRQ_EVENT_EN_3]);
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_IRQ_EVENT_EN_3],
+ int_en | (0x1 << 7));
+
+ /* set monitor channel, should same as ARB_EN */
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_MONITOR_TARGET_CHAN_0],
+ 0x2f5);
+ /* [31:16] addr mask, ffff mean all bit check
+ * [15:0] addr, which addr been checked
+ */
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_MONITOR_TARGET_ADDR_0],
+ 0xffff03a5);
+ /* [31:16] wdata mask, ffff mean all bit check
+ * [15:0] data, which data been checked
+ */
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_MONITOR_TARGET_WDATA_0],
+ 0xffff005a);
+ /*
+ * BIT[0] MONITOR_TARGET_WRITE_0
+ * BIT[1] MONITOR_TARGET_WRITE_0_MASK: 0, rw all check, 1, check
+ * BIT[0] if BIT[0] = 0, only check read;otherwise only check write.
+ */
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_MONITOR_TARGET_WRITE],
+ 0x3);
+ /* reset then enable */
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_MONITOR_CTRL], 0x800);
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_MONITOR_CTRL], 0x405);
+#else
+ /* init pmif debug mechanism, hw matching mode or sw logging mode */
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_MONITOR_TARGET_CHAN_0],
+ 0x2f5);
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_MONITOR_TARGET_ADDR_0],
+ 0x0);
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_MONITOR_TARGET_WDATA_0],
+ 0x0);
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_MONITOR_TARGET_WRITE],
+ 0x001);
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_MONITOR_CTRL], 0x800);
+ DRV_WriteReg32(arb->base + arb->dbgregs[PMIF_MONITOR_CTRL], 0x5);
+#endif /* end of PMIF_MATCH_SUPPORT */
+ return 0;
+}
+#endif /* endif SPMI_NO_PMIC */