blob: 359cc683c31da06be96b2e760733a68e45f60b8a [file] [log] [blame]
/*****************************************************************************
* 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) 2012
*
* 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_rstctl.c
*
* Project:
* --------
* Maui_Software
*
* Description:
* ------------
* This Module defines DCL (Driver Common Layer) of the wdt driver.
*
* Author:
* -------
* -------
*
*============================================================================
* HISTORY
* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*------------------------------------------------------------------------------
*
*
*------------------------------------------------------------------------------
* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*============================================================================
****************************************************************************/
#include "drv_comm.h"
#include "rstctl_reg.h"
#include "drv_rstctl.h"
#include "intrCtrl.h"
#include "dcl_wdt.h"
#include "dcl.h"
#include "kal_general_types.h"
#include "kal_public_api.h"
#include "kal_internal_api.h"
#include "kal_ex_api.h"
/*Begin: for share memory debug information dump*/
#include "ex_mem_manager_public.h"
#include "ex_public.h"
#include "ccci_if.h"
#include "us_timer.h"
/*End: for share memory debug information dump*/
#if defined(MT6290_S00)
#include "drv_bsi.h"
#define PMIC_6339_ANALDO_CON1_ADDR (0x21)
/*VTCXO1_ON_CTRL : 0: SW controll by RG_VTXCO1_EN*/
/* 1: SRCLKEN */
#define VTCXO1_ON_CTRL_BIT (0x1)
/*RG_VTCXO1_EN : 0: Disable */
/* 1: Enable */
#define RG_VTCXO1_EN_BIT (0x0)
#endif
// Global variable for DCL WDT API usage
#define DCL_WDT_DEV_MAGIC_NUM (0x80000000)
#define DCL_WDT_GET_DEV(handle_) ((handle_) & (~DCL_WDT_DEV_MAGIC_NUM))
kal_atomic_uint32 dcl_wdt_handle_count = 0;
// The event is presented by 32-bit variable
kal_atomic_uint32 handle_assign[32];
#define MAX_DCL_WDT_EVENT_NUM 1
PFN_DCL_CALLBACK dcl_wdt_event_callback[MAX_DCL_WDT_EVENT_NUM];
void dcl_wdt_hisr(){
// Try to call rgistered callback function
// Search mapping array and assign callback to specofic array entry
{
kal_uint32 i;
kal_uint32 event_bit;
// TODO: integrate the code bellow in the call back function mechanism.
for (i=0;i<MAX_DCL_WDT_EVENT_NUM;i++){
event_bit = 1 << i;
if ((event_bit & EVENT_WDT_TIMEOUT) != 0){
if (dcl_wdt_event_callback[i] != NULL){
dcl_wdt_event_callback[i](EVENT_WDT_TIMEOUT);
}
}
}
}
}
#if defined(MT6297)
void dcl_wdt_ap2md_wdt_lisr()
{
// Just Need to Trigger Fatal Error !!!
kal_fatal_error_handler(KAL_ERROR_CC_SAP_WDT_TIMEOUT_EXCP, 0);
}
void dcl_wdt_register_ap2md_wdt_isr()
{
//IRQ_Register_LISR(IRQ_AP2MD_APWDT_IRQ_CODE, dcl_wdt_ap2md_wdt_lisr, "AP2MD WDT LISR");
//IRQSensitivity(IRQ_AP2MD_APWDT_IRQ_CODE, KAL_FALSE); // Low Level Active
IRQUnmask(IRQ_AP2MD_APWDT_IRQ_CODE);
}
#else
#define dcl_wdt_register_ap2md_wdt_isr()
#endif
void dcl_wdt_lisr()
{
mips_isr_mdwdt_handler();
}
void dcl_wdt_register_md_wdt_isr()
{
//IRQ_Register_LISR(IRQ_MDWDT_CODE, dcl_wdt_lisr,"DCL WDT LISR");
//IRQSensitivity(IRQ_MDWDT_CODE,KAL_TRUE);
IRQUnmask(IRQ_MDWDT_CODE);
}
kal_bool dcl_wdt_lisr_register_flag = KAL_FALSE;
void dcl_wdt_register_lisr(){
if (dcl_wdt_lisr_register_flag){
return;
}
dcl_wdt_register_md_wdt_isr();
dcl_wdt_register_ap2md_wdt_isr();
dcl_wdt_lisr_register_flag=KAL_TRUE;
}
/*************************************************************************
* FUNCTION
* DclWDT_Initialize
*
* DESCRIPTION
* This function is to initialize WDT module
*
* PARAMETERS
* N/A
*
* RETURNS
* STATUS_OK
*
*************************************************************************/
DCL_STATUS DclWDT_Initialize(void)
{
kal_uint8 count = 0;
drv_rstctl_wdt_init();
for(count=0;count<32;count++)
kal_atomic_set(&(handle_assign[count]), 0);
kal_atomic_set(&dcl_wdt_handle_count, 0);
return STATUS_OK;
}
/*************************************************************************
* FUNCTION
* DclWDT_Open
*
* DESCRIPTION
* This function is to open the WDT module and return a handle
*
* PARAMETERS
* dev: only valid for DCL_WDT
* flags: no sepcial flags is needed. Please use FLAGS_NONE
*
* RETURNS
* DCL_HANDLE_INVALID: Open failed.
* other value: a valid handle
*
*************************************************************************/
DCL_HANDLE DclWDT_Open(DCL_DEV dev, DCL_FLAGS flags)
{
kal_uint32 handle;
kal_uint8 index=0;
if (dev != DCL_WDT){
return DCL_HANDLE_INVALID; // Incorrecr device ID
}
for(index=0;index<32;index++)
{
if(kal_atomic_compare_and_swap_return(&handle_assign[index],0,1)==0)
break;
}
if (index==32)
return DCL_HANDLE_INVALID;
kal_atomic_inc(&dcl_wdt_handle_count);
handle = (DCL_WDT_DEV_MAGIC_NUM | index);
// Register DCL default lisr
return handle;
}
/*************************************************************************
* FUNCTION
* DclWDT_ReadData
*
* DESCRIPTION
* This function is not supported for the WDT module now.
*
* PARAMETERS
* N/A
*
* RETURNS
* STATUS_UNSUPPORTED
*
*************************************************************************/
DCL_STATUS DclWDT_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
{
return STATUS_UNSUPPORTED;
}
/*************************************************************************
* FUNCTION
* DclWDT_WriteData
*
* DESCRIPTION
* This function is not supported for the WDT module now.
*
* PARAMETERS
* N/A
*
* RETURNS
* STATUS_UNSUPPORTED
*
*************************************************************************/
DCL_STATUS DclWDT_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
{
return STATUS_UNSUPPORTED;
}
/*************************************************************************
* FUNCTION
* DclWDT_Configure
*
* DESCRIPTION
* This function is not supported for the WDT module now.
*
* PARAMETERS
* N/A
*
* RETURNS
* STATUS_UNSUPPORTED
*
*************************************************************************/
DCL_STATUS DclWDT_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
{
return STATUS_UNSUPPORTED;
}
/*************************************************************************
* FUNCTION
* DclWDT_RegisterCallback
*
* DESCRIPTION
* This function is to set callback function for the WDT module.
*
* PARAMETERS
* handle: the returned handle value of DclWDT_Open
* event: Supported events:
* EVENT_WDT_TIMEOUT: Watch dog time out interrupt
* callback: the callback function for registered events
*
* RETURNS
* STATUS_OK: Successfully register the callback function.
* STATUS_INVALID_DCL_HANDLE: It's a invalid handle.
* STATUS_NOT_OPENED: The module has not been opened.
* STATUS_INVALID_EVENT: The event parameter is invalid.
*
*************************************************************************/
DCL_STATUS DclWDT_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
{
//kal_uint32 i;
// Check magic number
if ((handle & DCL_WDT_DEV_MAGIC_NUM) != DCL_WDT_DEV_MAGIC_NUM){
DEBUG_ASSERT(0);
return STATUS_INVALID_DCL_HANDLE;
}
// Error check
if (kal_atomic_read(&dcl_wdt_handle_count) == 0){
DEBUG_ASSERT(0);
return STATUS_NOT_OPENED;
}
// Check if the passed-in event bitmap is supported or NOT
if (((kal_uint32)event & (~(EVENT_WDT_TIMEOUT))) != 0){
DEBUG_ASSERT(0);
return STATUS_INVALID_EVENT;
}
//i=DCL_WDT_GET_DEV(handle);
dcl_wdt_register_lisr();
return STATUS_OK;
}
/*************************************************************************
* FUNCTION
* DclWDT_Control
*
* DESCRIPTION
* This function is to send command to control the WDT module.
*
* PARAMETERS
* handle: The handle value returned from DclWDT_Open
* cmd: a control command for WDT module
* 1. WDT_CMD_ENABLE: to enable/disable WDT
* 2. WDT_CMD_SET_EXT_POL: to set ploarity of external pin when WDT expired
* 3. WDT_CMD_SET_EXT_RESET: to generate an external watchdog reset signal when WDT expired
* 4. WDT_CMD_SET_VALUE: to set WDT count value
* 5 WDT_CMD_RESTART: to restart counter
* 6. WDT_CMD_DRV_RESET: to reset device
* 7. WDT_CMD_ABN_RESET: to reset device with abnormal flag set to indicate it is a abnormal reset
* 8. WDT_CMD_IRQ: to generate interrupt instead of reseting device
* data: The data of the control command
* 1. WDT_CMD_ENABLE: pointer to a WDT_CTRL_ENABLE_T structure
* 2. WDT_CMD_SET_EXT_POL: pointer to a WDT_CTRL_SET_EXT_POL_T structure
* 3. WDT_CMD_SET_EXT_RESET: pointer to a WDT_CTRL_SET_EXT_RESET_T structure
* 4. WDT_CMD_SET_VALUE: pointer to a WDT_CTRL_SET_VALUE_T structure
* 5 WDT_CMD_RESTART: A null pointer
* 6. WDT_CMD_DRV_RESET: A null pointer
* 7. WDT_CMD_ABN_RESET: A null pointer
* 8. WDT_CMD_IRQ: pointer to a WDT_CTRL_IRQ_T structure
*
* RETURNS
* STATUS_OK: command is executed successfully.
* STATUS_FAIL: command is failed.
* STATUS_INVALID_CMD: It's a invalid command.
*
*************************************************************************/
DCL_STATUS DclWDT_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
{
WDT_CTRL_GET_RSTINTERVAL_T *prst;
WDT_CTRL_SET_VALUE_T *prSetValue;
WDT_CTRL_ENABLE_T *prEnable;
WDT_CTRL_IRQ_T *prIRQ;
WDT_CTRL_DEBUG_T *prWDTDebug;
/*Begin: preserve debug information in share memory. */
volatile kal_uint32 callerAddr;
volatile kal_uint32 callerVPE;
volatile kal_uint32 usTime;
/*End: preserve debug information in share memory. */
#if defined(MT6290_S00)
kal_uint16 val;
#endif
if (sst_get_exception_count() == 0) {
// Check magic number
if ((handle & DCL_WDT_DEV_MAGIC_NUM) != DCL_WDT_DEV_MAGIC_NUM){
DEBUG_ASSERT(0);
return STATUS_INVALID_DCL_HANDLE;
}
// Error check
if (kal_atomic_read(&dcl_wdt_handle_count) == 0){
DEBUG_ASSERT(0);
return STATUS_NOT_OPENED;
}
}
/*Begin: preserve debug information in share memory. */
GET_RETURN_ADDRESS(callerAddr);
callerVPE = kal_get_current_vpe_id();
usTime = ust_get_current_time();
/*End: preserve debug information in share memory. */
switch (cmd)
{
case WDT_CMD_ENABLE:
prEnable = &(data->rWDTEnable);
/*Begin: preserve debug information in share memory. */
if(prEnable->fgEnable)
{
EMM_WriteDbgInfo(EMM_WDT1_EN_CALLER, (void*)&callerAddr);
EMM_WriteDbgInfo(EMM_WDT1_EN_TIME, (void*)&usTime);
EMM_WriteDbgInfo(EMM_WDT2_EN_CALLER, (void*)&callerAddr);
EMM_WriteDbgInfo(EMM_WDT2_EN_TIME, (void*)&usTime);
}
else
{
EMM_WriteDbgInfo(EMM_WDT1_DIS_CALLER, (void*)&callerAddr);
EMM_WriteDbgInfo(EMM_WDT1_DIS_TIME, (void*)&usTime);
EMM_WriteDbgInfo(EMM_WDT2_DIS_CALLER, (void*)&callerAddr);
EMM_WriteDbgInfo(EMM_WDT2_DIS_TIME, (void*)&usTime);
}
/*End: preserve debug information in share memory. */
drv_rstctl_wdt_enable((kal_bool)prEnable->fgEnable);
drv_rstctl_wdt_enable_aux((kal_bool)prEnable->fgEnable);
break;
case WDT_CMD_SET_EXT_POL:
//MT6290 wait for new feature release
break;
case WDT_CMD_SET_EXT_RESET:
//MT6290 wait for new feature release
break;
case WDT_CMD_SET_VALUE:
prSetValue = &(data->rWDTSetValue);
drv_rstctl_wdt_setInterval(prSetValue->u2Value);
drv_rstctl_wdt_setInterval_aux(prSetValue->u2Value);
break;
case WDT_CMD_RESTART:
drv_rstctl_restartWDT();
break;
case WDT_CMD_DRV_RESET:
/*Begin: preserve debug information in share memory. */
EMM_WriteDbgInfo(EMM_WDT_DRV_RST_CALLER, (void*)&callerAddr);
EMM_WriteDbgInfo(EMM_WDT_DRV_RST_TIME, (void*)&usTime);
/*End: preserve debug information in share memory. */
drv_rstctl_wdt_reset();
break;
case WDT_CMD_GET_RSTINTERVAL:
prst = &(data->rRstValue);
prst->rstInterval = drv_rstctl_wd_getInterval();
break;
case WDT_CMD_GET_RSTINTERVAL_AUX:
prst = &(data->rRstValue);
prst->rstInterval = drv_rstctl_wd_getInterval_aux();
break;
case WDT_CMD_ABN_RESET:
/*Begin: preserve debug information in share memory. */
EMM_WriteDbgInfo(EMM_WDT_ABN_RST_CALLER, (void*)&callerAddr);
EMM_WriteDbgInfo(EMM_WDT_ABN_RST_TIME, (void*)&usTime);
/*End: preserve debug information in share memory. */
drv_rstctl_wdt_abnReset();
break;
case WDT_CMD_IRQ:
prIRQ = &(data->rWDTIRQ);
drv_rstctl_wdt_enableInterrupt((kal_bool)prIRQ->fgEnable);
break;
case WDT_CMD_IRQ_AUX:
prIRQ = &(data->rWDTIRQ);
drv_rstctl_wdt_enableInterrupt_aux((kal_bool)prIRQ->fgEnable);
break;
case WDT_CMD_ENABLE_DEBUG:
prWDTDebug=&(data->rWDTDebug);
drv_rstctl_wdt_enableDebugMode(prWDTDebug->fgEnable);
break;
case WDT_CMD_CLR_CHECK:
prSetValue = &(data->rWDTSetValue);
EMM_WriteDbgInfo(EMM_VPE0_WDT_CLR_CHK_CALLER + ((prSetValue->u2Value)*3), (void*)&callerAddr);
EMM_WriteDbgInfo(EMM_VPE0_WDT_CLR_CHK_CALLERVPE + ((prSetValue->u2Value)*3), (void*)&callerVPE);
EMM_WriteDbgInfo(EMM_VPE0_WDT_CLR_CHK_TIME + ((prSetValue->u2Value)*3), (void*)&usTime);
drv_rstctl_clr_check_bit(prSetValue->u2Value);
break;
case WDT_CMD_SET_CHECK:
prSetValue = &(data->rWDTSetValue);
EMM_WriteDbgInfo(EMM_VPE0_WDT_SET_CHK_CALLER + ((prSetValue->u2Value)*3), (void*)&callerAddr);
EMM_WriteDbgInfo(EMM_VPE0_WDT_SET_CHK_CALLERVPE + ((prSetValue->u2Value)*3), (void*)&callerVPE);
EMM_WriteDbgInfo(EMM_VPE0_WDT_SET_CHK_TIME + ((prSetValue->u2Value)*3), (void*)&usTime);
drv_rstctl_set_check_bit(prSetValue->u2Value);
break;
case WDT_CMD_CLR_KICK:
prSetValue = &(data->rWDTSetValue);
drv_rstctl_clr_kick_bit(prSetValue->u2Value);
break;
case WDT_CMD_SET_KICK:
prSetValue = &(data->rWDTSetValue);
drv_rstctl_set_kick_bit(prSetValue->u2Value);
break;
default:
return STATUS_INVALID_CMD;
}
return STATUS_OK;
}
/*************************************************************************
* FUNCTION
* DclWDT_Close
*
* DESCRIPTION
* This function is to close the WDT module.
*
* PARAMETERS
* handle: the returned handle value of DclWDT_Open
*
* RETURNS
* STATUS_OK
*
*************************************************************************/
DCL_STATUS DclWDT_Close(DCL_HANDLE handle)
{
kal_uint32 i;
// Check magic number
if ((handle & DCL_WDT_DEV_MAGIC_NUM) != DCL_WDT_DEV_MAGIC_NUM){
DEBUG_ASSERT(0);
return STATUS_INVALID_DCL_HANDLE;
}
// Error check
if (kal_atomic_read(&dcl_wdt_handle_count) == 0){
DEBUG_ASSERT(0);
return STATUS_NOT_OPENED;
}
/*
// Clear all registered event callbacks for the specific handle
// Note: If we support multiple handles, we need to take care of the clear
{
kal_uint32 i;
for (i=0;i<MAX_DCL_WDT_EVENT_NUM;i++){
dcl_wdt_event_callback[i] = NULL;
}
}
*/
i=(handle & ~DCL_WDT_DEV_MAGIC_NUM);
kal_atomic_set(&(handle_assign[i]), 0);
dcl_wdt_event_callback[i%MAX_DCL_WDT_EVENT_NUM] = NULL;
kal_atomic_dec(&dcl_wdt_handle_count);
return STATUS_OK;
}